From 9e6d54ecfe6776de84d0b84e21242c224cb65b9a Mon Sep 17 00:00:00 2001 From: Travis Collins Date: Thu, 1 May 2025 09:11:40 -0600 Subject: SCA-195 use sonar.exclusions in SCA --- .../main/java/org/sonar/scanner/sca/CliService.java | 14 ++++++++++---- .../java/org/sonar/scanner/sca/CliServiceTest.java | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/CliService.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/CliService.java index 6fe099a7209..530798c4395 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/CliService.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/CliService.java @@ -37,12 +37,14 @@ import org.apache.commons.csv.CSVPrinter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.platform.Server; import org.sonar.api.utils.System2; import org.sonar.core.util.ProcessWrapperFactory; import org.sonar.scanner.config.DefaultConfiguration; import org.sonar.scanner.repository.TelemetryCache; +import org.sonar.scanner.scan.filesystem.ProjectExclusionFilters; import org.sonar.scanner.scm.ScmConfiguration; import org.sonar.scm.git.JGitUtils; @@ -62,13 +64,16 @@ public class CliService { private final System2 system2; private final Server server; private final ScmConfiguration scmConfiguration; + private final ProjectExclusionFilters projectExclusionFilters; - public CliService(ProcessWrapperFactory processWrapperFactory, TelemetryCache telemetryCache, System2 system2, Server server, ScmConfiguration scmConfiguration) { + public CliService(ProcessWrapperFactory processWrapperFactory, TelemetryCache telemetryCache, System2 system2, Server server, ScmConfiguration scmConfiguration, + ProjectExclusionFilters projectExclusionFilters) { this.processWrapperFactory = processWrapperFactory; this.telemetryCache = telemetryCache; this.system2 = system2; this.server = server; this.scmConfiguration = scmConfiguration; + this.projectExclusionFilters = projectExclusionFilters; } public File generateManifestsZip(DefaultInputModule module, File cliExecutable, DefaultConfiguration configuration) throws IOException, IllegalStateException { @@ -123,7 +128,7 @@ public class CliService { } private @Nullable String getExcludeFlag(DefaultInputModule module, DefaultConfiguration configuration) throws IOException { - List configExcludedPaths = getConfigExcludedPaths(configuration); + List configExcludedPaths = getConfigExcludedPaths(configuration, projectExclusionFilters); List scmIgnoredPaths = getScmIgnoredPaths(module); ArrayList mergedExclusionPaths = new ArrayList<>(); @@ -143,11 +148,12 @@ public class CliService { return toCsvString(mergedExclusionPaths); } - private static List getConfigExcludedPaths(DefaultConfiguration configuration) { + private static List getConfigExcludedPaths(DefaultConfiguration configuration, ProjectExclusionFilters projectExclusionFilters) { + String[] sonarExclusions = projectExclusionFilters.getExclusionsConfig(InputFile.Type.MAIN); String[] scaExclusions = configuration.getStringArray(SCA_EXCLUSIONS_KEY); String[] scaExclusionsLegacy = configuration.getStringArray(LEGACY_SCA_EXCLUSIONS_KEY); - return Stream.of(scaExclusions, scaExclusionsLegacy) + return Stream.of(sonarExclusions, scaExclusions, scaExclusionsLegacy) .flatMap(Arrays::stream) .distinct() .toList(); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java index a6b10a95efa..7926860b731 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java @@ -36,6 +36,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.io.TempDir; import org.mockito.MockedStatic; import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.platform.Server; @@ -44,6 +45,7 @@ import org.sonar.api.utils.System2; import org.sonar.core.util.ProcessWrapperFactory; import org.sonar.scanner.config.DefaultConfiguration; import org.sonar.scanner.repository.TelemetryCache; +import org.sonar.scanner.scan.filesystem.ProjectExclusionFilters; import org.sonar.scanner.scm.ScmConfiguration; import org.sonar.scm.git.GitScmProvider; import org.sonar.scm.git.JGitUtils; @@ -69,6 +71,7 @@ class CliServiceTest { ProcessWrapperFactory processWrapperFactory = mock(ProcessWrapperFactory.class, CALLS_REAL_METHODS); private MockedStatic jGitUtilsMock; DefaultConfiguration configuration = mock(DefaultConfiguration.class); + ProjectExclusionFilters projectExclusionFilters = mock(ProjectExclusionFilters.class); private CliService underTest; @@ -86,11 +89,12 @@ class CliServiceTest { jGitUtilsMock.when(() -> JGitUtils.getAllIgnoredPaths(any(Path.class))).thenReturn(List.of("ignored.txt")); when(server.getVersion()).thenReturn("1.0.0"); logTester.setLevel(INFO); + when(projectExclusionFilters.getExclusionsConfig(InputFile.Type.MAIN)).thenReturn(new String[0]); when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[0]); when(configuration.getStringArray(CliService.LEGACY_SCA_EXCLUSIONS_KEY)).thenReturn(new String[0]); when(configuration.getBoolean("sonar.sca.debug")).thenReturn(Optional.of(true)); - underTest = new CliService(processWrapperFactory, telemetryCache, System2.INSTANCE, server, scmConfiguration); + underTest = new CliService(processWrapperFactory, telemetryCache, System2.INSTANCE, server, scmConfiguration, projectExclusionFilters); } @AfterEach @@ -296,6 +300,18 @@ class CliServiceTest { assertThat(capturedArgs).contains("--exclude **/test1/**,**/test2/**,**/test3/**,ignored.txt,.scannerwork/**"); } + @Test + void generateZip_withExcludedManifestsAndSonarExcludesContainingDupes_mergesAndDedupes() throws Exception { + when(projectExclusionFilters.getExclusionsConfig(InputFile.Type.MAIN)).thenReturn(new String[] {"**/test1/**", "**/test4/**"}); + when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test1/**", "**/test2/**", "**/test1/**"}); + when(configuration.getStringArray(CliService.LEGACY_SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test1/**", "**/test3/**"}); + + underTest.generateManifestsZip(rootInputModule, scriptDir(), configuration); + + String capturedArgs = logTester.logs().stream().filter(log -> log.contains("Arguments Passed In:")).findFirst().get(); + assertThat(capturedArgs).contains("--exclude **/test1/**,**/test4/**,**/test2/**,**/test3/**,ignored.txt,.scannerwork/**"); + } + @Test void generateZip_withScmIgnoresContainingBadCharacters_handlesTheBadCharacters() throws Exception { jGitUtilsMock.when(() -> JGitUtils.getAllIgnoredPaths(any(Path.class))) -- cgit v1.2.3