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

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"""