43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Enforce per-file coverage thresholds from SlipCover JSON output."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import argparse
|
||
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> int:
|
||
|
|
"""Check each production file against a minimum coverage percentage."""
|
||
|
|
|
||
|
|
parser = argparse.ArgumentParser()
|
||
|
|
parser.add_argument("coverage_json")
|
||
|
|
parser.add_argument("--root", default="atlasbot")
|
||
|
|
parser.add_argument("--threshold", type=float, default=95.0)
|
||
|
|
args = parser.parse_args()
|
||
|
|
|
||
|
|
data = json.loads(Path(args.coverage_json).read_text(encoding="utf-8"))
|
||
|
|
files = data.get("files") if isinstance(data, dict) else {}
|
||
|
|
violations: list[tuple[float, str]] = []
|
||
|
|
for path, payload in sorted(files.items()):
|
||
|
|
if not path.startswith(f"{args.root}/"):
|
||
|
|
continue
|
||
|
|
summary = payload.get("summary") if isinstance(payload, dict) else {}
|
||
|
|
percent = summary.get("percent_covered") if isinstance(summary, dict) else None
|
||
|
|
if not isinstance(percent, (int, float)):
|
||
|
|
continue
|
||
|
|
if float(percent) < args.threshold:
|
||
|
|
violations.append((float(percent), path))
|
||
|
|
|
||
|
|
if violations:
|
||
|
|
for percent, path in sorted(violations):
|
||
|
|
print(f"{path}: {percent:.2f}% < {args.threshold:.2f}%")
|
||
|
|
return 1
|
||
|
|
return 0
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
raise SystemExit(main())
|
||
|
|
|