archiver_3_5.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. def create_archive(self, scm_object, **kwargs):
  2. """Create Debian source artefacts using git-buildpackage.
  3. """
  4. args = kwargs['cli']
  5. version = kwargs['version']
  6. (workdir, topdir) = os.path.split(scm_object.clone_dir)
  7. cwd = os.getcwd()
  8. os.chdir(workdir)
  9. if not args.revision:
  10. revision = 'origin/master'
  11. else:
  12. revision = 'origin/' + args.revision
  13. command = ['gbp', 'buildpackage', '--git-notify=off',
  14. '--git-force-create', '--git-cleaner="true"']
  15. # we are not on a proper local branch due to using git-reset but we
  16. # anyway use the --git-export option
  17. command.extend(['--git-ignore-branch',
  18. "--git-export=%s" % revision])
  19. # gbp can load submodules without having to run the git command, and
  20. # will ignore submodules even if loaded manually unless this option is
  21. # passed.
  22. if args.submodules:
  23. command.extend(['--git-submodules'])
  24. # create local pristine-tar branch if present
  25. ret, output = self.helpers.run_cmd(['git', 'rev-parse', '--verify',
  26. '--quiet', 'origin/pristine-tar'],
  27. cwd=scm_object.clone_dir)
  28. if not ret:
  29. ret, output = self.helpers.run_cmd(['git', 'update-ref',
  30. 'refs/heads/pristine-tar',
  31. 'origin/pristine-tar'],
  32. cwd=scm_object.clone_dir)
  33. if not ret:
  34. command.append('--git-pristine-tar')
  35. else:
  36. command.append('--git-no-pristine-tar')
  37. else:
  38. command.append('--git-no-pristine-tar')
  39. # Prevent potentially dangerous arguments from being passed to gbp,
  40. # e.g. via cleaner, postexport or other hooks.
  41. if args.gbp_build_args:
  42. build_args = args.gbp_build_args.split(' ')
  43. safe_args = re.compile(
  44. '--git-verbose|--git-upstream-tree=.*|--git-no-pristine-tar')
  45. p = re.compile('--git-.*|--hook-.*|--.*-hook=.*')
  46. gbp_args = [arg for arg in build_args if safe_args.match(arg)]
  47. dpkg_args = [arg for arg in build_args if not p.match(arg)]
  48. ignored_args = list(set(build_args) - set(gbp_args + dpkg_args))
  49. if ignored_args:
  50. logging.info("Ignoring build_args: %s" % ignored_args)
  51. command.extend(gbp_args + dpkg_args)
  52. # Set the version in the changelog. Note that we can't simply use
  53. # --source-option=-Dversion=$ver as it will not change the tarball
  54. # name, which means dpkg-source -x pkg.dsc will fail as the names
  55. # and version will not match
  56. cl_path = os.path.join(scm_object.clone_dir, 'debian', 'changelog')
  57. skip_versions = ['', '_none_', '_auto_', None]
  58. if (os.path.isfile(cl_path) and version not in skip_versions):
  59. # Some characters are legal in Debian's versions but not in a git
  60. # tag, so they get substituted
  61. version = re.sub(r'_', r'~', version)
  62. version = re.sub(r'%', r':', version)
  63. with open(cl_path, 'r') as cl:
  64. lines = cl.readlines()
  65. old_version = re.search(r'.+ \((.+)\) .+', lines[0]).group(1)
  66. # non-native packages MUST have a debian revision (-xyz)
  67. drev_ov = re.search(r'-', old_version)
  68. drev_v = re.search(r'-', version)
  69. if (drev_ov is not None and drev_v) is None:
  70. logging.warning("Package is non-native but requested version"
  71. " %s is native! Ignoring.", version)
  72. else:
  73. with open(cl_path, 'w+') as cl:
  74. # A valid debian changelog has 'package (version) release'
  75. # as the first line, if it's malformed we don't care as it
  76. # will not even build
  77. logging.debug("Setting version to %s", version)
  78. # gbp by default complains about uncommitted changes
  79. command.append("--git-ignore-new")
  80. lines[0] = re.sub(r'^(.+) \(.+\) (.+)',
  81. r'\1 (%s) \2' % version, lines[0])
  82. cl.write("".join(lines))
  83. logging.debug("Running in %s", scm_object.clone_dir)
  84. self.helpers.safe_run(command, cwd=scm_object.clone_dir)
  85. # Use dpkg to find out what source artefacts have been built and copy
  86. # them back, which allows the script to be future-proof and work with
  87. # all present and future package formats
  88. sources = self.helpers.safe_run(['dpkg-scansources', workdir],
  89. cwd=workdir)[1]
  90. FILES_PATTERN = re.compile(
  91. r'^Files:(.*(?:\n .*)+)', flags=re.MULTILINE)
  92. for match in FILES_PATTERN.findall(sources):
  93. logging.info("Files:")
  94. for line in match.strip().split("\n"):
  95. fname = line.strip().split(' ')[2]
  96. logging.info(" %s", fname)
  97. input_file = os.path.join(workdir, fname)
  98. output_file = os.path.join(args.outdir, fname)
  99. filename_matches_dsc = fnmatch.fnmatch(fname, '*.dsc')
  100. if (args.gbp_dch_release_update and filename_matches_dsc):
  101. # This tag is used by the build-recipe-dsc to set the OBS
  102. # revision: https://github.com/openSUSE/obs-build/pull/192
  103. logging.debug("Setting OBS-DCH-RELEASE in %s", input_file)
  104. with open(input_file, "a") as dsc_file:
  105. dsc_file.write("OBS-DCH-RELEASE: 1")
  106. shutil.copy(input_file, output_file)
  107. os.chdir(cwd)