(connection: sqlite3.Connection, args: argparse.Namespace)
| 2477 | |
| 2478 | |
| 2479 | def export_findings(connection: sqlite3.Connection, args: argparse.Namespace) -> dict[str, Any]: |
| 2480 | scan = require_scan(connection, args.scan_id) |
| 2481 | if scan["status"] != "complete": |
| 2482 | raise SystemExit("Findings can be exported after the scan completes.") |
| 2483 | scan_dir = require_canonical_scan_directory(Path(scan["scan_dir"])) |
| 2484 | require_recorded_manifest_digest(scan, scan_dir) |
| 2485 | verify_manifest_binding(scan, read_json_object(scan_dir / ARTIFACTS["manifest"])) |
| 2486 | try: |
| 2487 | manifest, _, _ = finalize_scan( |
| 2488 | scan_dir, |
| 2489 | expected_coverage_mode=expected_coverage_mode(scan), |
| 2490 | ) |
| 2491 | except ContractError as exc: |
| 2492 | raise SystemExit(str(exc)) from exc |
| 2493 | verify_manifest_binding(scan, manifest) |
| 2494 | manifest_digest = published_manifest_digest(scan_dir, manifest) |
| 2495 | pin_legacy_manifest_digest(connection, scan["id"], manifest_digest) |
| 2496 | if args.format == "json": |
| 2497 | path = artifact_path(scan_dir, ARTIFACTS["findings"], required=True) |
| 2498 | elif args.format == "sarif": |
| 2499 | try: |
| 2500 | write_sarif_projection(scan_dir) |
| 2501 | except ContractError as exc: |
| 2502 | raise SystemExit(str(exc)) from exc |
| 2503 | path = artifact_path(scan_dir, "exports/results.sarif", required=True) |
| 2504 | else: |
| 2505 | path = write_csv_export(connection, scan) |
| 2506 | if path is None: |
| 2507 | raise SystemExit(f"Could not export Codex Security findings as {args.format.upper()}.") |
| 2508 | return { |
| 2509 | "export": {"format": args.format, "path": str(path)}, |
| 2510 | "scan": scan_result(connection, scan), |
| 2511 | "workspace": workspace_state(connection, scan["workspace_id"]), |
| 2512 | } |
| 2513 | |
| 2514 | |
| 2515 | def write_csv_export(connection: sqlite3.Connection, scan: sqlite3.Row) -> Path: |
no test coverage detected