sync-pre-commit-with-uv is a pre-commit hook that does 2 things:
- Ensures that the different
revkeys in your.pre-commit-config.yamlare in sync with the versions of corresponding packages in yourpyproject.toml. - Map specific hooks with uv groups. It will ensure that all the dependencies of
your uv group will be added as
additional_dependenciesin the corresponding pre-commit hook. This is mainly useful for hooks that need a complete environment to run, like static type checkers (mypy,basedpyright, etc.).
If your .pre-commit-config.yaml file looks like this:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.11
hooks:
- id: ruffbut your uv.lock says you're using ruff at version 0.12.0, then the hook will change
.pre-commit-config.yaml to:
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.11.11
+ rev: v0.12.0
hooks:
- id: ruffAnd if it looks like this:
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.400
hooks:
- id: pyright
additional_dependencies:
- django-stubs==5.1.3And you've added configuration in pyproject.toml to synchronize the
additional_dependencies with the uv dependency group named types:
[tool.sync-pre-commit-with-uv.pyright-python]
pypi_package_name = "pyright"
additional_dependencies_uv_params = ["--group", "types"]Then when uv upgrades django-stubs to 5.1.4, the hook will upgrade
.pre-commit-config.yaml to:
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.400
hooks:
- id: pyright
additional_dependencies:
- - django-stubs==5.1.3
+ - django-stubs==5.1.4# .pre-commit-config.yaml
repos:
# ...
- repo: https://github.com/ewjoachim/sync-pre-commit-with-uv
rev: "<current release>"
hooks:
- id: sync# pyproject.toml
# ...
[tool.sync-pre-commit-with-uv.pyright-python]
pypi_package_name = "pyright"
additional_dependencies_uv_params = ["--group", "pyright"]
[[tool.sync-pre-commit-with-uv."ruff-pre-commit"]]
pypi_package_name = "ruff"This hook:
- Look for all the
repokeys in your.pre-commit-config.yaml - By default, the tool will try a simple heuristic to match repository URLs with pypi
names, but you can explicitly provide the mapping by providing entries in your
pyproject.tomlconfiguration (see below for details of the heuristic and supported configuration attributes) - From the list of pypi package names, the hook will extract the corresponding version
in
uv.lock. If it detects that the version is different from what you have, it will replace the value in.pre-commit-config.yaml. - In case you define
additional_dependencies_uv_params, it will runuv exportwith your supplied parameters (letting you select/unselect any group/extra) and will add all resulting values in theadditional_dependenciesobject for the corresponding hook.
Here's the anatomy of the entries in your pyproject.toml:
[tool.sync-pre-commit-with-uv.repo_name]
pypi_package_name = "..."
skipped = true
additional_dependencies_uv_params = ["..."]
# or
additional_dependencies_uv_params = { hook_id = ["..."] }
repo_name: the name of the repository, the part after the last/in the URL, omitting potential.gitsuffix.pypi_package_name: optional string matching the name of the repository (it will be normalized). If not provided, it will be assumed to be the normalizedrepo_name, removing potentialmirrors-orpre-commit-prefixes and-pre-commitsuffix.skipped: optional boolean, defaults tofalse. If set totrue, the hook will not try to synchronize the version of the repository with the one inuv.lock.additional_dependencies_uv_params: optional list of strings, which will be passed touv exportto get the dependencies that should be added to theadditional_dependencieskey of the hook. Can also be set to a dict: in that case the key will be understood as ahook_id, and that configuration will only apply to this specific hook. Can be set to[]if you don't need anyuv exportparameters.
If a repository in .pre-commit-config.yaml does not have a corresponding entry in
pyproject.toml, all the attributes will be set to their default values, if the
corresponding pypi package isn't found, it will be ignored.
Note
It's perfectly possible that you could end up without any specific
configuration in your pyproject.toml file. You only need to write configuration for
the projects where the default configuration doesn't work, or if you want to sync
additional dependencies.
This project is heavily inspired by poetry-to-pre-commit, itself inspired by sync_with_poetry.