40-validation/report-verification-coverage.py

#!/usr/bin/env python3
import argparse, json
from collections import Counter
from pathlib import Path

p=argparse.ArgumentParser()
p.add_argument("repository", type=Path)
p.add_argument("--output", type=Path)
args=p.parse_args()

rows=[]
for mf in sorted(args.repository.rglob("artifact-manifest.json")):
    d=json.loads(mf.read_text())
    for a in d.get("verification",{}).get("codeAreas",[]):
        rows.append((d["artifact"]["name"], a))

counts=Counter(a.get("status","") for _,a in rows)
lines=["# Verification Coverage Report","",
       "## Zusammenfassung","",
       f"- directly-verified: {counts['directly-verified']}",
       f"- indirectly-verified: {counts['indirectly-verified']}",
       f"- not-applicable: {counts['not-applicable']}",
       f"- verification-gap: {counts['verification-gap']}","",
       "| Modul | Pfad | Klasse | Status | Severity | Begründung |",
       "|---|---|---|---|---|---|"]
for module,a in rows:
    reason=a.get("reason","").replace("|","\\|")
    lines.append(f"| {module} | `{a.get('path','')}` | {a.get('classification','')} | {a.get('status','')} | {a.get('severity','')} | {reason} |")
content="\n".join(lines)+"\n"
if args.output:
    args.output.parent.mkdir(parents=True, exist_ok=True)
    args.output.write_text(content)
else:
    print(content,end="")