(
scan_dir: Path,
schema_dir: Path | None = None,
source_root: Path | None = None,
*,
expected_coverage_mode: str | None = None,
)
| 1300 | |
| 1301 | |
| 1302 | def finalize_scan( |
| 1303 | scan_dir: Path, |
| 1304 | schema_dir: Path | None = None, |
| 1305 | source_root: Path | None = None, |
| 1306 | *, |
| 1307 | expected_coverage_mode: str | None = None, |
| 1308 | ) -> tuple[dict[str, Any], dict[str, Any], dict[str, Any]]: |
| 1309 | scan_dir = _require_scan_directory(scan_dir) |
| 1310 | schema_dir = schema_dir or Path(__file__).resolve().parent.parent / "schemas" |
| 1311 | manifest = _read_scan_local_json(scan_dir, "scan-manifest.json", "scan-manifest.json") |
| 1312 | scan = _require_dict(manifest, "scan", "manifest") |
| 1313 | _validate_contract_refs(scan) |
| 1314 | findings, findings_input_bytes = _read_scan_local_json_bytes( |
| 1315 | scan_dir, scan["findingsRef"], scan["findingsRef"] |
| 1316 | ) |
| 1317 | coverage, coverage_input_bytes = _read_scan_local_json_bytes( |
| 1318 | scan_dir, scan["coverageRef"], scan["coverageRef"] |
| 1319 | ) |
| 1320 | |
| 1321 | if manifest.get("schemaVersion") != SCHEMA_VERSION: |
| 1322 | raise ContractError(f"manifest.schemaVersion: expected {SCHEMA_VERSION}") |
| 1323 | if scan.get("status") != "completed": |
| 1324 | raise ContractError("manifest.scan.status: expected completed before sealing") |
| 1325 | if expected_coverage_mode is not None and coverage.get("mode") != expected_coverage_mode: |
| 1326 | raise ContractError( |
| 1327 | f"coverage.mode: must match selected scan mode {expected_coverage_mode}" |
| 1328 | ) |
| 1329 | was_sealed = scan.get("sealedAt") is not None or scan.get("artifacts") is not None |
| 1330 | _validate_existing_seal( |
| 1331 | scan_dir, |
| 1332 | scan, |
| 1333 | artifact_contents={ |
| 1334 | scan["findingsRef"]: findings_input_bytes, |
| 1335 | scan["coverageRef"]: coverage_input_bytes, |
| 1336 | }, |
| 1337 | ) |
| 1338 | scan["sealedAt"] = _require_str(scan, "completedAt", "manifest.scan") |
| 1339 | _validate_target(_require_dict(scan, "target", "manifest.scan")) |
| 1340 | if was_sealed: |
| 1341 | _validate_findings(manifest, findings) |
| 1342 | _enrich_findings(manifest, findings) |
| 1343 | _validate_findings(manifest, findings) |
| 1344 | _validate_coverage(manifest, coverage, scan_dir) |
| 1345 | _validate_canonical_schemas_before_projection(manifest, findings, coverage, schema_dir) |
| 1346 | if was_sealed: |
| 1347 | _validate_sealed_coverage_receipts(scan, coverage) |
| 1348 | _validate_manifest(manifest) |
| 1349 | validate_against_schema(manifest, schema_dir / "scan-manifest.schema.json") |
| 1350 | validate_against_schema(findings, schema_dir / "findings.schema.json") |
| 1351 | validate_against_schema(coverage, schema_dir / "coverage.schema.json") |
| 1352 | report_markdown_bytes = _generate_report_projection(manifest, findings, coverage) |
| 1353 | _validate_report_output_paths(scan_dir) |
| 1354 | write_scan_local_bytes(scan_dir, "report.md", report_markdown_bytes) |
| 1355 | _remove_scan_local_file_if_exists(scan_dir, "report.html") |
| 1356 | _write_sarif_projection_if_possible(scan_dir, source_root, schema_dir) |
| 1357 | return manifest, findings, coverage |
| 1358 | |
| 1359 | findings_bytes = _json_bytes(findings) |
no test coverage detected