Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repos:
hooks:
- id: check-vcs-permalinks
- id: end-of-file-fixer
exclude: "tests/((commands|data)/|test_).+"
exclude: "tests/((commands|data|providers/test_uv_provider)/|test_).+"
- id: trailing-whitespace
args: [ --markdown-linebreak-ext=md ]
exclude: '\.svg$'
Expand Down
2 changes: 2 additions & 0 deletions commitizen/providers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from commitizen.providers.pep621_provider import Pep621Provider
from commitizen.providers.poetry_provider import PoetryProvider
from commitizen.providers.scm_provider import ScmProvider
from commitizen.providers.uv_provider import UvProvider

__all__ = [
"get_provider",
Expand All @@ -28,6 +29,7 @@
"Pep621Provider",
"PoetryProvider",
"ScmProvider",
"UvProvider",
]

PROVIDER_ENTRYPOINT = "commitizen.provider"
Expand Down
41 changes: 41 additions & 0 deletions commitizen/providers/uv_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

import tomlkit

from commitizen.providers.base_provider import TomlProvider

if TYPE_CHECKING:
import tomlkit.items


class UvProvider(TomlProvider):
"""
uv.lock and pyproject.tom version management
"""

filename = "pyproject.toml"
lock_filename = "uv.lock"

@property
def lock_file(self) -> Path:
return Path() / self.lock_filename

def set_version(self, version: str) -> None:
super().set_version(version)
self.set_lock_version(version)

def set_lock_version(self, version: str) -> None:
pyproject_toml_content = tomlkit.parse(self.file.read_text())
project_name = pyproject_toml_content["project"]["name"] # type: ignore[index]

document = tomlkit.parse(self.lock_file.read_text())

packages: tomlkit.items.AoT = document["package"] # type: ignore[assignment]
for i, package in enumerate(packages):
if package["name"] == project_name:
document["package"][i]["version"] = version # type: ignore[index]
break
self.lock_file.write_text(tomlkit.dumps(document))
21 changes: 10 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ npm = "commitizen.providers:NpmProvider"
pep621 = "commitizen.providers:Pep621Provider"
poetry = "commitizen.providers:PoetryProvider"
scm = "commitizen.providers:ScmProvider"
uv = "commitizen.providers:UvProvider"

[project.entry-points."commitizen.scheme"]
pep440 = "commitizen.version_schemes:Pep440"
Expand Down Expand Up @@ -165,9 +166,7 @@ omit = [

[tool.pytest.ini_options]
addopts = "--strict-markers"
testpaths = [
"tests/",
]
testpaths = ["tests/"]

[tool.tox]
requires = ["tox>=4.22"]
Expand All @@ -178,7 +177,7 @@ description = "Run tests suite against Python {base_python}"
skip_install = true
deps = ["poetry>=2.0"]
commands_pre = [["poetry", "install", "--only", "main,test"]]
commands = [["pytest", { replace = "posargs", extend = true}]]
commands = [["pytest", { replace = "posargs", extend = true }]]

[tool.ruff]
line-length = 88
Expand Down Expand Up @@ -227,14 +226,14 @@ poetry_command = ""
[tool.poe.tasks]
format.help = "Format the code"
format.sequence = [
{cmd = "ruff check --fix commitizen tests"},
{cmd = "ruff format commitizen tests"},
{ cmd = "ruff check --fix commitizen tests" },
{ cmd = "ruff format commitizen tests" },
]

lint.help = "Lint the code"
lint.sequence = [
{cmd = "ruff check commitizen/ tests/ --fix"},
{cmd = "mypy commitizen/ tests/"},
{ cmd = "ruff check commitizen/ tests/ --fix" },
{ cmd = "mypy commitizen/ tests/" },
]

check-commit.help = "Check the commit message"
Expand All @@ -254,7 +253,7 @@ all.sequence = [
"format",
"lint",
"cover",
"check-commit"
"check-commit",
]

"doc:screenshots".help = "Render documentation screeenshots"
Expand All @@ -268,10 +267,10 @@ doc.cmd = "mkdocs serve"

ci.help = "Run all tasks in CI"
ci.sequence = [
{cmd="pre-commit run --all-files"},
{ cmd = "pre-commit run --all-files" },
"cover",
]
ci.env = {SKIP = "no-commit-to-branch"}
ci.env = { SKIP = "no-commit-to-branch" }

setup-pre-commit.help = "Install pre-commit hooks"
setup-pre-commit.cmd = "pre-commit install"
97 changes: 97 additions & 0 deletions tests/providers/test_uv_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from commitizen.config.base_config import BaseConfig
from commitizen.providers import get_provider
from commitizen.providers.uv_provider import UvProvider

if TYPE_CHECKING:
from pytest_regressions.file_regression import FileRegressionFixture


PYPROJECT_TOML = """
[project]
name = "test-uv"
version = "4.2.1"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = ["commitizen==4.2.1"]
"""

UV_LOCK_SIMPLIFIED = """
version = 1
revision = 1
requires-python = ">=3.13"

[[package]]
name = "commitizen"
version = "4.2.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "argcomplete" },
{ name = "charset-normalizer" },
{ name = "colorama" },
{ name = "decli" },
{ name = "jinja2" },
{ name = "packaging" },
{ name = "pyyaml" },
{ name = "questionary" },
{ name = "termcolor" },
{ name = "tomlkit" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d8/a3/77ffc9aee014cbf46c84c9f156a1ddef2d4c7cfb87d567decf2541464245/commitizen-4.2.1.tar.gz", hash = "sha256:5255416f6d6071068159f0b97605777f3e25d00927ff157b7a8d01efeda7b952", size = 50645 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/57/ce/2f5d8ebe8376991b5f805e9f33d20c7f4c9ca6155bdbda761117dc41dff1/commitizen-4.2.1-py3-none-any.whl", hash = "sha256:a347889e0fe408c3b920a34130d8f35616be3ea8ac6b7b20c5b9aac19762661b", size = 72646 },
]

[[package]]
name = "decli"
version = "0.6.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/3d/a0/a4658f93ecb589f479037b164dc13c68d108b50bf6594e54c820749f97ac/decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f", size = 7424 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bf/70/3ea48dc9e958d7d66c44c9944809181f1ca79aaef25703c023b5092d34ff/decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed", size = 7854 },
]

[[package]]
name = "test-uv"
version = "4.2.1"
source = { virtual = "." }
dependencies = [
{ name = "commitizen" },
]
"""


def test_uv_provider(
config: BaseConfig, tmpdir, file_regression: FileRegressionFixture
):
with tmpdir.as_cwd():
pyproject_toml_file = tmpdir / UvProvider.filename
pyproject_toml_file.write_text(PYPROJECT_TOML, encoding="utf-8")

uv_lock_file = tmpdir / UvProvider.lock_filename
uv_lock_file.write_text(UV_LOCK_SIMPLIFIED, encoding="utf-8")

config.settings["version_provider"] = "uv"

provider = get_provider(config)
assert isinstance(provider, UvProvider)
assert provider.get_version() == "4.2.1"

provider.set_version("100.100.100")
assert provider.get_version() == "100.100.100"

updated_pyproject_toml_content = pyproject_toml_file.read_text(encoding="utf-8")
updated_uv_lock_content = uv_lock_file.read_text(encoding="utf-8")

for content in (updated_pyproject_toml_content, updated_uv_lock_content):
# updated project version
assert "100.100.100" in content
# commitizen version which was the same as project version and should not be affected
assert "4.2.1" in content

file_regression.check(updated_pyproject_toml_content, extension=".toml")
file_regression.check(updated_uv_lock_content, extension=".lock")
42 changes: 42 additions & 0 deletions tests/providers/test_uv_provider/test_uv_provider.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

version = 1
revision = 1
requires-python = ">=3.13"

[[package]]
name = "commitizen"
version = "4.2.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "argcomplete" },
{ name = "charset-normalizer" },
{ name = "colorama" },
{ name = "decli" },
{ name = "jinja2" },
{ name = "packaging" },
{ name = "pyyaml" },
{ name = "questionary" },
{ name = "termcolor" },
{ name = "tomlkit" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d8/a3/77ffc9aee014cbf46c84c9f156a1ddef2d4c7cfb87d567decf2541464245/commitizen-4.2.1.tar.gz", hash = "sha256:5255416f6d6071068159f0b97605777f3e25d00927ff157b7a8d01efeda7b952", size = 50645 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/57/ce/2f5d8ebe8376991b5f805e9f33d20c7f4c9ca6155bdbda761117dc41dff1/commitizen-4.2.1-py3-none-any.whl", hash = "sha256:a347889e0fe408c3b920a34130d8f35616be3ea8ac6b7b20c5b9aac19762661b", size = 72646 },
]

[[package]]
name = "decli"
version = "0.6.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/3d/a0/a4658f93ecb589f479037b164dc13c68d108b50bf6594e54c820749f97ac/decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f", size = 7424 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bf/70/3ea48dc9e958d7d66c44c9944809181f1ca79aaef25703c023b5092d34ff/decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed", size = 7854 },
]

[[package]]
name = "test-uv"
version = "100.100.100"
source = { virtual = "." }
dependencies = [
{ name = "commitizen" },
]
8 changes: 8 additions & 0 deletions tests/providers/test_uv_provider/test_uv_provider.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

[project]
name = "test-uv"
version = "100.100.100"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = ["commitizen==4.2.1"]
Loading