Skip to content

feat(providers): add uv_provider #1351

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 28, 2025
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