Viewing is open to everyone. Downloading and starring need a GitHub sign-in.
Sign in with GitHub
check_version.py
v0.1.0-build.85
Latest
Commit ede38f5
Sign in with GitHub to download. Each download is recorded with your GitHub username.
| 1 | #!/usr/bin/env python3 |
| 2 | """Fail if the current software version is stale in a versioned project node.""" |
| 3 | import json |
| 4 | import re |
| 5 | from pathlib import Path |
| 6 | |
| 7 | root = Path(__file__).resolve().parents[1] |
| 8 | version = (root / "VERSION").read_text().strip() |
| 9 | header = (root / "include/ckey/ckey.h").read_text() |
| 10 | # CONTEXT.md is the engineering record kept on `scratch`; release branches |
| 11 | # ship without it, so its checks run only where it exists. |
| 12 | context_path = root / "CONTEXT.md" |
| 13 | context = context_path.read_text() if context_path.exists() else None |
| 14 | changelog = (root / "CHANGELOG.md").read_text() |
| 15 | readme = (root / "README.md").read_text() |
| 16 | fixture = json.loads((root / "tests/vectors/locator-v14.json").read_text()) |
| 17 | support = json.loads((root / "docs/support-matrix.json").read_text()) |
| 18 | format_doc = root / "spec/CKey-Format-v0.14.0.md" |
| 19 | format_text = format_doc.read_text() |
| 20 | text_format_text = (root / "spec/CKey-Format-v0.25.0.md").read_text() |
| 21 | extended_format_text = (root / "spec/CKey-Format-v0.26.0.md").read_text() |
| 22 | scalable_format_text = (root / "spec/CKey-Format-v0.27.0.md").read_text() |
| 23 | print_format_text = (root / "spec/CKey-Format-v0.28.0.md").read_text() |
| 24 | |
| 25 | software_checks = { |
| 26 | "public C ABI header": re.search(r'#define CKEY_SOFTWARE_VERSION "([^"]+)"', header).group(1), |
| 27 | "interoperability fixture": fixture["software_version"], |
| 28 | "changelog head": re.search(r"^## ([^ ]+)", changelog, re.MULTILINE).group(1), |
| 29 | "support matrix": support["current_build"], |
| 30 | } |
| 31 | if context is not None: |
| 32 | software_checks["living context"] = re.search(r"Current software version:\*\* `([^`]+)`", context).group(1) |
| 33 | stale = {name: value for name, value in software_checks.items() if value != version} |
| 34 | format_checks = { |
| 35 | "format specification": "format=14" in format_text and "profile=1" in format_text, |
| 36 | "public format byte": re.search(r"#define CKEY_FORMAT_VERSION (\d+)u", header).group(1) == "14", |
| 37 | "fixture format": fixture["format_version"] == "0.14.0", |
| 38 | "current README links": all(f"spec/CKey-Format-v{v}.md" in readme for v in ("0.14.0", "0.25.0", "0.26.0", "0.27.0", "0.28.0")), |
| 39 | "text format specification": "decimal 25" in text_format_text and "profile byte `0x02`" in text_format_text, |
| 40 | "extended format specification": "decimal 26" in extended_format_text and "profile byte `0x03`" in extended_format_text, |
| 41 | "public text format byte": re.search(r"#define CKEY_TEXT_FORMAT_VERSION (\d+)u", header).group(1) == "25", |
| 42 | "public extended format byte": re.search(r"#define CKEY_EXTENDED_FORMAT_VERSION (\d+)u", header).group(1) == "26", |
| 43 | "scalable format specification": "decimal 27" in scalable_format_text and "profile byte `0x00`" in scalable_format_text, |
| 44 | "public scalable format byte": re.search(r"#define CKEY_SCALABLE_FORMAT_VERSION (\d+)u", header).group(1) == "27", |
| 45 | "support matrix ABI": support["abi"] == int(re.search(r"#define CKEY_ABI_VERSION (\d+)u", header).group(1)), |
| 46 | "release map and branch changelogs": all((root / f).exists() and f in readme for f in ("docs/RELEASE-AND-VERSIONING-MAP.md", "CHANGELOG-STABLE.md", "CHANGELOG-COMMUNITY.md")), |
| 47 | "print format specification": "decimal 28" in print_format_text and "profile byte `0x00`" in print_format_text, |
| 48 | "public print format byte": re.search(r"#define CKEY_SCALABLE_PRINT_FORMAT_VERSION (\d+)u", header).group(1) == "28", |
| 49 | } |
| 50 | if context is not None: |
| 51 | format_checks.update({ |
| 52 | "living context formats": "CKey Format 0.14.0" in context and "0.25.0" in context and "0.26.0" in context and "byte `0E`" in context, |
| 53 | # The context must not describe an older dense format as current. |
| 54 | "living context has no stale current-format claim": not re.search(r"current Format 0\.(1\d|2[0-4])\.0", context), |
| 55 | "living context scalable format": "0.27.0" in context, |
| 56 | "living context print format": "0.28.0" in context, |
| 57 | }) |
| 58 | if not all(format_checks.values()): |
| 59 | raise SystemExit(f"Current format nodes are inconsistent: {format_checks}") |
| 60 | if stale: |
| 61 | raise SystemExit(f"VERSION is {version}; stale version references: {stale}") |
| 62 | print(f"Software and format version nodes are synchronized: {version} / 0.14.0, 0.25.0, 0.26.0, 0.27.0, 0.28.0") |