Skip to content

Commit 708aa3f

Browse files
authored
feat: accept context as the second argument to version_format function (#258)
1 parent a67b61f commit 708aa3f

File tree

10 files changed

+123
-102
lines changed

10 files changed

+123
-102
lines changed

.pre-commit-config.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@ ci:
33

44
exclude: ^src/pdm/backend/_vendor
55
repos:
6-
- repo: https://github.com/asottile/pyupgrade
7-
rev: v3.17.0
8-
hooks:
9-
- id: pyupgrade
10-
args:
11-
- --py38-plus
12-
136
- repo: https://github.com/astral-sh/ruff-pre-commit
147
rev: 'v0.6.3'
158
hooks:

docs/metadata.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ def format_version(version: SCMVersion) -> str:
9393
return f"{version.version}.post{version.distance}"
9494
```
9595

96+
+++ 2.4.0
97+
98+
From 2.4.0, the `version_format` function **can** take `context` as the second argument.
99+
96100
### Get with a specific function
97101

98102
```toml

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ extend-select = [
4848
"C4", # flake8-comprehensions
4949
"W", # pycodestyle
5050
"YTT", # flake8-2020
51+
"UP", # pyupgrade
52+
"FA", # flake8-annotations
5153
]
5254

5355
[tool.ruff.lint.mccabe]

src/pdm/backend/hooks/version/__init__.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
from __future__ import annotations
22

3+
import inspect
34
import os
45
import re
56
import warnings
67
from pathlib import Path
8+
from typing import Callable
79

810
from pdm.backend.exceptions import ConfigError, PDMWarning, ValidationError
911
from pdm.backend.hooks.base import Context
1012
from pdm.backend.hooks.version.scm import SCMVersion as SCMVersion
11-
from pdm.backend.hooks.version.scm import get_version_from_scm
13+
from pdm.backend.hooks.version.scm import (
14+
default_version_formatter,
15+
get_version_from_scm,
16+
)
1217
from pdm.backend.utils import evaluate_module_attribute
1318

1419

@@ -82,19 +87,19 @@ def resolve_version_from_scm(
8287
if os.environ.get("PDM_BUILD_SCM_VERSION"):
8388
version = os.environ["PDM_BUILD_SCM_VERSION"]
8489
else:
90+
version_formatter: (
91+
Callable[[SCMVersion, Context], str] | Callable[[SCMVersion], str]
92+
)
8593
if version_format is not None:
8694
version_formatter, _ = evaluate_module_attribute(
8795
version_format, context.root
8896
)
8997
else:
90-
version_formatter = None
91-
version = get_version_from_scm(
92-
context.root,
93-
tag_regex=tag_regex,
94-
version_formatter=version_formatter,
95-
tag_filter=tag_filter,
98+
version_formatter = default_version_formatter
99+
scm_version = get_version_from_scm(
100+
context.root, tag_regex=tag_regex, tag_filter=tag_filter
96101
)
97-
if version is None:
102+
if scm_version is None:
98103
if fallback_version is not None:
99104
version = fallback_version
100105
else:
@@ -103,6 +108,12 @@ def resolve_version_from_scm(
103108
"You can still specify the version via environment variable "
104109
"`PDM_BUILD_SCM_VERSION`, or specify `fallback_version` config."
105110
)
111+
else:
112+
params = inspect.signature(version_formatter).parameters
113+
if len(params) > 1:
114+
version = version_formatter(scm_version, context) # type: ignore[call-arg]
115+
else:
116+
version = version_formatter(scm_version) # type: ignore[call-arg]
106117

107118
self._write_version(context, version, write_to, write_template)
108119
return version

src/pdm/backend/hooks/version/scm.py

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from dataclasses import dataclass
1515
from datetime import datetime, timezone
1616
from pathlib import Path
17-
from typing import TYPE_CHECKING, Callable, NamedTuple
17+
from typing import TYPE_CHECKING, NamedTuple
1818

1919
from pdm.backend._vendor.packaging.version import Version
2020

@@ -219,28 +219,15 @@ def hg_get_graph_distance(root: StrPath, tag: str | None) -> int:
219219

220220
def _hg_tagdist_normalize_tagcommit(
221221
config: Config,
222-
root: StrPath,
223222
tag: str,
224223
dist: int,
225224
node: str,
226225
branch: str,
227226
dirty: bool,
228227
) -> SCMVersion:
229-
# Detect changes since the specified tag
230-
if tag != "0.0":
231-
_, commits, _ = _subprocess_call(
232-
["hg", "log", "-r", get_distance_revset(tag), "--template", "{node|short}"],
233-
root,
234-
)
235-
else:
236-
commits = "True"
237-
238-
if commits or dirty:
239-
return meta(
240-
config, tag, distance=dist or None, node=node, dirty=dirty, branch=branch
241-
)
242-
else:
243-
return meta(config, tag)
228+
return meta(
229+
config, tag, distance=dist or None, node=node, dirty=dirty, branch=branch
230+
)
244231

245232

246233
def guess_next_version(tag_version: Version) -> str:
@@ -305,13 +292,13 @@ def hg_parse_version(root: StrPath, config: Config) -> SCMVersion | None:
305292
if tag is None:
306293
tag = "0.0"
307294
return _hg_tagdist_normalize_tagcommit(
308-
config, root, tag, dist, node, branch, dirty=dirty
295+
config, tag, dist, node, branch, dirty=dirty
309296
)
310297
except ValueError:
311298
return None # unpacking failed, old hg
312299

313300

314-
def format_version(version: SCMVersion) -> str:
301+
def default_version_formatter(version: SCMVersion) -> str:
315302
if version.distance is None:
316303
main_version = str(version.version)
317304
else:
@@ -330,20 +317,14 @@ def format_version(version: SCMVersion) -> str:
330317

331318

332319
def get_version_from_scm(
333-
root: str | Path,
334-
*,
335-
tag_regex: str | None = None,
336-
tag_filter: str | None = None,
337-
version_formatter: Callable[[SCMVersion], str] | None = None,
338-
) -> str | None:
320+
root: str | Path, *, tag_regex: str | None = None, tag_filter: str | None = None
321+
) -> SCMVersion | None:
339322
config = Config(
340323
tag_regex=re.compile(tag_regex) if tag_regex else DEFAULT_TAG_REGEX,
341324
tag_filter=tag_filter,
342325
)
343326
for func in (git_parse_version, hg_parse_version):
344327
version = func(root, config)
345328
if version:
346-
if version_formatter is None:
347-
version_formatter = format_version
348-
return version_formatter(version)
329+
return version
349330
return None

src/pdm/backend/utils.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import sys
1010
import types
1111
import urllib.parse
12-
from contextlib import contextmanager
1312
from fnmatch import fnmatchcase
1413
from pathlib import Path
1514
from typing import Any, Callable, Generator, Iterable, Match
@@ -106,16 +105,6 @@ def _build_filter(patterns: Iterable[str]) -> Callable[[str], bool]:
106105
dirs.append(dir)
107106

108107

109-
@contextmanager
110-
def cd(path: str | Path) -> Generator[None]:
111-
_old_cwd = os.getcwd()
112-
os.chdir(path)
113-
try:
114-
yield
115-
finally:
116-
os.chdir(_old_cwd)
117-
118-
119108
def normalize_path(filename: str | Path) -> str:
120109
"""Normalize a file/dir name for comparison purposes"""
121110
filename = os.path.abspath(filename) if sys.platform == "cygwin" else filename

tests/conftest.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
import shutil
22
import subprocess
33
from pathlib import Path
4-
from typing import Generator
54

65
import pytest
76

8-
from pdm.backend import utils
97
from tests import FIXTURES
108

119

1210
@pytest.fixture
13-
def fixture_project(tmp_path: Path, name: str) -> Generator[Path, None, None]:
11+
def fixture_project(tmp_path: Path, name: str, monkeypatch: pytest.MonkeyPatch) -> Path:
1412
project = FIXTURES / "projects" / name
1513
shutil.copytree(project, tmp_path / name)
16-
with utils.cd(tmp_path / name):
17-
yield tmp_path / name
14+
monkeypatch.chdir(tmp_path / name)
15+
return tmp_path / name
1816

1917

2018
@pytest.fixture

0 commit comments

Comments
 (0)