33import os
44import re
55from collections import OrderedDict
6- from collections .abc import Iterable
6+ from collections .abc import Callable , Iterable
77from glob import iglob
88from logging import getLogger
99from string import Template
10- from typing import cast
10+ from typing import TextIO , cast
11+
12+ from typing_extensions import Never
1113
1214from commitizen .defaults import BUMP_MESSAGE , ENCODING , MAJOR , MINOR , PATCH
1315from commitizen .exceptions import CurrentVersionNotFoundError
@@ -75,36 +77,46 @@ def update_version_in_files(
7577
7678 Returns the list of updated files.
7779 """
78- # TODO: separate check step and write step
7980 updated = []
80- for path , regex in _files_and_regexes (files , current_version ):
81- current_version_found , version_file = _bump_with_regex (
82- path ,
83- current_version ,
84- new_version ,
85- regex ,
86- encoding = encoding ,
81+
82+ for path , pattern in _resolve_files_and_regexes (files , current_version ):
83+ error = CurrentVersionNotFoundError (
84+ f"Current version { current_version } is not found in { path } .\n "
85+ "The version defined in commitizen configuration and the ones in "
86+ "version_files are possibly inconsistent."
87+ )
88+ error_on_not_found = (
89+ None if not check_consistency else lambda : (_ for _ in ()).throw (error )
8790 )
8891
89- if check_consistency and not current_version_found :
90- raise CurrentVersionNotFoundError (
91- f"Current version { current_version } is not found in { path } .\n "
92- "The version defined in commitizen configuration and the ones in "
93- "version_files are possibly inconsistent."
92+ def bump_line (line : str ) -> str :
93+ return (
94+ line .replace (current_version , new_version )
95+ if pattern .search (line )
96+ else line
97+ )
98+
99+ with open (path , encoding = encoding ) as file :
100+ bumped_version_file_content = _get_bumped_version_file_content (
101+ file ,
102+ bump_line ,
103+ error_on_not_found ,
94104 )
95105
96106 # Write the file out again
97107 with smart_open (path , "w" , encoding = encoding ) as file :
98- file .write (version_file )
108+ file .write (bumped_version_file_content )
99109 updated .append (path )
100110 return updated
101111
102112
103- def _files_and_regexes (patterns : Iterable [str ], version : str ) -> list [tuple [str , str ]]:
113+ def _resolve_files_and_regexes (
114+ patterns : Iterable [str ], version : str
115+ ) -> list [tuple [str , re .Pattern ]]:
104116 """
105117 Resolve all distinct files with their regexp from a list of glob patterns with optional regexp
106118 """
107- out : set [tuple [str , str ]] = set ()
119+ out : set [tuple [str , re . Pattern ]] = set ()
108120 for pattern in patterns :
109121 drive , tail = os .path .splitdrive (pattern )
110122 path , _ , regex = tail .partition (":" )
@@ -113,33 +125,30 @@ def _files_and_regexes(patterns: Iterable[str], version: str) -> list[tuple[str,
113125 regex = re .escape (version )
114126
115127 for file in iglob (filepath ):
116- out .add ((file , regex ))
128+ out .add ((file , re . compile ( regex ) ))
117129
118130 return sorted (out )
119131
120132
121- def _bump_with_regex (
122- version_filepath : str ,
123- current_version : str ,
124- new_version : str ,
125- regex : str ,
126- encoding : str = ENCODING ,
127- ) -> tuple [bool , str ]:
133+ def _get_bumped_version_file_content (
134+ version_file : TextIO ,
135+ bump_line : Callable [[str ], str ],
136+ error_on_not_found : Callable [[], Never ] | None ,
137+ ) -> str :
128138 current_version_found = False
129139 lines = []
130- pattern = re .compile (regex )
131- with open (version_filepath , encoding = encoding ) as f :
132- for line in f :
133- if not pattern .search (line ):
134- lines .append (line )
135- continue
136-
137- bumped_line = line .replace (current_version , new_version )
138- if bumped_line != line :
139- current_version_found = True
140- lines .append (bumped_line )
141-
142- return current_version_found , "" .join (lines )
140+
141+ for line in version_file :
142+ bumped_line = bump_line (line )
143+ if bumped_line != line :
144+ current_version_found = True
145+
146+ lines .append (bumped_line )
147+
148+ if error_on_not_found is not None and not current_version_found :
149+ error_on_not_found ()
150+
151+ return "" .join (lines )
143152
144153
145154def create_commit_message (
0 commit comments