@@ -152,24 +152,15 @@ def update_version_in_files(
152
152
for location in files :
153
153
filepath , * regexes = location .split (":" )
154
154
regex = regexes [0 ] if regexes else None
155
- current_version_found = False
156
155
157
156
with open (filepath , "r" ) as f :
158
157
version_file = f .read ()
159
158
160
159
if regex :
161
- for match in re .finditer (regex , version_file , re .MULTILINE ):
162
- left = version_file [: match .end ()]
163
- right = version_file [match .end () :]
164
- line_break = _get_line_break_position (right )
165
- middle = right [:line_break ]
166
- current_version_found = current_version in middle
167
- right = right [line_break :]
168
- version_file = (
169
- left + middle .replace (current_version , new_version ) + right
170
- )
171
-
172
- if not regex :
160
+ current_version_found , version_file = _bump_with_regex (
161
+ version_file , current_version , new_version , regex
162
+ )
163
+ else :
173
164
current_version_regex = _version_to_regex (current_version )
174
165
current_version_found = bool (current_version_regex .search (version_file ))
175
166
version_file = current_version_regex .sub (new_version , version_file )
@@ -186,6 +177,27 @@ def update_version_in_files(
186
177
file .write ("" .join (version_file ))
187
178
188
179
180
+ def _bump_with_regex (version_file_contents , current_version , new_version , regex ):
181
+ current_version_found = False
182
+ # Bumping versions that change the string length move the offset on the file contents as finditer keeps a
183
+ # reference to the initial string that was used and calling search many times would lead in infinite loops
184
+ # e.g.: 1.1.9 -> 1.1.20
185
+ offset = 0
186
+ for match in re .finditer (regex , version_file_contents , re .MULTILINE ):
187
+ left = version_file_contents [: match .end () + offset ]
188
+ right = version_file_contents [match .end () + offset :]
189
+ line_break = _get_line_break_position (right )
190
+ middle = right [:line_break ]
191
+ current_version_found_in_block = current_version in middle
192
+ offset += len (new_version ) - len (current_version )
193
+ current_version_found |= current_version_found_in_block
194
+ right = right [line_break :]
195
+ version_file_contents = (
196
+ left + middle .replace (current_version , new_version ) + right
197
+ )
198
+ return current_version_found , version_file_contents
199
+
200
+
189
201
def _get_line_break_position (text : str ) -> int :
190
202
position = text .find ("\n " )
191
203
return max (position , 0 )
0 commit comments