Core scan orchestrator. When *show_stats* is True a StatsCollector is attached to the run. It samples resource usage in a background thread, records per-phase metrics, and prints the ASCII stats table after the normal report.
(
scan_path: Path,
config_path: Optional[Path],
output_file: Optional[Path],
report_format: str,
severity_level: str,
ai_scan: bool,
supply_chain_scan: bool = False,
syntax_warnings: bool = False,
show_stats: bool = False,
debug: bool = False,
)
| 664 | click.style( |
| 665 | f"Error: Failed to clone repository.\n{e.stderr}", fg="red" |
| 666 | ) |
| 667 | ) |
| 668 | sys.exit(1) |
| 669 | except FileNotFoundError: |
| 670 | click.echo( |
| 671 | click.style( |
| 672 | "Error: 'git' command not found. " |
| 673 | "Please ensure Git is installed and in your PATH.", |
| 674 | fg="red", |
| 675 | ) |
| 676 | ) |
| 677 | sys.exit(1) |
| 678 | else: |
| 679 | _execute_scan( |
| 680 | path, config_path, output_file, |
| 681 | report_format, severity_level, ai_scan, |
| 682 | supply_chain, |
| 683 | syntax_warnings, show_stats, debug, |
| 684 | ) |
| 685 | |
| 686 | |
| 687 | def _execute_scan( |
| 688 | scan_path: Path, |
| 689 | config_path: Optional[Path], |
| 690 | output_file: Optional[Path], |
| 691 | report_format: str, |
| 692 | severity_level: str, |
| 693 | ai_scan: bool, |
| 694 | supply_chain_scan: bool = False, |
| 695 | syntax_warnings: bool = False, |
| 696 | show_stats: bool = False, |
| 697 | debug: bool = False, |
| 698 | ): |
| 699 | """ |
| 700 | Core scan orchestrator. |
| 701 | |
| 702 | When *show_stats* is True a StatsCollector is attached to the run. |
| 703 | It samples resource usage in a background thread, records per-phase |
| 704 | metrics, and prints the ASCII stats table after the normal report. |
| 705 | """ |
| 706 | |
| 707 | # ── Stats initialisation ────────────────────────────────────────────── |
| 708 | stats: Optional[StatsCollector] = None |
| 709 | if show_stats: |
| 710 | stats = StatsCollector() |
| 711 | stats.start() |
| 712 | |
| 713 | start_time = time.time() |
| 714 | |
| 715 | config = load_config(config_path) |
| 716 | rules_toml_str = get_default_rules(ai_scan) |
| 717 | |
| 718 | # Let the stats collector parse the rule TOML to build its detection map |
| 719 | if stats: |
| 720 | stats.record_rules(rules_toml_str) |
| 721 | |
| 722 | _dbg(debug, f"[*] Starting PySpector scan on '{scan_path}'...") |
| 723 |
no test coverage detected