71 lines
2.9 KiB
Python
71 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Index native Python API names from passing P6 runtime evidence."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
P6 = ROOT / "docs/p6"
|
|
OUT = P6 / "python-api-runtime-evidence.json"
|
|
|
|
|
|
def names(value):
|
|
if isinstance(value, str):
|
|
return [item.strip() for item in value.replace("\n", ",").split(",") if item.strip()]
|
|
if isinstance(value, list):
|
|
return [str(item).strip() for item in value if str(item).strip()]
|
|
if isinstance(value, dict):
|
|
result = []
|
|
for item in value.values():
|
|
result.extend(names(item))
|
|
return result
|
|
return []
|
|
|
|
|
|
evidence = {}
|
|
for path in sorted(P6.glob("*.json")):
|
|
try:
|
|
report = json.loads(path.read_text(encoding="utf-8"))
|
|
except (OSError, json.JSONDecodeError):
|
|
continue
|
|
result_value = report.get("result", report.get("status"))
|
|
if not isinstance(result_value, str) or result_value not in {"pass", "passed", "completed"}:
|
|
continue
|
|
action = report.get("action")
|
|
explicit_python = action == "python-api" or "python" in path.stem.lower()
|
|
if not explicit_python:
|
|
continue
|
|
module = report.get("module")
|
|
if not isinstance(module, str) or not module:
|
|
stem = path.stem.lower()
|
|
inferred = [("openscad", "OpenSCAD"), ("meshpart", "MeshPart"), ("points", "Points"), ("sketcher", "Sketcher"), ("techdraw", "TechDraw"), ("robot", "Robot"), ("measure", "Measure"), ("surface", "Surface"), ("spreadsheet", "Spreadsheet"), ("inspection", "Inspection"), ("sandbox", "Sandbox")]
|
|
module = next((value for token, value in inferred if token in stem), None)
|
|
if not isinstance(module, str) or not module:
|
|
continue
|
|
found = []
|
|
def walk(value, key=""):
|
|
if isinstance(value, dict):
|
|
for child_key, child in value.items():
|
|
if child_key.lower() in {"apinames", "pythonapi", "pythonapinames", "api_names"}:
|
|
found.extend(names(child))
|
|
walk(child, child_key)
|
|
elif isinstance(value, list):
|
|
for child in value:
|
|
walk(child, key)
|
|
walk(report)
|
|
for name in found:
|
|
normalized = name.strip()
|
|
if normalized:
|
|
key = f"{module}:{normalized}"
|
|
evidence.setdefault(key, []).append(str(path.relative_to(ROOT)))
|
|
|
|
report = {
|
|
"schema": "freecad-web-python-api-runtime-evidence/v1",
|
|
"policy": "only passing python-api-named runtime artifacts are indexed; source-only inventory is excluded",
|
|
"names": [{"module": key.split(":", 1)[0], "name": key.split(":", 1)[1], "artifacts": sorted(set(paths))} for key, paths in sorted(evidence.items())],
|
|
"count": len(evidence),
|
|
}
|
|
OUT.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps({"output": str(OUT.relative_to(ROOT)), "names": len(evidence)}, ensure_ascii=False))
|