@@ -21,6 +21,7 @@ import (
2121 "github.com/vulnetix/cli/v3/internal/memory"
2222 "github.com/vulnetix/cli/v3/internal/sast"
2323 "github.com/vulnetix/cli/v3/internal/scan"
24+ "github.com/vulnetix/cli/v3/internal/testsuite"
2425 "github.com/vulnetix/cli/v3/internal/triage"
2526 "github.com/vulnetix/cli/v3/internal/tui"
2627 "github.com/vulnetix/cli/v3/internal/update"
@@ -379,6 +380,7 @@ func runScanWithFeatures(ctx context.Context, cmd *cobra.Command, noSAST, noSCA,
379380 if cmd .Flags ().Changed ("snippet-context" ) {
380381 snippetContext , _ = cmd .Flags ().GetInt ("snippet-context" )
381382 }
383+ suppressTestCode , _ = cmd .Flags ().GetBool ("suppress-test-code" )
382384 excludes , _ := cmd .Flags ().GetStringArray ("exclude" )
383385 ignoreGlobs , _ := cmd .Flags ().GetStringArray ("ignore" )
384386 ignoreGit , _ := cmd .Flags ().GetBool ("ignore-git" )
@@ -1508,6 +1510,31 @@ func runLocalScan(
15081510 fmt .Sprintf ("%d finding(s) suppressed by ignore rules" , n ))
15091511 }
15101512 }
1513+
1514+ // Test-suite attribution: mark findings that live in the project's
1515+ // test code, corroborated by test-runner config files and declared
1516+ // test-framework dependencies found in the repo. The resulting
1517+ // metadata rides the SARIF (result properties) + typed wire findings,
1518+ // and the detected config files ride the SAST env. Run before SARIF
1519+ // build so both on-disk and uploaded artefacts carry it.
1520+ var testSuppressionMints []vdb.CliSuppressionMint
1521+ testActive := testsuite .Scan (rootPath )
1522+ testMarked := testsuite .Annotate (sastReport .Findings , testActive )
1523+ testConfigMeta := testConfigsToWire (testActive .Configs )
1524+ if testMarked > 0 {
1525+ sastReport .Degradations = append (sastReport .Degradations ,
1526+ fmt .Sprintf ("%d finding(s) attributed to test suites" , testMarked ))
1527+ }
1528+ // Optionally suppress test-code SAST findings when the user opts in.
1529+ if suppressTestCode && testMarked > 0 {
1530+ if kept , mints := suppressTestFindings (sastReport .Findings , gitCtx ); len (mints ) > 0 {
1531+ sastReport .Findings = kept
1532+ testSuppressionMints = mints
1533+ sastReport .Degradations = append (sastReport .Degradations ,
1534+ fmt .Sprintf ("%d test-code finding(s) suppressed (--suppress-test-code)" , len (mints )))
1535+ }
1536+ }
1537+
15111538 rec .SASTRulesLoaded = sastReport .RulesLoaded
15121539 rec .SASTFindingCount = len (sastReport .Findings )
15131540
@@ -1662,6 +1689,8 @@ func runLocalScan(
16621689 if ! disableMemory {
16631690 suppressionMints = reconcileScanSuppressions (mem , gitCtx , nosecHits , rootPath , time .Now ().Unix ())
16641691 }
1692+ // Test-code suppressions (--suppress-test-code) ride the same mint list.
1693+ suppressionMints = append (suppressionMints , testSuppressionMints ... )
16651694 if ! isUnauthenticatedScan () {
16661695 // Which SARIF-family scanners actually ran — an enabled one that
16671696 // found nothing still submits so the backend records coverage.
@@ -1672,7 +1701,7 @@ func runLocalScan(
16721701 "oci" : ! noContainers ,
16731702 }
16741703 var suppResults []vdb.CliSuppressionResult
1675- sarifSnapshots , sarifSnapshotUuids , suppResults = postScanSARIF (sastReport , enabledKinds , gitCtx , rootPath , snippetContext , scaSnapshotUuid , suppressionMints , progressStderr )
1704+ sarifSnapshots , sarifSnapshotUuids , suppResults = postScanSARIF (sastReport , enabledKinds , gitCtx , rootPath , snippetContext , scaSnapshotUuid , suppressionMints , testConfigMeta , progressStderr )
16761705 applyMintedSuppressionUUIDs (mem , suppResults )
16771706 }
16781707 }
@@ -4408,8 +4437,14 @@ func addSASTFlags(cmd *cobra.Command) {
44084437 "Override default registry (https://github.com) for all --rule repos" )
44094438 cmd .Flags ().String ("rule-id" , "" ,
44104439 "Run only the single SAST rule with this ID (e.g. VNX-GQL-004); skips SCA and license checks" )
4440+ cmd .Flags ().Bool ("suppress-test-code" , false ,
4441+ "Suppress SAST findings located in the project's test suite (test files corroborated by test-runner config/dependencies)" )
44114442}
44124443
4444+ // suppressTestCode is set from the --suppress-test-code flag in
4445+ // runScanWithFeatures and read by runLocalScan.
4446+ var suppressTestCode bool
4447+
44134448// filterFilesByFeature removes detected files excluded by the active feature flags.
44144449// noSCA removes ordinary package manifests; noContainers removes docker/OCI
44154450// manifests; noIAC removes HCL and Nix manifests.
0 commit comments