Skip to content

Commit 8ef6581

Browse files
authored
Use _version.py that includes details using git (#784)
1 parent c42c9e3 commit 8ef6581

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

fastplotlib/_version.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,113 @@
1+
"""
2+
Versioning: we use a hard-coded version number, because it's simple and always
3+
works. For dev installs we add extra version info from Git.
4+
"""
5+
6+
import logging
7+
import subprocess
8+
from pathlib import Path
9+
10+
11+
# This is the reference version number, to be bumped before each release.
12+
# The build system detects this definition when building a distribution.
113
__version__ = "0.5.0"
214

15+
# Allow using nearly the same code in different projects
16+
project_name = "fastplotlib"
17+
18+
19+
logger = logging.getLogger(project_name.lower())
20+
21+
# Get whether this is a repo. If so, repo_dir is the path, otherwise repo_dir is None.
22+
repo_dir = Path(__file__).parents[1]
23+
repo_dir = repo_dir if repo_dir.joinpath(".git").is_dir() else None
24+
25+
26+
def get_version():
27+
"""Get the version string."""
28+
if repo_dir:
29+
return get_extended_version()
30+
else:
31+
return __version__
32+
33+
34+
def get_extended_version():
35+
"""Get an extended version string with information from git."""
36+
37+
release, post, labels = get_version_info_from_git()
38+
39+
# Sample first 3 parts of __version__
40+
base_release = ".".join(__version__.split(".")[:3])
41+
42+
# Check release
43+
if not release:
44+
release = base_release
45+
elif release != base_release:
46+
logger.warning(
47+
f"{project_name} version from git ({release}) and __version__ ({base_release}) don't match."
48+
)
49+
50+
# Build the total version
51+
version = release
52+
if post and post != "0":
53+
version += f".post{post}"
54+
if labels:
55+
version += "+" + ".".join(labels)
56+
57+
return version
58+
59+
60+
def get_version_info_from_git():
61+
"""Get (release, post, labels) from Git.
62+
63+
With `release` the version number from the latest tag, `post` the
64+
number of commits since that tag, and `labels` a tuple with the
65+
git-hash and optionally a dirty flag.
66+
"""
67+
68+
# Call out to Git
69+
command = [
70+
"git",
71+
"describe",
72+
"--long",
73+
"--always",
74+
"--tags",
75+
"--dirty",
76+
"--first-parent",
77+
]
78+
try:
79+
p = subprocess.run(command, cwd=repo_dir, capture_output=True)
80+
except Exception as e:
81+
logger.warning(f"Could not get {project_name} version: {e}")
82+
p = None
83+
84+
# Parse the result into parts
85+
if p is None:
86+
parts = (None, None, "unknown")
87+
else:
88+
output = p.stdout.decode(errors="ignore")
89+
if p.returncode:
90+
stderr = p.stderr.decode(errors="ignore")
91+
logger.warning(
92+
f"Could not get {project_name} version.\n\nstdout: "
93+
+ output
94+
+ "\n\nstderr: "
95+
+ stderr
96+
)
97+
parts = (None, None, "unknown")
98+
else:
99+
parts = output.strip().lstrip("v").split("-")
100+
if len(parts) <= 2:
101+
# No tags (and thus also no post). Only git hash and maybe 'dirty'
102+
parts = (None, None, *parts)
103+
104+
# Return unpacked parts
105+
release, post, *labels = parts
106+
return release, post, labels
107+
108+
109+
__version__ = get_version()
110+
3111
version_info = tuple(
4112
int(i) if i.isnumeric() else i for i in __version__.split("+")[0].split(".")
5113
)

0 commit comments

Comments
 (0)