55import os
66import re
77import subprocess
8+ import textwrap
89import warnings
910from collections .abc import Mapping
1011from datetime import datetime
11- from distutils .errors import DistutilsSetupError
1212from pathlib import Path
13- from typing import Any , Callable
13+ from typing import TYPE_CHECKING , Any , Callable
1414
1515from setuptools .dist import Distribution
1616
17+ if TYPE_CHECKING :
18+ from packaging .version import Version
19+
1720DEFAULT_TEMPLATE = "{tag}"
1821DEFAULT_DEV_TEMPLATE = "{tag}.post{ccount}+git.{sha}"
1922DEFAULT_DIRTY_TEMPLATE = "{tag}.post{ccount}+git.{sha}.dirty"
@@ -146,6 +149,8 @@ def read_toml(file_name: str | os.PathLike) -> dict:
146149
147150# TODO: remove along with version_config
148151def parse_config (dist : Distribution , attr : Any , value : Any ) -> None :
152+ from distutils .errors import DistutilsOptionError
153+
149154 if attr == "version_config" and value is not None :
150155 warnings .warn (
151156 "`version_config` option is deprecated "
@@ -156,14 +161,16 @@ def parse_config(dist: Distribution, attr: Any, value: Any) -> None:
156161 )
157162
158163 if getattr (dist , "setuptools_git_versioning" , None ) is not None :
159- raise DistutilsSetupError (
164+ raise DistutilsOptionError (
160165 "You can set either `version_config` or `setuptools_git_versioning` "
161166 "but not both of them at the same time"
162167 )
163168
164169
165170# real version is generated here
166171def infer_version (dist : Distribution ) -> None :
172+ from distutils .errors import DistutilsOptionError , DistutilsSetupError
173+
167174 value = getattr (dist , "setuptools_git_versioning" , None ) or getattr (dist , "version_config" , None )
168175
169176 if isinstance (value , bool ):
@@ -190,7 +197,7 @@ def infer_version(dist: Distribution) -> None:
190197 return
191198
192199 if not isinstance (value , Mapping ):
193- raise DistutilsSetupError (f"Wrong config format. Expected dict, got: { value } " )
200+ raise DistutilsOptionError (f"Wrong config format. Expected dict, got: { value } " )
194201
195202 if not value or not value .get ("enabled" , True ):
196203 # Nothing to do here
@@ -439,3 +446,35 @@ def version_from_git(
439446 local_sanitized = LOCAL_REGEXP .sub ("." , local )
440447 public_sanitized = VERSION_PREFIX_REGEXP .sub ("" , public ) # for version "v1.0.0" drop leading "v" symbol
441448 return public_sanitized + sep + local_sanitized
449+
450+
451+ def main (config : dict | None = None ) -> Version :
452+ value = config or read_toml ("pyproject.toml" )
453+
454+ if not value or not value .get ("enabled" , True ):
455+ raise RuntimeError (
456+ textwrap .dedent (
457+ """
458+ 'setuptools-git-versioning' command can be used only with 'pyproject.toml'
459+ file setup (see https://setuptools-git-versioning.readthedocs.io/en/stable/install.html)
460+ """ ,
461+ ),
462+ )
463+
464+ if not isinstance (value , Mapping ):
465+ raise RuntimeError (f"Wrong config format. Expected dict, got: { value } " )
466+
467+ config = load_config_from_dict (value )
468+ result = version_from_git (** config )
469+
470+ from packaging .version import Version
471+
472+ return Version (result )
473+
474+
475+ def __main__ ():
476+ print (main ().public )
477+
478+
479+ if __name__ == "__main__" :
480+ __main__ ()
0 commit comments