diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 36bbcfb646..a5c2d68036 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,7 @@ repos: hooks: - id: check-vcs-permalinks - id: end-of-file-fixer + exclude: "tests/[test_*|data]/*" - id: trailing-whitespace args: [--markdown-linebreak-ext=md] - id: debug-statements diff --git a/commitizen/bump.py b/commitizen/bump.py index 3a93575941..9312491044 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -186,21 +186,18 @@ def _bump_with_regex(version_file_contents, current_version, new_version, regex) 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) + + line_break = right.find("\n") 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) + if current_version in middle: + offset += len(new_version) - len(current_version) + current_version_found = True + version_file_contents = ( + left + middle.replace(current_version, new_version) + right + ) + return current_version_found, version_file_contents def _version_to_regex(version: str): diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index 284e8d41b5..b5b7f7b2a1 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -49,8 +49,8 @@ def _parse_setting(self, data: Union[bytes, str]): name = "cz_conventional_commits" ``` """ - doc = parse(data) + doc = parse(data) # type: ignore try: - self.settings.update(doc["tool"]["commitizen"]) + self.settings.update(doc["tool"]["commitizen"]) # type: ignore except exceptions.NonExistentKey: self.is_empty_config = True diff --git a/pyproject.toml b/pyproject.toml index ee8a8622bb..b344305706 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,7 @@ isort = "^5.7.0" freezegun = "^0.3.15" pydocstyle = "^5.0.2" pre-commit = "^2.6.0" +pytest-regressions = "^2.2.0" [tool.poetry.scripts] cz = "commitizen.cli:main" diff --git a/tests/data/inconsistent_version.py b/tests/data/inconsistent_version.py new file mode 100644 index 0000000000..47646762dc --- /dev/null +++ b/tests/data/inconsistent_version.py @@ -0,0 +1,4 @@ +__title__ = "requests" +__description__ = "Python HTTP for Humans." +__url__ = "http://python-requests.org" +__version__ = "2.10.3" diff --git a/tests/data/multiple_versions_to_update_pyproject.toml b/tests/data/multiple_versions_to_update_pyproject.toml new file mode 100644 index 0000000000..de4ead0343 --- /dev/null +++ b/tests/data/multiple_versions_to_update_pyproject.toml @@ -0,0 +1,27 @@ +[[package]] +name = "to-update-1" +version = "1.2.9" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "to-update-2" +version = "1.2.9" diff --git a/tests/data/multiple_versions_to_update_pyproject_wo_eol.toml b/tests/data/multiple_versions_to_update_pyproject_wo_eol.toml new file mode 100644 index 0000000000..e2746fa9eb --- /dev/null +++ b/tests/data/multiple_versions_to_update_pyproject_wo_eol.toml @@ -0,0 +1,27 @@ +[[package]] +name = "to-update-1" +version = "1.2.9" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "to-update-2" +version = "1.2.9" \ No newline at end of file diff --git a/tests/data/repeated_version_number.json b/tests/data/repeated_version_number.json new file mode 100644 index 0000000000..8421026df9 --- /dev/null +++ b/tests/data/repeated_version_number.json @@ -0,0 +1,7 @@ +{ + "name": "magictool", + "version": "1.2.3", + "dependencies": { + "lodash": "1.2.3" + } +} diff --git a/tests/data/sample_cargo.lock b/tests/data/sample_cargo.lock new file mode 100644 index 0000000000..a3a0b1bb7a --- /dev/null +++ b/tests/data/sample_cargo.lock @@ -0,0 +1,11 @@ +[[package]] +name = "textwrap" +version = "1.2.3" + +[[package]] +name = "there-i-fixed-it" +version = "1.2.3" + +[[package]] +name = "other-project" +version = "1.2.3" diff --git a/tests/data/sample_docker_compose.yaml b/tests/data/sample_docker_compose.yaml new file mode 100644 index 0000000000..9da8caf1f6 --- /dev/null +++ b/tests/data/sample_docker_compose.yaml @@ -0,0 +1,6 @@ +version: "3.3" + +services: + app: + image: my-repo/my-container:v1.2.3 + command: my-command diff --git a/tests/data/sample_pyproject.toml b/tests/data/sample_pyproject.toml new file mode 100644 index 0000000000..9f50155cb7 --- /dev/null +++ b/tests/data/sample_pyproject.toml @@ -0,0 +1,3 @@ +[tool.poetry] +name = "commitizen" +version = "1.2.3" diff --git a/tests/data/sample_version.py b/tests/data/sample_version.py new file mode 100644 index 0000000000..4dd4512dba --- /dev/null +++ b/tests/data/sample_version.py @@ -0,0 +1,4 @@ +__title__ = "requests" +__description__ = "Python HTTP for Humans." +__url__ = "http://python-requests.org" +__version__ = "1.2.3" diff --git a/tests/test_bump_update_version_in_files.py b/tests/test_bump_update_version_in_files.py index 4b0cf19a44..a00286df71 100644 --- a/tests/test_bump_update_version_in_files.py +++ b/tests/test_bump_update_version_in_files.py @@ -1,101 +1,73 @@ -import re +from shutil import copyfile import pytest +from py._path.local import LocalPath from commitizen import bump from commitizen.exceptions import CurrentVersionNotFoundError -PYPROJECT = """ -[tool.poetry] -name = "commitizen" -version = "1.2.3" -""" - -VERSION_PY = """ -__title__ = 'requests' -__description__ = 'Python HTTP for Humans.' -__url__ = 'http://python-requests.org' -__version__ = '1.2.3' -""" - -INCONSISTENT_VERSION_PY = """ -__title__ = 'requests' -__description__ = 'Python HTTP for Humans.' -__url__ = 'http://python-requests.org' -__version__ = '2.10.3' -""" - -REPEATED_VERSION_NUMBER = """ -{ - "name": "magictool", - "version": "1.2.3", - "dependencies": { - "lodash": "1.2.3" - } -} -""" - -# The order cannot be guaranteed here -CARGO_LOCK = """ -[[package]] -name = "textwrap" -version = "1.2.3" - -[[package]] -name = "there-i-fixed-it" -version = "1.2.3" - -[[package]] -name = "other-project" -version = "1.2.3" -""" - -DOCKER_COMPOSE = """ -version: "3.3" - -services: - app: - image: my-repo/my-container:v1.2.3 - command: my-command -""" - MULTIPLE_VERSIONS_INCREASE_STRING = 'version = "1.2.9"\n' * 30 MULTIPLE_VERSIONS_REDUCE_STRING = 'version = "1.2.10"\n' * 30 +TESTING_FILE_PREFIX = "tests/data" + + +def _copy_sample_file_to_tmpdir( + tmpdir: LocalPath, source_filename: str, dest_filename: str +) -> str: + tmp_file = tmpdir.join(dest_filename) + copyfile(f"{TESTING_FILE_PREFIX}/{source_filename}", str(tmp_file)) + return str(tmp_file) + @pytest.fixture(scope="function") def commitizen_config_file(tmpdir): - tmp_file = tmpdir.join("pyproject.toml") - tmp_file.write(PYPROJECT) - return str(tmp_file) + return _copy_sample_file_to_tmpdir( + tmpdir, "sample_pyproject.toml", "pyproject.toml" + ) @pytest.fixture(scope="function") -def python_version_file(tmpdir): - tmp_file = tmpdir.join("__verion__.py") - tmp_file.write(VERSION_PY) - return str(tmp_file) +def python_version_file(tmpdir, request): + return _copy_sample_file_to_tmpdir(tmpdir, "sample_version.py", "__version__.py") @pytest.fixture(scope="function") def inconsistent_python_version_file(tmpdir): - tmp_file = tmpdir.join("__verion__.py") - tmp_file.write(INCONSISTENT_VERSION_PY) - return str(tmp_file) + return _copy_sample_file_to_tmpdir( + tmpdir, "inconsistent_version.py", "__version__.py" + ) @pytest.fixture(scope="function") def random_location_version_file(tmpdir): - tmp_file = tmpdir.join("Cargo.lock") - tmp_file.write(CARGO_LOCK) - return str(tmp_file) + return _copy_sample_file_to_tmpdir(tmpdir, "sample_cargo.lock", "Cargo.lock") @pytest.fixture(scope="function") def version_repeated_file(tmpdir): - tmp_file = tmpdir.join("package.json") - tmp_file.write(REPEATED_VERSION_NUMBER) - return str(tmp_file) + return _copy_sample_file_to_tmpdir( + tmpdir, "repeated_version_number.json", "package.json" + ) + + +@pytest.fixture(scope="function") +def docker_compose_file(tmpdir): + return _copy_sample_file_to_tmpdir( + tmpdir, "sample_docker_compose.yaml", "docker-compose.yaml" + ) + + +@pytest.fixture( + scope="function", + params=( + "multiple_versions_to_update_pyproject.toml", + "multiple_versions_to_update_pyproject_wo_eol.toml", + ), + ids=("with_eol", "without_eol"), +) +def multiple_versions_to_update_poetry_lock(tmpdir, request): + return _copy_sample_file_to_tmpdir(tmpdir, request.param, "pyproject.toml") @pytest.fixture(scope="function") @@ -112,13 +84,6 @@ def multiple_versions_reduce_string(tmpdir): return str(tmp_file) -@pytest.fixture(scope="function") -def docker_compose_file(tmpdir): - tmp_file = tmpdir.join("docker-compose.yaml") - tmp_file.write(DOCKER_COMPOSE) - return str(tmp_file) - - @pytest.fixture(scope="function") def version_files( commitizen_config_file, @@ -126,25 +91,27 @@ def version_files( version_repeated_file, docker_compose_file, ): - return [ + return ( commitizen_config_file, python_version_file, version_repeated_file, docker_compose_file, - ] + ) -def test_update_version_in_files(version_files): +def test_update_version_in_files(version_files, file_regression): old_version = "1.2.3" new_version = "2.0.0" bump.update_version_in_files(old_version, new_version, version_files) + + file_contents = "" for filepath in version_files: with open(filepath, "r") as f: - data = f.read() - assert new_version in data + file_contents += f.read() + file_regression.check(file_contents, extension=".txt") -def test_partial_update_of_file(version_repeated_file): +def test_partial_update_of_file(version_repeated_file, file_regression): old_version = "1.2.3" new_version = "2.0.0" regex = "version" @@ -152,59 +119,53 @@ def test_partial_update_of_file(version_repeated_file): bump.update_version_in_files(old_version, new_version, [location]) with open(version_repeated_file, "r") as f: - data = f.read() - assert new_version in data - assert old_version in data + file_regression.check(f.read(), extension=".json") -def test_random_location(random_location_version_file): +def test_random_location(random_location_version_file, file_regression): old_version = "1.2.3" new_version = "2.0.0" location = f"{random_location_version_file}:there-i-fixed-it.+\nversion" bump.update_version_in_files(old_version, new_version, [location]) with open(random_location_version_file, "r") as f: - data = f.read() - assert len(re.findall(old_version, data)) == 2 - assert len(re.findall(new_version, data)) == 1 + file_regression.check(f.read(), extension=".lock") -def test_duplicates_are_change_with_no_regex(random_location_version_file): +def test_duplicates_are_change_with_no_regex( + random_location_version_file, file_regression +): old_version = "1.2.3" new_version = "2.0.0" location = f"{random_location_version_file}:version" bump.update_version_in_files(old_version, new_version, [location]) with open(random_location_version_file, "r") as f: - data = f.read() - assert len(re.findall(old_version, data)) == 0 - assert len(re.findall(new_version, data)) == 3 + file_regression.check(f.read(), extension=".lock") -def test_version_bump_increase_string_length(multiple_versions_increase_string): +def test_version_bump_increase_string_length( + multiple_versions_increase_string, file_regression +): old_version = "1.2.9" new_version = "1.2.10" - version_bump_change_string_size( - multiple_versions_increase_string, old_version, new_version - ) + location = f"{multiple_versions_increase_string}:version" + + bump.update_version_in_files(old_version, new_version, [location]) + with open(multiple_versions_increase_string, "r") as f: + file_regression.check(f.read(), extension=".txt") -def test_version_bump_reduce_string_length(multiple_versions_reduce_string): +def test_version_bump_reduce_string_length( + multiple_versions_reduce_string, file_regression +): 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" + location = f"{multiple_versions_reduce_string}: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 + with open(multiple_versions_reduce_string, "r") as f: + file_regression.check(f.read(), extension=".txt") def test_file_version_inconsistent_error( @@ -228,3 +189,15 @@ def test_file_version_inconsistent_error( "version_files are possibly inconsistent." ) assert expected_msg in str(excinfo.value) + + +def test_multiplt_versions_to_bump( + multiple_versions_to_update_poetry_lock, file_regression +): + old_version = "1.2.9" + new_version = "1.2.10" + location = f"{multiple_versions_to_update_poetry_lock}:version" + + bump.update_version_in_files(old_version, new_version, [location]) + with open(multiple_versions_to_update_poetry_lock, "r") as f: + file_regression.check(f.read(), extension=".toml") diff --git a/tests/test_bump_update_version_in_files/test_duplicates_are_change_with_no_regex.lock b/tests/test_bump_update_version_in_files/test_duplicates_are_change_with_no_regex.lock new file mode 100644 index 0000000000..eed8f4c79d --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_duplicates_are_change_with_no_regex.lock @@ -0,0 +1,11 @@ +[[package]] +name = "textwrap" +version = "2.0.0" + +[[package]] +name = "there-i-fixed-it" +version = "2.0.0" + +[[package]] +name = "other-project" +version = "2.0.0" diff --git a/tests/test_bump_update_version_in_files/test_multiplt_versions_to_bump_with_eol_.toml b/tests/test_bump_update_version_in_files/test_multiplt_versions_to_bump_with_eol_.toml new file mode 100644 index 0000000000..f279eb4d61 --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_multiplt_versions_to_bump_with_eol_.toml @@ -0,0 +1,27 @@ +[[package]] +name = "to-update-1" +version = "1.2.10" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "to-update-2" +version = "1.2.10" diff --git a/tests/test_bump_update_version_in_files/test_multiplt_versions_to_bump_without_eol_.toml b/tests/test_bump_update_version_in_files/test_multiplt_versions_to_bump_without_eol_.toml new file mode 100644 index 0000000000..47092b958b --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_multiplt_versions_to_bump_without_eol_.toml @@ -0,0 +1,27 @@ +[[package]] +name = "to-update-1" +version = "1.2.10" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "to-update-2" +version = "1.2.10" \ No newline at end of file diff --git a/tests/test_bump_update_version_in_files/test_partial_update_of_file.json b/tests/test_bump_update_version_in_files/test_partial_update_of_file.json new file mode 100644 index 0000000000..59224bca04 --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_partial_update_of_file.json @@ -0,0 +1,7 @@ +{ + "name": "magictool", + "version": "2.0.0", + "dependencies": { + "lodash": "1.2.3" + } +} diff --git a/tests/test_bump_update_version_in_files/test_random_location.lock b/tests/test_bump_update_version_in_files/test_random_location.lock new file mode 100644 index 0000000000..94422116aa --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_random_location.lock @@ -0,0 +1,11 @@ +[[package]] +name = "textwrap" +version = "1.2.3" + +[[package]] +name = "there-i-fixed-it" +version = "2.0.0" + +[[package]] +name = "other-project" +version = "1.2.3" diff --git a/tests/test_bump_update_version_in_files/test_update_version_in_files.txt b/tests/test_bump_update_version_in_files/test_update_version_in_files.txt new file mode 100644 index 0000000000..c4e527ac47 --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_update_version_in_files.txt @@ -0,0 +1,20 @@ +[tool.poetry] +name = "commitizen" +version = "2.0.0" +__title__ = "requests" +__description__ = "Python HTTP for Humans." +__url__ = "http://python-requests.org" +__version__ = "2.0.0" +{ + "name": "magictool", + "version": "2.0.0", + "dependencies": { + "lodash": "2.0.0" + } +} +version: "3.3" + +services: + app: + image: my-repo/my-container:v2.0.0 + command: my-command diff --git a/tests/test_bump_update_version_in_files/test_version_bump_increase_string_length.txt b/tests/test_bump_update_version_in_files/test_version_bump_increase_string_length.txt new file mode 100644 index 0000000000..4b6d6d64be --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_version_bump_increase_string_length.txt @@ -0,0 +1,30 @@ +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" +version = "1.2.10" diff --git a/tests/test_bump_update_version_in_files/test_version_bump_reduce_string_length.txt b/tests/test_bump_update_version_in_files/test_version_bump_reduce_string_length.txt new file mode 100644 index 0000000000..8e619de1ab --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_version_bump_reduce_string_length.txt @@ -0,0 +1,30 @@ +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" +version = "2.0.0" diff --git a/tests/test_git.py b/tests/test_git.py index 8ba2f64cb8..1fe2b9251a 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -152,3 +152,14 @@ def test_get_latest_tag_name(tmp_commitizen_project): cmd.run("git tag 1.0") tag_name = git.get_latest_tag_name() assert tag_name == "1.0" + + +def test_is_staging_clean(tmp_commitizen_project): + with tmp_commitizen_project.as_cwd(): + assert git.is_staging_clean() is True + + cmd.run("touch test_file") + cmd.run("git add test_file") + cmd.run("echo 'test' > test_file") + + assert git.is_staging_clean() is False