41
41
Template ,
42
42
)
43
43
44
- from commitizen import out
45
- from commitizen .bump import normalize_tag
46
44
from commitizen .cz .base import ChangelogReleaseHook
47
- from commitizen .defaults import get_tag_regexes
48
45
from commitizen .exceptions import InvalidConfigurationError , NoCommitsFoundError
49
46
from commitizen .git import GitCommit , GitTag
50
- from commitizen .version_schemes import (
51
- DEFAULT_SCHEME ,
52
- BaseVersion ,
53
- InvalidVersion ,
54
- )
47
+ from commitizen .tags import TagRules
55
48
56
49
if TYPE_CHECKING :
57
50
from commitizen .cz .base import MessageBuilderHook
58
- from commitizen .version_schemes import VersionScheme
59
51
60
52
61
53
@dataclass
@@ -68,50 +60,19 @@ class Metadata:
68
60
unreleased_end : int | None = None
69
61
latest_version : str | None = None
70
62
latest_version_position : int | None = None
63
+ latest_version_tag : str | None = None
64
+
65
+ def __post_init__ (self ):
66
+ if self .latest_version and not self .latest_version_tag :
67
+ # Test syntactic sugar
68
+ # latest version tag is optional if same as latest version
69
+ self .latest_version_tag = self .latest_version
71
70
72
71
73
72
def get_commit_tag (commit : GitCommit , tags : list [GitTag ]) -> GitTag | None :
74
73
return next ((tag for tag in tags if tag .rev == commit .rev ), None )
75
74
76
75
77
- def tag_included_in_changelog (
78
- tag : GitTag ,
79
- used_tags : list ,
80
- merge_prerelease : bool ,
81
- scheme : VersionScheme = DEFAULT_SCHEME ,
82
- ) -> bool :
83
- if tag in used_tags :
84
- return False
85
-
86
- try :
87
- version = scheme (tag .name )
88
- except InvalidVersion :
89
- return False
90
-
91
- if merge_prerelease and version .is_prerelease :
92
- return False
93
-
94
- return True
95
-
96
-
97
- def get_version_tags (
98
- scheme : type [BaseVersion ], tags : list [GitTag ], tag_format : str
99
- ) -> list [GitTag ]:
100
- valid_tags : list [GitTag ] = []
101
- TAG_FORMAT_REGEXS = get_tag_regexes (scheme .parser .pattern )
102
- tag_format_regex = tag_format
103
- for pattern , regex in TAG_FORMAT_REGEXS .items ():
104
- tag_format_regex = tag_format_regex .replace (pattern , regex )
105
- for tag in tags :
106
- if re .match (tag_format_regex , tag .name ):
107
- valid_tags .append (tag )
108
- else :
109
- out .warn (
110
- f"InvalidVersion { tag .name } doesn't match configured tag format { tag_format } "
111
- )
112
- return valid_tags
113
-
114
-
115
76
def generate_tree_from_commits (
116
77
commits : list [GitCommit ],
117
78
tags : list [GitTag ],
@@ -121,13 +82,13 @@ def generate_tree_from_commits(
121
82
change_type_map : dict [str , str ] | None = None ,
122
83
changelog_message_builder_hook : MessageBuilderHook | None = None ,
123
84
changelog_release_hook : ChangelogReleaseHook | None = None ,
124
- merge_prerelease : bool = False ,
125
- scheme : VersionScheme = DEFAULT_SCHEME ,
85
+ rules : TagRules | None = None ,
126
86
) -> Iterable [dict ]:
127
87
pat = re .compile (changelog_pattern )
128
88
map_pat = re .compile (commit_parser , re .MULTILINE )
129
89
body_map_pat = re .compile (commit_parser , re .MULTILINE | re .DOTALL )
130
90
current_tag : GitTag | None = None
91
+ rules = rules or TagRules ()
131
92
132
93
# Check if the latest commit is not tagged
133
94
if commits :
@@ -147,8 +108,10 @@ def generate_tree_from_commits(
147
108
for commit in commits :
148
109
commit_tag = get_commit_tag (commit , tags )
149
110
150
- if commit_tag is not None and tag_included_in_changelog (
151
- commit_tag , used_tags , merge_prerelease , scheme = scheme
111
+ if (
112
+ commit_tag
113
+ and commit_tag not in used_tags
114
+ and rules .include_in_changelog (commit_tag )
152
115
):
153
116
used_tags .append (commit_tag )
154
117
release = {
@@ -342,8 +305,7 @@ def get_smart_tag_range(
342
305
def get_oldest_and_newest_rev (
343
306
tags : list [GitTag ],
344
307
version : str ,
345
- tag_format : str ,
346
- scheme : VersionScheme | None = None ,
308
+ rules : TagRules ,
347
309
) -> tuple [str | None , str | None ]:
348
310
"""Find the tags for the given version.
349
311
@@ -357,22 +319,28 @@ def get_oldest_and_newest_rev(
357
319
oldest , newest = version .split (".." )
358
320
except ValueError :
359
321
newest = version
360
- newest_tag = normalize_tag (newest , tag_format = tag_format , scheme = scheme )
322
+ if not (newest_tag := rules .find_tag_for (tags , newest )):
323
+ raise NoCommitsFoundError ("Could not find a valid revision range." )
361
324
362
325
oldest_tag = None
326
+ oldest_tag_name = None
363
327
if oldest :
364
- oldest_tag = normalize_tag (oldest , tag_format = tag_format , scheme = scheme )
328
+ if not (oldest_tag := rules .find_tag_for (tags , oldest )):
329
+ raise NoCommitsFoundError ("Could not find a valid revision range." )
330
+ oldest_tag_name = oldest_tag .name
365
331
366
- tags_range = get_smart_tag_range (tags , newest = newest_tag , oldest = oldest_tag )
332
+ tags_range = get_smart_tag_range (
333
+ tags , newest = newest_tag .name , oldest = oldest_tag_name
334
+ )
367
335
if not tags_range :
368
336
raise NoCommitsFoundError ("Could not find a valid revision range." )
369
337
370
338
oldest_rev : str | None = tags_range [- 1 ].name
371
- newest_rev = newest_tag
339
+ newest_rev = newest_tag . name
372
340
373
341
# check if it's the first tag created
374
342
# and it's also being requested as part of the range
375
- if oldest_rev == tags [- 1 ].name and oldest_rev == oldest_tag :
343
+ if oldest_rev == tags [- 1 ].name and oldest_rev == oldest_tag_name :
376
344
return None , newest_rev
377
345
378
346
# when they are the same, and it's also the
0 commit comments