Skip to content

Commit c0f3951

Browse files
fix(bump): Search for version number line by line
Avoid the complexities of multiline regex matching and inconsistencies with the case where no regex is specified. Simplify the implementation by eliminating the need to track an offset into the file. Ensure that the version number will be found even if it is to the left of the portion of the line matching the regex.
1 parent c3acc75 commit c0f3951

File tree

5 files changed

+25
-40
lines changed

5 files changed

+25
-40
lines changed

commitizen/bump.py

+21-36
Original file line numberDiff line numberDiff line change
@@ -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, re.compile(regex)
150+
)
157151

158152
if check_consistency and not current_version_found:
159153
raise CurrentVersionNotFoundError(
@@ -168,33 +162,24 @@ def update_version_in_files(
168162

169163

170164
def _bump_with_regex(
171-
version_file_contents: str, current_version: str, new_version: str, regex: str
165+
version_filepath: str, current_version: str, new_version: str, regex: re.Pattern
172166
) -> Tuple[bool, str]:
173167
current_version_found = False
174-
# Bumping versions that change the string length move the offset on the file contents as finditer keeps a
175-
# reference to the initial string that was used and calling search many times would lead in infinite loops
176-
# e.g.: 1.1.9 -> 1.1.20
177-
offset = 0
178-
for match in re.finditer(regex, version_file_contents, re.MULTILINE):
179-
left = version_file_contents[: match.end() + offset]
180-
right = version_file_contents[match.end() + offset :]
181-
182-
line_break = right.find("\n")
183-
middle = right[:line_break]
184-
right = right[line_break:]
185-
186-
if current_version in middle:
187-
offset += len(new_version) - len(current_version)
188-
current_version_found = True
189-
version_file_contents = (
190-
left + middle.replace(current_version, new_version) + right
191-
)
192-
return current_version_found, version_file_contents
193-
194-
195-
def _version_to_regex(version: str) -> re.Pattern:
196-
clean_regex = version.replace(".", r"\.").replace("+", r"\+")
197-
return re.compile(f"{clean_regex}")
168+
lines = []
169+
with open(version_filepath, "r") as f:
170+
for line in f:
171+
if regex.search(line):
172+
bumped_line = line.replace(current_version, new_version)
173+
if bumped_line != line:
174+
current_version_found = True
175+
lines.append(bumped_line)
176+
else:
177+
lines.append(line)
178+
return current_version_found, "".join(lines)
179+
180+
181+
def _version_to_regex(version: str) -> str:
182+
return version.replace(".", r"\.").replace("+", r"\+")
198183

199184

200185
def normalize_tag(

tests/data/sample_cargo.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "1.2.3"
44

55
[[package]]
66
name = "there-i-fixed-it"
7-
version = "1.2.3"
7+
version = "1.2.3" # automatically bumped by Commitizen
88

99
[[package]]
1010
name = "other-project"

tests/test_bump_update_version_in_files.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def test_partial_update_of_file(version_repeated_file, file_regression):
125125
def test_random_location(random_location_version_file, file_regression):
126126
old_version = "1.2.3"
127127
new_version = "2.0.0"
128-
location = f"{random_location_version_file}:there-i-fixed-it.+\nversion"
128+
location = f"{random_location_version_file}:version.+Commitizen"
129129

130130
bump.update_version_in_files(old_version, new_version, [location])
131131
with open(random_location_version_file, "r") as f:

tests/test_bump_update_version_in_files/test_duplicates_are_change_with_no_regex.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "2.0.0"
44

55
[[package]]
66
name = "there-i-fixed-it"
7-
version = "2.0.0"
7+
version = "2.0.0" # automatically bumped by Commitizen
88

99
[[package]]
1010
name = "other-project"

tests/test_bump_update_version_in_files/test_random_location.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "1.2.3"
44

55
[[package]]
66
name = "there-i-fixed-it"
7-
version = "2.0.0"
7+
version = "2.0.0" # automatically bumped by Commitizen
88

99
[[package]]
1010
name = "other-project"

0 commit comments

Comments
 (0)