build-vocab.py parses ./cvar_list (live L4D2 cvarlist dump, 2196 entries) into static/data/srccfg-vocab.json — 1523 cvars + 671 commands. Idempotent. Records the source-file SHA256 in the JSON header so regenerations are auditable. cvar_list is committed as a tracked data file so the generation is reproducible from the repo alone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
59 lines
1.9 KiB
Python
Executable file
59 lines
1.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""Convert ./cvar_list (cvarlist dump) to static/data/srccfg-vocab.json.
|
|
|
|
Usage: ./l4d2web/scripts/build-vocab.py
|
|
Reads from the repo root (auto-detected via this script's path).
|
|
Writes idempotently. Run after regenerating cvar_list."""
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import pathlib
|
|
import re
|
|
import sys
|
|
|
|
HERE = pathlib.Path(__file__).resolve().parent
|
|
REPO_ROOT = HERE.parent.parent
|
|
SOURCE = REPO_ROOT / "cvar_list"
|
|
DEST = REPO_ROOT / "l4d2web" / "l4d2web" / "static" / "data" / "srccfg-vocab.json"
|
|
|
|
|
|
def parse(text: str) -> tuple[list[dict], list[dict]]:
|
|
cvars: list[dict] = []
|
|
commands: list[dict] = []
|
|
for raw in text.splitlines()[2:]: # skip "cvar list" + "--------…"
|
|
if not raw.strip():
|
|
continue
|
|
parts = [p.strip() for p in re.split(r"\s*:\s*", raw, maxsplit=3)]
|
|
if len(parts) < 3:
|
|
continue
|
|
name = parts[0]
|
|
value = parts[1]
|
|
desc = parts[3] if len(parts) >= 4 else ""
|
|
target = commands if value == "cmd" else cvars
|
|
target.append({"name": name, "desc": desc} if desc else {"name": name})
|
|
return cvars, commands
|
|
|
|
|
|
def main() -> int:
|
|
if not SOURCE.exists():
|
|
print(f"ERROR: {SOURCE} not found", file=sys.stderr)
|
|
return 1
|
|
text = SOURCE.read_text(encoding="utf-8", errors="replace")
|
|
cvars, commands = parse(text)
|
|
src_sha = hashlib.sha256(text.encode("utf-8")).hexdigest()
|
|
payload = {
|
|
"version": 1,
|
|
"generated_from": "cvar_list",
|
|
"source_sha256": src_sha,
|
|
"cvars": cvars,
|
|
"commands": commands,
|
|
}
|
|
DEST.parent.mkdir(parents=True, exist_ok=True)
|
|
DEST.write_text(json.dumps(payload, indent=2, sort_keys=False) + "\n", encoding="utf-8")
|
|
print(f"wrote {DEST}: {len(cvars)} cvars + {len(commands)} commands")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|