23 lines
1.8 KiB
Python
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)
|