-
Notifications
You must be signed in to change notification settings - Fork 69
/
debug_version.py
executable file
·131 lines (109 loc) · 3.7 KB
/
debug_version.py
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python3
#
# Created by FozzTexx
import argparse
import subprocess
import os, sys
import re
import shlex
from datetime import datetime
from pathlib import Path
VERSION_H = "include/version.h"
PLATFORMS = "build-platforms"
MACRO_PATTERN = r"^\s*#define\s+(.*?)\s+(.*?)\s*(?://.*|/\*[\s\S]*?\*/)?$"
def build_argparser():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--use_modified_date", action="store_true",
help="use date of newest modified file instead of commit date")
parser.add_argument("--update_version_h", action="store_true",
help="update include/version.h with current commit information")
return parser
def run_command(cmd):
return subprocess.check_output(cmd, universal_newlines=True).strip()
def get_repo_base():
return run_command(["git", "rev-parse", "--show-toplevel"])
def is_fujinet_repo(base):
if os.path.exists(os.path.join(base, VERSION_H)) \
and os.path.isdir(os.path.join(base, PLATFORMS)):
return True
return False
def get_commit_version():
return run_command(["git", "describe", "--always", "HEAD"])
def get_modified_files():
files = run_command(["git", "diff", "--name-only"]).split("\n")
files = [f for f in files if f]
return files
def load_version_macros(path):
txt = [line for line in open(path)]
macros = {}
for line in txt:
m = re.match(MACRO_PATTERN, line)
if m:
name = m.group(1)
if '(' in name:
continue
value = m.group(2)
if not value:
value = None
macros[name] = value
return macros
def main():
base = get_repo_base()
if not is_fujinet_repo(base):
print("Not in FujiNet firmware repo")
return 0
args = build_argparser().parse_args()
# FIXME - don't allow update_version_h unless on the actual tag?
version_h_path = os.path.join(base, VERSION_H)
version = get_commit_version()
modified = get_modified_files()
commit_id_long = run_command(["git", "rev-parse", "HEAD"])
mtime = int(run_command(["git", "show", "--no-patch", "--format=%ct", "HEAD"]))
if args.use_modified_date:
for path in modified:
if os.path.exists(path):
mt = os.path.getmtime(path)
if not mtime or mt > mtime:
mtime = mt
macros = {
'FN_VERSION_BUILD': commit_id_long,
}
cur_macros = load_version_macros(version_h_path)
ver_major = int(cur_macros['FN_VERSION_MAJOR'])
ver_minor = int(cur_macros['FN_VERSION_MINOR'])
m = re.match(r"^v([0-9]+)[.]([0-9]+)[.]([0-9]+)-([0-9]+)-g(.*)", version)
if m:
ver_major = macros['FN_VERSION_MAJOR'] = int(m.group(1))
ver_minor = macros['FN_VERSION_MINOR'] = int(m.group(2))
version = f"v{m.group(1)}.{m.group(2)}-{m.group(5)}"
else:
m = re.match(r"^([a-z0-9]{8})$", version)
if m:
version = f"v{ver_major}.{ver_minor}-{version}"
if modified:
version += "*"
macros['FN_VERSION_FULL'] = version
macros['FN_VERSION_DATE'] = datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M:%S")
new_macros = cur_macros.copy()
new_macros.update(macros)
if new_macros != cur_macros:
for key in macros:
if isinstance(macros[key], str):
macros[key] = f'"{macros[key]}"'
cur_macros.update(macros)
macro_defs = []
for key in cur_macros:
value = cur_macros[key]
mdef = f"-D{key}"
if value is not None:
mdef += f"={value}"
macro_defs.append(shlex.quote(mdef))
# FIXME - if args.update_version_h then update, don't print
macro_defs = " ".join(macro_defs)
print(macro_defs)
#Path(version_h_path).touch()
return
if __name__ == "__main__":
exit(main() or 0)
elif __name__ == "SCons.Script":
print("Running as build script")