(connection: sqlite3.Connection, args: argparse.Namespace)
| 1575 | |
| 1576 | |
| 1577 | def update_progress(connection: sqlite3.Connection, args: argparse.Namespace) -> dict[str, Any]: |
| 1578 | scan_id = require_uuid(args.scan_id, "scan-id") |
| 1579 | connection.execute("BEGIN IMMEDIATE") |
| 1580 | try: |
| 1581 | timestamp = now() |
| 1582 | scan = require_scan(connection, scan_id) |
| 1583 | if scan["status"] != "running": |
| 1584 | raise SystemExit("Only a running scan can update progress.") |
| 1585 | if args.deep_review_pass is not None and scan["mode"] != "deep": |
| 1586 | raise SystemExit("Only Deep Scan can record a deep review pass.") |
| 1587 | progress = connection.execute( |
| 1588 | "SELECT * FROM scan_progress WHERE scan_id = ?", (scan["id"],) |
| 1589 | ).fetchone() |
| 1590 | if args.phase is not None and PHASES.index(args.phase) < PHASES.index(scan["phase"]): |
| 1591 | raise SystemExit("Scan progress cannot move to an earlier phase.") |
| 1592 | updates: list[str] = [] |
| 1593 | values: list[Any] = [] |
| 1594 | for column, value in ( |
| 1595 | ("review_items_total", args.review_items_total), |
| 1596 | ("review_items_completed", args.review_items_completed), |
| 1597 | ( |
| 1598 | "reportable_findings_count", |
| 1599 | reportable_count(scan["phase"], args.phase, args.reportable_findings_count), |
| 1600 | ), |
| 1601 | ("deep_review_pass", args.deep_review_pass), |
| 1602 | ): |
| 1603 | if value is not None: |
| 1604 | updates.append(f"{column} = ?") |
| 1605 | values.append(value) |
| 1606 | current_pass = progress["deep_review_pass"] or 0 |
| 1607 | requested_pass = args.deep_review_pass or current_pass |
| 1608 | if requested_pass < current_pass: |
| 1609 | raise SystemExit("Deep Scan progress cannot move to an earlier review pass.") |
| 1610 | advancing_pass = requested_pass > current_pass |
| 1611 | if advancing_pass and args.review_items_completed != 0: |
| 1612 | raise SystemExit("A new Deep Scan review pass must start with zero completed items.") |
| 1613 | if not advancing_pass: |
| 1614 | if ( |
| 1615 | args.review_items_total is not None |
| 1616 | and args.review_items_total < progress["review_items_total"] |
| 1617 | ): |
| 1618 | raise SystemExit("Review item total cannot decrease within a review pass.") |
| 1619 | if ( |
| 1620 | args.review_items_completed is not None |
| 1621 | and args.review_items_completed < progress["review_items_completed"] |
| 1622 | ): |
| 1623 | raise SystemExit("Completed review items cannot decrease within a review pass.") |
| 1624 | total = args.review_items_total |
| 1625 | if total is None: |
| 1626 | total = progress["review_items_total"] |
| 1627 | completed = args.review_items_completed |
| 1628 | if completed is None: |
| 1629 | completed = progress["review_items_completed"] |
| 1630 | if completed > total: |
| 1631 | raise SystemExit("Completed review items cannot exceed total review items.") |
| 1632 | updated = connection.execute( |
| 1633 | """ |
| 1634 | UPDATE scans |
no test coverage detected