Skip to content

Commit

Permalink
fix: fix multiple versions bumps when version changes the string size
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysonsantos authored and Lee-W committed Apr 19, 2021
1 parent b94418b commit 127d1b0
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 13 deletions.
38 changes: 25 additions & 13 deletions commitizen/bump.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,24 +152,15 @@ def update_version_in_files(
for location in files:
filepath, *regexes = location.split(":")
regex = regexes[0] if regexes else None
current_version_found = False

with open(filepath, "r") as f:
version_file = f.read()

if regex:
for match in re.finditer(regex, version_file, re.MULTILINE):
left = version_file[: match.end()]
right = version_file[match.end() :]
line_break = _get_line_break_position(right)
middle = right[:line_break]
current_version_found = current_version in middle
right = right[line_break:]
version_file = (
left + middle.replace(current_version, new_version) + right
)

if not regex:
current_version_found, version_file = _bump_with_regex(
version_file, current_version, new_version, regex
)
else:
current_version_regex = _version_to_regex(current_version)
current_version_found = bool(current_version_regex.search(version_file))
version_file = current_version_regex.sub(new_version, version_file)
Expand All @@ -186,6 +177,27 @@ def update_version_in_files(
file.write("".join(version_file))


def _bump_with_regex(version_file_contents, current_version, new_version, regex):
current_version_found = False
# Bumping versions that change the string length move the offset on the file contents as finditer keeps a
# reference to the initial string that was used and calling search many times would lead in infinite loops
# e.g.: 1.1.9 -> 1.1.20
offset = 0
for match in re.finditer(regex, version_file_contents, re.MULTILINE):
left = version_file_contents[: match.end() + offset]
right = version_file_contents[match.end() + offset :]
line_break = _get_line_break_position(right)
middle = right[:line_break]
current_version_found_in_block = current_version in middle
offset += len(new_version) - len(current_version)
current_version_found |= current_version_found_in_block
right = right[line_break:]
version_file_contents = (
left + middle.replace(current_version, new_version) + right
)
return current_version_found, version_file_contents


def _get_line_break_position(text: str) -> int:
position = text.find("\n")
return max(position, 0)
Expand Down
43 changes: 43 additions & 0 deletions tests/test_bump_update_version_in_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
version = "1.2.3"
"""

MULTIPLE_VERSIONS_INCREASE_STRING = 'version = "1.2.9"\n' * 30
MULTIPLE_VERSIONS_REDUCE_STRING = 'version = "1.2.10"\n' * 30


@pytest.fixture(scope="function")
def commitizen_config_file(tmpdir):
Expand Down Expand Up @@ -86,6 +89,20 @@ def version_repeated_file(tmpdir):
return str(tmp_file)


@pytest.fixture(scope="function")
def multiple_versions_increase_string(tmpdir):
tmp_file = tmpdir.join("anyfile")
tmp_file.write(MULTIPLE_VERSIONS_INCREASE_STRING)
return str(tmp_file)


@pytest.fixture(scope="function")
def multiple_versions_reduce_string(tmpdir):
tmp_file = tmpdir.join("anyfile")
tmp_file.write(MULTIPLE_VERSIONS_REDUCE_STRING)
return str(tmp_file)


@pytest.fixture(scope="function")
def version_files(commitizen_config_file, python_version_file, version_repeated_file):
return [commitizen_config_file, python_version_file, version_repeated_file]
Expand Down Expand Up @@ -138,6 +155,32 @@ def test_duplicates_are_change_with_no_regex(random_location_version_file):
assert len(re.findall(new_version, data)) == 3


def test_version_bump_increase_string_length(multiple_versions_increase_string):
old_version = "1.2.9"
new_version = "1.2.10"
version_bump_change_string_size(
multiple_versions_increase_string, old_version, new_version
)


def test_version_bump_reduce_string_length(multiple_versions_reduce_string):
old_version = "1.2.10"
new_version = "2.0.0"
version_bump_change_string_size(
multiple_versions_reduce_string, old_version, new_version
)


def version_bump_change_string_size(filename, old_version, new_version):
location = f"{filename}:version"

bump.update_version_in_files(old_version, new_version, [location])
with open(filename, "r") as f:
data = f.read()
assert len(re.findall(old_version, data)) == 0
assert len(re.findall(new_version, data)) == 30


def test_file_version_inconsistent_error(
commitizen_config_file, inconsistent_python_version_file, version_repeated_file
):
Expand Down

0 comments on commit 127d1b0

Please sign in to comment.