diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 08c31ba..ad78003 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.6.3 # automatically updated by Commitizen + rev: v4.7.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index dbad463..7ca4f2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v4.7.0 (2025-05-10) + +### Feat + +- **providers**: add support for `Cargo.lock` + +### Refactor + +- **tests**: increase verbosity of variables + ## v4.6.3 (2025-05-07) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index de3842d..8355eb4 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.6.3" +__version__ = "4.7.0" diff --git a/commitizen/providers/cargo_provider.py b/commitizen/providers/cargo_provider.py index cee687c..2e73ff3 100644 --- a/commitizen/providers/cargo_provider.py +++ b/commitizen/providers/cargo_provider.py @@ -1,5 +1,7 @@ from __future__ import annotations +from pathlib import Path + import tomlkit from commitizen.providers.base_provider import TomlProvider @@ -13,6 +15,11 @@ class CargoProvider(TomlProvider): """ filename = "Cargo.toml" + lock_filename = "Cargo.lock" + + @property + def lock_file(self) -> Path: + return Path() / self.lock_filename def get(self, document: tomlkit.TOMLDocument) -> str: try: @@ -28,3 +35,23 @@ class CargoProvider(TomlProvider): except tomlkit.exceptions.NonExistentKey: ... document["package"]["version"] = version # type: ignore + + def set_version(self, version: str) -> None: + super().set_version(version) + if self.lock_file.exists(): + self.set_lock_version(version) + + def set_lock_version(self, version: str) -> None: + cargo_toml_content = tomlkit.parse(self.file.read_text()) + try: + package_name = cargo_toml_content["package"]["name"] # type: ignore + except tomlkit.exceptions.NonExistentKey: + package_name = cargo_toml_content["workspace"]["package"]["name"] # type: ignore + + cargo_lock_content = tomlkit.parse(self.lock_file.read_text()) + packages: tomlkit.items.AoT = cargo_lock_content["package"] # type: ignore[assignment] + for i, package in enumerate(packages): + if package["name"] == package_name: + cargo_lock_content["package"][i]["version"] = version # type: ignore[index] + break + self.lock_file.write_text(tomlkit.dumps(cargo_lock_content)) diff --git a/docs/config.md b/docs/config.md index d1ae90b..a522312 100644 --- a/docs/config.md +++ b/docs/config.md @@ -353,7 +353,7 @@ Commitizen provides some version providers for some well known formats: | `pep621` | Get and set version from `pyproject.toml` `project.version` field | | `poetry` | Get and set version from `pyproject.toml` `tool.poetry.version` field | | `uv` | Get and set version from `pyproject.toml` `project.version` field and `uv.lock` `package.version` field whose `package.name` field is the same as `pyproject.toml` `project.name` field | -| `cargo` | Get and set version from `Cargo.toml` `project.version` field | +| `cargo` | Get and set version from `Cargo.toml` `package.version` field and `Cargo.lock` `package.version` field whose `package.name` field is the same as `Cargo.toml` `package.name` field | | `npm` | Get and set version from `package.json` `version` field, `package-lock.json` `version,packages.''.version` fields if the file exists, and `npm-shrinkwrap.json` `version,packages.''.version` fields if the file exists | | `composer` | Get and set version from `composer.json` `project.version` field | diff --git a/pyproject.toml b/pyproject.toml index 92b28fd..02c6d12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.6.3" +version = "4.7.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.6.3" +version = "4.7.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", diff --git a/tests/providers/test_cargo_provider.py b/tests/providers/test_cargo_provider.py index 646ef3a..4b20c6e 100644 --- a/tests/providers/test_cargo_provider.py +++ b/tests/providers/test_cargo_provider.py @@ -15,7 +15,7 @@ name = "whatever" version = "0.1.0" """ -CARGO_EXPECTED = """\ +CARGO_TOML_EXPECTED = """\ [package] name = "whatever" version = "42.1" @@ -27,18 +27,44 @@ name = "whatever" version = "0.1.0" """ -CARGO_WORKSPACE_EXPECTED = """\ +CARGO_WORKSPACE_TOML_EXPECTED = """\ [workspace.package] name = "whatever" version = "42.1" """ +CARGO_LOCK = """\ +[[package]] +name = "whatever" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123abc" +dependencies = [ + "packageA", + "packageB", + "packageC", +] +""" + +CARGO_LOCK_EXPECTED = """\ +[[package]] +name = "whatever" +version = "42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123abc" +dependencies = [ + "packageA", + "packageB", + "packageC", +] +""" + @pytest.mark.parametrize( "content, expected", ( - (CARGO_TOML, CARGO_EXPECTED), - (CARGO_WORKSPACE_TOML, CARGO_WORKSPACE_EXPECTED), + (CARGO_TOML, CARGO_TOML_EXPECTED), + (CARGO_WORKSPACE_TOML, CARGO_WORKSPACE_TOML_EXPECTED), ), ) def test_cargo_provider( @@ -58,3 +84,46 @@ def test_cargo_provider( provider.set_version("42.1") assert file.read_text() == dedent(expected) + + +@pytest.mark.parametrize( + "toml_content, lock_content, toml_expected, lock_expected", + ( + ( + CARGO_TOML, + CARGO_LOCK, + CARGO_TOML_EXPECTED, + CARGO_LOCK_EXPECTED, + ), + ( + CARGO_WORKSPACE_TOML, + CARGO_LOCK, + CARGO_WORKSPACE_TOML_EXPECTED, + CARGO_LOCK_EXPECTED, + ), + ), +) +def test_cargo_provider_with_lock( + config: BaseConfig, + chdir: Path, + toml_content: str, + lock_content: str, + toml_expected: str, + lock_expected: str, +): + filename = CargoProvider.filename + file = chdir / filename + file.write_text(dedent(toml_content)) + + lock_filename = CargoProvider.lock_filename + lock_file = chdir / lock_filename + lock_file.write_text(dedent(lock_content)) + config.settings["version_provider"] = "cargo" + + provider = get_provider(config) + assert isinstance(provider, CargoProvider) + assert provider.get_version() == "0.1.0" + + provider.set_version("42.1") + assert file.read_text() == dedent(toml_expected) + assert lock_file.read_text() == dedent(lock_expected)