-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathbuild_versions.py
More file actions
executable file
·54 lines (41 loc) · 1.67 KB
/
Copy pathbuild_versions.py
File metadata and controls
executable file
·54 lines (41 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env python3
import os
import re
import shutil
import sys
BACKUP_SUFFIX = ".build-version.bak"
VERSION_RE = re.compile(r'^(?P<prefix>\s*version\s*=\s*")(?P<version>[^"]+)(?P<suffix>".*)$')
def post_version(version: str, post_n: str) -> str:
base = re.sub(r"\.post\d+$", "", version)
if not re.fullmatch(r"\d+(?:\.\d+)*(?:(?:a|b|rc)\d+)?", base):
raise ValueError(f"unsupported version: {version}")
return f"{base}.post{post_n}"
def apply(post_n: str, paths: list[str]) -> None:
if not post_n.isdigit():
raise ValueError("post number must be a non-negative integer")
for path in paths:
shutil.copy2(path, path + BACKUP_SUFFIX)
lines = open(path, encoding="utf-8").read().splitlines(keepends=True)
in_project = changed = False
for i, line in enumerate(lines):
stripped = line.strip()
if stripped.startswith("[") and stripped.endswith("]"):
in_project = stripped == "[project]"
if in_project and (match := VERSION_RE.match(line)):
lines[i] = f"{match['prefix']}{post_version(match['version'], post_n)}{match['suffix']}\n"
changed = True
if not changed:
raise RuntimeError(f"no [project] version found in {path}")
open(path, "w", encoding="utf-8").writelines(lines)
def restore(paths: list[str]) -> None:
for path in paths:
backup = path + BACKUP_SUFFIX
if os.path.exists(backup):
os.replace(backup, path)
if __name__ == "__main__":
if len(sys.argv) < 3 or sys.argv[1] not in {"apply", "restore"}:
raise SystemExit("usage: build_versions.py apply POST_N FILE... | restore FILE...")
if sys.argv[1] == "apply":
apply(sys.argv[2], sys.argv[3:])
else:
restore(sys.argv[2:])