Skip to content
This repository has been archived by the owner on Mar 8, 2024. It is now read-only.

Commit

Permalink
feat(writer): Sort changes in changelog by breaking changes, scoped c…
Browse files Browse the repository at this point in the history
…hanges then by issue ref. (#78)

Refs: 75
Authors: (edgy)
  • Loading branch information
EdgyEdgemond authored Mar 2, 2024
1 parent eed0a04 commit 21021dd
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 14 deletions.
5 changes: 5 additions & 0 deletions changelog_gen/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ class Change: # noqa: D101
scope: str = ""
breaking: bool = False

def __lt__(self: typing.Self, other: Change) -> bool: # noqa: D105
s = (not self.breaking, self.scope if self.scope else "zzz", self.issue_ref)
o = (not other.breaking, other.scope if other.scope else "zzz", other.issue_ref)
return s < o


SectionDict = dict[str, dict[str, Change]]

Expand Down
18 changes: 13 additions & 5 deletions changelog_gen/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ def consume(self: typing.Self, supported_sections: dict[str, str], sections: Sec
def add_section(self: typing.Self, header: str, lines: dict[str, dict]) -> None:
"""Add a section to changelog file."""
self._add_section_header(header)
# TODO(edgy): sort based on change attributes
# https://github.com/EdgyEdgemond/changelog-gen/issues/75
for _, change in sorted(lines.items()):
description = f"{change.scope} {change.description}" if change.scope else change.description
description = f"**Breaking:** {description}" if change.breaking else description
for change in sorted(lines.values()):
description = (
f"{self.italic_string(change.scope)} {change.description}" if change.scope else change.description
)
description = f"{self.bold_string('Breaking:')} {description}" if change.breaking else description
description = f"{description} {change.authors}" if change.authors else description

self._add_section_line(
Expand All @@ -67,6 +67,14 @@ def add_section(self: typing.Self, header: str, lines: dict[str, dict]) -> None:
)
self._post_section()

def bold_string(self: typing.Self, string: str) -> str:
"""Render a string as bold."""
return f"**{string}**"

def italic_string(self: typing.Self, string: str) -> str:
"""Render a string as italic."""
return f"*{string}*"

def _add_section_header(self: typing.Self, header: str) -> None:
raise NotImplementedError

Expand Down
22 changes: 22 additions & 0 deletions tests/test_extractor.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import random
from unittest import mock

import pytest
Expand Down Expand Up @@ -333,3 +334,24 @@ def test_extract_version_tag(sections, semver_mapping, expected_semver, monkeypa
extractor.extract_version_tag(sections, semver_mapping)

assert extractor.BumpVersion.get_version_info.call_args == mock.call(expected_semver)


def test_change_ordering():
changes = [
Change(issue_ref="23", description="Small change", authors="(edgy, tom)", scope="", breaking=False),
Change(issue_ref="24", description="A description", authors="(edgy)", scope="(writer)", breaking=True),
Change(issue_ref="25", description="Another change", authors="(tom)", scope="(extractor)", breaking=False),
Change(issue_ref="26", description="Bugfix", authors="", scope="(extractor)", breaking=False),
Change(issue_ref="27", description="Upgrade python", authors="(tom)", scope="", breaking=True),
Change(issue_ref="28", description="Update config", authors="(edgy)", scope="(config)", breaking=False),
]
random.shuffle(changes)

assert sorted(changes) == [
Change(issue_ref="24", description="A description", authors="(edgy)", scope="(writer)", breaking=True),
Change(issue_ref="27", description="Upgrade python", authors="(tom)", scope="", breaking=True),
Change(issue_ref="28", description="Update config", authors="(edgy)", scope="(config)", breaking=False),
Change(issue_ref="25", description="Another change", authors="(tom)", scope="(extractor)", breaking=False),
Change(issue_ref="26", description="Bugfix", authors="", scope="(extractor)", breaking=False),
Change(issue_ref="23", description="Small change", authors="(edgy, tom)", scope="", breaking=False),
]
40 changes: 31 additions & 9 deletions tests/test_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,30 @@ def test_add_section(self, monkeypatch, changelog):
assert w._add_section_header.call_args == mock.call("header")
assert w._add_section_line.call_args_list == [
mock.call("**Breaking:** line1", "1"),
mock.call("*(config)* line3", "3"),
mock.call("line2 (a, b)", "2"),
]

def test_add_section_sorting(self, monkeypatch, changelog):
monkeypatch.setattr(writer.BaseWriter, "_add_section_header", mock.Mock())
monkeypatch.setattr(writer.BaseWriter, "_add_section_line", mock.Mock())

w = writer.BaseWriter(changelog)

w.add_section(
"header",
{
"3": Change("3", "line3", breaking=True),
"2": Change("2", "line2", authors="(a, b)"),
"1": Change("1", "line1", scope="(config)"),
},
)

assert w._add_section_header.call_args == mock.call("header")
assert w._add_section_line.call_args_list == [
mock.call("**Breaking:** line3", "3"),
mock.call("*(config)* line1", "1"),
mock.call("line2 (a, b)", "2"),
mock.call("(config) line3", "3"),
]


Expand Down Expand Up @@ -258,9 +280,9 @@ def test_write(self, changelog_md):
### header
- *(config)* line3 [#3]
- line1 [#1]
- line2 [#2]
- (config) line3 [#3]
"""
)

Expand Down Expand Up @@ -299,9 +321,9 @@ def test_write_with_existing_content(self, changelog_md):
### header
- *(config)* line6 [#6]
- line4 [#4]
- line5 [#5]
- (config) line6 [#6]
## 0.0.1
Expand Down Expand Up @@ -436,12 +458,12 @@ def test_str_with_links(self, changelog_rst):
header
------
* *(config)* line3 [`#3`_]
* line1 [`#1`_]
* line2 [`#2`_]
* (config) line3 [`#3`_]
.. _`#1`: http://url/issues/1
.. _`#2`: http://url/issues/2
.. _`#3`: http://url/issues/3
Expand Down Expand Up @@ -494,11 +516,11 @@ def test_write(self, changelog_rst):
header
------
* *(config)* line3 [#3]
* line1 [#1]
* line2 [#2]
* (config) line3 [#3]
"""
)

Expand Down Expand Up @@ -547,12 +569,12 @@ def test_write_with_existing_content(self, changelog_rst):
header
------
* *(config)* line6 [`#6`_]
* line4 [`#4`_]
* line5 [`#5`_]
* (config) line6 [`#6`_]
0.0.1
=====
Expand Down

0 comments on commit 21021dd

Please sign in to comment.