allow release notes sections to be single strings

Release notes entries may now be made up of single strings. This
simplifies formatting for smaller notes, and eliminates a class of
errors associated with escaping reStructuredText inside YAML lists.

Change-Id: I7f2fb2d2fd16f49e7ee061582df7bcdd4116f215
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2017-06-05 15:33:16 -04:00
parent 942bbd8427
commit bc3d1241dd
4 changed files with 22 additions and 6 deletions

View File

@ -26,3 +26,6 @@ other:
This example is also rendered
correctly on multiple lines
as a pre-formatted block.
features:
This note is a simple string, and does not retain its
formatting when it is rendered in HTML.

View File

@ -0,0 +1,5 @@
---
features:
Release notes entries may now be made up of single strings. This
simplifies formatting for smaller notes, and eliminates a class of
errors associated with escaping reStructuredText inside YAML lists.

View File

@ -101,6 +101,8 @@ class Loader(object):
body = self._scanner.get_file_at_commit(filename, sha)
content = yaml.safe_load(body)
cleaned_content = {}
for section_name, section_content in content.items():
if section_name == 'prelude':
if not isinstance(section_content, six.string_types):
@ -111,10 +113,15 @@ class Loader(object):
filename,
)
else:
if not isinstance(section_content, list):
if isinstance(section_content, six.string_types):
# A single string is OK, but wrap it with a list
# so the rest of the code can treat the data model
# consistently.
section_content = [section_content]
elif not isinstance(section_content, list):
LOG.warning(
('The %s section of %s '
'does not parse as a list of strings. '
'does not parse as a string or list of strings. '
'Is the YAML input escaped properly?') % (
section_name, filename),
)
@ -128,5 +135,6 @@ class Loader(object):
) % (item, section_name,
filename, type(item)),
)
cleaned_content[section_name] = section_content
return content
return cleaned_content

View File

@ -67,7 +67,7 @@ class TestValidate(base.TestCase):
ldr.parse_note_file('note1', None)
self.assertIn('prelude', self.logger.output)
def test_non_prelude_single_string(self):
def test_non_prelude_single_string_converted_to_list(self):
note_bodies = yaml.safe_load(textwrap.dedent('''
issues: |
This is a single string.
@ -75,8 +75,8 @@ class TestValidate(base.TestCase):
print(type(note_bodies['issues']))
self.assertIsInstance(note_bodies['issues'], six.string_types)
ldr = self._make_loader(note_bodies)
ldr.parse_note_file('note1', None)
self.assertIn('list of strings', self.logger.output)
parse_results = ldr.parse_note_file('note1', None)
self.assertIsInstance(parse_results['issues'], list)
def test_note_with_colon_as_dict(self):
note_bodies = yaml.safe_load(textwrap.dedent('''