aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-scanner-engine')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/CliService.java28
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/ScaProperties.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/sca/CliServiceTest.java45
3 files changed, 58 insertions, 17 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 013ac2df109..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
@@ -30,18 +30,21 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.apache.commons.csv.CSVFormat;
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;
@@ -53,20 +56,24 @@ import org.sonar.scm.git.JGitUtils;
*/
public class CliService {
private static final Logger LOG = LoggerFactory.getLogger(CliService.class);
- public static final String EXCLUDED_MANIFESTS_PROP_KEY = "sonar.sca.excludedManifests";
+ public static final String SCA_EXCLUSIONS_KEY = "sonar.sca.exclusions";
+ public static final String LEGACY_SCA_EXCLUSIONS_KEY = "sonar.sca.excludedManifests";
private final ProcessWrapperFactory processWrapperFactory;
private final TelemetryCache telemetryCache;
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 {
@@ -121,7 +128,7 @@ public class CliService {
}
private @Nullable String getExcludeFlag(DefaultInputModule module, DefaultConfiguration configuration) throws IOException {
- List<String> configExcludedPaths = getConfigExcludedPaths(configuration);
+ List<String> configExcludedPaths = getConfigExcludedPaths(configuration, projectExclusionFilters);
List<String> scmIgnoredPaths = getScmIgnoredPaths(module);
ArrayList<String> mergedExclusionPaths = new ArrayList<>();
@@ -141,12 +148,15 @@ public class CliService {
return toCsvString(mergedExclusionPaths);
}
- private static List<String> getConfigExcludedPaths(DefaultConfiguration configuration) {
- String[] excludedPaths = configuration.getStringArray(EXCLUDED_MANIFESTS_PROP_KEY);
- if (excludedPaths == null) {
- return List.of();
- }
- return Arrays.stream(excludedPaths).toList();
+ private static List<String> 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(sonarExclusions, scaExclusions, scaExclusionsLegacy)
+ .flatMap(Arrays::stream)
+ .distinct()
+ .toList();
}
private List<String> getScmIgnoredPaths(DefaultInputModule module) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/ScaProperties.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/ScaProperties.java
index e5086149c03..a697aef3e20 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/ScaProperties.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sca/ScaProperties.java
@@ -31,6 +31,8 @@ public class ScaProperties {
private static final Pattern sonarScaPropertyRegex = Pattern.compile("^sonar\\.sca\\.([a-zA-Z]+)$");
private static final String SONAR_SCA_PREFIX = "sonar.sca.";
private static final Set<String> IGNORED_PROPERTIES = Set.of(
+ // sonar.sca.exclusions is a special case which we handle when building --exclude
+ "sonar.sca.exclusions",
// excludedManifests is a special case which we handle when building --exclude
"sonar.sca.excludedManifests",
// keep recursive enabled to better match sonar-scanner behavior
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 e907294d6fd..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<JGitUtils> jGitUtilsMock;
DefaultConfiguration configuration = mock(DefaultConfiguration.class);
+ ProjectExclusionFilters projectExclusionFilters = mock(ProjectExclusionFilters.class);
private CliService underTest;
@@ -86,9 +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
@@ -102,8 +108,8 @@ class CliServiceTest {
void generateZip_shouldCallProcessCorrectly_andRegisterTelemetry() throws IOException, URISyntaxException {
assertThat(rootModuleDir.resolve("test_file").toFile().createNewFile()).isTrue();
- when(configuration.getProperties()).thenReturn(Map.of(CliService.EXCLUDED_MANIFESTS_PROP_KEY, "foo,bar,baz/**"));
- when(configuration.getStringArray(CliService.EXCLUDED_MANIFESTS_PROP_KEY)).thenReturn(new String[] {"foo", "bar", "baz/**"});
+ when(configuration.getProperties()).thenReturn(Map.of(CliService.SCA_EXCLUSIONS_KEY, "foo,bar,baz/**"));
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"foo", "bar", "baz/**"});
File producedZip = underTest.generateManifestsZip(rootInputModule, scriptDir(), configuration);
@@ -239,7 +245,7 @@ class CliServiceTest {
}
@Test
- void generateZip_withExclusionDisabled_doesNotIncludeScmIgnoredPaths() throws Exception {
+ void generateZip_withScmExclusionDisabled_doesNotIncludeScmIgnoredPaths() throws Exception {
when(scmConfiguration.isExclusionDisabled()).thenReturn(true);
underTest.generateManifestsZip(rootInputModule, scriptDir(), configuration);
@@ -259,8 +265,8 @@ class CliServiceTest {
}
@Test
- void generateZip_withExistingExcludedManifests_appendsScmIgnoredPaths() throws Exception {
- when(configuration.getStringArray(CliService.EXCLUDED_MANIFESTS_PROP_KEY)).thenReturn(new String[] {"**/test/**"});
+ void generateZip_withExcludedManifests_appendsScmIgnoredPaths() throws Exception {
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {"**/test/**"});
underTest.generateManifestsZip(rootInputModule, scriptDir(), configuration);
@@ -269,8 +275,8 @@ class CliServiceTest {
}
@Test
- void generateZip_withExcludedManifestsSettingContainingBadCharacters_handlesTheBadCharacters() throws Exception {
- when(configuration.getStringArray(CliService.EXCLUDED_MANIFESTS_PROP_KEY)).thenReturn(new String[] {
+ void generateZip_withExcludedManifestsContainingBadCharacters_handlesTheBadCharacters() throws Exception {
+ when(configuration.getStringArray(CliService.SCA_EXCLUSIONS_KEY)).thenReturn(new String[] {
"**/test/**", "**/path with spaces/**", "**/path,with,commas/**", "**/path'with'quotes/**", "**/path\"with\"double\"quotes/**"});
underTest.generateManifestsZip(rootInputModule, scriptDir(), configuration);
@@ -284,6 +290,29 @@ class CliServiceTest {
}
@Test
+ void generateZip_withExcludedManifestsContainingDupes_dedupes() throws Exception {
+ 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/**,**/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)))
.thenReturn(List.of("**/test/**", "**/path with spaces/**", "**/path,with,commas/**", "**/path'with'quotes/**", "**/path\"with\"double\"quotes/**"));