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
2 changes: 1 addition & 1 deletion .mise.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[tools]
pdm = "2.25"
pdm = "2.26"
python = ["3.12", "3.13", "3.14", "3.11", "3.10", "3.9"]
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ PDM and Poetry plugin to sync your pre-commit versions with your lockfile and au
- ⏩ Run every time you run the lockfile is updated, not as a pre-commit hook
- 🔄 Install pre-commit hooks automatically, no need to run `pre-commit install` manually
- 💫 Preserve your pre-commit config file formatting
- ✨ Support [prek](https://prek.j178.dev/) configuration files (preserve `prek` specific keys)
- 🍃 Lightweight, only depends on [strictyaml](https://pypi.org/project/strictyaml/) and [packaging](https://pypi.org/project/packaging/)

## Supported versions

- Python 3.9+ to 3.14+
- PDM 2.7.4 to 2.26+
- Python 3.12.7+ requires PDM 2.20.1+
- Poetry 1.6 to 2.2+
- Poetry 1.6 to 2.3+
- uv (lock version 1)

> ℹ️ While we only test these versions, it should work with more recent versions.
Expand Down Expand Up @@ -87,6 +88,7 @@ disable-sync-from-lock = false
# Packages to ignore when syncing from lock
ignore = []
# Name of the pre-commit config file to sync with
# Can be set to ".pre-commit-config.yml" to support prek alternate config file
pre-commit-config-file = ".pre-commit-config.yaml"
# Additional mapping of URLs to python packages
# Default is empty, but will merge with the default mapping
Expand Down
52 changes: 52 additions & 0 deletions tests/test_pre_commit_config_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,55 @@ def test_update_additional_dependencies_versions(base: str) -> None:
def test_precommit_repo_equality(repo1: PreCommitRepo, repo2: PreCommitRepo, equal: bool):
assert (repo1 == repo2) is equal
assert (hash(repo1) == hash(repo2)) is equal


def test_prek_config_support() -> None:
# A config file with prek-specific keys
file_content = """\
minimum_prek_version: "0.1.0"
orphan: true
repos:
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
priority: 10
env:
FOO: bar
"""
mock_path = MagicMock(spec=Path)
mock_path.open = mock_open(read_data=file_content)

config = PreCommitHookConfig.from_yaml_file(mock_path)

updated_repo = PreCommitRepo(
"https://github.com/psf/black",
"23.4.0",
[PreCommitHook("black")],
)

mock_path.open = mock_open()
config.update_pre_commit_repo_versions({config.repos[0]: updated_repo})

mock_path.open.assert_called_with("w")
handle = mock_path.open()

written_lines = []
for call in handle.writelines.call_args_list:
written_lines.extend(call[0][0])

written_content = "".join(written_lines)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test uses unnecessarily complex assertion pattern

Low Severity

The new test manually iterates over call_args_list to collect written lines and then joins them for comparison. This is unnecessarily complex when the same file already has an established simpler pattern at line 107: mock_file.open().writelines.assert_called_once_with(expected.splitlines(keepends=True)). The new test could use mock_path.open().writelines.assert_called_once_with(expected_content.splitlines(keepends=True)) for consistency and simplicity.

Fix in Cursor Fix in Web


expected_content = """\
minimum_prek_version: "0.1.0"
orphan: true
repos:
- repo: https://github.com/psf/black
rev: 23.4.0
hooks:
- id: black
priority: 10
env:
FOO: bar
"""
assert written_content == expected_content
28 changes: 17 additions & 11 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ env_list =
py{313, 312}-pdm{226, 225, 224, 223, 222, 221, 220, HEAD}
py{311, 310, 39}-pdm{226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 29, 28, 27, HEAD}
py{313, 312, 311, 310, 39}-poetry{22, 21, 20, 18, 17, 16, HEAD}
py{314}-poetry{22, 18, HEAD}
py{314}-poetry{23, 22, 18, HEAD}

[testenv]
set_env =
py{312,313}-pdm{220,221,222,223,226, 225, 224, 226,HEAD}: COVERAGE_FILE = .coverage.{envname}
py{314}-pdm{224,HEAD}: COVERAGE_FILE = .coverage.{envname}
py{39,310,311,312,313,314}-poetry{22, 21, 20, 18, 17, 16, HEAD}: COVERAGE_FILE = .coverage.{envname}
py{314}-pdm{224,225,226,HEAD}: COVERAGE_FILE = .coverage.{envname}
py{39,310,311,312,313,314}-poetry{23,22, 21, 20, 18, 17, 16, HEAD}: COVERAGE_FILE = .coverage.{envname}
py{39,310,311}-pdm{27,28,29,210,211,212,213,214,215,216,217,218,219,220,221,222,223,226, 225, 224,HEAD}: COVERAGE_FILE = .coverage.{envname}
commands =
pytest --cov --cov-append --cov-report=term-missing {posargs:-vv} --cov-config=pyproject.toml
Expand All @@ -26,7 +26,7 @@ depends =
report: py{314, 313, 312, 311, 310, 39}-pdm{226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 29, 28, 27, HEAD}
report: py{314, 313, 312, 311, 310, 39}-poetry{22, 21, 20, 18, 17, 16, HEAD}
py{314, 313, 312, 311, 310, 39}-pdm{226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 29, 28, 27, HEAD}: clean
py{314, 313, 312, 311, 310, 39}-poetry{22, 21, 20, 18, 17, 16, HEAD}: clean
py{314, 313, 312, 311, 310, 39}-poetry{23, 22, 21, 20, 18, 17, 16, HEAD}: clean

[testenv:clean]
skip_install = true
Expand All @@ -52,6 +52,11 @@ deps =
-r requirements-tox.txt
py310-pdm214: httpx<0.28
py311-pdm214: httpx<0.28
py312-pdm221: hishel<1.0
py312-pdm222: hishel<1.0
py312-pdm223: hishel<1.0
py312-pdm224: hishel<1.0
py312-pdm225: hishel<1.0
py39-pdm214: httpx<0.28
py39-pdm27: importlib-metadata<8
pdm210: pdm<2.11,>=2.10
Expand All @@ -76,7 +81,7 @@ deps =
pdm29: pdm<2.10,>=2.9
pdmHEAD: pdm@ git+https://github.com/pdm-project/pdm.git

[testenv:py{314,313,312, 311, 310, 39}-poetry{16, 17, 18, 20, 21, 22, HEAD}]
[testenv:py{314,313,312, 311, 310, 39}-poetry{16, 17, 18, 20, 21, 22, 23,HEAD}]
package = editable
deps =
-r requirements-tox.txt
Expand All @@ -86,14 +91,15 @@ deps =
poetry20: poetry<2.1,>=2
poetry21: poetry<2.2,>=2.1
poetry22: poetry<2.3,>=2.2
poetry23: poetry<2.4,>=2.3
poetryHEAD: poetry@ git+https://github.com/python-poetry/poetry.git

[gh]
python =
3.9= py39-pdm{27,28,29,210,211,212,213,214,215,216,217,218,219,220,221,222,223,225,224,HEAD},py39-poetry{22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.10= py310-pdm{27,28,29,210,211,212,213,214,215,216,217,218,219,220,221,222,223,225,224,HEAD}, py310-poetry{22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.11= py311-pdm{27,28,29,210,211,212,213,214,215,216,217,218,219,220,221,222,223,225,224,HEAD}, py311-poetry{22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.12= py312-pdm{220,221,222,223,225,224,226,HEAD}, py312-poetry{22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.13= py313-pdm{220,221,222,223,225,224,226,HEAD}, py313-poetry{22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.14= py314-pdm{226,HEAD}, py314-poetry{22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.9= py39-pdm{27,28,29,210,211,212,213,214,215,216,217,218,219,220,221,222,223,225,224,HEAD},py39-poetry{23, 22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.10= py310-pdm{27,28,29,210,211,212,213,214,215,216,217,218,219,220,221,222,223,225,224,HEAD}, py310-poetry{23, 22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.11= py311-pdm{27,28,29,210,211,212,213,214,215,216,217,218,219,220,221,222,223,225,224,HEAD}, py311-poetry{23, 22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.12= py312-pdm{220,221,222,223,225,224,226,HEAD}, py312-poetry{23, 22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.13= py313-pdm{220,221,222,223,225,224,226,HEAD}, py313-poetry{23, 22, 21, 20, 18, 17, 16, HEAD}, report, clean
3.14= py314-pdm{226,HEAD}, py314-poetry{23, 22, 21, 20, 18, 17, 16, HEAD}, report, clean
fail_on_no_env = True
Loading