61 lines
2.0 KiB
Python
Executable File
61 lines
2.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import argparse
|
|
import json
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
|
|
def load_rows(path: Path):
|
|
rows = []
|
|
with path.open("r", encoding="utf-8") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if line:
|
|
rows.append(json.loads(line))
|
|
return rows
|
|
|
|
|
|
def main() -> int:
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--results", required=True)
|
|
ap.add_argument("--out", required=True)
|
|
args = ap.parse_args()
|
|
|
|
rows = load_rows(Path(args.results))
|
|
by_category = defaultdict(lambda: {"total": 0, "fullstack_contract_invalid": 0, "ab_ready": 0, "prod_ready": 0})
|
|
|
|
for r in rows:
|
|
cat = str(r.get("category", "unknown"))
|
|
by_category[cat]["total"] += 1
|
|
if not bool((r.get("fullstack_contract") or {}).get("ok", True)):
|
|
by_category[cat]["fullstack_contract_invalid"] += 1
|
|
if bool((r.get("ab") or {}).get("path_b_ready", False)):
|
|
by_category[cat]["ab_ready"] += 1
|
|
if bool((r.get("production_loop") or {}).get("overall_ready", False)):
|
|
by_category[cat]["prod_ready"] += 1
|
|
|
|
out = {"by_category": {}, "pass": True}
|
|
for cat, s in sorted(by_category.items()):
|
|
total = s["total"]
|
|
invalid = s["fullstack_contract_invalid"]
|
|
ab_ready = s["ab_ready"]
|
|
prod_ready = s["prod_ready"]
|
|
row = {
|
|
"total": total,
|
|
"fullstack_contract_invalid": invalid,
|
|
"fullstack_contract_invalid_rate": round((invalid / total), 4) if total else 0.0,
|
|
"ab_ready_rate": round((ab_ready / total), 4) if total else 0.0,
|
|
"prod_ready_rate": round((prod_ready / total), 4) if total else 0.0,
|
|
}
|
|
out["by_category"][cat] = row
|
|
if invalid > 0:
|
|
out["pass"] = False
|
|
|
|
Path(args.out).write_text(json.dumps(out, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps(out))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|