111 """Entry point for this script."""
112 args = parse_args()
113 output_dir = (REPO_ROOT / args.output_dir).resolve()
114 output_dir.mkdir(parents=True, exist_ok=True)
115
116 targets_raw = args.target if args.target else DEFAULT_TARGETS
117 targets = [Path(REPO_ROOT / rel).resolve() for rel in targets_raw]
118 for target in targets:
119 if not target.exists():
120 raise SystemExit(f"[coverage-python] target not found: {target}")
121
122 pytest_args =
list(args.pytest_args)
123 if pytest_args and pytest_args[0] == "--":
124 pytest_args = pytest_args[1:]
125 if not pytest_args:
126 pytest_args = ["-q"]
127
128 ignoredirs = build_trace_ignoredirs()
129
130 import pytest
131
132 tracer = trace.Trace(count=True, trace=False, ignoredirs=ignoredirs)
133 exit_code = tracer.runfunc(pytest.main, pytest_args)
134 results = tracer.results()
135
136 counts_by_file = collect_counts(results)
137
138 print("[coverage-python] per-file line coverage")
139 print("[coverage-python] -----------------------------------------------")
140
141 total_cov = 0
142 total_exec = 0
143 for target in targets:
144 covered, executable, percent = compute_file_coverage(target, counts_by_file)
145 total_cov += covered
146 total_exec += executable
147 rel = target.relative_to(REPO_ROOT)
148 print(f"[coverage-python] {rel}: {covered}/{executable} ({percent:.2f}%)")
149
150 overall = 100.0 if total_exec == 0 else (100.0 * total_cov) / total_exec
151 print("[coverage-python] -----------------------------------------------")
152 print(f"[coverage-python] weighted total: {total_cov}/{total_exec} ({overall:.2f}%)")
153 print(f"[coverage-python] minimum required: {args.min_line:.2f}%")
154
155 summary_path = output_dir / "summary.txt"
156 summary_path.write_text(
157 "\n".join(
158 [
159 f"weighted_total={overall:.4f}",
160 f"covered_lines={total_cov}",
161 f"executable_lines={total_exec}",
162 f"minimum_required={args.min_line:.4f}",
163 ]
164 )
165 + "\n",
166 encoding="utf-8",
167 )
168
169 if int(exit_code) != 0:
170 print(f"[coverage-python] pytest failed with exit code {exit_code}.", file=sys.stderr)
171 return int(exit_code)
172 if overall < args.min_line:
173 print(
174 f"[coverage-python] FAIL: coverage {overall:.2f}% is below required {args.min_line:.2f}%.",
175 file=sys.stderr,
176 )
177 return 2
178 return 0
179
180
int main(int argc, char **argv)