diff --git a/scripts/audit_weak_types.py b/scripts/audit_weak_types.py index 0a7bf201..55fc0c4f 100644 --- a/scripts/audit_weak_types.py +++ b/scripts/audit_weak_types.py @@ -202,6 +202,8 @@ def main() -> int: parser.add_argument("--json", action="store_true", help="Output JSON instead of human-readable report") parser.add_argument("--top", type=int, default=10, help="Show top N files by weak count (default: 10)") parser.add_argument("--verbose", action="store_true", help="Show every finding inline (default: top N per file)") + parser.add_argument("--strict", action="store_true", help="CI mode; exits 1 if current count exceeds the baseline file") + parser.add_argument("--baseline", default="scripts/audit_weak_types.baseline.json", help="Baseline file for --strict mode (default: scripts/audit_weak_types.baseline.json)") args = parser.parse_args() src = Path(args.src) @@ -214,6 +216,25 @@ def main() -> int: reports: list[FileReport] = [audit_file(f) for f in files] reports = [r for r in reports if r.weak_count > 0 or r.positive_count > 0] + if args.strict: + baseline_path = Path(args.baseline) + if not baseline_path.exists(): + print(f"ERROR: baseline file not found: {baseline_path}", file=sys.stderr) + return 1 + try: + with baseline_path.open("r", encoding="utf-8") as f: + baseline_data = json.load(f) + baseline_count = baseline_data.get("total_weak", 0) + except (OSError, json.JSONDecodeError) as e: + print(f"ERROR: could not read baseline {baseline_path}: {e}", file=sys.stderr) + return 1 + current_count = sum(r.weak_count for r in reports) + if current_count > baseline_count: + print(f"STRICT: {current_count} weak sites found, baseline is {baseline_count} (regression of {current_count - baseline_count})", file=sys.stderr) + return 1 + print(f"STRICT OK: {current_count} weak sites <= baseline {baseline_count}") + return 0 + if args.json: output = { "src_dir": str(src),