Files
gaokao-volunteer-system/scripts/check_coverage_gate.py
Hermes Agent ca480ebf84
Some checks failed
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
chore(quality): close T5.5 coverage gate
2026-06-13 22:31:40 +08:00

81 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""Fail CI when coverage gates are not met."""
from __future__ import annotations
import sys
import xml.etree.ElementTree as ET
from pathlib import Path
OVERALL_MIN = 0.80
CORE_MIN = 1.00
CORE_FILES = (
"gaokao-spec-checker/scripts/spec_checker_v2.py",
"gaokao-college-advisor/scripts/gaokao_visual_report.py",
)
def _format_percent(value: float) -> str:
return f"{value * 100:.2f}%"
def main(argv: list[str]) -> int:
coverage_path = Path(argv[1]) if len(argv) > 1 else Path("coverage.xml")
if not coverage_path.exists():
print(f"coverage gate failed: missing file {coverage_path}", file=sys.stderr)
return 2
root = ET.parse(coverage_path).getroot()
overall = float(root.attrib["line-rate"])
classes = root.findall(".//class")
class_by_filename = {
cls.attrib.get("filename", ""): float(cls.attrib["line-rate"])
for cls in classes
}
lines_by_filename = {
cls.attrib.get("filename", ""): len(cls.findall("./lines/line"))
for cls in classes
}
missing = [name for name in CORE_FILES if name not in class_by_filename]
if missing:
print("coverage gate failed: missing core coverage entries:", file=sys.stderr)
for name in missing:
print(f" - {name}", file=sys.stderr)
return 2
covered_lines = 0.0
total_lines = 0
for name in CORE_FILES:
line_count = lines_by_filename[name]
total_lines += line_count
covered_lines += class_by_filename[name] * line_count
core = covered_lines / total_lines if total_lines else 0.0
failures: list[str] = []
if overall < OVERALL_MIN:
failures.append(
f"overall coverage {_format_percent(overall)} < required {_format_percent(OVERALL_MIN)}"
)
if core < CORE_MIN:
failures.append(
f"core coverage {_format_percent(core)} < required {_format_percent(CORE_MIN)}"
)
print(
"coverage gate summary: "
f"overall={_format_percent(overall)}, core={_format_percent(core)}"
)
if failures:
print("coverage gate failed:", file=sys.stderr)
for failure in failures:
print(f" - {failure}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv))