Build legal manifest / build-manifest (push) Successful in 14s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
104 lines
4.2 KiB
Python
104 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Resolves each project's _templates/*.md against its _data.json and overwrites
|
|
the tracked *.md files with the result.
|
|
|
|
Why this exists: the legal documents repeat the same provider identity, hosting
|
|
entity, and sub-processor names/countries across several files — each document
|
|
phrases its surrounding table differently, so it's the *values*, not whole
|
|
blocks, that repeat. Before this script, changing e.g. the company address
|
|
meant editing every document by hand and risking them drifting apart.
|
|
|
|
The templates are the edit source; the tracked *.md files are a build output,
|
|
exactly like dist/legal-manifest.json is a build output of build-manifest.py.
|
|
Both are committed to git, so build-manifest.py's content_hash/version (which
|
|
hash the tracked *.md, not the template) keep meaning exactly what they did
|
|
before this script existed — and downstream consumers that read the tracked
|
|
H2W-Ticketing/*.md directly are unaffected, since they still see fully
|
|
resolved text, never a placeholder.
|
|
|
|
Placeholder syntax: {{ dotted.path }}, resolved against _data.json.
|
|
|
|
Missing data: a value of "-", "—" or "" in _data.json means "nincs ilyen adat" (pl. egyéni
|
|
vállalkozónak nincs cégjegyzékszáma). Such a value is never printed:
|
|
- a markdown table row ("| ... |") containing such a token is dropped entirely;
|
|
- an optional inline segment [[ ... ]] containing such a token is dropped (otherwise only
|
|
its brackets are removed), e.g. "[[, nyilvántartási szám: {{ provider.registration_number }}]]". Deliberately
|
|
NOT used for numeric periods (30 nap, 8 nap, 99%, ...) that happen to repeat —
|
|
those repeat by coincidence of value, not by shared identity, and collapsing
|
|
them would risk an edit to one clause silently changing an unrelated one.
|
|
|
|
Usage:
|
|
python3 scripts/render-templates.py # resolve and overwrite
|
|
python3 scripts/render-templates.py --check # exit 1 on drift, write nothing
|
|
"""
|
|
|
|
import json
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
TOKEN_RE = re.compile(r"\{\{\s*([\w.]+)\s*\}\}")
|
|
|
|
|
|
def resolve_token(data: dict, dotted_path: str) -> str:
|
|
value = data
|
|
for part in dotted_path.split("."):
|
|
value = value[part]
|
|
return value
|
|
|
|
|
|
MISSING_VALUES = {"", "-", "—"}
|
|
OPTIONAL_RE = re.compile(r"\[\[(.*?)\]\]", re.DOTALL)
|
|
|
|
|
|
def _has_missing(text: str, data: dict) -> bool:
|
|
return any(str(resolve_token(data, m.group(1))).strip() in MISSING_VALUES for m in TOKEN_RE.finditer(text))
|
|
|
|
|
|
def render(template: str, data: dict) -> str:
|
|
# 1) opcionális szakaszok: hiányzó adattal együtt kimaradnak
|
|
template = OPTIONAL_RE.sub(lambda m: "" if _has_missing(m.group(1), data) else m.group(1), template)
|
|
# 2) táblázatsor hiányzó adattal: az egész sor kimarad
|
|
lines = [
|
|
line
|
|
for line in template.split("\n")
|
|
if not (line.lstrip().startswith("|") and _has_missing(line, data))
|
|
]
|
|
return TOKEN_RE.sub(lambda m: resolve_token(data, m.group(1)), "\n".join(lines))
|
|
|
|
|
|
def main() -> None:
|
|
check_only = "--check" in sys.argv
|
|
drift = False
|
|
|
|
for project_dir in sorted(REPO_ROOT.iterdir()):
|
|
templates_dir = project_dir / "_templates"
|
|
if not templates_dir.is_dir():
|
|
continue
|
|
|
|
data_path = project_dir / "_data.json"
|
|
data = json.loads(data_path.read_text(encoding="utf-8"))
|
|
|
|
for template_path in sorted(templates_dir.glob("*.md")):
|
|
target_path = project_dir / template_path.name
|
|
resolved = render(template_path.read_text(encoding="utf-8"), data)
|
|
|
|
if check_only:
|
|
current = target_path.read_text(encoding="utf-8") if target_path.exists() else None
|
|
if current != resolved:
|
|
print(f"ELTÉRÉS: {target_path.relative_to(REPO_ROOT)}")
|
|
drift = True
|
|
continue
|
|
|
|
target_path.write_text(resolved, encoding="utf-8")
|
|
print(f"Feloldva: {target_path.relative_to(REPO_ROOT)}")
|
|
|
|
if check_only and drift:
|
|
print("A sablonokból generált tartalom eltér a commitolt fájloktól — futtasd: python3 scripts/render-templates.py")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|