Skip to content

Commit 653460f

Browse files
committed
meson: dynamically generate version from tag
1 parent cb50f8b commit 653460f

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

.git_archival.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node: $Format:%H$
2+
node-date: $Format:%cI$
3+
describe-name: $Format:%(describe:tags=true,abbrev=9,match=*[0-9]*)$

generate_version.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import subprocess
5+
6+
from datetime import datetime
7+
from typing import Optional
8+
9+
10+
def git_describe() -> subprocess.CompletedProcess:
11+
return subprocess.run(
12+
["git", "describe", "--abbrev=9", "--tags", "--match=*[0-9]*"],
13+
text=True,
14+
capture_output=True,
15+
)
16+
17+
18+
def version_from_git_describe(desc: str, timestamp: Optional[datetime] = None) -> str:
19+
desc = desc.removeprefix("v").strip()
20+
version, *rest = desc.split("-", maxsplit=2)
21+
# we're directly on a tag
22+
if not rest:
23+
return version
24+
25+
# guess next version
26+
version_parts = [int(v) for v in version.split(".")]
27+
version_parts.append(version_parts.pop() + 1)
28+
29+
# dev tailer
30+
commits_since_tag, commit = rest
31+
t = timestamp or datetime.now()
32+
trailer = f".dev{commits_since_tag}+{commit}.d{t:%Y%m%d}"
33+
34+
return ".".join(str(v) for v in version_parts) + trailer
35+
36+
37+
def read_git_archival_txt() -> dict[str, str]:
38+
archive = {}
39+
with open(".git_archival.txt") as txt:
40+
for line in txt.read().splitlines():
41+
key, var = line.split(":", maxsplit=1)
42+
archive[key.strip()] = var.strip()
43+
return archive
44+
45+
46+
def version_from_archival_txt(info: dict[str, str], timestamp: Optional[datetime] = None) -> str:
47+
desc = info['describe-name']
48+
49+
t = timestamp or datetime.fromisoformat(info['node-date'])
50+
return version_from_git_describe(desc, timestamp=t)
51+
52+
53+
def main() -> str:
54+
# if SOURCE_DATE_EPOCH is set, we're going to use it as the timestamp
55+
sde = None
56+
if (t := os.environ.get("SOURCE_DATE_EPOCH")) is not None:
57+
sde = datetime.fromtimestamp(int(t))
58+
59+
p = git_describe()
60+
if p.returncode == 0:
61+
return version_from_git_describe(p.stdout, timestamp=sde)
62+
elif p.returncode == 128: # not a git repo
63+
info = read_git_archival_txt()
64+
return version_from_archival_txt(info, timestamp=sde)
65+
66+
return "unknown"
67+
68+
69+
if __name__ == "__main__":
70+
print(main())

meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
project(
44
'python-systemd',
55
'c',
6-
version: '236',
6+
version: run_command(meson.project_source_root() / 'generate_version.py', check: true).stdout().strip(),
77
license: 'LGPL-2.1-or-later',
88
default_options: ['warning_level=2', 'c_std=c99'],
99
meson_version: '>= 1.8.0',

0 commit comments

Comments
 (0)