Skip to content

Commit c1a528b

Browse files
authored
fix(pdm): update post_lock hook for pdm>=2.17 (#32)
1 parent 8e0cb1d commit c1a528b

File tree

7 files changed

+587
-533
lines changed

7 files changed

+587
-533
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ repos:
4646
verbose: true
4747
files: ^db\.py|README\.md$
4848

49-
- rev: v0.3.5
49+
- rev: v0.5.4
5050
repo: https://github.com/astral-sh/ruff-pre-commit
5151
hooks:
5252
- id: ruff
5353
args: [--fix, --exit-non-zero-on-fix]
5454
- id: ruff-format
5555

5656
- repo: https://github.com/pdm-project/pdm
57-
rev: 2.13.2
57+
rev: 2.17.1
5858
hooks:
5959
- id: pdm-lock-check

.tool-versions

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
pdm 2.13.2
2-
python 3.12.2 3.11.8 3.10.13 3.9.18
1+
pdm 2.17.1
2+
python 3.12.4 3.11.9 3.10.14 3.9.19

pdm.lock

Lines changed: 529 additions & 506 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/sync_pre_commit_lock/actions/install_hooks.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ def execute(self) -> None:
4444
def _install_pre_commit_hooks(self) -> None:
4545
try:
4646
self.printer.info("Installing pre-commit hooks...")
47-
return_code = subprocess.check_call(
48-
self.install_pre_commit_hooks_command, # noqa: S603
47+
return_code = subprocess.check_call( # noqa: S603
48+
self.install_pre_commit_hooks_command,
4949
# XXX We probably want to see the output, at least in verbose mode or if it fails
5050
stdout=subprocess.DEVNULL,
5151
stderr=subprocess.DEVNULL,
@@ -61,8 +61,8 @@ def _install_pre_commit_hooks(self) -> None:
6161
def _is_pre_commit_package_installed(self) -> bool:
6262
try:
6363
# Try is `pre-commit --version` works
64-
output = subprocess.check_output(
65-
self.check_pre_commit_version_command, # noqa: S603
64+
output = subprocess.check_output( # noqa: S603
65+
self.check_pre_commit_version_command,
6666
).decode()
6767
except (subprocess.CalledProcessError, FileNotFoundError):
6868
return False
@@ -75,8 +75,8 @@ def _are_pre_commit_hooks_installed(git_root: Path) -> bool:
7575

7676
def _get_git_directory_path(self) -> Path | None:
7777
try:
78-
result = subprocess.check_output(
79-
["git", "rev-parse", "--show-toplevel"], # noqa: S603, S607
78+
result = subprocess.check_output( # noqa: S603
79+
["git", "rev-parse", "--show-toplevel"], # noqa: S607
8080
stderr=subprocess.PIPE,
8181
)
8282
return Path(result.decode().strip()) / ".git"

src/sync_pre_commit_lock/pdm_plugin.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Any, ClassVar
3+
from collections.abc import Iterable
4+
from typing import TYPE_CHECKING, Any, ClassVar, Union
45

56
from pdm import termui
67
from pdm.cli.commands.base import BaseCommand
@@ -117,17 +118,29 @@ def on_pdm_install_setup_pre_commit(
117118
action.execute()
118119

119120

121+
if TYPE_CHECKING:
122+
Resolution = Union[dict[str, list[Candidate]], dict[str, Candidate]]
123+
124+
125+
def select_candidate(candidate: Union[Candidate, list[Candidate]]) -> Candidate | None:
126+
if isinstance(candidate, Iterable):
127+
return next(iter(candidate), None)
128+
return candidate
129+
130+
120131
@post_lock.connect
121132
def on_pdm_lock_check_pre_commit(
122-
project: Project, *, resolution: dict[str, Candidate], dry_run: bool, with_prefix: bool = True, **kwargs: Any
133+
project: Project, *, resolution: Resolution, dry_run: bool, with_prefix: bool = True, **kwargs: Any
123134
) -> None:
124135
project_root: Path = project.root
125136
plugin_config: SyncPreCommitLockConfig = load_config(project_root / project.PYPROJECT_FILENAME)
126137
printer = PDMPrinter(project.core.ui, with_prefix=with_prefix)
127138

128139
file_path = project_root / plugin_config.pre_commit_config_file
129140
resolved_packages: dict[str, GenericLockedPackage] = {
130-
k: GenericLockedPackage(v.name, v.version) for k, v in resolution.items() if v.name and v.version
141+
k: GenericLockedPackage(c.name, c.version)
142+
for k, v in resolution.items()
143+
if (c := select_candidate(v)) and c.name and c.version
131144
}
132145
action = SyncPreCommitHooksVersion(
133146
printer=printer,

tests/test_pdm/test_pdm_sync_pre_commit_hook.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
from __future__ import annotations
2+
13
from pathlib import Path
4+
from typing import TYPE_CHECKING
25
from unittest.mock import MagicMock, patch
36

47
import pytest
8+
from packaging.version import Version
59

610
pdm_module = pytest.importorskip("pdm")
711
# ruff: noqa: E402
12+
from pdm.__version__ import __version__ as pdm_version
813
from pdm.core import Core
914
from pdm.models.candidates import Candidate
1015
from pdm.models.requirements import NamedRequirement
@@ -16,6 +21,9 @@
1621
from sync_pre_commit_lock.config import SyncPreCommitLockConfig
1722
from sync_pre_commit_lock.pdm_plugin import on_pdm_lock_check_pre_commit, register_pdm_plugin
1823

24+
if TYPE_CHECKING:
25+
from sync_pre_commit_lock.pdm_plugin import Resolution
26+
1927

2028
@pytest.fixture()
2129
def project() -> Project:
@@ -36,6 +44,15 @@ def printer() -> Printer:
3644
return x
3745

3846

47+
@pytest.fixture
48+
def resolution() -> Resolution:
49+
"""
50+
Mock resolution depending on pdm version
51+
"""
52+
candidate = Candidate(NamedRequirement("some-library"), "1.0.0", "https://example.com/some-library")
53+
return {"some-library": [candidate] if Version(pdm_version) >= Version("2.17") else candidate}
54+
55+
3956
def test_register_pdm_plugin(project: Project) -> None:
4057
core = project.core
4158
register_pdm_plugin(core)
@@ -44,10 +61,7 @@ def test_register_pdm_plugin(project: Project) -> None:
4461

4562

4663
@patch("sync_pre_commit_lock.pdm_plugin.load_config")
47-
def test_on_pdm_lock_check_pre_commit(mock_load_config: MagicMock, project: MagicMock) -> None:
64+
def test_on_pdm_lock_check_pre_commit(mock_load_config: MagicMock, project: MagicMock, resolution: Resolution) -> None:
4865
mock_load_config.return_value = SyncPreCommitLockConfig(disable_sync_from_lock=True)
49-
resolution = {
50-
"some-library": Candidate(NamedRequirement("some-library"), "1.0.0", "https://example.com/some-library")
51-
}
5266
on_pdm_lock_check_pre_commit(project, dry_run=False, resolution=resolution)
5367
mock_load_config.assert_called_once()

tox.ini

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ requires =
44
env_list =
55
clean
66
report
7-
py{312, 311, 310, 39}-pdm{213, 212, 211, 210, 29, 28, 27}
7+
py{312, 311, 310, 39}-pdm{217, 216, 215, 214, 213, 212, 211, 210, 29, 28, 27}
88
py{312, 311, 310, 39}-poetry{18, 17, 16}
99

1010
[testenv]
1111
set_env =
12-
py{39,310,311,312}-pdm{27,28,29,210,211,212,213}: COVERAGE_FILE = .coverage.{envname}
12+
py{39,310,311,312}-pdm{27,28,29,210,211,212,213,214,215,216,217}: COVERAGE_FILE = .coverage.{envname}
1313
py{39,310,311,312}-poetry{16, 17, 18}: COVERAGE_FILE = .coverage.{envname}
1414
commands =
1515
pytest --cov --cov-append --cov-report=term-missing {posargs:-vv} --cov-config=pyproject.toml
@@ -18,16 +18,16 @@ allowlist_externals =
1818
pdm
1919
pytest
2020
depends =
21-
report: py{312, 311, 310, 39}-pdm{213, 212, 211, 210, 29, 28, 27}
21+
report: py{312, 311, 310, 39}-pdm{217, 216, 215, 214, 213, 212, 211, 210, 29, 28, 27}
2222
report: py{312, 311, 310, 39}-poetry{17, 16}
23-
py{312, 311, 310, 39}-pdm{213, 212, 211, 210, 29, 28, 27}: clean
23+
py{312, 311, 310, 39}-pdm{217, 216, 215, 214, 213, 212, 211, 210, 29, 28, 27}: clean
2424
py{312, 311, 310, 39}-poetry{18, 17, 16}: clean
2525

2626
[testenv:clean]
2727
skip_install = true
2828
commands =
2929
coverage erase
30-
pdm export --dev --group testtox -o requirements-tox.txt
30+
pdm export --dev --group testtox -o requirements-tox.txt --no-hashes
3131
groups =
3232
testtox
3333

@@ -41,14 +41,18 @@ commands =
4141
coverage html
4242
coverage xml
4343

44-
[testenv:py{39,310,311,312}-pdm{27,28,29,210,211,212,213}]
44+
[testenv:py{39,310,311,312}-pdm{27,28,29,210,211,212,213,214,215,216,217}]
4545
package = editable
4646
deps =
4747
-r requirements-tox.txt
4848
pdm210: pdm<2.11,>=2.10
4949
pdm211: pdm<2.12,>=2.11
5050
pdm212: pdm<2.13,>=2.12
5151
pdm213: pdm<2.14,>=2.13.2
52+
pdm214: pdm<2.15,>=2.14
53+
pdm215: pdm<2.16,>=2.15
54+
pdm216: pdm<2.17,>=2.16
55+
pdm217: pdm<2.18,>=2.17
5256
pdm27: pdm<2.8,>=2.7
5357
pdm28: pdm<2.9,>=2.8
5458
pdm29: pdm<2.10,>=2.9
@@ -63,8 +67,8 @@ deps =
6367

6468
[gh]
6569
python =
66-
3.9= py39-pdm{27,28,29,210,211,212,213},py39-poetry{16, 17, 18}, report, clean
67-
3.10= py310-pdm{27,28,29,210,211,212,213}, py310-poetry{16, 17, 18}, report, clean
68-
3.11= py311-pdm{27,28,29,210,211,212,213}, py311-poetry{16, 17, 18}, report, clean
69-
3.12= py312-pdm{27,28,29,210,211,212,213}, py312-poetry{16, 17, 18}, report, clean
70+
3.9= py39-pdm{27,28,29,210,211,212,213,214,215,216,217},py39-poetry{16, 17, 18}, report, clean
71+
3.10= py310-pdm{27,28,29,210,211,212,213,214,215,216,217}, py310-poetry{16, 17, 18}, report, clean
72+
3.11= py311-pdm{27,28,29,210,211,212,213,214,215,216,217}, py311-poetry{16, 17, 18}, report, clean
73+
3.12= py312-pdm{27,28,29,210,211,212,213,214,215,216,217}, py312-poetry{16, 17, 18}, report, clean
7074
fail_on_no_env = True

0 commit comments

Comments
 (0)