diff options
-rw-r--r-- | docs/manpages/gbp-buildpackage.xml | 2 | ||||
-rw-r--r-- | docs/manpages/gbp-export-orig.xml | 2 | ||||
-rw-r--r-- | gbp/deb/git.py | 6 | ||||
-rw-r--r-- | gbp/pkg/pkgpolicy.py | 38 | ||||
-rwxr-xr-x | gbp/scripts/buildpackage.py | 5 | ||||
-rwxr-xr-x | gbp/scripts/export_orig.py | 5 | ||||
-rw-r--r-- | tests/component/deb/test_buildpackage.py | 21 | ||||
-rw-r--r-- | tests/component/deb/test_export_orig.py | 25 |
8 files changed, 99 insertions, 5 deletions
diff --git a/docs/manpages/gbp-buildpackage.xml b/docs/manpages/gbp-buildpackage.xml index d25f5c89..c59be845 100644 --- a/docs/manpages/gbp-buildpackage.xml +++ b/docs/manpages/gbp-buildpackage.xml @@ -222,6 +222,8 @@ Search for upstream tarballs in <replaceable>DIRECTORY</replaceable> instead of generating them. If a tarball is not found here it will be generated nevertheless. + <replaceable>DIRECTORY</replaceable> can contain a version format + substitution pattern, eg: <replaceable>foo-%(version)s</replaceable>. </para> </listitem> </varlistentry> diff --git a/docs/manpages/gbp-export-orig.xml b/docs/manpages/gbp-export-orig.xml index 9a9fa845..9711e0f0 100644 --- a/docs/manpages/gbp-export-orig.xml +++ b/docs/manpages/gbp-export-orig.xml @@ -146,6 +146,8 @@ <para> Search for original tarballs in <replaceable>DIRECTORY</replaceable> instead of generating them. + <replaceable>DIRECTORY</replaceable> can contain a version format + substitution pattern, eg: <replaceable>foo-%(version)s</replaceable>. </para> </listitem> </varlistentry> diff --git a/gbp/deb/git.py b/gbp/deb/git.py index fa865ee2..85c9da5e 100644 --- a/gbp/deb/git.py +++ b/gbp/deb/git.py @@ -22,9 +22,9 @@ import re from gbp.command_wrappers import CommandExecFailed from gbp.git import GitRepositoryError from gbp.deb.pristinetar import DebianPristineTar -from gbp.format import format_str from gbp.paths import to_bin from gbp.pkg.git import PkgGitRepository +from gbp.pkg.pkgpolicy import PkgPolicy import gbp.log @@ -169,9 +169,7 @@ class DebianGitRepository(PkgGitRepository): >>> DebianGitRepository.version_to_tag(r'%(version%-%\\%)s', "0-1.2.3") '0%1.2.3' """ - f, v = cls._mangle_version(format, version) - return format_str(f, dict(version=cls._sanitize_version(v), - hversion=cls._sanitize_version(v).replace('.', '-'))) + return PkgPolicy.version_subst(format, version, cls._sanitize_version) @classmethod def _mangle_version(cls, format, version): diff --git a/gbp/pkg/pkgpolicy.py b/gbp/pkg/pkgpolicy.py index 53887fee..b525ce20 100644 --- a/gbp/pkg/pkgpolicy.py +++ b/gbp/pkg/pkgpolicy.py @@ -20,6 +20,7 @@ import os import re from gbp.pkg.archive import Archive +from gbp.format import format_str class PkgPolicy(object): @@ -165,3 +166,40 @@ class PkgPolicy(object): @classmethod def symlink_orig(cls, orig_file, orig_dir, output_dir, force=False): return cls.symlink_origs([orig_file], orig_dir, output_dir, force=force) + + @staticmethod + def version_subst(format, version, sanitizer=lambda arg: arg): + """Generate a string from a given format and a version. The extracted + version can be passed through the sanitizer function argument before + being formatted into a string. + + %(version)s provides a clean version. + + %(hversion)s provides the same thing, but with '.' replaced with '-'. + hversion is useful for upstreams with tagging policies that prohibit . + characters. + + %(version%A%B)s provides %(version)s with string 'A' replaced by 'B'. + This way, simple version mangling is possible via substitution. + Inside the substition string, '%' needs to be escaped. See the + examples below. + + >>> PkgPolicy.version_subst("debian/%(version)s", "0:0~0") + 'debian/0:0~0' + >>> PkgPolicy.version_subst("libfoo-%(hversion)s", "1.8.1") + 'libfoo-1-8-1' + >>> PkgPolicy.version_subst("v%(version%.%_)s", "1.2.3") + 'v1_2_3' + >>> PkgPolicy.version_subst(r'%(version%-%\\%)s', "0-1.2.3") + '0%1.2.3' + """ + version_mangle_re = (r'%\(version' + r'%(?P<M>[^%])' + r'%(?P<R>([^%]|\\%))+' + r'\)s') + r = re.search(version_mangle_re, format) + if r: + format = re.sub(version_mangle_re, "%(version)s", format) + version = version.replace(r.group('M'), r.group('R').replace(r'\%', '%')) + return format_str(format, dict(version=sanitizer(version), + hversion=sanitizer(version).replace('.', '-'))) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index d3a3222e..bd939974 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -45,6 +45,7 @@ from gbp.scripts.common.hook import Hook from gbp.scripts.export_orig import prepare_upstream_tarballs, guess_comp_type from gbp.scripts.tag import perform_tagging +from gbp.pkg.pkgpolicy import PkgPolicy # Functions to handle export-dir @@ -499,7 +500,9 @@ def main(argv): if not options.tag_only: output_dir = prepare_output_dir(options.export_dir) - tarball_dir = options.tarball_dir or output_dir + tarball_dir = output_dir + if options.tarball_dir and source.upstream_version is not None: + tarball_dir = PkgPolicy.version_subst(options.tarball_dir, source.upstream_version) tmp_dir = os.path.join(output_dir, "%s-tmp" % source.sourcepkg) build_env, hook_env = setup_pbuilder(options, repo, source.is_native()) major = (source.debian_version if source.is_native() diff --git a/gbp/scripts/export_orig.py b/gbp/scripts/export_orig.py index 1afbe6db..181c9093 100755 --- a/gbp/scripts/export_orig.py +++ b/gbp/scripts/export_orig.py @@ -29,6 +29,7 @@ import gbp.log import gbp.notifications from gbp.scripts.common import ExitCodes from gbp.pkg import Compressor, Archive +from gbp.pkg.pkgpolicy import PkgPolicy def prepare_upstream_tarballs(repo, source, options, tarball_dir, output_dir): @@ -335,6 +336,10 @@ def main(argv): except Exception as e: raise GbpError("Can't determine package type: %s" % e) + if options.tarball_dir and source.upstream_version is not None: + options.tarball_dir = PkgPolicy.version_subst(options.tarball_dir, + source.upstream_version) + output_dir = options.tarball_dir or os.path.join(repo.path, '..') if source.is_native(): diff --git a/tests/component/deb/test_buildpackage.py b/tests/component/deb/test_buildpackage.py index c8a31e77..fe0802a0 100644 --- a/tests/component/deb/test_buildpackage.py +++ b/tests/component/deb/test_buildpackage.py @@ -312,3 +312,24 @@ class TestBuildpackage(ComponentTestBase): '--git-preexport=printenv > %s' % preexport_out]) ok_(os.path.exists(preexport_out)) self.check_hook_vars('../preexport', ["GBP_BUILD_DIR", "GBP_GIT_DIR"]) + + @RepoFixtures.overlay() + def test_export_dir_version_replacement(self, repo): + """Test that building in overlay mode with export dir with versioned name works""" + tarball_dir = os.path.join(DEB_TEST_DATA_DIR, 'foo-%(version)s') + self._test_buildpackage(repo, ['--git-overlay', + '--git-compression=auto', + '--git-tarball-dir=%s' % tarball_dir, + '--git-no-purge', + '--git-component=foo', + '--git-export-dir=../foo']) + # Check if main tarball got unpacked + ok_(os.path.exists('../foo/hello-debhelper-2.8/configure')) + # Check if debian dir is there + ok_(os.path.exists('../foo/hello-debhelper-2.8/debian/changelog')) + # Check if additional tarball got unpacked + ok_(os.path.exists('../foo/hello-debhelper-2.8/foo/test1')) + # Check if upstream tarballs is in export_dir + eq_(sorted(glob.glob('../foo/*')), ['../foo/hello-debhelper-2.8', + '../foo/hello-debhelper_2.8.orig-foo.tar.gz', + '../foo/hello-debhelper_2.8.orig.tar.gz']) diff --git a/tests/component/deb/test_export_orig.py b/tests/component/deb/test_export_orig.py index e42a1fc2..b2a8e8bb 100644 --- a/tests/component/deb/test_export_orig.py +++ b/tests/component/deb/test_export_orig.py @@ -111,3 +111,28 @@ class TestExportOrig(ComponentTestBase): '--pristine-tar']) ok_(ret == 1, "Exporting tarballs must fail") self._check_log(-1, ".*git show refs/heads/pristine-tar:.*failed") + + def test_tarball_dir_version_replacement(self): + """Test that generating tarball from directory version substitution works""" + pkg = 'hello-debhelper' + dsc = self._dsc_name(pkg, '2.8-1', 'dsc-3.0-additional-tarballs') + tarballs = ["%s_2.8.orig-foo.tar.gz" % pkg, + "%s_2.8.orig.tar.gz" % pkg] + + assert import_dsc(['arg0', '--no-pristine-tar', dsc]) == 0 + ComponentTestGitRepository(pkg) + os.chdir(pkg) + for t in tarballs: + self.assertFalse(os.path.exists(os.path.join('..', t)), "Tarball %s must not exist" % t) + + tarball_dir = os.path.join(DEB_TEST_DATA_DIR, 'foo-%(version)s') + ret = export_orig(['arg0', + '--tarball-dir=%s' % tarball_dir, + '--component=foo', + '--no-pristine-tar']) + ok_(ret == 0, "Exporting tarballs failed") + # tarballs should be found in existing --tarball-dir directory and thus + # not get recreated by export-orig + for t in tarballs: + self.assertFalse(os.path.exists(os.path.join('..', t)), "Tarball %s found" % t) + self.assertTrue(os.path.exists(os.path.join(DEB_TEST_DATA_DIR, 'foo-2.8', t)), "Tarball %s not found" % t) |