pq: support the pq-branch format "patch-queue/%(branch)s".
authorwanchao-xu <wanchao.xu@samsung.com>
Wed, 17 Apr 2024 11:21:55 +0000 (19:21 +0800)
committerwanchao-xu <wanchao.xu@samsung.com>
Wed, 17 Apr 2024 12:49:32 +0000 (20:49 +0800)
Change-Id: I2a4cb6a5e0ac9ad68f1aac9c651441ceb3df2ad5
Signed-off-by: wanchao-xu <wanchao.xu@samsung.com>
gbp/scripts/common/pq.py

index 1a80ec054eac727f1ed13497c79b32b949ff6bcf..40b1d9961e2319cf87744c1019339dd7bc1667ef 100644 (file)
@@ -32,10 +32,26 @@ 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 pq_branch_match(branch, pq_fmt_str):
+    """
+    Match branch name with pq branch name pattern
+
+    >>> pq_branch_match('patch-queue/foo', 'patch-queue/%(br)s').groupdict()
+    {'br': 'foo'}
+    >>> pq_branch_match('pq/foo/bar', 'pq/%(br)s/baz')
+    >>> pq_branch_match('pq/foo/bar', 'pq/%(br)s/bar').groupdict()
+    {'br': 'foo'}
+    >>> pq_branch_match('foo/bar/1.0/pq', 'foo/%(br)s/%(ver)s/pq').groupdict()
+    {'br': 'bar', 'ver': '1.0'}
+    """
+    pq_re = '^%s$' % re.sub(r'%\(([a-z_\-]+)\)s', r'(?P<\1>\\S+)', pq_fmt_str)
+    return re.match(pq_re, branch)
+
+
+def is_pq_branch(branch, pq_fmt=None):
     """
     is branch a patch-queue branch?
 
@@ -43,11 +59,32 @@ def is_pq_branch(branch):
     False
     >>> is_pq_branch("patch-queue/foo")
     True
+    >>> pq_fmt = "%(branch)s/development"
+    >>> is_pq_branch("foo/development/bar", pq_fmt)
+    False
+    >>> is_pq_branch("bar/foo/development", pq_fmt)
+    True
+    >>> pq_fmt = "development"
+    >>> is_pq_branch("development", pq_fmt)
+    True
+    >>> pq_fmt = "my/%(branch)s/pq"
+    >>> is_pq_branch("my/foo/pqb", pq_fmt)
+    False
+    >>> is_pq_branch("my/foo/pq", pq_fmt)
+    True
+    >>> pq_fmt = "my/%(branch)s/%(version)s"
+    >>> is_pq_branch("my/foo", pq_fmt)
+    False
+    >>> is_pq_branch("my/foo/1.0", pq_fmt)
+    True
     """
-    return [False, True][branch.startswith(PQ_BRANCH_PREFIX)]
+    pq_format_str = pq_fmt if pq_fmt else DEFAULT_PQ_BRANCH_NAME
+    if pq_branch_match(branch, pq_format_str):
+        return True
+    return False
 
 
-def pq_branch_name(branch):
+def pq_branch_name(branch, pq_fmt=None, extra_keys=None):
     """
     get the patch queue branch corresponding to branch
 
@@ -55,14 +92,27 @@ def pq_branch_name(branch):
     'patch-queue/master'
     >>> pq_branch_name("foo")
     'patch-queue/foo'
+    >>> pq_fmt = "%(branch)s/development"
+    >>> pq_branch_name("foo", pq_fmt)
+    'foo/development'
+    >>> pq_fmt = "development"
+    >>> pq_branch_name("foo", pq_fmt)
+    'development'
+    >>> pq_fmt = "pq/%(branch)s/%(ver)s"
+    >>> pq_branch_name("foo", pq_fmt, {'ver': '1.0'})
+    'pq/foo/1.0'
     """
-    if not is_pq_branch(branch):
-        return PQ_BRANCH_PREFIX + branch
+    pq_format_str = pq_fmt if pq_fmt else DEFAULT_PQ_BRANCH_NAME
+    format_fields = {'branch': branch}
+    if extra_keys:
+        format_fields.update(extra_keys)
+    if not is_pq_branch(branch, pq_fmt):
+        return pq_format_str % format_fields
     else:
         return branch
 
 
-def pq_branch_base(branch):
+def pq_branch_base(branch, pq_fmt=None):
     """
     get the branch corresponding to the given patch queue branch
 
@@ -70,11 +120,21 @@ def pq_branch_base(branch):
     'master'
     >>> pq_branch_base("foo")
     'foo'
+    >>> pq_fmt = "my/%(branch)s/development"
+    >>> pq_branch_base("my/foo/development", pq_fmt)
+    'foo'
+    >>> pq_fmt = "development"
+    >>> pq_branch_base("foo/development", pq_fmt)
+    'foo/development'
+    >>> pq_branch_base("development", pq_fmt)
+    'development'
     """
-    if is_pq_branch(branch):
-        return branch[len(PQ_BRANCH_PREFIX):]
-    else:
-        return branch
+    pq_format_str = pq_fmt if pq_fmt else DEFAULT_PQ_BRANCH_NAME
+    m = pq_branch_match(branch, pq_format_str)
+    if m:
+        if 'branch' in m.groupdict():
+            return m.group('branch')
+    return branch
 
 
 def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds, filter_cmds=None):
@@ -288,15 +348,15 @@ def get_maintainer_from_control(repo):
     return GitModifier()
 
 
-def switch_to_pq_branch(repo, branch):
+def switch_to_pq_branch(repo, branch, pq_fmt=None, name_keys=None):
     """
     Switch to patch-queue branch if not already on it.
     doesn't exist yet
     """
-    if is_pq_branch(branch):
+    if is_pq_branch(branch, pq_fmt):
         return
 
-    pq_branch = pq_branch_name(branch)
+    pq_branch = pq_branch_name(branch, pq_fmt, name_keys)
     if not repo.has_branch(pq_branch):
         raise GbpError("Branch '%s' does not exist, try "
                        "'import' instead" % pq_branch)
@@ -305,8 +365,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, topic=None,
+                       pq_fmt=None):
+    switch_to_pq_branch(repo, branch, pq_fmt)
     apply_and_commit_patch(repo, patch, fallback_author, topic)
     gbp.log.info("Applied %s" % os.path.basename(patch.path))
 
@@ -346,9 +407,9 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None, name=None):
     repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path)
 
 
-def drop_pq(repo, branch):
-    repo.checkout(pq_branch_base(branch))
-    pq_branch = pq_branch_name(branch)
+def drop_pq(repo, branch, pq_fmt=None, name_keys=None):
+    repo.checkout(pq_branch_base(branch, pq_fmt))
+    pq_branch = pq_branch_name(branch, pq_fmt, name_keys)
     if repo.has_branch(pq_branch):
         repo.delete_branch(pq_branch)
         gbp.log.info("Dropped branch '%s'." % pq_branch)