debian/lib/python/debian_linux/debian.py: Parse bottom lines of changelog entries

Changelog doesn't currently provide access to the maintainer
name/address and date.  We need this when updating the signed template
changelog.

While we're at it, make sure we don't ignore any important lines.
Anything beginning with exactly zero or one spaces is a top or bottom
line, respectively; anything else is internal text we can ignore.
This commit is contained in:
Ben Hutchings 2018-04-07 18:12:33 +02:00
parent 9f8aafcd1f
commit a7e85cb155
2 changed files with 52 additions and 22 deletions

2
debian/changelog vendored
View File

@ -52,6 +52,8 @@ linux (4.16-1~exp1) UNRELEASED; urgency=medium
* debian/rules.d/tools/lib/lockdep/Makefile: Fix repeated 'make install'
* Add template source package to support code signing
* Use a dummy build profile for udebs that we test-build before signing
* debian/lib/python/debian_linux/debian.py: Parse bottom lines of changelog
entries
-- Roger Shimizu <rogershimizu@gmail.com> Fri, 23 Mar 2018 21:10:34 +0900

View File

@ -6,7 +6,7 @@ from . import utils
class Changelog(list):
_rules = r"""
_top_rules = r"""
^
(?P<source>
\w[-+0-9a-z.]+
@ -25,15 +25,30 @@ class Changelog(list):
(?P<urgency>
\w+
)
\n
"""
_re = re.compile(_rules, re.X)
_top_re = re.compile(_top_rules, re.X)
_bottom_rules = r"""
^
\ --\
(?P<maintainer>
\S(?:\ ?\S)*
)
\ \
(?P<date>
(.*)
)
\n
"""
_bottom_re = re.compile(_bottom_rules, re.X)
_ignore_re = re.compile(r'^(?: |\s*\n)')
class Entry(object):
__slot__ = 'distribution', 'source', 'version', 'urgency'
__slot__ = 'distribution', 'source', 'version', 'urgency', 'maintainer', 'date'
def __init__(self, distribution, source, version, urgency):
self.distribution, self.source, self.version, self.urgency = \
distribution, source, version, urgency
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
def __init__(self, dir='', version=None, file=None):
if version is None:
@ -45,23 +60,36 @@ class Changelog(list):
self._parse(version, f)
def _parse(self, version, f):
while True:
line = f.readline()
if not line:
break
match = self._re.match(line)
if not match:
continue
try:
v = version(match.group('version'))
except Exception:
if not len(self):
raise
v = Version(match.group('version'))
self.append(self.Entry(match.group('distribution'),
match.group('source'), v,
match.group('urgency')))
top_match = None
line_no = 0
for line in f:
line_no += 1
if self._ignore_re.match(line):
pass
elif top_match is None:
top_match = self._top_re.match(line)
if not top_match:
raise Exception('invalid top line %d in changelog' % line_no)
try:
v = version(top_match.group('version'))
except Exception:
if not len(self):
raise
v = Version(top_match.group('version'))
else:
bottom_match = self._bottom_re.match(line)
if not bottom_match:
raise Exception('invalid bottom line %d in changelog' % line_no)
self.append(self.Entry(distribution=top_match.group('distribution'),
source=top_match.group('source'),
version=v,
urgency=top_match.group('urgency'),
maintainer=bottom_match.group('maintainer'),
date=bottom_match.group('date')))
top_match = bottom_match = None
class Version(object):
_version_rules = r"""