Skip to content

Commit 5fdc68a

Browse files
pawamoychme
andcommitted
refactor: Ignore tags that are not valid given versioning scheme
Co-authored-by: Christian Meffert <[email protected]>
1 parent 2e017e9 commit 5fdc68a

File tree

3 files changed

+65
-26
lines changed

3 files changed

+65
-26
lines changed

src/git_changelog/build.py

+17-23
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import sys
88
import warnings
99
from subprocess import CalledProcessError, check_output
10-
from typing import TYPE_CHECKING, Callable, ClassVar, Literal, Type, Union
10+
from typing import TYPE_CHECKING, ClassVar, Literal, Type, Union
1111
from urllib.parse import urlsplit, urlunsplit
1212

1313
from git_changelog.commit import (
@@ -18,7 +18,7 @@
1818
ConventionalCommitConvention,
1919
)
2020
from git_changelog.providers import Bitbucket, GitHub, GitLab, ProviderRefParser
21-
from git_changelog.versioning import ParsedVersion, VersionBumper, bump_pep440, bump_semver, parse_pep440, parse_semver
21+
from git_changelog.versioning import ParsedVersion, bump_pep440, bump_semver, parse_pep440, parse_semver
2222

2323
if TYPE_CHECKING:
2424
from pathlib import Path
@@ -266,20 +266,20 @@ def __init__(
266266
)
267267
self.sections = sections
268268

269+
# get version parser based on selected versioning scheme
270+
self.version_parser, self.version_bumper = {
271+
"semver": (parse_semver, bump_semver),
272+
"pep440": (parse_pep440, bump_pep440),
273+
}[versioning]
274+
269275
# get git log and parse it into list of commits
270276
self.raw_log: str = self.get_log()
271277
self.commits: list[Commit] = self.parse_commits()
272278
self.tag_commits: list[Commit] = [commit for commit in self.commits[1:] if commit.tag]
273279
self.tag_commits.insert(0, self.commits[0])
274280

275-
# get version parser based on selected versioning scheme
276-
version_parser, version_bumper = {
277-
"semver": (parse_semver, bump_semver),
278-
"pep440": (parse_pep440, bump_pep440),
279-
}[versioning]
280-
281281
# apply dates to commits and group them by version
282-
v_list, v_dict = self._group_commits_by_version(version_parser=version_parser)
282+
v_list, v_dict = self._group_commits_by_version()
283283
self.versions_list = v_list
284284
self.versions_dict = v_dict
285285

@@ -293,7 +293,7 @@ def __init__(
293293
if bump is None:
294294
bump = "auto"
295295
if bump:
296-
self._bump(bump, version_bumper=version_bumper)
296+
self._bump(bump)
297297

298298
# fix a single, initial version to the user specified version or 0.1.0 if none is specified
299299
self._fix_single_version(bump)
@@ -386,6 +386,7 @@ def parse_commits(self) -> list[Commit]:
386386
subject=lines[pos + 9],
387387
body=body,
388388
parse_trailers=self.parse_trailers,
389+
version_parser=self.version_parser,
389390
)
390391

391392
pos += nbl_index + 1
@@ -406,19 +407,12 @@ def parse_commits(self) -> list[Commit]:
406407

407408
return list(commits_map.values())
408409

409-
def _group_commits_by_version(
410-
self,
411-
version_parser: Callable[[str], tuple[ParsedVersion, str]],
412-
) -> tuple[list[Version], dict[str, Version]]:
410+
def _group_commits_by_version(self) -> tuple[list[Version], dict[str, Version]]:
413411
"""Group commits into versions.
414412
415413
Commits are assigned to the version they were first released with.
416414
A commit is assigned to exactly one version.
417415
418-
Parameters:
419-
version_parser: Version parser to use when grouping commits by versions.
420-
Versions that cannot be parsed by the given parser will be ignored.
421-
422416
Returns:
423417
versions_list: The list of versions order descending by timestamp.
424418
versions_dict: A dictionary of versions with the tag name as keys.
@@ -441,7 +435,7 @@ def _group_commits_by_version(
441435
while next_commits:
442436
next_commit = next_commits.pop(0)
443437
if next_commit.tag:
444-
parsed_version, _ = version_parser(next_commit.tag)
438+
parsed_version, _ = self.version_parser(next_commit.tag)
445439
if not previous_parsed_version or parsed_version > previous_parsed_version:
446440
previous_parsed_version = parsed_version
447441
previous_versions[version.tag] = next_commit.tag
@@ -484,7 +478,7 @@ def _assign_previous_versions(self, versions_dict: dict[str, Version], previous_
484478
target=version.tag or "HEAD",
485479
)
486480

487-
def _bump(self, version: str, version_bumper: VersionBumper) -> None:
481+
def _bump(self, version: str) -> None:
488482
last_version = self.versions_list[0]
489483
if not last_version.tag and last_version.previous_version:
490484
last_tag = last_version.previous_version.tag
@@ -499,13 +493,13 @@ def _bump(self, version: str, version_bumper: VersionBumper) -> None:
499493
if commit.convention["is_minor"]:
500494
version = "minor"
501495
version = "+".join((version, *plus))
502-
if version in version_bumper.strategies:
496+
if version in self.version_bumper.strategies:
503497
# bump version
504-
last_version.planned_tag = version_bumper(last_tag, version, zerover=self.zerover)
498+
last_version.planned_tag = self.version_bumper(last_tag, version, zerover=self.zerover)
505499
else:
506500
# user specified version
507501
try:
508-
version_bumper(version)
502+
self.version_bumper(version)
509503
except ValueError as error:
510504
raise ValueError(f"{error}; typo in bumping strategy? Check the CLI help and our docs") from error
511505
last_version.planned_tag = version

src/git_changelog/commit.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
from collections import defaultdict
88
from contextlib import suppress
99
from datetime import datetime, timezone
10-
from typing import TYPE_CHECKING, Any, ClassVar, Pattern
10+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Pattern
1111

1212
if TYPE_CHECKING:
1313
from git_changelog.providers import ProviderRefParser, Ref
14+
from git_changelog.versioning import ParsedVersion
1415

1516

1617
def _clean_body(lines: list[str]) -> list[str]:
@@ -21,6 +22,14 @@ def _clean_body(lines: list[str]) -> list[str]:
2122
return lines
2223

2324

25+
def _is_valid_version(version: str, version_parser: Callable[[str], tuple[ParsedVersion, str]]) -> bool:
26+
try:
27+
version_parser(version)
28+
except ValueError:
29+
return False
30+
return True
31+
32+
2433
class Commit:
2534
"""A class to represent a commit."""
2635

@@ -41,6 +50,7 @@ def __init__(
4150
parse_trailers: bool = False,
4251
parent_hashes: str | list[str] = "",
4352
commits_map: dict[str, Commit] | None = None,
53+
version_parser: Callable[[str], tuple[ParsedVersion, str]] | None = None,
4454
):
4555
"""Initialization method.
4656
@@ -82,8 +92,10 @@ def __init__(
8292
for ref in refs.split(","):
8393
ref = ref.strip() # noqa: PLW2901
8494
if ref.startswith("tag: "):
85-
tag = ref.replace("tag: ", "")
86-
break
95+
ref = ref.replace("tag: ", "") # noqa: PLW2901
96+
if version_parser is None or _is_valid_version(ref, version_parser):
97+
tag = ref
98+
break
8799
self.tag: str = tag
88100
self.version: str = tag
89101

tests/test_build.py

+33
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,36 @@ def test_build_changelog_with_pep440_versions(repo: GitRepo) -> None:
272272
changelog = Changelog(repo.path, convention=AngularConvention, versioning="pep440")
273273
assert len(changelog.versions_list) == 3
274274
assert changelog.versions_list[1].tag == "1.0.0.post0"
275+
276+
277+
def test_ignore_nonsemver_tag(repo: GitRepo) -> None:
278+
"""Test parsing and grouping commits to versions.
279+
280+
Commit graph:
281+
1.0.0
282+
|
283+
main A-B-C
284+
|
285+
dummy
286+
287+
Expected:
288+
- 1.0.0: C B A
289+
290+
Parameters:
291+
repo: GitRepo to a temporary repository.
292+
"""
293+
commit_a = repo.first_hash
294+
commit_b = repo.commit("fix: B")
295+
repo.tag("dummy")
296+
commit_c = repo.commit("feat: C")
297+
repo.tag("1.0.0")
298+
299+
changelog = Changelog(repo.path, convention=AngularConvention)
300+
301+
assert len(changelog.versions_list) == 1
302+
_assert_version(
303+
changelog.versions_list[0],
304+
expected_tag="1.0.0",
305+
expected_prev_tag=None,
306+
expected_commits=[commit_c, commit_b, commit_a],
307+
)

0 commit comments

Comments
 (0)