Skip to content

Commit

Permalink
feat: accept context as the second argument to version_format function (
Browse files Browse the repository at this point in the history
  • Loading branch information
frostming authored Sep 19, 2024
1 parent a67b61f commit 708aa3f
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 102 deletions.
7 changes: 0 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ ci:

exclude: ^src/pdm/backend/_vendor
repos:
- repo: https://github.com/asottile/pyupgrade
rev: v3.17.0
hooks:
- id: pyupgrade
args:
- --py38-plus

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.6.3'
hooks:
Expand Down
4 changes: 4 additions & 0 deletions docs/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ def format_version(version: SCMVersion) -> str:
return f"{version.version}.post{version.distance}"
```

+++ 2.4.0

From 2.4.0, the `version_format` function **can** take `context` as the second argument.

### Get with a specific function

```toml
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ extend-select = [
"C4", # flake8-comprehensions
"W", # pycodestyle
"YTT", # flake8-2020
"UP", # pyupgrade
"FA", # flake8-annotations
]

[tool.ruff.lint.mccabe]
Expand Down
27 changes: 19 additions & 8 deletions src/pdm/backend/hooks/version/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
from __future__ import annotations

import inspect
import os
import re
import warnings
from pathlib import Path
from typing import Callable

from pdm.backend.exceptions import ConfigError, PDMWarning, ValidationError
from pdm.backend.hooks.base import Context
from pdm.backend.hooks.version.scm import SCMVersion as SCMVersion
from pdm.backend.hooks.version.scm import get_version_from_scm
from pdm.backend.hooks.version.scm import (
default_version_formatter,
get_version_from_scm,
)
from pdm.backend.utils import evaluate_module_attribute


Expand Down Expand Up @@ -82,19 +87,19 @@ def resolve_version_from_scm(
if os.environ.get("PDM_BUILD_SCM_VERSION"):
version = os.environ["PDM_BUILD_SCM_VERSION"]
else:
version_formatter: (
Callable[[SCMVersion, Context], str] | Callable[[SCMVersion], str]
)
if version_format is not None:
version_formatter, _ = evaluate_module_attribute(
version_format, context.root
)
else:
version_formatter = None
version = get_version_from_scm(
context.root,
tag_regex=tag_regex,
version_formatter=version_formatter,
tag_filter=tag_filter,
version_formatter = default_version_formatter
scm_version = get_version_from_scm(
context.root, tag_regex=tag_regex, tag_filter=tag_filter
)
if version is None:
if scm_version is None:
if fallback_version is not None:
version = fallback_version
else:
Expand All @@ -103,6 +108,12 @@ def resolve_version_from_scm(
"You can still specify the version via environment variable "
"`PDM_BUILD_SCM_VERSION`, or specify `fallback_version` config."
)
else:
params = inspect.signature(version_formatter).parameters
if len(params) > 1:
version = version_formatter(scm_version, context) # type: ignore[call-arg]
else:
version = version_formatter(scm_version) # type: ignore[call-arg]

self._write_version(context, version, write_to, write_template)
return version
Expand Down
37 changes: 9 additions & 28 deletions src/pdm/backend/hooks/version/scm.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import TYPE_CHECKING, Callable, NamedTuple
from typing import TYPE_CHECKING, NamedTuple

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

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

def _hg_tagdist_normalize_tagcommit(
config: Config,
root: StrPath,
tag: str,
dist: int,
node: str,
branch: str,
dirty: bool,
) -> SCMVersion:
# Detect changes since the specified tag
if tag != "0.0":
_, commits, _ = _subprocess_call(
["hg", "log", "-r", get_distance_revset(tag), "--template", "{node|short}"],
root,
)
else:
commits = "True"

if commits or dirty:
return meta(
config, tag, distance=dist or None, node=node, dirty=dirty, branch=branch
)
else:
return meta(config, tag)
return meta(
config, tag, distance=dist or None, node=node, dirty=dirty, branch=branch
)


def guess_next_version(tag_version: Version) -> str:
Expand Down Expand Up @@ -305,13 +292,13 @@ def hg_parse_version(root: StrPath, config: Config) -> SCMVersion | None:
if tag is None:
tag = "0.0"
return _hg_tagdist_normalize_tagcommit(
config, root, tag, dist, node, branch, dirty=dirty
config, tag, dist, node, branch, dirty=dirty
)
except ValueError:
return None # unpacking failed, old hg


def format_version(version: SCMVersion) -> str:
def default_version_formatter(version: SCMVersion) -> str:
if version.distance is None:
main_version = str(version.version)
else:
Expand All @@ -330,20 +317,14 @@ def format_version(version: SCMVersion) -> str:


def get_version_from_scm(
root: str | Path,
*,
tag_regex: str | None = None,
tag_filter: str | None = None,
version_formatter: Callable[[SCMVersion], str] | None = None,
) -> str | None:
root: str | Path, *, tag_regex: str | None = None, tag_filter: str | None = None
) -> SCMVersion | None:
config = Config(
tag_regex=re.compile(tag_regex) if tag_regex else DEFAULT_TAG_REGEX,
tag_filter=tag_filter,
)
for func in (git_parse_version, hg_parse_version):
version = func(root, config)
if version:
if version_formatter is None:
version_formatter = format_version
return version_formatter(version)
return version
return None
11 changes: 0 additions & 11 deletions src/pdm/backend/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import sys
import types
import urllib.parse
from contextlib import contextmanager
from fnmatch import fnmatchcase
from pathlib import Path
from typing import Any, Callable, Generator, Iterable, Match
Expand Down Expand Up @@ -106,16 +105,6 @@ def _build_filter(patterns: Iterable[str]) -> Callable[[str], bool]:
dirs.append(dir)


@contextmanager
def cd(path: str | Path) -> Generator[None]:
_old_cwd = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(_old_cwd)


def normalize_path(filename: str | Path) -> str:
"""Normalize a file/dir name for comparison purposes"""
filename = os.path.abspath(filename) if sys.platform == "cygwin" else filename
Expand Down
8 changes: 3 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import shutil
import subprocess
from pathlib import Path
from typing import Generator

import pytest

from pdm.backend import utils
from tests import FIXTURES


@pytest.fixture
def fixture_project(tmp_path: Path, name: str) -> Generator[Path, None, None]:
def fixture_project(tmp_path: Path, name: str, monkeypatch: pytest.MonkeyPatch) -> Path:
project = FIXTURES / "projects" / name
shutil.copytree(project, tmp_path / name)
with utils.cd(tmp_path / name):
yield tmp_path / name
monkeypatch.chdir(tmp_path / name)
return tmp_path / name


@pytest.fixture
Expand Down
Loading

0 comments on commit 708aa3f

Please sign in to comment.