from __future__ import annotations
import re
import sys
import tomllib
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
SNIPPET_GLOBS = ("README.md", "site/content/**/*.md", "src/lib.rs")
def main() -> int:
cargo = tomllib.loads((ROOT / "Cargo.toml").read_text())
expected = cargo["package"]["version"]
major_minor = ".".join(expected.split(".")[:2])
errors: list[str] = []
checked = 0
for lock in sorted(ROOT.glob("**/Cargo.lock")):
if "target" in lock.parts:
continue
text = lock.read_text()
m = re.search(r'^name = "krafka"\nversion = "([^"]+)"', text, re.M)
if not m:
continue
checked += 1
if m.group(1) != expected:
line = text[: m.start()].count("\n") + 2
errors.append(
f"{lock.relative_to(ROOT)}:{line} krafka is locked at "
f"{m.group(1)!r}, but Cargo.toml says {expected!r}.\n"
f" Refresh it: cargo update --manifest-path "
f"{lock.parent.relative_to(ROOT) or '.'}/Cargo.toml --package krafka"
)
zola = ROOT / "site" / "zola.toml"
if zola.exists():
site_version = tomllib.loads(zola.read_text()).get("extra", {}).get("version")
checked += 1
if site_version != expected:
errors.append(
f"site/zola.toml extra.version is {site_version!r}, "
f"but Cargo.toml says {expected!r}"
)
snippet = re.compile(r'krafka\s*=\s*(?:\{[^}]*?version\s*=\s*)?"([^"]+)"')
paths: list[Path] = []
for pattern in SNIPPET_GLOBS:
paths.extend(ROOT.glob(pattern))
for path in sorted(set(paths)):
text = path.read_text()
for m in snippet.finditer(text):
found = m.group(1)
checked += 1
if found in (expected, major_minor):
continue
line = text[: m.start()].count("\n") + 1
errors.append(
f"{path.relative_to(ROOT)}:{line} snippet says krafka = "
f"{found!r}; expected {expected!r} or {major_minor!r}"
)
if errors:
print("Version consistency check FAILED\n", file=sys.stderr)
for e in errors:
print(f" - {e}\n", file=sys.stderr)
return 1
print(f"✓ Version consistency: {checked} declarations all agree on {expected}")
return 0
if __name__ == "__main__":
sys.exit(main())