|
1 | 1 | #!/usr/bin/env python3 |
2 | | - |
3 | | -import os |
4 | | -import pathlib |
| 2 | +from pathlib import Path |
5 | 3 | import re |
6 | 4 |
|
7 | | - |
8 | | -root = os.path.abspath(pathlib.Path(__file__).parent.parent.parent) |
9 | | - |
10 | | -# filename, pattern, number of occurrences |
11 | | -file_pattern_count = [ |
12 | | - (f"{root}/CMakeLists.txt", r"^\s+VERSION (\d+)\.(\d+)\.(\d+)\n", 1), |
13 | | - (f"{root}/include/ankerl/stl.h", r"Version (\d+)\.(\d+)\.(\d+)\n", 1), |
14 | | - (f"{root}/include/ankerl/unordered_dense.h", r"Version (\d+)\.(\d+)\.(\d+)\n", 1), |
15 | | - (f"{root}/meson.build", r"version: '(\d+)\.(\d+)\.(\d+)'", 1), |
16 | | - (f"{root}/test/unit/namespace.cpp", r"unordered_dense::v(\d+)_(\d+)_(\d+)", 1), |
| 5 | +# fmt: off |
| 6 | +ROOT = Path(__file__).resolve().parents[2] |
| 7 | +HEADER = ROOT / "include" / "ankerl" / "unordered_dense.h" |
| 8 | +CHECKS = [ |
| 9 | + (HEADER, r"Version (\d+)\.(\d+)\.(\d+)", 1), |
| 10 | + (ROOT / "CMakeLists.txt", r"^\s+VERSION (\d+)\.(\d+)\.(\d+)", 1), |
| 11 | + (ROOT / "include" / "ankerl" / "stl.h", r"Version (\d+)\.(\d+)\.(\d+)", 1), |
| 12 | + (ROOT / "meson.build", r"version:\s*'?(\d+)\.(\d+)\.(\d+)'?", 1), |
| 13 | + (ROOT / "test" / "unit" / "namespace.cpp", r"unordered_dense::v(\d+)_(\d+)_(\d+)", 1), |
17 | 14 | ] |
18 | | - |
19 | | -# let's parse the reference from svector.h |
20 | | -major = "??" |
21 | | -minor = "??" |
22 | | -patch = "??" |
23 | | -with open(f"{root}/include/ankerl/unordered_dense.h", "r") as f: |
24 | | - for line in f: |
25 | | - r = re.search(r"#define ANKERL_UNORDERED_DENSE_VERSION_([A-Z]+) (\d+)", line) |
26 | | - if not r: |
27 | | - continue |
28 | | - |
29 | | - if "MAJOR" == r.group(1): |
30 | | - major = r.group(2) |
31 | | - elif "MINOR" == r.group(1): |
32 | | - minor = r.group(2) |
33 | | - elif "PATCH" == r.group(1): |
34 | | - patch = r.group(2) |
35 | | - else: |
36 | | - "match but with something else!" |
37 | | - exit(1) |
38 | | - |
39 | | -is_ok = True |
40 | | -for filename, pattern, count in file_pattern_count: |
41 | | - num_found = 0 |
42 | | - with open(filename, "r") as f: |
43 | | - for line in f: |
44 | | - r = re.search(pattern, line) |
45 | | - if r: |
46 | | - num_found += 1 |
47 | | - if major != r.group(1) or minor != r.group(2) or patch != r.group(3): |
48 | | - is_ok = False |
49 | | - print( |
50 | | - f"ERROR in {filename}: got '{line.strip()}' but version should be '{major}.{minor}.{patch}'" |
51 | | - ) |
52 | | - if num_found != count: |
53 | | - is_ok = False |
54 | | - print( |
55 | | - f"ERROR in {filename}: expected {count} occurrences but found it {num_found} times" |
| 15 | +# fmt: on |
| 16 | + |
| 17 | + |
| 18 | +def read_version_from_header(p: Path) -> str: |
| 19 | + m = re.findall( |
| 20 | + r"#define\s+ANKERL_UNORDERED_DENSE_VERSION_(MAJOR|MINOR|PATCH)\s+(\d+)", |
| 21 | + p.read_text(), |
| 22 | + ) |
| 23 | + d = dict(m) |
| 24 | + return f"{d['MAJOR']}.{d['MINOR']}.{d['PATCH']}" |
| 25 | + |
| 26 | + |
| 27 | +def main(): |
| 28 | + ref = read_version_from_header(HEADER) |
| 29 | + errs = [] |
| 30 | + for path, pattern, count in CHECKS: |
| 31 | + matches = list(re.finditer(pattern, path.read_text(), re.M)) |
| 32 | + if (n := len(matches)) != count: |
| 33 | + errs.append(f"ERROR: {path}: expected {count} matches, found {n}") |
| 34 | + errs.extend( |
| 35 | + f"ERROR: {path}: found version {found}, expected {ref}" |
| 36 | + for m in matches |
| 37 | + if (found := ".".join(m.groups())) != ref |
56 | 38 | ) |
57 | 39 |
|
58 | | -if not is_ok: |
59 | | - exit(1) |
| 40 | + print("\n".join(errs)) |
| 41 | + raise SystemExit(1 if errs else 0) |
| 42 | + |
| 43 | + |
| 44 | +if __name__ == "__main__": |
| 45 | + main() |
0 commit comments