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
- 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 number incrementing in `release`.
- 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.
- `header` attribute on the changelog class has been split into `title` and `preamble`
- 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.
### 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
## 0.3.3 - 2021-04-27
### 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 works with logs that have only unreleased changes
## 0.3.2 - 2021-04-24
### 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.
## 0.3.1 - 2021-04-24
### Added
- `yaclog` tool for manipulating changelogs from the command line
- `init` command to make a new changelog
- `format` command to reformat the changelog
- `show` command to show changes from the changelog
- `entry` command for manipulating entries in the changelog
- `tag` command for manipulating tags in the changelog
- `release` command for creating releases
- `init` command to make a new changelog
- `format` command to reformat the changelog
- `show` command to show changes from the changelog
- `entry` command for manipulating entries in the changelog
- `tag` command for manipulating tags in the changelog
- `release` command for creating releases
## 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
- Rewrote parser to use a 2-step method that is more flexible.
- Parser can now handle code blocks.
- Parser can now handle setext-style headers and H2s not conforming to the schema.
- Parser can now handle code blocks.
- Parser can now handle setext-style headers and H2s not conforming to the schema.
## 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.
## Title
The title is the first H1 in the file giving its title, usually `# Changlog`.
## 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
@ -17,9 +13,11 @@ Version information begins with a header, which is an H2 containing the version'
```markdown
## 1.0.0
```
```markdown
## 3.2.0 "Columbia" - 1981-07-20
```
```markdown
## Version 8.0.0rc1 1988-11-15 [PRERELEASE]
```
@ -54,7 +52,6 @@ Yanked due to issues with oxygen tanks, currently investigating
- Replaced Ken Mattingly
- Stirred oxygen tanks
## 0.12.0 "Intrepid" - 1969-11-14
### Added
@ -71,7 +68,6 @@ Yanked due to issues with oxygen tanks, currently investigating
- Lightning strike during launch: No effect on performance
## 0.11.0 "Eagle" - 1969-07-20
Initial stable release

@ -46,8 +46,8 @@ log_segments = [
log_text = '\n\n'.join(log_segments)
log = yaclog.Changelog()
log.title = 'Changelog'
log.preamble = ['This changelog is for testing the parser, and has many things in it that might trip it up.']
log.preamble = '# Changelog\n\n' \
'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.versions = [yaclog.changelog.VersionEntry(), yaclog.changelog.VersionEntry(), yaclog.changelog.VersionEntry()]

@ -22,10 +22,6 @@ class TestParser(unittest.TestCase):
"""Test the log's 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):
"""Test the preamble at the top of the file"""
self.assertEqual(log.preamble, self.log.preamble)
@ -56,11 +52,11 @@ class TestWriter(unittest.TestCase):
log.write(cls.path)
with open(cls.path) as fd:
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"""
self.assertEqual(log_segments[1], self.log_segments[1])
self.assertEqual(log_segments[0:2], self.log_segments[0:2])
def test_links(self):
"""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
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
@ -33,7 +33,10 @@ import yaclog.version
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
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:
"""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,
title: str = 'Changelog',
preamble: str = "All notable changes to this project will be documented in this file"):
preamble: str = "Changelog\n\nAll notable changes to this project will be documented in this file"):
"""
Contents will be automatically read from disk if the file exists
:param path: The changelog's path on disk
:param str title: The changelog title to use if the file does not exist.
:param path: The changelog's path on disk.
:param str preamble: The changelog preamble to use if the file does not exist.
"""
self.path = os.path.abspath(path) if path else None
"""The path of the changelog's file on disk"""
self.title: str = title
"""The title of the changelog"""
self.preamble: List[str] = preamble
"""Any text at the top of the changelog before any version information as a list of paragraphs"""
self.preamble: str = preamble
"""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
information for use with other tools."""
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] = {}
"""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):
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
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:
@ -263,8 +265,7 @@ class Changelog:
section = ''
versions = []
title = None
preamble = []
preamble_segments = []
for token in tokens:
text = '\n'.join(token.lines)
@ -276,11 +277,8 @@ class Changelog:
elif len(versions) == 0:
# we haven't encountered any version headers yet,
# so its best to just add this line to the preamble or title
if token.kind == 'h1' and not title:
title = text.strip('#').strip()
else:
preamble.append(text)
# so its best to just add this line to the preamble
preamble_segments.append(text)
elif token.kind == 'h3':
# start of a version section
@ -306,14 +304,13 @@ class Changelog:
# id-matched link
version.link = links[version.link_id]
self.title = title
self.preamble = preamble
self.preamble = markdown.join(preamble_segments)
self.versions = versions
self.links = links
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.
"""
@ -324,10 +321,8 @@ class Changelog:
segments = []
if self.title:
segments.append(f'# {self.title}')
if self.preamble:
segments += self.preamble
segments.append(self.preamble)
v_links = {**self.links}
@ -335,7 +330,7 @@ class Changelog:
if 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()]
@ -386,7 +381,7 @@ class Changelog:
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
:return: The first version with the selected name

Loading…
Cancel
Save