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