[git-buildpackage] [PATCH dpkg-buildpackage v3] gbp-dch: allow bug number format to be overridden

Jonathan Toppins jtoppins at cumulusnetworks.com
Thu Aug 27 16:09:37 CEST 2015


Some derivatives and non Debian exclusive projects don't use just
numbers for their bug numbers. gbp-dch should still be able to parse
these bug numbers and generate useful changelog entries. This doesn't
solve dpkg-parsechangelog but is a start.

	Examples of non-Debian bug numbers are:
		example change header

		Example: EX-12345

	Should produce the following change log:
		* example change header (Example: EX-12345)

This also helps in pulling CVE numbers simply by letting the user
modify the regex to something like 'cve-\d+-\d+'.

Signed-off-by: Jonathan Toppins <jtoppins at cumulusnetworks.com>
---

since v1:
	* changed the cmdline and config entry to be "meta-closes-bugnum"
	* rebased on top of the latest master
	* added unit tests - pretty simple could be more complicated but
      should catch changes that just flat out break things
    * fixed a few grammar error pointed out

since v2:
	* created tests/23_test_dch_extract_bts_cmds.py to specifically test
	  gbp.dch.extract_bts_cmds()
	* corrected example given in gbp-dch.sgml

 debian/git-buildpackage.zsh-completion |  2 ++
 docs/manpages/gbp-dch.sgml             | 23 +++++++++++++++
 gbp.conf                               |  2 ++
 gbp/config.py                          |  3 ++
 gbp/dch.py                             |  7 ++---
 gbp/scripts/dch.py                     |  1 +
 tests/11_test_dch_main.py              | 35 ++++++++++++++++++++++
 tests/23_test_dch_extract_bts_cmds.py  | 54 ++++++++++++++++++++++++++++++++++
 8 files changed, 122 insertions(+), 5 deletions(-)
 create mode 100644 tests/23_test_dch_extract_bts_cmds.py

diff --git a/debian/git-buildpackage.zsh-completion b/debian/git-buildpackage.zsh-completion
index 1fc843e..8c7d98d 100644
--- a/debian/git-buildpackage.zsh-completion
+++ b/debian/git-buildpackage.zsh-completion
@@ -137,6 +137,7 @@ _gbp-dch () {
 		'(--meta --no-meta)--meta[Parse meta tags]' \
 		'(--meta --no-meta)--no-meta[Do not parse meta tags]' \
 		'--meta-closes=-[What meta tags to look for  to  generate  bug-closing  changelog entries]' \
+		'--meta-closes-bugnum=-[What bug number format to look for to generate bug-closing changelog entries]' \
 		'(--full --no-full)--full[Include the full commit message]' \
 		'(--full --no-full)--no-full[Do not include the full commit message]' \
 		'(--snapshot -S)'{-S,--snapshot}'[Create a snapshot release entry]' \
@@ -381,6 +382,7 @@ _gbp-dch () {
 		'(--meta --no-meta)--meta[Parse meta tags]' \
 		'(--meta --no-meta)--no-meta[Do not parse meta tags]' \
 		'--meta-closes=-[What meta tags to look for  to  generate  bug-closing  changelog entries]' \
+		'--meta-closes-bugnum=-[What bug number format to look for to generate bug-closing changelog entries]' \
 		'(--full --no-full)--full[Include the full commit message]' \
 		'(--full --no-full)--no-full[Do not include the full commit message]' \
 		'(--snapshot -S)'{-S,--snapshot}'[Create a snapshot release entry]' \
diff --git a/docs/manpages/gbp-dch.sgml b/docs/manpages/gbp-dch.sgml
index 888d987..b77ab72 100644
--- a/docs/manpages/gbp-dch.sgml
+++ b/docs/manpages/gbp-dch.sgml
@@ -46,6 +46,7 @@
       <arg><option>--[no-]full</option></arg>
       <arg><option>--[no-]meta</option></arg>
       <arg><option>--meta-closes=bug-close-tags</option></arg>
+      <arg><option>--meta-closes-bugnum=bug-number-format</option></arg>
       <arg><option>--snapshot-number=</option><replaceable>expression</replaceable></arg>
       <arg><option>--id-length=</option><replaceable>number</replaceable></arg>
       <arg><option>--git-log=</option><replaceable>git-log-options</replaceable></arg>
@@ -183,6 +184,28 @@
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><option>--meta-closes-bugnum=</option><replaceable>bug-number-format</replaceable>
+        </term>
+        <listitem>
+          <para>
+          What regular expression should be used to parse out the bug number.
+          The default is '(?:bug|issue)?\#?\s?\d+'. Note: the regex should
+          suppress all portions of the bug number that are not wanted using
+          "(?:)", see pyhton regex manual for details.
+          Example:
+              --meta-closes-bugnum="(?:bug)?\s*ex-\d+"
+
+              would match all of the following:
+                 Possible Txt  Match?    Result
+                 ------------  ------    ------
+                 bug EX-12345    Y       EX-12345
+                 ex-01273        Y       ex-01273
+                 bug ex-1ab      Y       ex-1
+                 EX--12345       N
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term><option>--[no-]full</option>
         </term>
         <listitem>
diff --git a/gbp.conf b/gbp.conf
index 43fc36d..64cd3a1 100644
--- a/gbp.conf
+++ b/gbp.conf
@@ -96,6 +96,8 @@
 #meta = False
 # what tags to look for to generate bug-closing changelog entries:
 #meta-closes = Closes|LP
+# what regex should be used to parse the bug number
+#meta-closes-bugnum = '(?:bug|issue)?\#?\s?\d+'
 # include the full commit message in the changelog:
 #full = True
 # ignore Signed-off-by: lines:
diff --git a/gbp/config.py b/gbp/config.py
index 3b483c0..9a86176 100644
--- a/gbp/config.py
+++ b/gbp/config.py
@@ -125,6 +125,7 @@ class GbpOptionParser(OptionParser):
                  'ignore-branch'   : 'False',
                  'meta'            : 'True',
                  'meta-closes'     : 'Closes|LP',
+                 'meta-closes-bugnum'  : r'(?:bug|issue)?\#?\s?\d+',
                  'full'            : 'False',
                  'id-length'       : '0',
                  'git-author'      : 'False',
@@ -212,6 +213,8 @@ class GbpOptionParser(OptionParser):
                   "Parse meta tags in commit messages, default is '%(meta)s'",
              'meta-closes':
                   "Meta tags for the bts close commands, default is '%(meta-closes)s'",
+             'meta-closes-bugnum':
+                  "Meta bug number format, default is '%(meta-closes-bugnum)s'",
              'ignore-new':
                   "Build with uncommited changes in the source tree, default is '%(ignore-new)s'",
              'ignore-branch':
diff --git a/gbp/dch.py b/gbp/dch.py
index 49b1020..3dcfc85 100644
--- a/gbp/dch.py
+++ b/gbp/dch.py
@@ -45,17 +45,14 @@ def filter_ignore_rx_matches(lines, options):
     else:
         return lines
 
-
-_bug_r = r'(?:bug|issue)?\#?\s?\d+'
-_bug_re = re.compile(_bug_r, re.I)
-
 def extract_bts_cmds(lines, opts):
     """Return a dictionary of the bug tracking system commands
     contained in the the given lines.  i.e. {'closed' : [1], 'fixed':
     [3, 4]}.  Right now, this will only notice a single directive
     clause on a line.  Also return all of the lines that do not
     contain bug tracking system commands."""
-    bts_rx = re.compile(r'(?P<bts>%s):\s+%s' % (opts.meta_closes, _bug_r), re.I)
+    _bug_re = re.compile(opts.meta_closes_bugnum, re.I)
+    bts_rx = re.compile(r'(?P<bts>%s):\s+%s' % (opts.meta_closes, opts.meta_closes_bugnum), re.I)
     commands = {}
     other_lines = []
     for line in lines:
diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py
index e3f7c7c..c555825 100644
--- a/gbp/scripts/dch.py
+++ b/gbp/scripts/dch.py
@@ -358,6 +358,7 @@ def build_parser(name):
     version_group.add_boolean_config_file_option(option_name="git-author", dest="use_git_author")
     commit_group.add_boolean_config_file_option(option_name="meta", dest="meta")
     commit_group.add_config_file_option(option_name="meta-closes", dest="meta_closes")
+    commit_group.add_config_file_option(option_name="meta-closes-bugnum", dest="meta_closes_bugnum")
     commit_group.add_boolean_config_file_option(option_name="full", dest="full")
     commit_group.add_config_file_option(option_name="id-length", dest="idlen",
                       help="include N digits of the commit id in the changelog entry, default is '%(id-length)s'",
diff --git a/tests/11_test_dch_main.py b/tests/11_test_dch_main.py
index 8f7d9bf..7e2a197 100644
--- a/tests/11_test_dch_main.py
+++ b/tests/11_test_dch_main.py
@@ -364,3 +364,38 @@ class TestScriptDch(DebianGitTestRepo):
         self.assertEqual(header.lastindex, 1)
         self.assertIsNotNone(re.search(snap_mark + header.group(1), lines[2]))
         self.assertIn("""  * added debian/control\n""", lines)
+
+
+    def test_dch_main_closes_default(self):
+        options = ["--meta"]
+        self.add_file("closes", "test file",
+                      msg="""test debian closes commit\n\nCloses: #123456""")
+        lines = self.run_dch(options)
+        self.assertIn("""  * test debian closes commit (Closes: #123456)\n""",
+                      lines)
+
+
+    def test_dch_main_closes_non_debian_bug_numbers(self):
+        self.add_file("closes", "test file",
+                      msg="""test non-debian closes 1\n\nCloses: EX-123""")
+        self.add_file("closes1", "test file",
+                      msg="""test non-debian closes 2\n\nCloses: EX-5678""")
+        options = ["--meta", '--meta-closes-bugnum=ex-\d+']
+        lines = self.run_dch(options)
+        self.assertIn("""  * test non-debian closes 1 (Closes: EX-123)\n""",
+                      lines)
+        self.assertIn("""  * test non-debian closes 2 (Closes: EX-5678)\n""",
+                      lines)
+
+    def test_dch_main_meta_closes_and_bug_numbers(self):
+        self.add_file("closes", "test file",
+                      msg="""test non-debian closes 1\n\nExample: EX-123""")
+        self.add_file("closes1", "test file",
+                      msg="""test non-debian closes 2\n\nExample: EX-5678""")
+        options = ["--meta", '--meta-closes-bugnum=ex-\d+',
+                   '--meta-closes=Example']
+        lines = self.run_dch(options)
+        self.assertIn("""  * test non-debian closes 1 (Example: EX-123)\n""",
+                      lines)
+        self.assertIn("""  * test non-debian closes 2 (Example: EX-5678)\n""",
+                      lines)
diff --git a/tests/23_test_dch_extract_bts_cmds.py b/tests/23_test_dch_extract_bts_cmds.py
new file mode 100644
index 0000000..3acff5e
--- /dev/null
+++ b/tests/23_test_dch_extract_bts_cmds.py
@@ -0,0 +1,54 @@
+# (C) 2015 Jonathan Toppins <jtoppins at cumulusnetworks.com>
+#    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
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, please see
+#    <http://www.gnu.org/licenses/>
+"""Test gbp.dch.extract_bts_cmds()"""
+
+import os
+import unittest
+
+from gbp.dch import extract_bts_cmds
+
+class OptionsStub:
+    def __init__(self):
+        self.meta_closes = "Closes|LP"
+        self.meta_closes_bugnum = r'(?:bug|issue)?\#?\s?\d+'
+
+class TestExtractBTSCmds(unittest.TestCase):
+    def test_debian_commands(self):
+        """Test default BTS command extraction that is applicable to Debian"""
+        options = OptionsStub()
+        lines = """This is a test commit
+
+Closes: bug#12345
+Closes: 456
+"""
+        bugs, dummy = extract_bts_cmds(lines.split('\n'), options)
+        self.assertEquals(bugs, {'Closes': ['bug#12345', '456']})
+
+    def test_nondebian_commands(self):
+        """Test non-default BTS commands. We use the example given in the
+        documentation manpages."""
+        options = OptionsStub()
+        options.meta_closes_bugnum = "(?:bug)?\s*ex-\d+"
+        lines = """This is a test commit
+some more lines...
+
+Closes: bug EX-12345
+Closes: ex-01273
+Closes: bug ex-1ab
+Closes: EX--12345
+"""
+        bugs, dummy = extract_bts_cmds(lines.split('\n'), options)
+        self.assertEquals(bugs, {'Closes': ['bug EX-12345', 'ex-01273',
+                                            'bug ex-1']})
-- 
2.1.4



More information about the git-buildpackage mailing list