From f2bc8889d52a8c824723703dfbe26bcf91c12d69 Mon Sep 17 00:00:00 2001 From: Arpit Jain Date: Mon, 24 Aug 2026 06:14:29 -0400 Subject: [PATCH] Do not silently drop findings listed in a baseline inside the scanned tree The baseline is read from .pyspector_baseline.json inside the directory being scanned, so when that directory came from somewhere else the file that suppresses findings came from there too. A scan of a tree carrying a baseline can therefore report clean while dropping results, and nothing says so: the Baseline-ignored counter only prints under --stats. Print the suppressed count unconditionally when it is non-zero, naming the file, and add --no-baseline for callers that never want a baseline picked up from the tree at all (CI scanning untrusted branches). Signed-off-by: Arpit Jain --- src/pyspector/cli.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/pyspector/cli.py b/src/pyspector/cli.py index 1a3ff52..edb490b 100644 --- a/src/pyspector/cli.py +++ b/src/pyspector/cli.py @@ -575,6 +575,8 @@ def run_wizard(): help="Treat Python SyntaxWarnings as errors and exclude affected files.") @click.option('--wizard', is_flag=True, help="Launch interactive guided scan mode — ideal for first-time users.") +@click.option('--no-baseline', 'no_baseline', is_flag=True, default=False, + help="Ignore any .pyspector_baseline.json found in the scanned tree.") @click.option('--stats', 'show_stats', is_flag=True, default=False, help=( "Print a detailed performance and findings statistics table " @@ -599,6 +601,7 @@ def run_scan_command( supply_chain: bool, syntax_warnings: bool, wizard: bool, + no_baseline: bool, show_stats: bool, debug: bool, show_msg: Optional[bool], @@ -685,6 +688,7 @@ def run_scan_command( report_format, severity_level, ai_scan, supply_chain, syntax_warnings, show_stats, debug, + no_baseline=no_baseline, ) except subprocess.CalledProcessError as e: click.echo( @@ -708,6 +712,7 @@ def run_scan_command( report_format, severity_level, ai_scan, supply_chain, syntax_warnings, show_stats, debug, + no_baseline=no_baseline, ) @@ -722,6 +727,7 @@ def _execute_scan( syntax_warnings: bool = False, show_stats: bool = False, debug: bool = False, + no_baseline: bool = False, ): """ Core scan orchestrator. @@ -758,7 +764,9 @@ def _execute_scan( else scan_path.parent / ".pyspector_baseline.json" ) ignored_fingerprints: set = set() - if baseline_path.exists(): + if no_baseline and baseline_path.exists(): + _dbg(debug, f"[*] Ignoring baseline '{baseline_path}' (--no-baseline).") + elif baseline_path.exists(): try: with baseline_path.open('r') as f: baseline_data = json.load(f) @@ -906,6 +914,17 @@ def _execute_scan( _severity_filtered = len(raw_issues) - len(severity_passed) _baseline_ignored = len(severity_passed) - len(final_issues) + # The baseline is read from inside the tree being scanned, so when that tree + # came from somewhere else the file that suppressed these findings did too. + # Say so unconditionally rather than only under --stats, so a scan can never + # report clean while quietly dropping results. + if _baseline_ignored: + click.echo(click.style( + f"[!] {_baseline_ignored} finding(s) suppressed by " + f"'{baseline_path}'. Use --no-baseline to ignore it.", + fg="yellow" + )) + if stats: stats.record_final_issues( final_issues,