Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions commitizen/providers/cargo_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ def set_lock_version(self, version: str) -> None:
).get("package", {})
if TYPE_CHECKING:
assert isinstance(package_content, dict)
try:
version_workspace = package_content["version"]["workspace"]
if version_workspace is True:
package_name = package_content["name"]
if TYPE_CHECKING:
assert isinstance(package_name, str)
members_inheriting.append(package_name)
except NonExistentKey:
pass
version_field = package_content.get("version")
if (
isinstance(version_field, dict)
and version_field.get("workspace") is True
):
package_name = package_content["name"]
if TYPE_CHECKING:
assert isinstance(package_name, str)
members_inheriting.append(package_name)

for i, package in enumerate(packages):
if package["name"] in members_inheriting:
Expand Down
77 changes: 77 additions & 0 deletions tests/providers/test_cargo_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,80 @@ def test_cargo_provider_workspace_member_without_workspace_key(
assert file.read_text() == dedent(expected_workspace_toml)
# The lock file should remain unchanged since the member doesn't inherit workspace version
assert lock_file.read_text() == dedent(expected_lock_content)


def test_cargo_provider_workspace_member_with_fixed_version(
config: BaseConfig,
chdir: Path,
):
"""Regression test for https://github.com/commitizen-tools/commitizen/issues/2001.

A workspace member with a hardcoded ``version = "x.y.z"`` string (rather
than ``version.workspace = true``) used to crash ``set_lock_version`` with
``TypeError: string indices must be integers, not 'str'`` because the code
unconditionally subscripted ``package["version"]["workspace"]``.
"""
workspace_toml = """\
[workspace]
members = ["member_with_fixed_version"]

[workspace.package]
version = "0.1.0"
"""

# Real Cargo syntax for a workspace member that opts out of the
# workspace-inherited version by pinning its own.
member_content = """\
[package]
name = "member_with_fixed_version"
version = "0.9.0"
"""

lock_content = """\
[[package]]
name = "member_with_fixed_version"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123abc"
"""

expected_workspace_toml = """\
[workspace]
members = ["member_with_fixed_version"]

[workspace.package]
version = "42.1"
"""

# The pinned member must not be bumped because it does not inherit the
# workspace version.
expected_lock_content = """\
[[package]]
name = "member_with_fixed_version"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123abc"
"""

filename = CargoProvider.filename
file = chdir / filename
file.write_text(dedent(workspace_toml))

os.mkdir(chdir / "member_with_fixed_version")
member_file = chdir / "member_with_fixed_version" / "Cargo.toml"
member_file.write_text(dedent(member_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"

# Must not raise TypeError: string indices must be integers, not 'str'.
provider.set_version("42.1")
assert file.read_text() == dedent(expected_workspace_toml)
assert lock_file.read_text() == dedent(expected_lock_content)
Loading