Merge "Allow users to change prelude section name"

This commit is contained in:
Jenkins 2017-07-05 22:08:23 +00:00 committed by Gerrit Code Review
commit 0864c37b73
7 changed files with 151 additions and 99 deletions

View File

@ -56,8 +56,8 @@ list:
prelude
General comments about the release. The prelude from all notes in a
section are combined, in note order, to produce a single prelude
General comments about the release. Prelude sections from all notes in a
release are combined, in note order, to produce a single prelude
introducing that release. This section is always included, regardless
of what sections are configured.
@ -197,6 +197,9 @@ the most convenient way to manage the values consistently.
- [api, API Changes]
- [security, Security Issues]
- [fixes, Bug Fixes]
# Change prelude_section_name to 'release_summary' from default value
# 'prelude'.
prelude_section_name: release_summary
template: |
<template-used-to-create-new-notes>
...
@ -284,6 +287,15 @@ The following options are configurable:
order in which the final report will be generated. A prelude section will
always be automatically inserted before the first element of this list.
`prelude_section_name`
The name of the prelude section in the note template. Note that the
value for this must be a single word, but can have underscores. The
value is displayed in titlecase in the report after replacing
underscores with spaces.
Defaults to ``prelude``
`ignore_null_merges`
OpenStack used to use null-merges to bring final release tags from

View File

@ -19,74 +19,6 @@ from reno import defaults
LOG = logging.getLogger(__name__)
_TEMPLATE = """\
---
prelude: >
Replace this text with content to appear at the top of the section for this
release. All of the prelude content is merged together and then rendered
separately from the items listed in other parts of the file, so the text
needs to be worded so that both the prelude and the other items make sense
when read independently. This may mean repeating some details. Not every
release note requires a prelude. Usually only notes describing major
features or adding release theme details should have a prelude.
features:
- |
List new features here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
issues:
- |
List known issues here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
upgrade:
- |
List upgrade notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
deprecations:
- |
List deprecations notes here, or remove this section. All of the list
items in this section are combined when the release notes are rendered, so
the text needs to be worded so that it does not depend on any information
only available in another section, such as the prelude. This may mean
repeating some details.
critical:
- |
Add critical notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
security:
- |
Add security notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
fixes:
- |
Add normal bug fixes here, or remove this section. All of the list items
in this section are combined when the release notes are rendered, so the
text needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
other:
- |
Add other notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
"""
class Config(object):
@ -113,7 +45,7 @@ class Config(object):
'earliest_version': None,
# The template used by reno new to create a note.
'template': _TEMPLATE,
'template': defaults.TEMPLATE.format(defaults.PRELUDE_SECTION_NAME),
# The RE pattern used to match the repo tags representing a valid
# release version. The pattern is compiled with the verbose and unicode
@ -154,6 +86,13 @@ class Config(object):
['other', 'Other Notes'],
],
# The name of the prelude section in the note template. This
# allows users to rename the section to, for example,
# 'release_summary' or 'project_wide_general_announcements',
# which is displayed in titlecase in the report after
# replacing underscores with spaces.
'prelude_section_name': defaults.PRELUDE_SECTION_NAME,
# When this option is set to True, any merge commits with no
# changes and in which the second or later parent is tagged
# are considered "null-merges" that bring the tag information
@ -220,6 +159,13 @@ class Config(object):
else:
self.override(**self._contents)
def _rename_prelude_section(self, **kwargs):
key = 'prelude_section_name'
if key in kwargs and kwargs[key] != self._OPTS[key]:
new_prelude_name = kwargs[key]
self.template = defaults.TEMPLATE.format(new_prelude_name)
def override(self, **kwds):
"""Set the values of the named configuration options.
@ -228,6 +174,9 @@ class Config(object):
present.
"""
# Replace prelude section name if it has been changed.
self._rename_prelude_section(**kwds)
for n, v in kwds.items():
if n not in self._OPTS:
LOG.warning('ignoring unknown configuration value %r = %r',
@ -269,6 +218,15 @@ class Config(object):
"""
return os.path.join(self.relnotesdir, self.notesdir)
@property
def options(self):
"""Get all configuration options as a dict.
Returns the actual configuration options after overrides.
"""
options = {o: getattr(self, o) for o in self._OPTS}
return options
# def parse_config_into(parsed_arguments):
# """Parse the user config onto the namespace arguments.

View File

@ -12,3 +12,72 @@
RELEASE_NOTES_SUBDIR = 'releasenotes'
NOTES_SUBDIR = 'notes'
PRELUDE_SECTION_NAME = 'prelude'
# This is a format string, so it needs to be formatted wherever it is used.
TEMPLATE = """\
---
{0}: >
Replace this text with content to appear at the top of the section for this
release. All of the prelude content is merged together and then rendered
separately from the items listed in other parts of the file, so the text
needs to be worded so that both the prelude and the other items make sense
when read independently. This may mean repeating some details. Not every
release note requires a prelude. Usually only notes describing major
features or adding release theme details should have a prelude.
features:
- |
List new features here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
issues:
- |
List known issues here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
upgrade:
- |
List upgrade notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
deprecations:
- |
List deprecations notes here, or remove this section. All of the list
items in this section are combined when the release notes are rendered, so
the text needs to be worded so that it does not depend on any information
only available in another section, such as the prelude. This may mean
repeating some details.
critical:
- |
Add critical notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
security:
- |
Add security notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
fixes:
- |
Add normal bug fixes here, or remove this section. All of the list items
in this section are combined when the release notes are rendered, so the
text needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
other:
- |
Add other notes here, or remove this section. All of the list items in
this section are combined when the release notes are rendered, so the text
needs to be worded so that it does not depend on any information only
available in another section, such as the prelude. This may mean repeating
some details.
"""

View File

@ -48,13 +48,21 @@ def format_report(loader, config, versions_to_include, title=None,
# Add the preludes.
notefiles = loader[version]
for n, sha in notefiles:
if 'prelude' in file_contents[n]:
if show_source:
report.append('.. %s @ %s\n' % (n, sha))
report.append(file_contents[n]['prelude'])
report.append('')
prelude_name = config.prelude_section_name
notefiles_with_prelude = [(n, sha) for n, sha in notefiles
if prelude_name in file_contents[n]]
if notefiles_with_prelude:
report.append(prelude_name.replace('_', ' ').title())
report.append('-' * len(prelude_name))
report.append('')
for n, sha in notefiles_with_prelude:
if show_source:
report.append('.. %s @ %s\n' % (n, sha))
report.append(file_contents[n][prelude_name])
report.append('')
# Add other sections.
for section_name, section_title in config.sections:
notes = [
(n, fn, sha)

View File

@ -30,8 +30,8 @@ def lint_cmd(args, conf):
error = 0
load = loader.Loader(conf, ignore_cache=True)
allowed_section_names = ['prelude'] + [s[0] for s in conf.sections]
allowed_section_names = [conf.prelude_section_name] + \
[s[0] for s in conf.sections]
uids = {}
for f in notes:

View File

@ -104,13 +104,13 @@ class Loader(object):
cleaned_content = {}
for section_name, section_content in content.items():
if section_name == 'prelude':
if section_name == self._config.prelude_section_name:
if not isinstance(section_content, six.string_types):
LOG.warning(
('The prelude section of %s '
('The %s section of %s '
'does not parse as a single string. '
'Is the YAML input escaped properly?') %
filename,
(self._config.prelude_section_name, filename),
)
else:
if isinstance(section_content, six.string_types):

View File

@ -17,6 +17,7 @@ import os
import fixtures
from reno import config
from reno import defaults
from reno import main
from reno.tests import base
@ -35,10 +36,7 @@ collapse_pre_releases: false
def test_defaults(self):
c = config.Config(self.tempdir.path)
actual = {
o: getattr(c, o)
for o in config.Config._OPTS.keys()
}
actual = c.options
self.assertEqual(config.Config._OPTS, actual)
def test_override(self):
@ -46,10 +44,7 @@ collapse_pre_releases: false
c.override(
collapse_pre_releases=False,
)
actual = {
o: getattr(c, o)
for o in config.Config._OPTS.keys()
}
actual = c.options
expected = {}
expected.update(config.Config._OPTS)
expected['collapse_pre_releases'] = False
@ -63,10 +58,7 @@ collapse_pre_releases: false
c.override(
notesdir='value2',
)
actual = {
o: getattr(c, o)
for o in config.Config._OPTS.keys()
}
actual = c.options
expected = {}
expected.update(config.Config._OPTS)
expected['notesdir'] = 'value2'
@ -125,10 +117,7 @@ collapse_pre_releases: false
c = self._run_override_from_parsed_args([
'--no-collapse-pre-releases',
])
actual = {
o: getattr(c, o)
for o in config.Config._OPTS.keys()
}
actual = c.options
expected = {}
expected.update(config.Config._OPTS)
expected['collapse_pre_releases'] = False
@ -164,6 +153,22 @@ class TestConfigProperties(base.TestCase):
self.assertEqual('releasenotes/thenotes', self.c.notespath)
def test_template(self):
self.assertEqual(config._TEMPLATE, self.c.template)
template = defaults.TEMPLATE.format(defaults.PRELUDE_SECTION_NAME)
self.assertEqual(template, self.c.template)
self.c.override(template='i-am-a-template')
self.assertEqual('i-am-a-template', self.c.template)
def test_prelude_override(self):
template = defaults.TEMPLATE.format(defaults.PRELUDE_SECTION_NAME)
self.assertEqual(template, self.c.template)
self.c.override(prelude_section_name='fake_prelude_name')
expected_template = defaults.TEMPLATE.format('fake_prelude_name')
self.assertEqual(expected_template, self.c.template)
def test_prelude_and_template_override(self):
template = defaults.TEMPLATE.format(defaults.PRELUDE_SECTION_NAME)
self.assertEqual(template, self.c.template)
self.c.override(prelude_section_name='fake_prelude_name',
template='i-am-a-template')
self.assertEqual('fake_prelude_name', self.c.prelude_section_name)
self.assertEqual('i-am-a-template', self.c.template)