Merge "Allow users to change prelude section name"
This commit is contained in:
commit
0864c37b73
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
"""
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user