#!/usr/bin/env python3 """Enforce Ariadne's per-file source coverage contract.""" from __future__ import annotations import argparse import json from pathlib import Path def _source_files(root: Path) -> list[str]: files: list[str] = [] for path in sorted(root.rglob("*.py")): if "__pycache__" in path.parts: continue files.append(path.as_posix()) return files def _coverage_percent(file_payload: object) -> float | None: if not isinstance(file_payload, dict): return None summary = file_payload.get("summary") if not isinstance(summary, dict): return None value = summary.get("percent_covered") if isinstance(value, (int, float)): return float(value) return None def main() -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("coverage_json") parser.add_argument("--source-root", default="ariadne") parser.add_argument("--threshold", type=float, default=95.0) args = parser.parse_args() coverage_path = Path(args.coverage_json) source_root = Path(args.source_root) payload = json.loads(coverage_path.read_text(encoding="utf-8")) files = payload.get("files") if isinstance(payload, dict) else None if not isinstance(files, dict): print(f"{coverage_path}: missing files coverage map") return 1 failures: list[str] = [] for source_file in _source_files(source_root): percent = _coverage_percent(files.get(source_file)) if percent is None: failures.append(f"{source_file}: missing from coverage report") elif percent < args.threshold: failures.append(f"{source_file}: {percent:.2f}% below {args.threshold:.2f}%") if failures: print("coverage contract failed:") for failure in failures: print(f" - {failure}") return 1 print(f"coverage contract passed: {len(_source_files(source_root))} files >= {args.threshold:.2f}%") return 0 if __name__ == "__main__": raise SystemExit(main())