import_dscs.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # vim: set fileencoding=utf-8 :
  2. #
  3. # (C) 2008, 2009, 2010 Guido Guenther <agx@sigxcpu.org>
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, please see
  16. # <http://www.gnu.org/licenses/>
  17. """Import multiple dsc files into Git in one go"""
  18. import glob
  19. import os
  20. import sys
  21. import tempfile
  22. import gbp.command_wrappers as gbpc
  23. from gbp.deb import DpkgCompareVersions
  24. from gbp.deb.dscfile import DscFile
  25. from gbp.errors import GbpError
  26. from gbp.git import GitRepository, GitRepositoryError
  27. from gbp.scripts import import_dsc
  28. from gbp.config import GbpOptionParser
  29. import gbp.log
  30. class DscCompareVersions(DpkgCompareVersions):
  31. def __init__(self):
  32. DpkgCompareVersions.__init__(self)
  33. def __call__(self, dsc1, dsc2):
  34. return DpkgCompareVersions.__call__(self, dsc1.version, dsc2.version)
  35. class GitImportDsc(object):
  36. def __init__(self, args):
  37. self.args = args
  38. def importdsc(self, dsc):
  39. return import_dsc.main(['import-dsc'] + self.args + [dsc.dscfile])
  40. def fetch_snapshots(pkg, downloaddir):
  41. "Fetch snapshots using debsnap from snapshots.debian.org"
  42. dscs = None
  43. gbp.log.info("Downloading snapshots of '%s' to '%s'..." %
  44. (pkg, downloaddir))
  45. debsnap = gbpc.Command("debsnap", ['--force', '--destdir=%s' %
  46. (downloaddir), pkg])
  47. try:
  48. debsnap()
  49. except gbpc.CommandExecFailed:
  50. if debsnap.retcode == 2:
  51. gbp.log.warn("Some packages failed to download. Continuing.")
  52. pass
  53. else:
  54. raise
  55. dscs = glob.glob(os.path.join(downloaddir, '*.dsc'))
  56. if not dscs:
  57. raise GbpError('No package downloaded')
  58. return [os.path.join(downloaddir, dsc) for dsc in dscs]
  59. def set_gbp_conf_files():
  60. """
  61. Filter out all gbp.conf files that are local to the git repository and set
  62. GBP_CONF_FILES accordingly so gbp import-dsc will only use these.
  63. """
  64. global_config = GbpOptionParser.get_config_files(no_local=True)
  65. gbp_conf_files = ':'.join(global_config)
  66. os.environ['GBP_CONF_FILES'] = gbp_conf_files
  67. gbp.log.debug("Setting GBP_CONF_FILES to '%s'" % gbp_conf_files)
  68. def print_help():
  69. print("""Usage: gbp import-dscs [options] [gbp-import-dsc options] /path/to/dsc1 [/path/to/dsc2] ...
  70. gbp import-dscs --debsnap [options] [gbp-import-dsc options] package
  71. Options:
  72. --debsnap: use debsnap command to download packages
  73. --ignore-repo-config ignore gbp.conf in git repo
  74. """)
  75. def main(argv):
  76. dirs = dict(top=os.path.abspath(os.curdir))
  77. dscs = []
  78. ret = 0
  79. verbose = False
  80. dsc_cmp = DscCompareVersions()
  81. use_debsnap = False
  82. try:
  83. import_args = argv[1:]
  84. if '--verbose' in import_args:
  85. verbose = True
  86. gbp.log.setup(False, verbose)
  87. if '--ignore-repo-config' in import_args:
  88. set_gbp_conf_files()
  89. import_args.remove('--ignore-repo-config')
  90. # Not using Configparser since we want to pass all unknown options
  91. # unaltered to gbp import-dsc
  92. if '--debsnap' in import_args:
  93. use_debsnap = True
  94. import_args.remove('--debsnap')
  95. if import_args == []:
  96. print_help()
  97. raise GbpError
  98. pkg = import_args[-1]
  99. import_args = import_args[:-1]
  100. else:
  101. for arg in argv[::-1]:
  102. if arg.endswith('.dsc'):
  103. dscs.append(DscFile.parse(arg))
  104. import_args.remove(arg)
  105. if not use_debsnap and not dscs:
  106. print_help()
  107. raise GbpError
  108. if use_debsnap:
  109. dirs['tmp'] = os.path.abspath(tempfile.mkdtemp())
  110. dscs = [DscFile.parse(f) for f in fetch_snapshots(pkg, dirs['tmp'])]
  111. dscs.sort(cmp=dsc_cmp)
  112. importer = GitImportDsc(import_args)
  113. try:
  114. repo = GitRepository('.')
  115. (clean, out) = repo.is_clean()
  116. if not clean:
  117. gbp.log.err("Repository has uncommitted changes, "
  118. "commit these first: ")
  119. raise GbpError(out)
  120. else:
  121. dirs['pkg'] = dirs['top']
  122. except GitRepositoryError:
  123. # no git repository there yet
  124. dirs['pkg'] = os.path.join(dirs['top'], dscs[0].pkg)
  125. if importer.importdsc(dscs[0]):
  126. raise GbpError("Failed to import '%s'" % dscs[0].dscfile)
  127. os.chdir(dirs['pkg'])
  128. for dsc in dscs[1:]:
  129. if importer.importdsc(dsc):
  130. raise GbpError("Failed to import '%s'" % dscs[0].dscfile)
  131. except KeyboardInterrupt:
  132. ret = 1
  133. gbp.log.err("Interrupted. Aborting.")
  134. except (GbpError, gbpc.CommandExecFailed, GitRepositoryError) as err:
  135. if str(err):
  136. gbp.log.err(err)
  137. ret = 1
  138. finally:
  139. if 'tmp' in dirs:
  140. gbpc.RemoveTree(dirs['tmp'])()
  141. os.chdir(dirs['top'])
  142. if not ret:
  143. gbp.log.info('Everything imported under %s' % dirs['pkg'])
  144. return ret
  145. if __name__ == '__main__':
  146. sys.exit(main(sys.argv))
  147. # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: