[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