Include tag distance and commit hash in dev versions when possible (#5664)

* Include tag distance and commit hash in dev versions when possible

* Fix test
This commit is contained in:
jack1142 2022-04-03 03:51:34 +02:00 committed by GitHub
parent febca8ccbb
commit 35f1681dc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 80 additions and 11 deletions

View File

@ -4,10 +4,11 @@ import sys
from typing import Match from typing import Match
import redbot import redbot
from redbot._version import __version__
if int(os.environ.get("JUST_RETURN_VERSION", 0)): if int(os.environ.get("JUST_RETURN_VERSION", 0)):
print(f"::set-output name=version::{redbot.__version__}") print(f"::set-output name=version::{__version__}")
sys.exit(0) sys.exit(0)
@ -33,7 +34,7 @@ def repl(match: Match[str]) -> str:
return f'__version__ = "{version_info}"' return f'__version__ = "{version_info}"'
with open("redbot/__init__.py", encoding="utf-8") as fp: with open("redbot/_version.py", encoding="utf-8") as fp:
new_contents, found = re.subn( new_contents, found = re.subn(
pattern=r'^__version__ = "(?P<version>[^"]*)"$', pattern=r'^__version__ = "(?P<version>[^"]*)"$',
repl=repl, repl=repl,
@ -46,7 +47,7 @@ if not found:
print("Couldn't find `__version__` line!") print("Couldn't find `__version__` line!")
sys.exit(1) sys.exit(1)
with open("redbot/__init__.py", "w", encoding="utf-8", newline="\n") as fp: with open("redbot/_version.py", "w", encoding="utf-8", newline="\n") as fp:
fp.write(new_contents) fp.write(new_contents)
print(f"::set-output name=new_version::{version_info}") print(f"::set-output name=new_version::{version_info}")

View File

@ -12,6 +12,8 @@ from typing import (
Union as _Union, Union as _Union,
) )
from redbot._version import _get_version
MIN_PYTHON_VERSION = (3, 8, 1) MIN_PYTHON_VERSION = (3, 8, 1)
@ -42,6 +44,7 @@ class VersionInfo:
r"(?:(?P<releaselevel>a|b|rc)(?P<serial>0|[1-9]\d*))?" r"(?:(?P<releaselevel>a|b|rc)(?P<serial>0|[1-9]\d*))?"
r"(?:\.post(?P<post_release>0|[1-9]\d*))?" r"(?:\.post(?P<post_release>0|[1-9]\d*))?"
r"(?:\.dev(?P<dev_release>0|[1-9]\d*))?" r"(?:\.dev(?P<dev_release>0|[1-9]\d*))?"
r"(?:\+(?P<local_version>g[a-z0-9]+(?:\.dirty)?))?"
r"$", r"$",
flags=_re.IGNORECASE, flags=_re.IGNORECASE,
) )
@ -61,6 +64,7 @@ class VersionInfo:
serial: _Optional[int] = None, serial: _Optional[int] = None,
post_release: _Optional[int] = None, post_release: _Optional[int] = None,
dev_release: _Optional[int] = None, dev_release: _Optional[int] = None,
local_version: _Optional[str] = None,
) -> None: ) -> None:
self.major: int = major self.major: int = major
self.minor: int = minor self.minor: int = minor
@ -73,6 +77,17 @@ class VersionInfo:
self.serial: _Optional[int] = serial self.serial: _Optional[int] = serial
self.post_release: _Optional[int] = post_release self.post_release: _Optional[int] = post_release
self.dev_release: _Optional[int] = dev_release self.dev_release: _Optional[int] = dev_release
self.local_version: _Optional[str] = local_version
@property
def short_commit_hash(self) -> _Optional[str]:
if self.local_version is None:
return None
return self.local_version[1:].split(".", 1)[0]
@property
def dirty(self) -> bool:
return self.local_version is not None and self.local_version.endswith(".dirty")
@classmethod @classmethod
def from_str(cls, version_str: str) -> "VersionInfo": def from_str(cls, version_str: str) -> "VersionInfo":
@ -99,6 +114,7 @@ class VersionInfo:
for key in ("serial", "post_release", "dev_release"): for key in ("serial", "post_release", "dev_release"):
if match[key] is not None: if match[key] is not None:
kwargs[key] = int(match[key]) kwargs[key] = int(match[key])
kwargs["local_version"] = match["local_version"]
return cls(**kwargs) return cls(**kwargs)
@classmethod @classmethod
@ -121,15 +137,18 @@ class VersionInfo:
"serial": self.serial, "serial": self.serial,
"post_release": self.post_release, "post_release": self.post_release,
"dev_release": self.dev_release, "dev_release": self.dev_release,
"local_version": self.local_version,
} }
def _generate_comparison_tuples( def _generate_comparison_tuples(
self, other: "VersionInfo" self, other: "VersionInfo"
) -> _List[ ) -> _List[
_Tuple[int, int, int, int, _Union[int, float], _Union[int, float], _Union[int, float]] _Tuple[int, int, int, int, _Union[int, float], _Union[int, float], _Union[int, float], int]
]: ]:
tups: _List[ tups: _List[
_Tuple[int, int, int, int, _Union[int, float], _Union[int, float], _Union[int, float]] _Tuple[
int, int, int, int, _Union[int, float], _Union[int, float], _Union[int, float], int
]
] = [] ] = []
for obj in (self, other): for obj in (self, other):
tups.append( tups.append(
@ -141,6 +160,7 @@ class VersionInfo:
obj.serial if obj.serial is not None else _inf, obj.serial if obj.serial is not None else _inf,
obj.post_release if obj.post_release is not None else -_inf, obj.post_release if obj.post_release is not None else -_inf,
obj.dev_release if obj.dev_release is not None else _inf, obj.dev_release if obj.dev_release is not None else _inf,
int(obj.dirty),
) )
) )
return tups return tups
@ -168,14 +188,16 @@ class VersionInfo:
ret += f".post{self.post_release}" ret += f".post{self.post_release}"
if self.dev_release is not None: if self.dev_release is not None:
ret += f".dev{self.dev_release}" ret += f".dev{self.dev_release}"
if self.local_version is not None:
ret += f"+{self.local_version}"
return ret return ret
def __repr__(self) -> str: def __repr__(self) -> str:
return ( return (
"VersionInfo(major={major}, minor={minor}, micro={micro}, " "VersionInfo(major={major}, minor={minor}, micro={micro}, "
"releaselevel={releaselevel}, serial={serial}, post={post_release}, " "releaselevel={releaselevel}, serial={serial}, post={post_release}, "
"dev={dev_release})".format(**self.to_json()) "dev={dev_release}, local={local_version})"
) ).format(**self.to_json())
def _update_event_loop_policy(): def _update_event_loop_policy():
@ -223,7 +245,7 @@ def _early_init():
_ensure_no_colorama() _ensure_no_colorama()
__version__ = "3.5.0.dev1" __version__ = _get_version()
version_info = VersionInfo.from_str(__version__) version_info = VersionInfo.from_str(__version__)
# Filter fuzzywuzzy slow sequence matcher warning # Filter fuzzywuzzy slow sequence matcher warning

36
redbot/_version.py Normal file
View File

@ -0,0 +1,36 @@
def _get_version(*, ignore_installed: bool = False) -> str:
if not __version__.endswith(".dev1"):
return __version__
try:
import os
import subprocess
path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
output = subprocess.check_output(
("git", "describe", "--tags", "--long", "--dirty"), cwd=path
)
_, count, commit, *dirty = output.decode("utf-8").strip().split("-", 3)
dirty_suffix = f".{dirty[0]}" if dirty else ""
return f"{__version__[:-1]}{count}+{commit}{dirty_suffix}"
except Exception:
# `ignore_installed` is `True` when building with setuptools.
if ignore_installed:
# we don't want any failure to raise here but we should print it
import traceback
traceback.print_exc()
else:
try:
from importlib.metadata import version
return version("Red-DiscordBot")
except Exception:
# we don't want any failure to raise here but we should print it
import traceback
traceback.print_exc()
return __version__
__version__ = "3.5.0.dev1"

View File

@ -1,6 +1,5 @@
[metadata] [metadata]
name = Red-DiscordBot name = Red-DiscordBot
version = attr: redbot.__version__
description = A highly customisable Discord bot description = A highly customisable Discord bot
license = GPL-3.0 license = GPL-3.0
long_description = file: README.md long_description = file: README.md

View File

@ -2,9 +2,16 @@ import os
import sys import sys
from setuptools import setup from setuptools import setup
# Since we're importing `redbot` package, we have to ensure that it's in sys.path.
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
from redbot._version import _get_version
version = _get_version(ignore_installed=True)
if os.getenv("TOX_RED", False) and sys.version_info >= (3, 10): if os.getenv("TOX_RED", False) and sys.version_info >= (3, 10):
# We want to be able to test Python versions that we do not support yet. # We want to be able to test Python versions that we do not support yet.
setup(python_requires=">=3.8.1") setup(python_requires=">=3.8.1", version=version)
else: else:
# Metadata and options defined in setup.cfg # Metadata and options defined in setup.cfg
setup() setup(version=version)

View File

@ -20,6 +20,10 @@ version_tests = (
"3.0.0rc1.dev1", "3.0.0rc1.dev1",
"3.0.0rc1", "3.0.0rc1",
"3.0.0", "3.0.0",
"3.0.1.dev1",
"3.0.1.dev2+gdbaf31e",
"3.0.1.dev2+gdbaf31e.dirty",
"3.0.1.dev3+gae98d77",
"3.0.1", "3.0.1",
"3.0.1.post1.dev1", "3.0.1.post1.dev1",
"3.0.1.post1", "3.0.1.post1",