4242    Template ,
4343)
4444
45- from  commitizen  import  out 
46- from  commitizen .bump  import  normalize_tag 
4745from  commitizen .cz .base  import  ChangelogReleaseHook 
48- from  commitizen .defaults  import  get_tag_regexes 
4946from  commitizen .exceptions  import  InvalidConfigurationError , NoCommitsFoundError 
5047from  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 
5649
5750if  TYPE_CHECKING :
5851    from  commitizen .cz .base  import  MessageBuilderHook 
59-     from  commitizen .version_schemes  import  VersionScheme 
6052
6153
6254@dataclass  
@@ -69,50 +61,19 @@ class Metadata:
6961    unreleased_end : int  |  None  =  None 
7062    latest_version : str  |  None  =  None 
7163    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 
7271
7372
7473def  get_commit_tag (commit : GitCommit , tags : list [GitTag ]) ->  GitTag  |  None :
7574    return  next ((tag  for  tag  in  tags  if  tag .rev  ==  commit .rev ), None )
7675
7776
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- 
11677def  generate_tree_from_commits (
11778    commits : list [GitCommit ],
11879    tags : list [GitTag ],
@@ -122,13 +83,13 @@ def generate_tree_from_commits(
12283    change_type_map : dict [str , str ] |  None  =  None ,
12384    changelog_message_builder_hook : MessageBuilderHook  |  None  =  None ,
12485    changelog_release_hook : ChangelogReleaseHook  |  None  =  None ,
125-     merge_prerelease : bool  =  False ,
126-     scheme : VersionScheme  =  DEFAULT_SCHEME ,
86+     rules : TagRules  |  None  =  None ,
12787) ->  Iterable [dict ]:
12888    pat  =  re .compile (changelog_pattern )
12989    map_pat  =  re .compile (commit_parser , re .MULTILINE )
13090    body_map_pat  =  re .compile (commit_parser , re .MULTILINE  |  re .DOTALL )
13191    current_tag : GitTag  |  None  =  None 
92+     rules  =  rules  or  TagRules ()
13293
13394    # Check if the latest commit is not tagged 
13495    if  commits :
@@ -148,8 +109,10 @@ def generate_tree_from_commits(
148109    for  commit  in  commits :
149110        commit_tag  =  get_commit_tag (commit , tags )
150111
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 )
153116        ):
154117            used_tags .append (commit_tag )
155118            release  =  {
@@ -343,8 +306,7 @@ def get_smart_tag_range(
343306def  get_oldest_and_newest_rev (
344307    tags : list [GitTag ],
345308    version : str ,
346-     tag_format : str ,
347-     scheme : VersionScheme  |  None  =  None ,
309+     rules : TagRules ,
348310) ->  tuple [str  |  None , str  |  None ]:
349311    """Find the tags for the given version. 
350312
@@ -358,22 +320,28 @@ def get_oldest_and_newest_rev(
358320        oldest , newest  =  version .split (".." )
359321    except  ValueError :
360322        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." )
362325
363326    oldest_tag  =  None 
327+     oldest_tag_name  =  None 
364328    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 
366332
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+     )
368336    if  not  tags_range :
369337        raise  NoCommitsFoundError ("Could not find a valid revision range." )
370338
371339    oldest_rev : str  |  None  =  tags_range [- 1 ].name 
372-     newest_rev  =  newest_tag 
340+     newest_rev  =  newest_tag . name 
373341
374342    # check if it's the first tag created 
375343    # 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 :
377345        return  None , newest_rev 
378346
379347    # when they are the same, and it's also the 
0 commit comments