Skip to content

Commit 6d94ba7

Browse files
committed
feat(tags): add support for finding latest matching tag for incomplete version
1 parent 956c8fb commit 6d94ba7

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

commitizen/tags.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,25 @@ def find_tag_for(
245245
) -> GitTag | None:
246246
"""Find the first matching tag for a given version."""
247247
version = self.scheme(version) if isinstance(version, str) else version
248+
release = version.release
249+
250+
# If the requested version is incomplete (e.g., "1.2"), try to find the latest
251+
# matching tag that shares the provided prefix.
252+
if len(release) < 3:
253+
matching_versions: list[tuple[Version, GitTag]] = []
254+
for tag in tags:
255+
try:
256+
tag_version = self.extract_version(tag)
257+
except InvalidVersion:
258+
continue
259+
if tag_version.release[: len(release)] != release:
260+
continue
261+
matching_versions.append((tag_version, tag))
262+
263+
if matching_versions:
264+
_, latest_tag = max(matching_versions, key=lambda vt: vt[0])
265+
return latest_tag
266+
248267
possible_tags = set(self.normalize_tag(version, f) for f in self.tag_formats)
249268
candidates = [t for t in tags if t.name in possible_tags]
250269
if len(candidates) > 1:

tests/test_tags.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from commitizen.git import GitTag
2+
from commitizen.tags import TagRules
3+
4+
5+
def _git_tag(name: str) -> GitTag:
6+
return GitTag(name, "rev", "2024-01-01")
7+
8+
9+
def test_find_tag_for_partial_version_returns_latest_match():
10+
tags = [
11+
_git_tag("1.2.0"),
12+
_git_tag("1.2.2"),
13+
_git_tag("1.2.1"),
14+
_git_tag("1.3.0"),
15+
]
16+
17+
rules = TagRules()
18+
19+
found = rules.find_tag_for(tags, "1.2")
20+
21+
assert found is not None
22+
assert found.name == "1.2.2"
23+
24+
25+
def test_find_tag_for_full_version_remains_exact():
26+
tags = [
27+
_git_tag("1.2.0"),
28+
_git_tag("1.2.2"),
29+
_git_tag("1.2.1"),
30+
]
31+
32+
rules = TagRules()
33+
34+
found = rules.find_tag_for(tags, "1.2.1")
35+
36+
assert found is not None
37+
assert found.name == "1.2.1"

0 commit comments

Comments
 (0)