From 601352fdbecbe96cb9daf0fe4d3838e0addb307c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 May 2012 10:56:17 +0300 Subject: gbp-pq: readiness to configure the pq branch name All other gbp branches have configurable names. This commit adds the readiness for user to configure/change the name of the patch-queue branches, as well. Patch-queue is defined in options as a format string, where '%(branch)s' refers to the debian/packaging branch. If the pq-branch format string does not contain '%(branch)s', there is only one patch-queue branch and the debian/packaging branch is used as its base branch. That is, e.g. a 'gbp-pq switch' operation from the patch-queue branch always switches to the debian/packaging branch. Signed-off-by: Markus Lehtonen Signed-off-by: Olev Kartau Minor adjustments, Signed-off-by: Tzafrir Cohen --- gbp/scripts/common/pq.py | 115 +++++++++++++++++++++++++++++++++++------------ gbp/scripts/pq.py | 44 +++++++++--------- tests/13_test_gbp_pq.py | 5 ++- 3 files changed, 111 insertions(+), 53 deletions(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index 9b2a887..4e5ca41 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -32,43 +32,99 @@ from gbp.git.modifier import GitModifier, GitTz from gbp.errors import GbpError import gbp.log -PQ_BRANCH_PREFIX = "patch-queue/" +DEFAULT_PQ_BRANCH_NAME = "patch-queue/%(branch)s" -def is_pq_branch(branch): +def is_pq_branch(branch, options): """ is branch a patch-queue branch? - >>> is_pq_branch("foo") + >>> from optparse import OptionParser + >>> (opts, args) = OptionParser().parse_args([]) + >>> is_pq_branch("foo", opts) False - >>> is_pq_branch("patch-queue/foo") + >>> is_pq_branch("patch-queue/foo", opts) + True + >>> opts.pq_branch = "%(branch)s/development" + >>> is_pq_branch("foo/development/bar", opts) + False + >>> is_pq_branch("bar/foo/development", opts) + True + >>> opts.pq_branch = "development" + >>> is_pq_branch("development", opts) + True + >>> opts.pq_branch = "my/%(branch)s/pq" + >>> is_pq_branch("my/foo/pqb", opts) + False + >>> is_pq_branch("my/foo/pq", opts) True """ - return [False, True][branch.startswith(PQ_BRANCH_PREFIX)] + pq_format_str = DEFAULT_PQ_BRANCH_NAME + if hasattr(options, 'pq_branch'): + pq_format_str = options.pq_branch + pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) + if pq_re.match(branch): + return True + return False -def pq_branch_name(branch): + +def pq_branch_name(branch, options): """ get the patch queue branch corresponding to branch - >>> pq_branch_name("patch-queue/master") - >>> pq_branch_name("foo") + >>> from optparse import OptionParser + >>> (opts, args) = OptionParser().parse_args([]) + >>> pq_branch_name("patch-queue/master", opts) + >>> pq_branch_name("foo", opts) 'patch-queue/foo' + >>> opts.pq_branch = "%(branch)s/development" + >>> pq_branch_name("foo", opts) + 'foo/development' + >>> opts.pq_branch = "development" + >>> pq_branch_name("foo", opts) + 'development' """ - if not is_pq_branch(branch): - return PQ_BRANCH_PREFIX + branch + pq_format_str = DEFAULT_PQ_BRANCH_NAME + if hasattr(options, 'pq_branch'): + pq_format_str = options.pq_branch + if not is_pq_branch(branch, options): + return pq_format_str % dict(branch=branch) -def pq_branch_base(pq_branch): - """ - get the branch corresponding to the given patch queue branch - >>> pq_branch_base("patch-queue/master") +def pq_branch_base(pq_branch, options): + """ + Get the branch corresponding to the given patch queue branch. + Returns the packaging/debian branch if pq format string doesn't contain + '%(branch)s' key. + + >>> from optparse import OptionParser + >>> (opts, args) = OptionParser().parse_args([]) + >>> opts.packaging_branch = "packaging" + >>> pq_branch_base("patch-queue/master", opts) 'master' - >>> pq_branch_base("foo") + >>> pq_branch_base("foo", opts) + >>> opts.pq_branch = "my/%(branch)s/development" + >>> pq_branch_base("foo/development", opts) + >>> pq_branch_base("my/foo/development/bar", opts) + >>> pq_branch_base("my/foo/development", opts) + 'foo' + >>> opts.pq_branch = "development" + >>> pq_branch_base("foo/development", opts) + >>> pq_branch_base("development", opts) + 'packaging' """ - if is_pq_branch(pq_branch): - return pq_branch[len(PQ_BRANCH_PREFIX):] + pq_format_str = DEFAULT_PQ_BRANCH_NAME + if hasattr(options, 'pq_branch'): + pq_format_str = options.pq_branch + + pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) + m = pq_re.match(pq_branch) + if m: + if 'base' in m.groupdict(): + return m.group('base') + return options.packaging_branch def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds, filter_cmds=None): @@ -251,15 +307,15 @@ def get_maintainer_from_control(repo): return GitModifier() -def switch_to_pq_branch(repo, branch): +def switch_to_pq_branch(repo, branch, options): """ Switch to patch-queue branch if not already there, create it if it doesn't exist yet """ - if is_pq_branch(branch): + if is_pq_branch(branch, options): return - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) if not repo.has_branch(pq_branch): try: repo.create_branch(pq_branch) @@ -271,8 +327,9 @@ def switch_to_pq_branch(repo, branch): repo.set_branch(pq_branch) -def apply_single_patch(repo, branch, patch, fallback_author, topic=None): - switch_to_pq_branch(repo, branch) +def apply_single_patch(repo, branch, patch, fallback_author, options): + switch_to_pq_branch(repo, branch, options) + topic = None if not hasattr(options, 'topic') else options.topic apply_and_commit_patch(repo, patch, fallback_author, topic) gbp.log.info("Applied %s" % os.path.basename(patch.path)) @@ -302,12 +359,12 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None): repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path) -def drop_pq(repo, branch): - if is_pq_branch(branch): +def drop_pq(repo, branch, options): + if is_pq_branch(branch, options): gbp.log.err("On a patch-queue branch, can't drop it.") raise GbpError else: - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) if repo.has_branch(pq_branch): repo.delete_branch(pq_branch) @@ -316,11 +373,11 @@ def drop_pq(repo, branch): gbp.log.info("No patch queue branch found - doing nothing.") -def switch_pq(repo, current): +def switch_pq(repo, current, options): """Switch to patch-queue branch if on base branch and vice versa""" - if is_pq_branch(current): - base = pq_branch_base(current) + if is_pq_branch(current, options): + base = pq_branch_base(current, options) gbp.log.info("Switching to %s" % base) repo.checkout(base) else: - switch_to_pq_branch(repo, current) + switch_to_pq_branch(repo, current, options) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 11af997..b58232d 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -170,13 +170,13 @@ def commit_patches(repo, branch, patches, options): def export_patches(repo, branch, options): """Export patches from the pq branch into a patch series""" - if is_pq_branch(branch): - base = pq_branch_base(branch) + if is_pq_branch(branch, options): + base = pq_branch_base(branch, options) gbp.log.info("On '%s', switching to '%s'" % (branch, base)) branch = base repo.set_branch(branch) - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) try: shutil.rmtree(PATCH_DIR) except OSError as (e, msg): @@ -205,7 +205,7 @@ def export_patches(repo, branch, options): gbp.log.info("No patches on '%s' - nothing to do." % pq_branch) if options.drop: - drop_pq(repo, branch) + drop_pq(repo, branch, options) def safe_patches(series): @@ -231,7 +231,7 @@ def safe_patches(series): return (tmpdir, series) -def import_quilt_patches(repo, branch, series, tries, force): +def import_quilt_patches(repo, branch, series, tries, options): """ apply a series of quilt patches in the series file 'series' to branch the patch-queue branch for 'branch' @@ -241,24 +241,24 @@ def import_quilt_patches(repo, branch, series, tries, force): @param series; series file to read patches from @param tries: try that many times to apply the patches going back one commit in the branches history after each failure. - @param force: import the patch series even if the branch already exists + @param options: gbp-pq command options """ tmpdir = None - if is_pq_branch(branch): - if force: - branch = pq_branch_base(branch) - pq_branch = pq_branch_name(branch) + if is_pq_branch(branch, options): + if options.force: + branch = pq_branch_base(branch, options) + pq_branch = pq_branch_name(branch, options) repo.checkout(branch) else: gbp.log.err("Already on a patch-queue branch '%s' - doing nothing." % branch) raise GbpError else: - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) if repo.has_branch(pq_branch): - if force: - drop_pq(repo, branch) + if options.force: + drop_pq(repo, branch, options) else: raise GbpError("Patch queue branch '%s'. already exists. Try 'rebase' instead." % pq_branch) @@ -305,11 +305,11 @@ def import_quilt_patches(repo, branch, series, tries, force): shutil.rmtree(tmpdir) -def rebase_pq(repo, branch): - if is_pq_branch(branch): - base = pq_branch_base(branch) +def rebase_pq(repo, branch, options): + if is_pq_branch(branch, options): + base = pq_branch_base(branch, options) else: - switch_to_pq_branch(repo, branch) + switch_to_pq_branch(repo, branch, options) base = branch GitCommand("rebase")([base]) @@ -399,20 +399,20 @@ def main(argv): elif action == "import": series = SERIES_FILE tries = options.time_machine if (options.time_machine > 0) else 1 - import_quilt_patches(repo, current, series, tries, options.force) + import_quilt_patches(repo, current, series, tries, options) current = repo.get_branch() gbp.log.info("Patches listed in '%s' imported on '%s'" % (series, current)) elif action == "drop": - drop_pq(repo, current) + drop_pq(repo, current, options) elif action == "rebase": - rebase_pq(repo, current) + rebase_pq(repo, current, options) elif action == "apply": patch = Patch(patchfile) maintainer = get_maintainer_from_control(repo) - apply_single_patch(repo, current, patch, maintainer, options.topic) + apply_single_patch(repo, current, patch, maintainer, options) elif action == "switch": - switch_pq(repo, current) + switch_pq(repo, current, options) except CommandExecFailed: retval = 1 except (GbpError, GitRepositoryError) as err: diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py index 57ce83b..dfcf87a 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -91,7 +91,8 @@ class TestApplySinglePatch(testutils.DebianGitTestRepo): patch = gbp.patch_series.Patch(_patch_path('foo.patch')) - pq.apply_single_patch(self.repo, 'master', patch, None) + dummy_opts = object() + pq.apply_single_patch(self.repo, 'master', patch, None, dummy_opts) self.assertIn('foo', self.repo.list_files()) class TestWritePatch(testutils.DebianGitTestRepo): @@ -146,7 +147,7 @@ class TestExport(testutils.DebianGitTestRepo): repo = self.repo start = repo.get_branch() pq_branch = os.path.join('patch-queue', start) - pq.switch_pq(repo, start) + pq.switch_pq(repo, start, TestExport.Options) self.assertEqual(repo.get_branch(), pq_branch) export_patches(repo, pq_branch, TestExport.Options) self.assertEqual(repo.get_branch(), start) -- cgit v1.2.3