Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 49f26c4

Browse files
refactor(changelog): code cleanup
1 parent 99a102c commit 49f26c4

File tree

3 files changed

+104
-63
lines changed

3 files changed

+104
-63
lines changed

‎commitizen/changelog.py‎

Lines changed: 85 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@ def get_commit_tag(commit: GitCommit, tags: list[GitTag]) -> GitTag | None:
7474
return next((tag for tag in tags if tag.rev == commit.rev), None)
7575

7676

77+
def _get_release_info(
78+
current_tag_name: str,
79+
current_tag_date: str,
80+
changes: dict[str | None, list],
81+
changelog_release_hook: ChangelogReleaseHook | None,
82+
commit_tag: GitTag | None,
83+
) -> dict[str, Any]:
84+
release = {
85+
"version": current_tag_name,
86+
"date": current_tag_date,
87+
"changes": changes,
88+
}
89+
if changelog_release_hook:
90+
return changelog_release_hook(release, commit_tag)
91+
return release
92+
93+
7794
def generate_tree_from_commits(
7895
commits: list[GitCommit],
7996
tags: list[GitTag],
@@ -88,24 +105,24 @@ def generate_tree_from_commits(
88105
pat = re.compile(changelog_pattern)
89106
map_pat = re.compile(commit_parser, re.MULTILINE)
90107
body_map_pat = re.compile(commit_parser, re.MULTILINE | re.DOTALL)
91-
current_tag: GitTag | None = None
92108
rules = rules or TagRules()
93109

110+
used_tags: set[GitTag] = set()
111+
current_tag_name = unreleased_version or "Unreleased"
112+
current_tag_date = (
113+
date.today().isoformat() if unreleased_version is not None else ""
114+
)
115+
94116
# Check if the latest commit is not tagged
95-
if commits:
96-
latest_commit = commits[0]
97-
current_tag = get_commit_tag(latest_commit, tags)
98-
99-
current_tag_name: str = unreleased_version or "Unreleased"
100-
current_tag_date: str = ""
101-
if unreleased_version is not None:
102-
current_tag_date = date.today().isoformat()
103-
if current_tag is not None and current_tag.name:
104-
current_tag_name = current_tag.name
105-
current_tag_date = current_tag.date
106-
107-
changes: dict = defaultdict(list)
108-
used_tags: list = [current_tag]
117+
current_tag = get_commit_tag(commits[0], tags) if commits else None
118+
if current_tag is not None:
119+
used_tags.add(current_tag)
120+
if current_tag.name:
121+
current_tag_name = current_tag.name
122+
current_tag_date = current_tag.date
123+
124+
changes: defaultdict[str | None, list] = defaultdict(list)
125+
commit_tag: GitTag | None = None
109126
for commit in commits:
110127
commit_tag = get_commit_tag(commit, tags)
111128

@@ -114,21 +131,21 @@ def generate_tree_from_commits(
114131
and commit_tag not in used_tags
115132
and rules.include_in_changelog(commit_tag)
116133
):
117-
used_tags.append(commit_tag)
118-
release = {
119-
"version": current_tag_name,
120-
"date": current_tag_date,
121-
"changes": changes,
122-
}
123-
if changelog_release_hook:
124-
release = changelog_release_hook(release, commit_tag)
125-
yield release
134+
used_tags.add(commit_tag)
135+
136+
yield _get_release_info(
137+
current_tag_name,
138+
current_tag_date,
139+
changes,
140+
changelog_release_hook,
141+
commit_tag,
142+
)
143+
126144
current_tag_name = commit_tag.name
127145
current_tag_date = commit_tag.date
128146
changes = defaultdict(list)
129147

130-
matches = pat.match(commit.message)
131-
if not matches:
148+
if not pat.match(commit.message):
132149
continue
133150

134151
# Process subject from commit message
@@ -153,14 +170,13 @@ def generate_tree_from_commits(
153170
change_type_map,
154171
)
155172

156-
release = {
157-
"version": current_tag_name,
158-
"date": current_tag_date,
159-
"changes": changes,
160-
}
161-
if changelog_release_hook:
162-
release = changelog_release_hook(release, commit_tag)
163-
yield release
173+
yield _get_release_info(
174+
current_tag_name,
175+
current_tag_date,
176+
changes,
177+
changelog_release_hook,
178+
commit_tag,
179+
)
164180

165181

166182
def process_commit_message(
@@ -170,21 +186,23 @@ def process_commit_message(
170186
changes: dict[str | None, list],
171187
change_type_map: dict[str, str] | None = None,
172188
):
173-
message: dict = {
189+
message: dict[str, str|list[str] |Any] = {
174190
"sha1": commit.rev,
175191
"parents": commit.parents,
176192
"author": commit.author,
177193
"author_email": commit.author_email,
178194
**parsed.groupdict(),
179195
}
180196

181-
if processed := hook(message, commit) if hook else message:
182-
messages = [processed] if isinstance(processed, dict) else processed
183-
for msg in messages:
184-
change_type = msg.pop("change_type", None)
185-
if change_type_map:
186-
change_type = change_type_map.get(change_type, change_type)
187-
changes[change_type].append(msg)
197+
if not (processed := hook(message, commit) if hook else message):
198+
return
199+
200+
processed_messages = [processed] if isinstance(processed, dict) else processed
201+
for msg in processed_messages:
202+
change_type = msg.pop("change_type", None)
203+
if change_type_map:
204+
change_type = change_type_map.get(change_type, change_type)
205+
changes[change_type].append(msg)
188206

189207

190208
def generate_ordered_changelog_tree(
@@ -228,8 +246,7 @@ def render_changelog(
228246
**kwargs,
229247
) -> str:
230248
jinja_template = get_changelog_template(loader, template)
231-
changelog: str = jinja_template.render(tree=tree, **kwargs)
232-
return changelog
249+
return jinja_template.render(tree=tree, **kwargs)
233250

234251

235252
def incremental_build(
@@ -256,7 +273,9 @@ def incremental_build(
256273
for index, line in enumerate(lines):
257274
if index == unreleased_start:
258275
skip = True
259-
elif index == unreleased_end:
276+
continue
277+
278+
if index == unreleased_end:
260279
skip = False
261280
if (
262281
latest_version_position is None
@@ -271,13 +290,15 @@ def incremental_build(
271290

272291
if index == latest_version_position:
273292
output_lines.extend([new_content, "\n"])
274-
275293
output_lines.append(line)
276-
if not isinstance(latest_version_position, int):
277-
if output_lines and output_lines[-1].strip():
278-
# Ensure at least one blank line between existing and new content.
279-
output_lines.append("\n")
280-
output_lines.append(new_content)
294+
295+
if isinstance(latest_version_position, int):
296+
return output_lines
297+
298+
if output_lines and output_lines[-1].strip():
299+
# Ensure at least one blank line between existing and new content.
300+
output_lines.append("\n")
301+
output_lines.append(new_content)
281302
return output_lines
282303

283304

@@ -327,8 +348,7 @@ def get_oldest_and_newest_rev(
327348
if not (newest_tag := rules.find_tag_for(tags, newest)):
328349
raise NoCommitsFoundError("Could not find a valid revision range.")
329350

330-
oldest_tag = None
331-
oldest_tag_name = None
351+
oldest_tag_name: str | None = None
332352
if oldest:
333353
if not (oldest_tag := rules.find_tag_for(tags, oldest)):
334354
raise NoCommitsFoundError("Could not find a valid revision range.")
@@ -340,17 +360,19 @@ def get_oldest_and_newest_rev(
340360
if not tags_range:
341361
raise NoCommitsFoundError("Could not find a valid revision range.")
342362

343-
oldest_rev: str | None = tags_range[-1].name
344363
newest_rev = newest_tag.name
345364

346-
# check if it's the first tag created
347-
# and it's also being requested as part of the range
348-
if oldest_rev == tags[-1].name and oldest_rev == oldest_tag_name:
349-
return None, newest_rev
350-
351-
# when they are the same, and it's also the
352-
# first tag created
353-
if oldest_rev == newest_rev:
354-
return None, newest_rev
365+
# Return None for oldest_rev if:
366+
# 1. The oldest tag is the last tag in the list and matches the requested oldest tag, or
367+
# 2. The oldest and newest tags are the same
368+
oldest_rev: str | None = (
369+
None
370+
if (
371+
tags_range[-1].name == tags[-1].name
372+
and tags_range[-1].name == oldest_tag_name
373+
or tags_range[-1].name == newest_rev
374+
)
375+
else tags_range[-1].name
376+
)
355377

356378
return oldest_rev, newest_rev

‎commitizen/git.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class GitObject:
4949
def __eq__(self, other) -> bool:
5050
return hasattr(other, "rev") and self.rev == other.rev
5151

52+
def __hash__(self):
53+
return hash(self.rev)
54+
5255

5356
class GitCommit(GitObject):
5457
def __init__(

‎tests/test_changelog.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,22 @@ def test_get_smart_tag_range_returns_an_extra_for_a_range(tags):
15291529
assert 4 == len(res)
15301530

15311531

1532+
def test_get_smart_tag_range_returns_all_tags_for_a_range(tags):
1533+
start = tags[0]
1534+
1535+
end = tags[-1]
1536+
res = changelog.get_smart_tag_range(tags, start.name, end.name)
1537+
assert len(tags) == len(res)
1538+
1539+
end = tags[-2]
1540+
res = changelog.get_smart_tag_range(tags, start.name, end.name)
1541+
assert len(tags) == len(res)
1542+
1543+
end = tags[-3]
1544+
res = changelog.get_smart_tag_range(tags, start.name, end.name)
1545+
assert len(tags) - 1 == len(res)
1546+
1547+
15321548
def test_get_smart_tag_range_returns_an_extra_for_a_single_tag(tags):
15331549
start = tags[0] # len here is 1, but we expect one more tag as designed
15341550
res = changelog.get_smart_tag_range(tags, start.name)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /