Skip to content

Commit cd7018e

Browse files
jaysonsantosLee-W
authored andcommitted
feat: Support versions on random positions
1 parent 8794f9c commit cd7018e

File tree

2 files changed

+64
-19
lines changed

2 files changed

+64
-19
lines changed

commitizen/bump.py

+28-19
Original file line numberDiff line numberDiff line change
@@ -150,26 +150,25 @@ def update_version_in_files(
150150
"""
151151
# TODO: separate check step and write step
152152
for location in files:
153-
filepath, *regexes = location.split(":", maxsplit=1)
153+
filepath, *regexes = location.split(":")
154154
regex = regexes[0] if regexes else None
155-
156-
# Read in the file
157-
file_content = []
158155
current_version_found = False
159-
with open(filepath, "r") as version_file:
160-
for line in version_file:
161-
if regex:
162-
match = re.search(regex, line)
163-
if not match:
164-
file_content.append(line)
165-
continue
166-
167-
# Replace the target string
168-
if current_version in line:
169-
current_version_found = True
170-
file_content.append(line.replace(current_version, new_version))
171-
else:
172-
file_content.append(line)
156+
157+
version_file = open(filepath, "r").read()
158+
match = regex and re.search(regex, version_file, re.MULTILINE)
159+
if match:
160+
left = version_file[: match.end()]
161+
right = version_file[match.end() :]
162+
line_break = _get_line_break_position(right)
163+
middle = right[:line_break]
164+
current_version_found = current_version in middle
165+
right = right[line_break:]
166+
version_file = left + middle.replace(current_version, new_version) + right
167+
168+
if not regex:
169+
current_version_regex = _version_to_regex(current_version)
170+
current_version_found = current_version_regex.search(version_file) and True
171+
version_file = current_version_regex.sub(new_version, version_file)
173172

174173
if check_consistency and not current_version_found:
175174
raise CurrentVersionNotFoundError(
@@ -180,7 +179,17 @@ def update_version_in_files(
180179

181180
# Write the file out again
182181
with open(filepath, "w") as file:
183-
file.write("".join(file_content))
182+
file.write("".join(version_file))
183+
184+
185+
def _get_line_break_position(text: str) -> int:
186+
position = text.find("\n")
187+
return max(position, 0)
188+
189+
190+
def _version_to_regex(version: str):
191+
clean_regex = version.replace(".", r"\.").replace("+", r"\+")
192+
return re.compile(f"\\b{clean_regex}\\b")
184193

185194

186195
def create_tag(version: Union[Version, str], tag_format: Optional[str] = None):

tests/test_bump_update_version_in_files.py

+36
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import re
2+
13
import pytest
24

35
from commitizen import bump
@@ -33,6 +35,21 @@
3335
}
3436
"""
3537

38+
# The order cannot be guaranteed here
39+
CARGO_LOCK = """
40+
[[package]]
41+
name = "textwrap"
42+
version = "1.2.3"
43+
44+
[[package]]
45+
name = "there-i-fixed-it"
46+
version = "1.2.3"
47+
48+
[[package]]
49+
name = "other-project"
50+
version = "1.2.3"
51+
"""
52+
3653

3754
@pytest.fixture(scope="function")
3855
def commitizen_config_file(tmpdir):
@@ -55,6 +72,13 @@ def inconsistent_python_version_file(tmpdir):
5572
return str(tmp_file)
5673

5774

75+
@pytest.fixture(scope="function")
76+
def random_location_version_file(tmpdir):
77+
tmp_file = tmpdir.join("Cargo.lock")
78+
tmp_file.write(CARGO_LOCK)
79+
return str(tmp_file)
80+
81+
5882
@pytest.fixture(scope="function")
5983
def version_repeated_file(tmpdir):
6084
tmp_file = tmpdir.join("package.json")
@@ -90,6 +114,18 @@ def test_partial_update_of_file(version_repeated_file):
90114
assert old_version in data
91115

92116

117+
def test_random_location(random_location_version_file):
118+
old_version = "1.2.3"
119+
new_version = "2.0.0"
120+
location = f"{random_location_version_file}:there-i-fixed-it.+\nversion"
121+
122+
bump.update_version_in_files(old_version, new_version, [location])
123+
with open(random_location_version_file, "r") as f:
124+
data = f.read()
125+
assert len(re.findall(old_version, data)) == 2
126+
assert len(re.findall(new_version, data)) == 1
127+
128+
93129
def test_file_version_inconsistent_error(
94130
commitizen_config_file, inconsistent_python_version_file, version_repeated_file
95131
):

0 commit comments

Comments
 (0)