Skip to content

Commit 9e06722

Browse files
committed
refactor(changelog): better typing, yield
1 parent 9420b44 commit 9e06722

File tree

3 files changed

+29
-24
lines changed

3 files changed

+29
-24
lines changed

commitizen/changelog.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929

3030
import re
3131
from collections import OrderedDict, defaultdict
32-
from collections.abc import Iterable
32+
from collections.abc import Generator, Iterable, Mapping
3333
from dataclasses import dataclass
3434
from datetime import date
35-
from typing import TYPE_CHECKING
35+
from typing import TYPE_CHECKING, Any
3636

3737
from jinja2 import (
3838
BaseLoader,
@@ -84,7 +84,7 @@ def generate_tree_from_commits(
8484
changelog_message_builder_hook: MessageBuilderHook | None = None,
8585
changelog_release_hook: ChangelogReleaseHook | None = None,
8686
rules: TagRules | None = None,
87-
) -> Iterable[dict]:
87+
) -> Generator[dict[str, Any], None, None]:
8888
pat = re.compile(changelog_pattern)
8989
map_pat = re.compile(commit_parser, re.MULTILINE)
9090
body_map_pat = re.compile(commit_parser, re.MULTILINE | re.DOTALL)
@@ -187,24 +187,27 @@ def process_commit_message(
187187
changes[change_type].append(msg)
188188

189189

190-
def order_changelog_tree(tree: Iterable, change_type_order: list[str]) -> Iterable:
190+
def generate_ordered_changelog_tree(
191+
tree: Iterable[Mapping[str, Any]], change_type_order: list[str]
192+
) -> Generator[dict[str, Any], None, None]:
191193
if len(set(change_type_order)) != len(change_type_order):
192194
raise InvalidConfigurationError(
193195
f"Change types contain duplicates types ({change_type_order})"
194196
)
195197

196-
sorted_tree = []
197198
for entry in tree:
198-
ordered_change_types = change_type_order + sorted(
199-
set(entry["changes"].keys()) - set(change_type_order)
200-
)
201-
changes = [
202-
(ct, entry["changes"][ct])
203-
for ct in ordered_change_types
204-
if ct in entry["changes"]
205-
]
206-
sorted_tree.append({**entry, **{"changes": OrderedDict(changes)}})
207-
return sorted_tree
199+
yield {
200+
**entry,
201+
"changes": _calculate_sorted_changes(change_type_order, entry["changes"]),
202+
}
203+
204+
205+
def _calculate_sorted_changes(
206+
change_type_order: list[str], changes: Mapping[str, Any]
207+
) -> OrderedDict[str, Any]:
208+
remaining_change_types = set(changes.keys()) - set(change_type_order)
209+
sorted_change_types = change_type_order + sorted(remaining_change_types)
210+
return OrderedDict((ct, changes[ct]) for ct in sorted_change_types if ct in changes)
208211

209212

210213
def get_changelog_template(loader: BaseLoader, template: str) -> Template:

commitizen/commands/changelog.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ def __call__(self):
214214
rules=self.tag_rules,
215215
)
216216
if self.change_type_order:
217-
tree = changelog.order_changelog_tree(tree, self.change_type_order)
217+
tree = changelog.generate_ordered_changelog_tree(
218+
tree, self.change_type_order
219+
)
218220

219221
extras = self.cz.template_extras.copy()
220222
extras.update(self.config.settings["extras"])

tests/test_changelog.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,26 +1215,26 @@ def test_generate_tree_from_commits_with_no_commits(tags):
12151215
),
12161216
),
12171217
)
1218-
def test_order_changelog_tree(change_type_order, expected_reordering):
1219-
tree = changelog.order_changelog_tree(COMMITS_TREE, change_type_order)
1218+
def test_generate_ordered_changelog_tree(change_type_order, expected_reordering):
1219+
tree = changelog.generate_ordered_changelog_tree(COMMITS_TREE, change_type_order)
12201220

12211221
for index, entry in enumerate(tuple(tree)):
1222-
version = tree[index]["version"]
1222+
version = entry["version"]
12231223
if version in expected_reordering:
12241224
# Verify that all keys are present
1225-
assert [*tree[index].keys()] == [*COMMITS_TREE[index].keys()]
1225+
assert [*entry.keys()] == [*COMMITS_TREE[index].keys()]
12261226
# Verify that the reorder only impacted the returned dict and not the original
12271227
expected = expected_reordering[version]
1228-
assert [*tree[index]["changes"].keys()] == expected["sorted"]
1228+
assert [*entry["changes"].keys()] == expected["sorted"]
12291229
assert [*COMMITS_TREE[index]["changes"].keys()] == expected["original"]
12301230
else:
1231-
assert [*entry["changes"].keys()] == [*tree[index]["changes"].keys()]
1231+
assert [*entry["changes"].keys()] == [*entry["changes"].keys()]
12321232

12331233

1234-
def test_order_changelog_tree_raises():
1234+
def test_generate_ordered_changelog_tree_raises():
12351235
change_type_order = ["BREAKING CHANGE", "feat", "refactor", "feat"]
12361236
with pytest.raises(InvalidConfigurationError) as excinfo:
1237-
changelog.order_changelog_tree(COMMITS_TREE, change_type_order)
1237+
list(changelog.generate_ordered_changelog_tree(COMMITS_TREE, change_type_order))
12381238

12391239
assert "Change types contain duplicates types" in str(excinfo)
12401240

0 commit comments

Comments
 (0)