Create a new level-2 section if needed

Automatically create a level-2 section for unreleased changes if needed.
This commit is contained in:
Gilles Peskine 2020-01-28 19:58:17 +01:00
parent da14e8225e
commit a26079613a

View file

@ -1,6 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Assemble Mbed Crypto change log entries into the change log file. """Assemble Mbed Crypto change log entries into the change log file.
Add changelog entries to the first level-2 section.
Create a new level-2 section for unreleased changes if needed.
Remove the input files unless --keep-entries is specified.
""" """
# Copyright (C) 2019, Arm Limited, All Rights Reserved # Copyright (C) 2019, Arm Limited, All Rights Reserved
@ -79,6 +83,28 @@ class ChangeLog:
level = re.match(self._title_re, line).end() level = re.match(self._title_re, line).end()
return level, line[level:].strip() return level, line[level:].strip()
# Only accept dotted version numbers (e.g. "3.1", not "3").
# Refuse ".x" in a version number: this indicates a version that is
# not yet released.
_version_number_re = re.compile(br'[0-9]\.[0-9][0-9.]+([^.]|\.[^0-9x])')
def section_is_released_version(self, title):
"""Whether this section is for a released version.
True if the given level-2 section title indicates that this section
contains released changes, otherwise False.
"""
# Assume that a released version has a numerical version number
# that follows a particular pattern. These criteria may be revised
# as needed in future versions of this script.
version_number = re.search(self._version_number_re, title)
return bool(version_number)
def unreleased_version_title(self):
"""The title to use if creating a new section for an unreleased version."""
# pylint: disable=no-self-use; this method may be overridden
return b'Unreleased changes'
def __init__(self, input_stream): def __init__(self, input_stream):
"""Create a changelog object. """Create a changelog object.
@ -105,18 +131,29 @@ class ChangeLog:
of the class and may not act sensibly on an object that is already of the class and may not act sensibly on an object that is already
partially populated. partially populated.
""" """
# Parse the first level-2 section. Everything before the first # Parse the first level-2 section, containing changelog entries
# for unreleased changes.
# If we'll be expanding this section, everything before the first
# level-3 section title ("###...") following the first level-2 # level-3 section title ("###...") following the first level-2
# section title ("##...") is passed through as the header # section title ("##...") is passed through as the header
# and everything after the second level-2 section title is passed # and everything after the second level-2 section title is passed
# through as the trailer. Inside the first level-2 section, # through as the trailer. Inside the first level-2 section,
# split out the level-3 sections. # split out the level-3 sections.
# If we'll be creating a new version, the header is everything
# before the point where we want to add the level-2 section
# for this version, and the trailer is what follows.
level_2_seen = 0 level_2_seen = 0
current_section = None current_section = None
for line in input_stream: for line in input_stream:
level, content = self.title_level(line) level, content = self.title_level(line)
if level == 2: if level == 2:
level_2_seen += 1 level_2_seen += 1
if level_2_seen == 1:
if self.section_is_released_version(content):
self.header.append(b'## ' +
self.unreleased_version_title() +
b'\n\n')
level_2_seen = 2
elif level == 3 and level_2_seen == 1: elif level == 3 and level_2_seen == 1:
current_section = content current_section = content
self.section_content.setdefault(content, []) self.section_content.setdefault(content, [])