add an internal sphinx extension to show the configuration defaults
Rather than relying on contributors to add configuration data to the usage page by hand, extract the information from the help text for the configuration options. Merge some of the existing documentation text with the old comments that were turned into help text (and remove the comment markers left behind in the last patch). Change-Id: Ic89e6f0a083648d332ae81d20b2adbf59e4207ce Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
parent
fab39dfcc8
commit
7d419d4df6
@ -25,7 +25,6 @@ else:
|
||||
has_theme = True
|
||||
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
@ -34,6 +33,7 @@ extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
# 'sphinx.ext.intersphinx',
|
||||
'reno.sphinxext',
|
||||
'reno._exts.show_reno_config',
|
||||
]
|
||||
|
||||
if has_theme:
|
||||
|
@ -220,102 +220,7 @@ using command-line switches. For example:
|
||||
|
||||
The following options are configurable:
|
||||
|
||||
`notesdir`
|
||||
The notes subdirectory within the `relnotesdir` where the notes live.
|
||||
|
||||
Defaults to ``notes``.
|
||||
|
||||
`collapse_pre_releases`
|
||||
Should pre-release versions be merged into the final release of the same
|
||||
number (`1.0.0.0a1` notes appear under `1.0.0`).
|
||||
|
||||
Defaults to ``True``.
|
||||
|
||||
`stop_at_branch_base`
|
||||
Should the scanner stop at the base of a branch (True) or go ahead and scan
|
||||
the entire history (False)?
|
||||
|
||||
Defaults to ``True``.
|
||||
|
||||
`branch`
|
||||
The git branch to scan. If a stable branch is specified but does not exist,
|
||||
reno attempts to automatically convert that to an "end-of-life" tag. For
|
||||
example, ``origin/stable/liberty`` would be converted to ``liberty-eol``.
|
||||
|
||||
Defaults to the "current" branch checked out.
|
||||
|
||||
`earliest_version`
|
||||
The earliest version to be included. This is usually the lowest version
|
||||
number, and is meant to be the oldest version. If unset, all versions will be
|
||||
scanned.
|
||||
|
||||
Defaults to ``None``.
|
||||
|
||||
`template`
|
||||
The template used by reno new to create a note.
|
||||
|
||||
`release_tag_re`
|
||||
The regex pattern used to match the repo tags representing a valid release
|
||||
version. The pattern is compiled with the verbose and unicode flags enabled.
|
||||
|
||||
Defaults to ``((?:[\d.ab]|rc)+)``.
|
||||
|
||||
`pre_release_tag_re`
|
||||
The regex pattern used to check if a valid release version tag is also a
|
||||
valid pre-release version. The pattern is compiled with the verbose and
|
||||
unicode flags enabled. The pattern must define a group called `pre_release`
|
||||
that matches the pre-release part of the tag and any separator, e.g for
|
||||
pre-release version `12.0.0.0rc1` the default RE pattern will identify
|
||||
`.0rc1` as the value of the group 'pre_release'.
|
||||
|
||||
Defaults to ``(?P<pre_release>\.\d+(?:[ab]|rc)+\d*)$``.
|
||||
|
||||
`branch_name_re`
|
||||
The pattern for names for branches that are relevant when scanning history to
|
||||
determine where to stop, to find the "base" of a branch. Other branches are
|
||||
ignored.
|
||||
|
||||
Defaults to ``stable/.+``.
|
||||
|
||||
`sections`
|
||||
The identifiers and names of permitted sections in the release notes, in the
|
||||
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
|
||||
stable branches back into the master branch. This confuses the
|
||||
regular traversal because it makes that stable branch appear to be
|
||||
part of master and/or the later stable branch. This option allows us
|
||||
to ignore those.
|
||||
|
||||
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 into the current branch
|
||||
but nothing else.
|
||||
|
||||
Defaults to ``True``.
|
||||
|
||||
`ignore_notes`
|
||||
A list of filenames or UIDs for notes that should be ignored by the
|
||||
reno scanner. It is most useful to set this when a note is edited on
|
||||
the wrong branch, making it appear to be part of a release that it
|
||||
is not.
|
||||
|
||||
.. warning::
|
||||
|
||||
Setting the option in the main configuration file makes it apply
|
||||
to all branches. To ignore a note in the HTML build, use the
|
||||
``ignore-notes`` parameter to the ``release-notes`` sphinx
|
||||
directive.
|
||||
.. show-reno-config::
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
0
reno/_exts/__init__.py
Normal file
0
reno/_exts/__init__.py
Normal file
75
reno/_exts/show_reno_config.py
Normal file
75
reno/_exts/show_reno_config.py
Normal file
@ -0,0 +1,75 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers import rst
|
||||
from docutils.statemachine import ViewList
|
||||
|
||||
from sphinx.util.nodes import nested_parse_with_titles
|
||||
|
||||
from reno import config
|
||||
import six
|
||||
|
||||
|
||||
def _multi_line_string(s, indent=''):
|
||||
output_lines = s.splitlines()
|
||||
if not output_lines[0].strip():
|
||||
output_lines = output_lines[1:]
|
||||
for l in output_lines:
|
||||
yield indent + l
|
||||
|
||||
|
||||
def _format_option_help(options):
|
||||
"Produce RST lines for the configuration options."
|
||||
for opt in options:
|
||||
yield '``{}``'.format(opt.name)
|
||||
for l in _multi_line_string(opt.help, ' '):
|
||||
yield l
|
||||
yield ''
|
||||
if isinstance(opt.default, six.string_types) and '\n' in opt.default:
|
||||
# Multi-line string
|
||||
yield ' Defaults to'
|
||||
yield ''
|
||||
yield ' ::'
|
||||
yield ''
|
||||
for l in _multi_line_string(opt.default, ' '):
|
||||
yield l
|
||||
else:
|
||||
yield ' Defaults to ``{!r}``'.format(opt.default)
|
||||
yield ''
|
||||
|
||||
|
||||
class ShowConfigDirective(rst.Directive):
|
||||
|
||||
option_spec = {}
|
||||
|
||||
has_content = True
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
app = env.app
|
||||
|
||||
result = ViewList()
|
||||
source_name = '<' + __name__ + '>'
|
||||
for line in _format_option_help(config._OPTIONS):
|
||||
app.info(line)
|
||||
result.append(line, source_name)
|
||||
|
||||
node = nodes.section()
|
||||
node.document = self.state.document
|
||||
nested_parse_with_titles(self.state, result, node)
|
||||
|
||||
return node.children
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('show-reno-config', ShowConfigDirective)
|
121
reno/config.py
121
reno/config.py
@ -26,71 +26,74 @@ Opt = collections.namedtuple('Opt', 'name default help')
|
||||
|
||||
_OPTIONS = [
|
||||
Opt('notesdir', defaults.NOTES_SUBDIR,
|
||||
textwrap.dedent("""
|
||||
textwrap.dedent("""\
|
||||
The notes subdirectory within the relnotesdir where the
|
||||
notes live.
|
||||
""")),
|
||||
|
||||
Opt('collapse_pre_releases', True,
|
||||
textwrap.dedent("""
|
||||
textwrap.dedent("""\
|
||||
Should pre-release versions be merged into the final release
|
||||
of the same number (1.0.0.0a1 notes appear under 1.0.0).
|
||||
""")),
|
||||
|
||||
Opt('stop_at_branch_base', True,
|
||||
textwrap.dedent("""
|
||||
textwrap.dedent("""\
|
||||
Should the scanner stop at the base of a branch (True) or go
|
||||
ahead and scan the entire history (False)?
|
||||
""")),
|
||||
|
||||
Opt('branch', None,
|
||||
textwrap.dedent("""
|
||||
# The git branch to scan. Defaults to the "current" branch
|
||||
# checked out.
|
||||
textwrap.dedent("""\
|
||||
The git branch to scan. Defaults to the "current" branch
|
||||
checked out. If a stable branch is specified but does not
|
||||
exist, reno attempts to automatically convert that to an
|
||||
"end-of-life" tag. For example, ``origin/stable/liberty``
|
||||
would be converted to ``liberty-eol``.
|
||||
""")),
|
||||
|
||||
Opt('earliest_version', None,
|
||||
textwrap.dedent("""
|
||||
# The earliest version to be included. This is usually the
|
||||
# lowest version number, and is meant to be the oldest
|
||||
# version.
|
||||
textwrap.dedent("""\
|
||||
The earliest version to be included. This is usually the
|
||||
lowest version number, and is meant to be the oldest
|
||||
version. If unset, all versions will be scanned.
|
||||
""")),
|
||||
|
||||
Opt('template', defaults.TEMPLATE.format(defaults.PRELUDE_SECTION_NAME),
|
||||
textwrap.dedent("""
|
||||
# The template used by reno new to create a note.
|
||||
textwrap.dedent("""\
|
||||
The template used by reno new to create a note.
|
||||
""")),
|
||||
|
||||
Opt('release_tag_re',
|
||||
textwrap.dedent('''
|
||||
textwrap.dedent('''\
|
||||
((?:[\d.ab]|rc)+) # digits, a, b, and rc cover regular and
|
||||
# pre-releases
|
||||
'''),
|
||||
textwrap.dedent("""
|
||||
# The RE pattern used to match the repo tags representing a valid
|
||||
# release version. The pattern is compiled with the verbose and unicode
|
||||
# flags enabled.
|
||||
textwrap.dedent("""\
|
||||
The regex pattern used to match the repo tags representing a
|
||||
valid release version. The pattern is compiled with the
|
||||
verbose and unicode flags enabled.
|
||||
""")),
|
||||
|
||||
Opt('pre_release_tag_re',
|
||||
textwrap.dedent('''
|
||||
textwrap.dedent('''\
|
||||
(?P<pre_release>\.\d+(?:[ab]|rc)+\d*)$
|
||||
'''),
|
||||
textwrap.dedent("""
|
||||
# The RE pattern used to check if a valid release version tag is also a
|
||||
# valid pre-release version. The pattern is compiled with the verbose
|
||||
# and unicode flags enabled. The pattern must define a group called
|
||||
# 'pre_release' that matches the pre-release part of the tag and any
|
||||
# separator, e.g for pre-release version '12.0.0.0rc1' the default RE
|
||||
# pattern will identify '.0rc1' as the value of the group
|
||||
# 'pre_release'.
|
||||
textwrap.dedent("""\
|
||||
The regex pattern used to check if a valid release version tag
|
||||
is also a valid pre-release version. The pattern is compiled
|
||||
with the verbose and unicode flags enabled. The pattern must
|
||||
define a group called 'pre_release' that matches the
|
||||
pre-release part of the tag and any separator, e.g for
|
||||
pre-release version '12.0.0.0rc1' the default pattern will
|
||||
identify '.0rc1' as the value of the group 'pre_release'.
|
||||
""")),
|
||||
|
||||
Opt('branch_name_re', 'stable/.+',
|
||||
textwrap.dedent("""
|
||||
# The pattern for names for branches that are relevant when
|
||||
# scanning history to determine where to stop, to find the
|
||||
# "base" of a branch. Other branches are ignored.
|
||||
textwrap.dedent("""\
|
||||
The pattern for names for branches that are relevant when
|
||||
scanning history to determine where to stop, to find the
|
||||
"base" of a branch. Other branches are ignored.
|
||||
""")),
|
||||
|
||||
Opt('sections',
|
||||
@ -104,42 +107,46 @@ _OPTIONS = [
|
||||
['fixes', 'Bug Fixes'],
|
||||
['other', 'Other Notes'],
|
||||
],
|
||||
textwrap.dedent("""
|
||||
# The identifiers and names of permitted sections in the
|
||||
# release notes, in the order in which the final report will
|
||||
# be generated. A prelude section will always be automatically
|
||||
# inserted before the first element of this list.
|
||||
textwrap.dedent("""\
|
||||
The identifiers and names of permitted sections in the
|
||||
release notes, in the order in which the final report will
|
||||
be generated. A prelude section will always be automatically
|
||||
inserted before the first element of this list.
|
||||
""")),
|
||||
|
||||
Opt('prelude_section_name', defaults.PRELUDE_SECTION_NAME,
|
||||
textwrap.dedent("""
|
||||
# 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.
|
||||
textwrap.dedent("""\
|
||||
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.
|
||||
""")),
|
||||
|
||||
Opt('ignore_null_merges', True,
|
||||
textwrap.dedent("""
|
||||
# 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
|
||||
# into the current branch but nothing else.
|
||||
#
|
||||
# OpenStack used to use null-merges to bring final release
|
||||
# tags from stable branches back into the master branch. This
|
||||
# confuses the regular traversal because it makes that stable
|
||||
# branch appear to be part of master and/or the later stable
|
||||
# branch. This option allows us to ignore those.
|
||||
textwrap.dedent("""\
|
||||
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
|
||||
into the current branch but nothing else.
|
||||
|
||||
OpenStack used to use null-merges to bring final release
|
||||
tags from stable branches back into the master branch. This
|
||||
confuses the regular traversal because it makes that stable
|
||||
branch appear to be part of master and/or the later stable
|
||||
branch. This option allows us to ignore those.
|
||||
""")),
|
||||
|
||||
Opt('ignore_notes', [],
|
||||
textwrap.dedent("""
|
||||
# Note files to be ignored. It's useful to be able to ignore a
|
||||
# file if it is edited on the wrong branch. Notes should be
|
||||
# specified by their filename or UID. Setting the value in the
|
||||
# configuration file makes it apply to all branches.
|
||||
textwrap.dedent("""\
|
||||
Note files to be ignored. It's useful to be able to ignore a
|
||||
file if it is edited on the wrong branch. Notes should be
|
||||
specified by their filename or UID.
|
||||
|
||||
Setting the option in the main configuration file makes it
|
||||
apply to all branches. To ignore a note in the HTML build, use
|
||||
the ``ignore-notes`` parameter to the ``release-notes`` sphinx
|
||||
directive.
|
||||
""")),
|
||||
]
|
||||
|
||||
|
126
reno/tests/test_exts.py
Normal file
126
reno/tests/test_exts.py
Normal file
@ -0,0 +1,126 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import textwrap
|
||||
|
||||
from reno._exts import show_reno_config
|
||||
from reno import config
|
||||
from reno.tests import base
|
||||
|
||||
|
||||
class TestMultiLineString(base.TestCase):
|
||||
|
||||
def test_no_indent(self):
|
||||
input = textwrap.dedent("""\
|
||||
The notes subdirectory within the relnotesdir where the
|
||||
notes live.
|
||||
""")
|
||||
expected = '\n'.join([
|
||||
'The notes subdirectory within the relnotesdir where the',
|
||||
'notes live.',
|
||||
])
|
||||
actual = '\n'.join(show_reno_config._multi_line_string(input))
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_with_indent(self):
|
||||
input = textwrap.dedent("""\
|
||||
The notes subdirectory within the relnotesdir where the
|
||||
notes live.
|
||||
""")
|
||||
expected = '\n'.join([
|
||||
' The notes subdirectory within the relnotesdir where the',
|
||||
' notes live.',
|
||||
])
|
||||
actual = '\n'.join(show_reno_config._multi_line_string(input, ' '))
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_first_line_blank(self):
|
||||
input = textwrap.dedent("""
|
||||
The notes subdirectory within the relnotesdir where the
|
||||
notes live.
|
||||
""")
|
||||
expected = '\n'.join([
|
||||
' The notes subdirectory within the relnotesdir where the',
|
||||
' notes live.',
|
||||
])
|
||||
actual = '\n'.join(show_reno_config._multi_line_string(input, ' '))
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
class TestFormatOptionHelp(base.TestCase):
|
||||
|
||||
def test_simple_default(self):
|
||||
opt = config.Opt(
|
||||
'notesdir', 'path/to/notes',
|
||||
textwrap.dedent("""\
|
||||
The notes subdirectory within the relnotesdir where the
|
||||
notes live.
|
||||
"""),
|
||||
)
|
||||
actual = '\n'.join(show_reno_config._format_option_help([opt]))
|
||||
expected = textwrap.dedent("""\
|
||||
``notesdir``
|
||||
The notes subdirectory within the relnotesdir where the
|
||||
notes live.
|
||||
|
||||
Defaults to ``'path/to/notes'``
|
||||
""")
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_bool_default(self):
|
||||
opt = config.Opt(
|
||||
'collapse_pre_releases', True,
|
||||
textwrap.dedent("""\
|
||||
Should pre-release versions be merged into the final release
|
||||
of the same number (1.0.0.0a1 notes appear under 1.0.0).
|
||||
"""),
|
||||
)
|
||||
actual = '\n'.join(show_reno_config._format_option_help([opt]))
|
||||
expected = textwrap.dedent("""\
|
||||
``collapse_pre_releases``
|
||||
Should pre-release versions be merged into the final release
|
||||
of the same number (1.0.0.0a1 notes appear under 1.0.0).
|
||||
|
||||
Defaults to ``True``
|
||||
""")
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_multiline_default(self):
|
||||
opt = config.Opt(
|
||||
'release_tag_re',
|
||||
textwrap.dedent('''\
|
||||
((?:[\d.ab]|rc)+) # digits, a, b, and rc cover regular and
|
||||
# pre-releases
|
||||
'''),
|
||||
textwrap.dedent("""\
|
||||
The regex pattern used to match the repo tags representing a
|
||||
valid release version. The pattern is compiled with the
|
||||
verbose and unicode flags enabled.
|
||||
"""),
|
||||
)
|
||||
actual = '\n'.join(show_reno_config._format_option_help([opt]))
|
||||
expected = textwrap.dedent("""\
|
||||
``release_tag_re``
|
||||
The regex pattern used to match the repo tags representing a
|
||||
valid release version. The pattern is compiled with the
|
||||
verbose and unicode flags enabled.
|
||||
|
||||
Defaults to
|
||||
|
||||
::
|
||||
|
||||
((?:[\d.ab]|rc)+) # digits, a, b, and rc cover regular and
|
||||
# pre-releases
|
||||
""")
|
||||
self.assertEqual(expected, actual)
|
Loading…
Reference in New Issue
Block a user