From 165623028660d14f43f586b388f1433d85215455 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Tue, 8 Oct 2024 09:18:49 +0800 Subject: [PATCH] feat: Use fallback_version for source = "call" (#264) Fixes #262 Signed-off-by: Frost Ming --- src/pdm/backend/hooks/version/__init__.py | 37 +++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/pdm/backend/hooks/version/__init__.py b/src/pdm/backend/hooks/version/__init__.py index b367a16..d3b7856 100644 --- a/src/pdm/backend/hooks/version/__init__.py +++ b/src/pdm/backend/hooks/version/__init__.py @@ -7,6 +7,7 @@ from pathlib import Path from typing import Callable +from pdm.backend._vendor.packaging.version import Version 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 @@ -55,12 +56,12 @@ def pdm_build_initialize(self, context: Context) -> None: ) return options = {k: v for k, v in version_config.items() if k != "source"} - metadata["version"] = getattr(self, f"resolve_version_from_{source}")( - context, **options + metadata["version"] = str( + getattr(self, f"resolve_version_from_{source}")(context, **options) ) metadata["dynamic"].remove("version") - def resolve_version_from_file(self, context: Context, path: str) -> str: + def resolve_version_from_file(self, context: Context, path: str) -> Version: """Resolve version from a file.""" version_source = context.root / path with open(version_source, encoding="utf-8") as fp: @@ -72,7 +73,7 @@ def resolve_version_from_file(self, context: Context, path: str) -> str: f"Couldn't find version in file {version_source!r}, " "it should appear as `__version__ = 'a.b.c'`.", ) - return match.group(1) + return Version(match.group(1)) def resolve_version_from_scm( self, @@ -83,7 +84,7 @@ def resolve_version_from_scm( tag_filter: str | None = None, version_format: str | None = None, fallback_version: str | None = None, - ) -> str: + ) -> Version: if os.environ.get("PDM_BUILD_SCM_VERSION"): version = os.environ["PDM_BUILD_SCM_VERSION"] else: @@ -114,9 +115,18 @@ def resolve_version_from_scm( version = version_formatter(scm_version, context) # type: ignore[call-arg] else: version = version_formatter(scm_version) # type: ignore[call-arg] - + try: + parsed_version = Version(version) + except ValueError: + if fallback_version is not None: + return Version(fallback_version) + raise ConfigError( + f"Invalid version {version}, it must comply with PEP 440. \n" + "You can still specify the version via environment variable " + "`PDM_BUILD_SCM_VERSION`, or specify `fallback_version` config." + ) self._write_version(context, version, write_to, write_template) - return version + return parsed_version def _write_version( self, @@ -146,8 +156,17 @@ def resolve_version_from_call( getter: str, write_to: str | None = None, write_template: str = "{}\n", - ) -> str: + fallback_version: str | None = None, + ) -> Version: version_getter, args = evaluate_module_attribute(getter, context.root) version = version_getter(*args) + if version is None: + if fallback_version is not None: + return Version(fallback_version) + else: + raise ConfigError( + "Cannot get version from the call, you can specify fallback version via `fallback_version` config." + ) + parsed_version = Version(version) self._write_version(context, version, write_to, write_template) - return version + return parsed_version