22from collections import OrderedDict
33from itertools import zip_longest
44from string import Template
5- from typing import List , Optional , Union
5+ from typing import List , Optional , Tuple , Union
66
77from packaging .version import Version
88
@@ -142,18 +142,12 @@ def update_version_in_files(
142142 # TODO: separate check step and write step
143143 for location in files :
144144 filepath , _ , regex = location .partition (":" )
145+ if not regex :
146+ regex = _version_to_regex (current_version )
145147
146- with open (filepath , "r" ) as f :
147- version_file = f .read ()
148-
149- if regex :
150- current_version_found , version_file = _bump_with_regex (
151- version_file , current_version , new_version , regex
152- )
153- else :
154- current_version_regex = _version_to_regex (current_version )
155- current_version_found = bool (current_version_regex .search (version_file ))
156- version_file = current_version_regex .sub (new_version , version_file )
148+ current_version_found , version_file = _bump_with_regex (
149+ filepath , current_version , new_version , regex
150+ )
157151
158152 if check_consistency and not current_version_found :
159153 raise CurrentVersionNotFoundError (
@@ -167,32 +161,26 @@ def update_version_in_files(
167161 file .write ("" .join (version_file ))
168162
169163
170- def _bump_with_regex (version_file_contents , current_version , new_version , regex ):
164+ def _bump_with_regex (
165+ version_filepath : str , current_version : str , new_version : str , regex : str
166+ ) -> Tuple [bool , str ]:
171167 current_version_found = False
172- # Bumping versions that change the string length move the offset on the file contents as finditer keeps a
173- # reference to the initial string that was used and calling search many times would lead in infinite loops
174- # e.g.: 1.1.9 -> 1.1.20
175- offset = 0
176- for match in re .finditer (regex , version_file_contents , re .MULTILINE ):
177- left = version_file_contents [: match .end () + offset ]
178- right = version_file_contents [match .end () + offset :]
179-
180- line_break = right .find ("\n " )
181- middle = right [:line_break ]
182- right = right [line_break :]
183-
184- if current_version in middle :
185- offset += len (new_version ) - len (current_version )
186- current_version_found = True
187- version_file_contents = (
188- left + middle .replace (current_version , new_version ) + right
189- )
190- return current_version_found , version_file_contents
191-
192-
193- def _version_to_regex (version : str ):
194- clean_regex = version .replace ("." , r"\." ).replace ("+" , r"\+" )
195- return re .compile (f"{ clean_regex } " )
168+ lines = []
169+ pattern = re .compile (regex )
170+ with open (version_filepath , "r" ) as f :
171+ for line in f :
172+ if pattern .search (line ):
173+ bumped_line = line .replace (current_version , new_version )
174+ if bumped_line != line :
175+ current_version_found = True
176+ lines .append (bumped_line )
177+ else :
178+ lines .append (line )
179+ return current_version_found , "" .join (lines )
180+
181+
182+ def _version_to_regex (version : str ) -> str :
183+ return version .replace ("." , r"\." ).replace ("+" , r"\+" )
196184
197185
198186def normalize_tag (
0 commit comments