Files
Blockline/tests/audit_gdscript.py
T

23 lines
1.8 KiB
Python

"""Godot 4 parser audit. Run from any directory with Python 3."""
from pathlib import Path
import concurrent.futures, json, re, subprocess
ROOT = Path(__file__).resolve().parents[1]
ENGINE = ROOT / "tools/godot/Godot_v4.5-stable_win64_console.exe"
FILES = sorted(p for p in ROOT.rglob("*.gd") if not set(p.relative_to(ROOT).parts) & {".godot", ".git", "tools", "dist"})
def check(path):
rel = path.relative_to(ROOT).as_posix()
result = subprocess.run([str(ENGINE), "--headless", "--path", str(ROOT), "--script", rel, "--check-only", "--log-file", str(ROOT / "logs" / ("audit-" + rel.replace("/", "_") + ".log"))], cwd=ROOT, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=45)
output = result.stdout + result.stderr
source = path.read_text(encoding="utf-8-sig")
untyped = [i for i,line in enumerate(source.splitlines(),1) if re.search(r"\bvar\s+\w+\s*(?:=|$)",line.split("#",1)[0])]
errors = [line for line in output.splitlines() if "SCRIPT ERROR" in line or "Parse Error" in line or "Compile Error" in line]
return {"file":rel,"exit":result.returncode,"errors":errors,"untyped_declarations":untyped,"explicit_variant_count":len(re.findall(r"\bvar\s+\w+\s*:\s*Variant",source))}
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as pool:
results = list(pool.map(check, FILES))
report = {"engine":"Godot 4.5", "files":len(results), "passed":sum(x["exit"]==0 and not x["errors"] and not x["untyped_declarations"] for x in results),"results":results}
(ROOT / "logs/gdscript-audit.json").write_text(json.dumps(report,indent=2),encoding="utf-8")
print("AUDIT",report["passed"],"/",report["files"])
for item in results:
if item["exit"] or item["errors"] or item["untyped_declarations"]: print(json.dumps(item))
raise SystemExit(0 if report["passed"] == report["files"] else 1)