walk back last change slightly

preamble now contains the title, to allow for representing Jekyll front matter or any other information above the title
dev
Andrew Cassidy 3 years ago
parent a230968736
commit a925a4e420

@ -6,11 +6,13 @@ All notable changes to this project will be documented in this file
### Changed ### Changed
- API changes:
- `header` attribute renamed to `preamble` to avoid confusion.
- improved version header parsing to be more robust and handle multi-word version names. - improved version header parsing to be more robust and handle multi-word version names.
- improved version number incrementing in `release`. - improved version number incrementing in `release`.
- can now handle other text surrounding a pep440-compliant version number, which will not be modified - can now handle other text surrounding a pep440-compliant version number, which will not be modified
- can now handle pre-releases correctly. The version to increment is the most recent version in the log with a valid pep440 version number in it. Release increment and prerelease increments can be mixed, allowing e.g: `yaclog release -mr` to create a release candidate with in incremented minor version number. - can now handle pre-releases correctly. The version to increment is the most recent version in the log with a valid pep440 version number in it.
- `header` attribute on the changelog class has been split into `title` and `preamble` - Release increment and prerelease increments can be mixed, allowing e.g: `yaclog release -mr` to create a release candidate with in incremented minor version number.
### Removed ### Removed
@ -20,6 +22,7 @@ All notable changes to this project will be documented in this file
- Terminal output has color to distinguish version names/headers, sections, and git information - Terminal output has color to distinguish version names/headers, sections, and git information
## 0.3.3 - 2021-04-27 ## 0.3.3 - 2021-04-27
### Added ### Added
@ -34,6 +37,7 @@ All notable changes to this project will be documented in this file
- `release` now resets lesser version values when incrementing - `release` now resets lesser version values when incrementing
- `release` now works with logs that have only unreleased changes - `release` now works with logs that have only unreleased changes
## 0.3.2 - 2021-04-24 ## 0.3.2 - 2021-04-24
### Added ### Added
@ -49,17 +53,19 @@ All notable changes to this project will be documented in this file
- `release` and `entry` commands now work using empty changelogs. - `release` and `entry` commands now work using empty changelogs.
## 0.3.1 - 2021-04-24 ## 0.3.1 - 2021-04-24
### Added ### Added
- `yaclog` tool for manipulating changelogs from the command line - `yaclog` tool for manipulating changelogs from the command line
- `init` command to make a new changelog - `init` command to make a new changelog
- `format` command to reformat the changelog - `format` command to reformat the changelog
- `show` command to show changes from the changelog - `show` command to show changes from the changelog
- `entry` command for manipulating entries in the changelog - `entry` command for manipulating entries in the changelog
- `tag` command for manipulating tags in the changelog - `tag` command for manipulating tags in the changelog
- `release` command for creating releases - `release` command for creating releases
## 0.2.0 - 2021-04-19 ## 0.2.0 - 2021-04-19
@ -71,8 +77,9 @@ All notable changes to this project will be documented in this file
- Updated package metadata - Updated package metadata
- Rewrote parser to use a 2-step method that is more flexible. - Rewrote parser to use a 2-step method that is more flexible.
- Parser can now handle code blocks. - Parser can now handle code blocks.
- Parser can now handle setext-style headers and H2s not conforming to the schema. - Parser can now handle setext-style headers and H2s not conforming to the schema.
## 0.1.0 - 2021-04-16 ## 0.1.0 - 2021-04-16

@ -2,13 +2,9 @@
Yaclog works on markdown changelog files, using a machine-readable format based on what is proposed by [Keep a Changelog](https://keepachangelog.com). Changelog files can be created using the {command}`yaclog init` command. Yaclog works on markdown changelog files, using a machine-readable format based on what is proposed by [Keep a Changelog](https://keepachangelog.com). Changelog files can be created using the {command}`yaclog init` command.
## Title
The title is the first H1 in the file giving its title, usually `# Changlog`.
## Preamble ## Preamble
The preamble is the text at the top of the file before any version information. It can contain an explanation of the file's purpose, as well as any general machine-readable information you may want to include for use with other tools. Yaclog does not provide any ways to manipulate the front matter from the command line due to its open-ended nature. The preamble is the text at the top of the file before any version information. It can contain the title, an explanation of the file's purpose, as well as any general machine-readable information you may want to include for use with other tools. Yaclog does not provide any ways to manipulate the front matter from the command line due to its open-ended nature.
## Versions ## Versions
@ -17,9 +13,11 @@ Version information begins with a header, which is an H2 containing the version'
```markdown ```markdown
## 1.0.0 ## 1.0.0
``` ```
```markdown ```markdown
## 3.2.0 "Columbia" - 1981-07-20 ## 3.2.0 "Columbia" - 1981-07-20
``` ```
```markdown ```markdown
## Version 8.0.0rc1 1988-11-15 [PRERELEASE] ## Version 8.0.0rc1 1988-11-15 [PRERELEASE]
``` ```
@ -54,7 +52,6 @@ Yanked due to issues with oxygen tanks, currently investigating
- Replaced Ken Mattingly - Replaced Ken Mattingly
- Stirred oxygen tanks - Stirred oxygen tanks
## 0.12.0 "Intrepid" - 1969-11-14 ## 0.12.0 "Intrepid" - 1969-11-14
### Added ### Added
@ -71,7 +68,6 @@ Yanked due to issues with oxygen tanks, currently investigating
- Lightning strike during launch: No effect on performance - Lightning strike during launch: No effect on performance
## 0.11.0 "Eagle" - 1969-07-20 ## 0.11.0 "Eagle" - 1969-07-20
Initial stable release Initial stable release

@ -46,8 +46,8 @@ log_segments = [
log_text = '\n\n'.join(log_segments) log_text = '\n\n'.join(log_segments)
log = yaclog.Changelog() log = yaclog.Changelog()
log.title = 'Changelog' log.preamble = '# Changelog\n\n' \
log.preamble = ['This changelog is for testing the parser, and has many things in it that might trip it up.'] 'This changelog is for testing the parser, and has many things in it that might trip it up.'
log.links = {'id': 'http://www.koalastothemax.com'} log.links = {'id': 'http://www.koalastothemax.com'}
log.versions = [yaclog.changelog.VersionEntry(), yaclog.changelog.VersionEntry(), yaclog.changelog.VersionEntry()] log.versions = [yaclog.changelog.VersionEntry(), yaclog.changelog.VersionEntry(), yaclog.changelog.VersionEntry()]

@ -22,10 +22,6 @@ class TestParser(unittest.TestCase):
"""Test the log's path""" """Test the log's path"""
self.assertEqual(self.path, self.log.path) self.assertEqual(self.path, self.log.path)
def test_title(self):
"""Test the title at the top of the file"""
self.assertEqual(log.title, self.log.title)
def test_preamble(self): def test_preamble(self):
"""Test the preamble at the top of the file""" """Test the preamble at the top of the file"""
self.assertEqual(log.preamble, self.log.preamble) self.assertEqual(log.preamble, self.log.preamble)
@ -56,11 +52,11 @@ class TestWriter(unittest.TestCase):
log.write(cls.path) log.write(cls.path)
with open(cls.path) as fd: with open(cls.path) as fd:
cls.log_text = fd.read() cls.log_text = fd.read()
cls.log_segments = [line for line in cls.log_text.split('\n\n') if line] cls.log_segments = [line.lstrip('\n') for line in cls.log_text.split('\n\n') if line]
def test_header(self): def test_preamble(self):
"""Test the header information at the top of the file""" """Test the header information at the top of the file"""
self.assertEqual(log_segments[1], self.log_segments[1]) self.assertEqual(log_segments[0:2], self.log_segments[0:2])
def test_links(self): def test_links(self):
"""Test the links at the end of the file""" """Test the links at the end of the file"""

@ -1,6 +1,6 @@
""" """
Contains the `Changelog` class that represents a parsed changelog file that can be read from and written to Contains the `Changelog` class that represents a parsed changelog file that can be read from and written to
disk as markdown, as well as the `VersionEntry` class that represents a single version within that changelog disk as markdown, as well as the `VersionEntry` class that represents a single version within that changelog.
""" """
# yaclog: yet another changelog tool # yaclog: yet another changelog tool
@ -33,7 +33,10 @@ import yaclog.version
class VersionEntry: class VersionEntry:
"""Holds a single version entry in a :py:class:`Changelog`""" """
A serialized representation of a single version entry in a `Changelog`,
containing the changes made since the previous version
"""
_header_regex = re.compile( # THE LANGUAGE OF THE GODS _header_regex = re.compile( # THE LANGUAGE OF THE GODS
r"##\s+(?P<name>.*?)(?:\s+-)?(?:\s+(?P<date>\d{4}-\d{2}-\d{2}))?(?P<tags>(?:\s+\[[^]]*?])*)\s*$") r"##\s+(?P<name>.*?)(?:\s+-)?(?:\s+(?P<date>\d{4}-\d{2}-\d{2}))?(?P<tags>(?:\s+\[[^]]*?])*)\s*$")
@ -215,32 +218,31 @@ class VersionEntry:
class Changelog: class Changelog:
"""A changelog made up of a header, several versions, and a link table""" """
A serialized representation of a Markdown changelog made up of a preamble, multiple versions, and a link table.
"""
def __init__(self, path=None, def __init__(self, path=None,
title: str = 'Changelog', preamble: str = "Changelog\n\nAll notable changes to this project will be documented in this file"):
preamble: str = "All notable changes to this project will be documented in this file"):
""" """
Contents will be automatically read from disk if the file exists Contents will be automatically read from disk if the file exists
:param path: The changelog's path on disk :param path: The changelog's path on disk.
:param str title: The changelog title to use if the file does not exist.
:param str preamble: The changelog preamble to use if the file does not exist. :param str preamble: The changelog preamble to use if the file does not exist.
""" """
self.path = os.path.abspath(path) if path else None self.path = os.path.abspath(path) if path else None
"""The path of the changelog's file on disk""" """The path of the changelog's file on disk"""
self.title: str = title self.preamble: str = preamble
"""The title of the changelog""" """Any text at the top of the changelog before any version information, including the title.
It can contain the title, an explanation of the file's purpose, as well as any general machine-readable
self.preamble: List[str] = preamble information for use with other tools."""
"""Any text at the top of the changelog before any version information as a list of paragraphs"""
self.versions: List[VersionEntry] = [] self.versions: List[VersionEntry] = []
"""A list of versions in the changelog""" """A list of versions in the changelog, with the most recent version first"""
self.links: Dict[str, str] = {} self.links: Dict[str, str] = {}
"""Link IDs at the end of the changelog""" """Link definitions at the end of the changelog, as a dictionary of ``{id: url}``"""
if path and os.path.exists(path): if path and os.path.exists(path):
self.read() self.read()
@ -250,7 +252,7 @@ class Changelog:
Read a markdown changelog file from disk. The object's contents will be overwritten by the file contents if Read a markdown changelog file from disk. The object's contents will be overwritten by the file contents if
reading is successful. reading is successful.
:param path: The changelog's path on disk. By default, :py:attr:`~Changelog.path` is used. :param path: The changelog's path on disk. By default, :py:attr:`~Changelog.path` is used
""" """
if not path: if not path:
@ -263,8 +265,7 @@ class Changelog:
section = '' section = ''
versions = [] versions = []
title = None preamble_segments = []
preamble = []
for token in tokens: for token in tokens:
text = '\n'.join(token.lines) text = '\n'.join(token.lines)
@ -276,11 +277,8 @@ class Changelog:
elif len(versions) == 0: elif len(versions) == 0:
# we haven't encountered any version headers yet, # we haven't encountered any version headers yet,
# so its best to just add this line to the preamble or title # so its best to just add this line to the preamble
if token.kind == 'h1' and not title: preamble_segments.append(text)
title = text.strip('#').strip()
else:
preamble.append(text)
elif token.kind == 'h3': elif token.kind == 'h3':
# start of a version section # start of a version section
@ -306,14 +304,13 @@ class Changelog:
# id-matched link # id-matched link
version.link = links[version.link_id] version.link = links[version.link_id]
self.title = title self.preamble = markdown.join(preamble_segments)
self.preamble = preamble
self.versions = versions self.versions = versions
self.links = links self.links = links
def write(self, path=None) -> None: def write(self, path=None) -> None:
""" """
Write a markdown changelog to a file. Write a changelog to a Markdown file.
:param path: The changelog's path on disk. By default, :py:attr:`~Changelog.path` is used. :param path: The changelog's path on disk. By default, :py:attr:`~Changelog.path` is used.
""" """
@ -324,10 +321,8 @@ class Changelog:
segments = [] segments = []
if self.title:
segments.append(f'# {self.title}')
if self.preamble: if self.preamble:
segments += self.preamble segments.append(self.preamble)
v_links = {**self.links} v_links = {**self.links}
@ -335,7 +330,7 @@ class Changelog:
if version.link: if version.link:
v_links[version.name.lower()] = version.link v_links[version.name.lower()] = version.link
segments.append(version.text()) segments.append(version.text() + '\n')
segments += [f'[{link_id}]: {link}' for link_id, link in v_links.items()] segments += [f'[{link_id}]: {link}' for link_id, link in v_links.items()]
@ -386,7 +381,7 @@ class Changelog:
def get_version(self, name: Optional[str] = None) -> VersionEntry: def get_version(self, name: Optional[str] = None) -> VersionEntry:
""" """
Get a version from the changelog Get a version from the changelog by name
:param name: The name of the version to get, or `None` to return the most recent :param name: The name of the version to get, or `None` to return the most recent
:return: The first version with the selected name :return: The first version with the selected name

Loading…
Cancel
Save