parse_gbp_commands: support command filtering
authorGuido Günther <agx@sigxcpu.org>
Sun, 8 Feb 2015 14:15:03 +0000 (15:15 +0100)
committerGuido Günther <agx@sigxcpu.org>
Sun, 8 Feb 2015 15:29:13 +0000 (16:29 +0100)
When we write out patches to subdirs using a topic we want to filter out
this topic from the commit message. Support for this was lost in

    7ce15d2434ee42aa5a1afce3d03069c5efb2db1b

add it back. Also fix parsing of the deprecated commands.

gbp/scripts/common/pq.py
gbp/scripts/pq.py
gbp/scripts/pq_rpm.py
tests/13_test_gbp_pq.py

index a82e462f3ab9f27d32d50114740b62e74e872d65..9b2a88784d47d7064671239a5bdb16c54cc4197a 100644 (file)
@@ -71,8 +71,23 @@ def pq_branch_base(pq_branch):
         return pq_branch[len(PQ_BRANCH_PREFIX):]
 
 
-def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds):
-    """Parse gbp commands from commit message"""
+def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds, filter_cmds=None):
+    """
+    Parses gbp commands from commit message. Args with and wthout
+    arguments are supported as is filtering out of commands from the
+    commit body.
+
+    @param info: the commit into to parse for commands
+    @param cmd_tag: the command tag
+    @param noarg_cmds: commands without an argument
+    @type  noarg_cmds: C{list} of C{str}
+    @param arg_cmds: command with an argumnt
+    @type  arg_cmds: C{list} of C{str}
+    @param filter_cmds: commands to filter out of the passed in info
+    @type  filter_cmds: C{list} of C{str}
+    @returns: the parsed commands and the filtered commit body.
+    """
+    body = []
     cmd_re = re.compile(r'^%s:\s*(?P<cmd>[a-z-]+)(\s+(?P<args>\S.*))?' %
                             cmd_tag, flags=re.I)
     commands = {}
@@ -91,7 +106,14 @@ def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds):
             else:
                 gbp.log.warn("Ignoring unknown gbp-command '%s' in commit %s"
                                 % (line, info['id']))
-    return commands
+            if filter_cmds is None or cmd not in filter_cmds:
+                body.append(line)
+        else:
+            body.append(line)
+    msg = '\n'.join(body)
+    # Add trailing newline if the originial body hat one
+    #msg += '\n' if info['body'] and info['body'][-1] == '\n' else ''
+    return (commands, msg)
 
 
 def patch_path_filter(file_status, exclude_regex=None):
index 543907b67b5db8fab84041bc0f0ef87d67ee0493..cf76c35d4c94300391b2957e54a79c498e8f3311 100755 (executable)
@@ -76,9 +76,22 @@ def generate_patches(repo, start, end, outdir, options):
     rev_list = reversed(repo.get_commits(start, end))
     for commit in rev_list:
         info = repo.get_commit_info(commit)
-        topic = parse_old_style_topic(info)
-        cmds = parse_gbp_commands(info, 'gbp', ('ignore'), ('topic'))
-        cmds.update(parse_gbp_commands(info, 'gbp-pq', ('ignore'), ('topic')))
+        # Parse 'gbp-pq-topic:'
+        topic  = parse_old_style_topic(info)
+        cmds ={'topic': topic } if topic else {}
+        # Parse 'Gbp: ' style commands
+        (cmds_gbp, info['body']) = parse_gbp_commands(info, 'gbp',
+                                                      ('ignore'),
+                                                      ('topic'),
+                                                      ('topic'))
+        cmds.update(cmds)
+        # Parse 'Gbp-Pq: ' style commands
+        (cmds_gbp_pq, info['body']) = parse_gbp_commands(info,
+                                                         'gbp-pq',
+                                                         ('ignore'),
+                                                         ('topic'),
+                                                         ('topic'))
+        cmds.update(cmds_gbp_pq)
         if not 'ignore' in cmds:
             if 'topic' in cmds:
                 topic = cmds['topic']
index 3d1c4bcd07e42c902d5bf913ae985e3d156a460a..ab50cad670658b4aff86ede9a82d82fe83c0a282 100755 (executable)
@@ -96,8 +96,10 @@ def generate_patches(repo, start, end, outdir, options):
     # Generate patches
     for commit in reversed(repo.get_commits(start, end_commit)):
         info = repo.get_commit_info(commit)
-        cmds = parse_gbp_commands(info, 'gbp-rpm', ('ignore'),
-                                  ('if', 'ifarch'))
+        (cmds, info['body']) = parse_gbp_commands(info,
+                                                  'gbp-rpm',
+                                                  ('ignore'),
+                                                  ('if', 'ifarch'))
         if not 'ignore' in cmds:
             patch_fn = format_patch(outdir, repo, info, patches,
                                     options.patch_numbers)
index c17b7151dcbeb2fd5ea3a53c3fe9913c6605c0b5..46110b1c5689234ca41f65b264844fc00485fdfc 100644 (file)
@@ -1,5 +1,5 @@
 # vim: set fileencoding=utf-8 :
-# (C) 2012 Guido Günther <agx@sigxcpu.org>
+# (C) 2012,2015 Guido Günther <agx@sigxcpu.org>
 #    This program is free software; you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation; either version 2 of the License, or
@@ -153,5 +153,30 @@ class TestExport(testutils.DebianGitTestRepo):
         self.assertFalse(repo.has_branch(pq_branch))
 
 
+class TestParseGbpCommand(unittest.TestCase):
+    def test_empty_body(self):
+        """Test command filtering with an empty body"""
+        info = { 'body': '' }
+        (cmds, body) = pq.parse_gbp_commands(info, ['tag'], ['cmd1'], ['cmd2'])
+        self.assertEquals(cmds, {})
+        self.assertEquals(body, '')
+
+    def test_noarg_cmd(self):
+        orig_body = '\n'.join(["Foo",
+                          "tag: cmd1"])
+        info = { 'body': orig_body }
+        (cmds, body) = pq.parse_gbp_commands(info, 'tag', ['cmd'], ['argcmd'])
+        self.assertEquals(cmds, {'cmd': None})
+        self.assertEquals(body, orig_body)
+
+    def test_filter_cmd(self):
+        orig_body = '\n'.join(["Foo",
+                               "tag: cmd1"])
+        info = { 'body': orig_body }
+        (cmds, body) = pq.parse_gbp_commands(info, 'tag', ['cmd'], ['argcmd'], ['cmd'])
+        self.assertEquals(cmds, {'cmd': None})
+        self.assertEquals(body, 'Foo')
+
+
 def _patch_path(name):
     return os.path.join(context.projectdir, 'tests/data', name)