versions: expand support for Python Package Versions
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
0ff1d79b5b
commit
17dc05c9b7
|
@ -6,7 +6,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import re
|
import re
|
||||||
from enum import Flag, auto
|
from enum import Flag, auto
|
||||||
from typing import Tuple, Optional, Dict, List
|
from typing import Tuple, Optional, Dict, List, Any
|
||||||
|
|
||||||
# Python regex for parsing version strings from PEP 440
|
# Python regex for parsing version strings from PEP 440
|
||||||
# https://peps.python.org/pep-0440/#appendix-b-parsing-version-strings-with-regular-expressions
|
# https://peps.python.org/pep-0440/#appendix-b-parsing-version-strings-with-regular-expressions
|
||||||
|
@ -58,7 +58,6 @@ GIT_VERSION_PATTERN = r"""
|
||||||
)?
|
)?
|
||||||
(?P<dirty>-dirty)?
|
(?P<dirty>-dirty)?
|
||||||
(?P<inferred>-(?:inferred|shallow))?
|
(?P<inferred>-(?:inferred|shallow))?
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_py_version_regex = re.compile(
|
_py_version_regex = re.compile(
|
||||||
|
@ -95,6 +94,12 @@ class BaseVersion:
|
||||||
def full_version(self) -> str:
|
def full_version(self) -> str:
|
||||||
return self._orig
|
return self._orig
|
||||||
|
|
||||||
|
@property
|
||||||
|
def short_version(self) -> str:
|
||||||
|
if not self._valid_version:
|
||||||
|
return "?"
|
||||||
|
return f"{self._tag}-{self._dev_count}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def release(self) -> str:
|
def release(self) -> str:
|
||||||
return self._release
|
return self._release
|
||||||
|
@ -233,10 +238,9 @@ class BaseVersion:
|
||||||
class PyVersion(BaseVersion):
|
class PyVersion(BaseVersion):
|
||||||
def __init__(self, version: str) -> None:
|
def __init__(self, version: str) -> None:
|
||||||
super().__init__(version)
|
super().__init__(version)
|
||||||
ver_match = _py_version_regex.match(version)
|
version_info = self._get_version_info()
|
||||||
if ver_match is None:
|
if version_info is None:
|
||||||
return
|
return
|
||||||
version_info = ver_match.groupdict()
|
|
||||||
release: Optional[str] = version_info["release"]
|
release: Optional[str] = version_info["release"]
|
||||||
if release is None:
|
if release is None:
|
||||||
return
|
return
|
||||||
|
@ -246,8 +250,9 @@ class PyVersion(BaseVersion):
|
||||||
self._release_tup = tuple(int(part) for part in release.split("."))
|
self._release_tup = tuple(int(part) for part in release.split("."))
|
||||||
self._extra_tup = (1, 0, 0)
|
self._extra_tup = (1, 0, 0)
|
||||||
if version_info["pre"] is not None:
|
if version_info["pre"] is not None:
|
||||||
|
pre_conv: Dict[str, int]
|
||||||
pre_conv = dict([("a", 1), ("b", 2), ("c", 3), ("r", 3), ("p", 3)])
|
pre_conv = dict([("a", 1), ("b", 2), ("c", 3), ("r", 3), ("p", 3)])
|
||||||
lbl = version_info["pre_l"][0].lower()
|
lbl: str = version_info["pre_l"][0].lower()
|
||||||
self._extra_tup = (0, pre_conv.get(lbl, 0), int(version_info["pre_n"] or 0))
|
self._extra_tup = (0, pre_conv.get(lbl, 0), int(version_info["pre_n"] or 0))
|
||||||
self._tag += version_info["pre"]
|
self._tag += version_info["pre"]
|
||||||
self._release_type |= ReleaseType(1 << pre_conv.get(lbl, 1))
|
self._release_type |= ReleaseType(1 << pre_conv.get(lbl, 1))
|
||||||
|
@ -272,23 +277,60 @@ class PyVersion(BaseVersion):
|
||||||
self._dev_count = int(version_info["dev_n"] or 0)
|
self._dev_count = int(version_info["dev_n"] or 0)
|
||||||
self.local: Optional[str] = version_info["local"]
|
self.local: Optional[str] = version_info["local"]
|
||||||
|
|
||||||
def convert_to_git(self, version_info: Dict[str, Optional[str]]) -> GitVersion:
|
@property
|
||||||
|
def short_version(self) -> str:
|
||||||
|
if not self._valid_version:
|
||||||
|
return "?"
|
||||||
|
if not self._dev_count:
|
||||||
|
return self._tag
|
||||||
|
return f"{self._tag}-{self._dev_count}"
|
||||||
|
|
||||||
|
def _get_version_info(self) -> Optional[Dict[str, Any]]:
|
||||||
|
ver_match = _py_version_regex.match(self._orig)
|
||||||
|
if ver_match is None:
|
||||||
|
return None
|
||||||
|
return ver_match.groupdict()
|
||||||
|
|
||||||
|
def bump_local_version(self, new_local: str) -> PyVersion:
|
||||||
|
# current patch version needs to be bumped
|
||||||
|
version_info = self._get_version_info()
|
||||||
|
if version_info is None:
|
||||||
|
return PyVersion("?")
|
||||||
|
new_ver = version_info["release"]
|
||||||
|
major, _, minor = new_ver.rpartition(".")
|
||||||
|
if major and not self._dev_count:
|
||||||
|
new_ver = f"v{major}.{int(minor) + 1}"
|
||||||
|
if version_info["pre"] is not None:
|
||||||
|
new_ver += version_info["pre"]
|
||||||
|
if version_info["post"] is not None:
|
||||||
|
new_ver += version_info["post"]
|
||||||
|
if self._dev_count:
|
||||||
|
new_ver += f".dev{self._dev_count + 1}"
|
||||||
|
else:
|
||||||
|
new_ver += ".dev1"
|
||||||
|
new_ver += f"+{new_local}"
|
||||||
|
return PyVersion(new_ver)
|
||||||
|
|
||||||
|
def convert_to_git(self) -> GitVersion:
|
||||||
|
version_info = self._get_version_info()
|
||||||
|
if version_info is None:
|
||||||
|
return GitVersion("?")
|
||||||
git_version: Optional[str] = version_info["release"]
|
git_version: Optional[str] = version_info["release"]
|
||||||
if git_version is None:
|
if git_version is None:
|
||||||
raise ValueError("Invalid version string")
|
raise ValueError("Invalid version string")
|
||||||
if self._orig[0].lower() == "v":
|
if self._orig[0].lower() == "v":
|
||||||
git_version == f"v{git_version}"
|
git_version = f"v{git_version}"
|
||||||
local: str = version_info["local"] or ""
|
local: str = version_info["local"] or ""
|
||||||
# Assume semantic versioning, convert the version string.
|
# Assume semantic versioning, convert the version string.
|
||||||
if version_info["dev_n"] is not None:
|
if self._dev_count > 0:
|
||||||
major, _, minor = git_version.rpartition(".")
|
major, _, minor = git_version.rpartition(".")
|
||||||
if major:
|
if major:
|
||||||
git_version = f"v{major}.{max(int(minor) - 1, 0)}"
|
git_version = f"v{major}.{max(int(minor) - 1, 0)}"
|
||||||
if version_info["pre"] is not None:
|
if version_info["pre"] is not None:
|
||||||
git_version = f"{git_version}{version_info['pre']}"
|
git_version = f"{git_version}{version_info['pre']}"
|
||||||
dev_num = version_info["dev_n"] or 0
|
git_version = f"{git_version}-{self._dev_count}"
|
||||||
git_version = f"{git_version}-{dev_num}"
|
if local:
|
||||||
local_parts = local.split(".", 1)[0]
|
local_parts = re.split(r"[-_\.]", local)
|
||||||
if local_parts[0]:
|
if local_parts[0]:
|
||||||
git_version = f"{git_version}-{local_parts[0]}"
|
git_version = f"{git_version}-{local_parts[0]}"
|
||||||
if len(local_parts) > 1:
|
if len(local_parts) > 1:
|
||||||
|
@ -322,6 +364,7 @@ class GitVersion(BaseVersion):
|
||||||
self._release_tup = tuple(int(part) for part in release.split("."))
|
self._release_tup = tuple(int(part) for part in release.split("."))
|
||||||
self._extra_tup = (1, 0, 0)
|
self._extra_tup = (1, 0, 0)
|
||||||
if version_info["pre"] is not None:
|
if version_info["pre"] is not None:
|
||||||
|
pre_conv: Dict[str, int]
|
||||||
pre_conv = dict([("a", 1), ("b", 2), ("c", 3), ("r", 3), ("p", 3)])
|
pre_conv = dict([("a", 1), ("b", 2), ("c", 3), ("r", 3), ("p", 3)])
|
||||||
lbl = version_info["pre_l"][0].lower()
|
lbl = version_info["pre_l"][0].lower()
|
||||||
self._extra_tup = (0, pre_conv.get(lbl, 0), int(version_info["pre_n"] or 0))
|
self._extra_tup = (0, pre_conv.get(lbl, 0), int(version_info["pre_n"] or 0))
|
||||||
|
@ -338,12 +381,6 @@ class GitVersion(BaseVersion):
|
||||||
self._is_inferred = version_info["inferred"] is not None
|
self._is_inferred = version_info["inferred"] is not None
|
||||||
self._is_dirty = version_info["dirty"] is not None
|
self._is_dirty = version_info["dirty"] is not None
|
||||||
|
|
||||||
@property
|
|
||||||
def short_version(self) -> str:
|
|
||||||
if not self._valid_version:
|
|
||||||
return "?"
|
|
||||||
return f"{self._tag}-{self._dev_count}"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dirty(self) -> bool:
|
def dirty(self) -> bool:
|
||||||
return self._is_dirty
|
return self._is_dirty
|
||||||
|
@ -360,7 +397,7 @@ class GitVersion(BaseVersion):
|
||||||
if self._is_inferred:
|
if self._is_inferred:
|
||||||
# We can't infer a previous release from another inferred release
|
# We can't infer a previous release from another inferred release
|
||||||
return self._tag
|
return self._tag
|
||||||
type_choices = dict([(1, "a"), (2, "b"), (3, "rc")])
|
type_choices: Dict[int, str] = dict([(1, "a"), (2, "b"), (3, "rc")])
|
||||||
if self.is_pre_release() and self._extra_tup > (0, 1, 0):
|
if self.is_pre_release() and self._extra_tup > (0, 1, 0):
|
||||||
type_idx = self._extra_tup[1]
|
type_idx = self._extra_tup[1]
|
||||||
type_count = self._extra_tup[2]
|
type_count = self._extra_tup[2]
|
||||||
|
|
Loading…
Reference in New Issue