From e66468ca6660c2517f87f576f8f8a58493997c45 Mon Sep 17 00:00:00 2001 From: Wojtek Wajerowicz <115081248+wojciech-wajerowicz-sonarsource@users.noreply.github.com> Date: Wed, 16 Nov 2022 11:34:47 +0100 Subject: [PATCH] SONAR-15651 display clear message when sources or tests contain '*'. --- .../scanner/scan/ProjectReactorBuilder.java | 26 ++++++++++--- .../scan/ProjectReactorBuilderTest.java | 37 ++++++++++++++----- .../sonar-project.properties | 6 +++ .../sonar-project.properties | 7 ++++ 4 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-sources/sonar-project.properties create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-tests/sonar-project.properties diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java index d6b58ef31bc..81e01d6d24f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorBuilder.java @@ -19,6 +19,7 @@ */ package org.sonar.scanner.scan; +import com.google.common.annotations.VisibleForTesting; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; @@ -60,8 +61,15 @@ public class ProjectReactorBuilder { private static final String INVALID_VALUE_OF_X_FOR_Y = "Invalid value of {0} for {1}"; + private static final Logger LOG = Loggers.get(ProjectReactorBuilder.class); + @VisibleForTesting + static final String WILDCARDS_NOT_SUPPORTED = "Wildcards ** and * are not supported in \"sonar.sources\" and \"sonar.tests\" properties. " + + "\"sonar.sources\" and \"sonar.tests\" properties support only comma separated list of directories. " + + "Use \"sonar.exclusions/sonar.inclusions\" and \"sonar.test.exclusions/sonar.test.inclusions\" " + + "to further filter files in \"sonar.sources\" and \"sonar.tests\" respectively. Please refer to SonarQube documentation for more details."; + /** * @since 4.1 but not yet exposed in {@link CoreProperties} */ @@ -274,9 +282,7 @@ public class ProjectReactorBuilder { childProps.put(MODULE_KEY_PROPERTY, parentKey + ":" + childKey); } } - if (!childProps.containsKey(CoreProperties.PROJECT_NAME_PROPERTY)) { - childProps.put(CoreProperties.PROJECT_NAME_PROPERTY, moduleId); - } + childProps.putIfAbsent(CoreProperties.PROJECT_NAME_PROPERTY, moduleId); // For backward compatibility with ProjectDefinition childProps.put(CoreProperties.PROJECT_KEY_PROPERTY, childProps.get(MODULE_KEY_PROPERTY)); } @@ -318,7 +324,7 @@ public class ProjectReactorBuilder { // Check sonar.tests String[] testPaths = getListFromProperty(props, PROPERTY_TESTS); - checkExistenceOfPaths(projectId, baseDir, testPaths, PROPERTY_TESTS); + checkExistenceAndValidateSourcePaths(projectId, baseDir, testPaths, PROPERTY_TESTS); } } @@ -357,7 +363,7 @@ public class ProjectReactorBuilder { // We need to check the existence of source directories String[] sourcePaths = getListFromProperty(properties, PROPERTY_SOURCES); - checkExistenceOfPaths(project.getKey(), project.getBaseDir(), sourcePaths, PROPERTY_SOURCES); + checkExistenceAndValidateSourcePaths(project.getKey(), project.getBaseDir(), sourcePaths, PROPERTY_SOURCES); } protected static void mergeParentProperties(Map childProps, Map parentProps) { @@ -370,8 +376,9 @@ public class ProjectReactorBuilder { } } - protected static void checkExistenceOfPaths(String moduleRef, File baseDir, String[] paths, String propName) { + protected static void checkExistenceAndValidateSourcePaths(String moduleRef, File baseDir, String[] paths, String propName) { for (String path : paths) { + validateNoAsterisksInSourcePath(path, propName, moduleRef); File sourceFolder = resolvePath(baseDir, path); if (!sourceFolder.exists()) { LOG.error(MessageFormat.format(INVALID_VALUE_OF_X_FOR_Y, propName, moduleRef)); @@ -381,6 +388,13 @@ public class ProjectReactorBuilder { } } + private static void validateNoAsterisksInSourcePath(String path, String propName, String moduleRef) { + if (path.contains("*")) { + LOG.error(MessageFormat.format(INVALID_VALUE_OF_X_FOR_Y, propName, moduleRef)); + throw MessageException.of(WILDCARDS_NOT_SUPPORTED); + } + } + protected static File resolvePath(File baseDir, String path) { Path filePath = Paths.get(path); if (!filePath.isAbsolute()) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java index 3584589dab3..a008f8e4763 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorBuilderTest.java @@ -41,6 +41,7 @@ import org.sonar.scanner.bootstrap.ScannerProperties; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; @@ -70,12 +71,14 @@ public class ProjectReactorBuilderTest { @Test public void should_not_fail_if_sources_are_missing_in_intermediate_module() { - loadProjectDefinition("multi-module-pom-in-root"); + assertThatNoException() + .isThrownBy(() -> loadProjectDefinition("multi-module-pom-in-root")); } @Test public void shouldNotFailIfBlankSourceDirectory() { - loadProjectDefinition("simple-project-with-blank-source-dir"); + assertThatNoException() + .isThrownBy(() -> loadProjectDefinition("simple-project-with-blank-source-dir")); } @Test @@ -127,8 +130,8 @@ public class ProjectReactorBuilderTest { assertThat(rootProject.getName()).isEqualTo("Foo Project"); assertThat(rootProject.getVersion()).isEqualTo("1.0-SNAPSHOT"); assertThat(rootProject.getDescription()).isEqualTo("Description of Foo Project"); - assertThat(rootProject.sources().contains("sources")).isTrue(); - assertThat(rootProject.tests().contains("tests")).isTrue(); + assertThat(rootProject.sources()).contains("sources"); + assertThat(rootProject.tests()).contains("tests"); // and module properties must have been cleaned assertThat(rootProject.properties().get("module1.sonar.projectKey")).isNull(); assertThat(rootProject.properties().get("module2.sonar.projectKey")).isNull(); @@ -138,7 +141,7 @@ public class ProjectReactorBuilderTest { // CHECK MODULES List modules = rootProject.getSubProjects(); - assertThat(modules.size()).isEqualTo(2); + assertThat(modules).hasSize(2); // Module 1 ProjectDefinition module1 = modules.get(0); @@ -189,7 +192,7 @@ public class ProjectReactorBuilderTest { // CHECK MODULES List modules = rootProject.getSubProjects(); - assertThat(modules.size()).isEqualTo(2); + assertThat(modules).hasSize(2); // Module 2 ProjectDefinition module2 = modules.get(1); @@ -208,7 +211,7 @@ public class ProjectReactorBuilderTest { // CHECK MODULES List modules = rootProject.getSubProjects(); - assertThat(modules.size()).isEqualTo(2); + assertThat(modules).hasSize(2); // Module 1 ProjectDefinition module1 = modules.get(0); @@ -267,6 +270,20 @@ public class ProjectReactorBuilderTest { + getResource(this.getClass(), "multi-module-with-explicit-unexisting-test-dir").getAbsolutePath() + File.separator + "module1)"); } + @Test + public void should_fail_with_asterisks_in_sources() { + assertThatThrownBy(() -> loadProjectDefinition("simple-project-with-asterisks-in-sources")) + .isInstanceOf(MessageException.class) + .hasMessage(ProjectReactorBuilder.WILDCARDS_NOT_SUPPORTED); + } + + @Test + public void should_fail_with_asterisks_in_tests() { + assertThatThrownBy(() -> loadProjectDefinition("simple-project-with-asterisks-in-tests")) + .isInstanceOf(MessageException.class) + .hasMessage(ProjectReactorBuilder.WILDCARDS_NOT_SUPPORTED); + } + @Test public void multiModuleProperties() { ProjectDefinition projectDefinition = loadProjectDefinition("big-multi-module-definitions-all-in-root"); @@ -530,8 +547,8 @@ public class ProjectReactorBuilderTest { assertThat(rootProject.getName()).isEqualTo("Foo Project"); assertThat(rootProject.getVersion()).isEqualTo("1.0-SNAPSHOT"); assertThat(rootProject.getDescription()).isEqualTo("Description of Foo Project"); - assertThat(rootProject.sources().contains("sources")).isTrue(); - assertThat(rootProject.tests().contains("tests")).isTrue(); + assertThat(rootProject.sources()).contains("sources"); + assertThat(rootProject.tests()).contains("tests"); // Module properties must have been cleaned assertThat(rootProject.properties().get("module1.sonar.projectKey")).isNull(); assertThat(rootProject.properties().get("module2.sonar.projectKey")).isNull(); @@ -543,7 +560,7 @@ public class ProjectReactorBuilderTest { // CHECK MODULES List modules = rootProject.getSubProjects(); - assertThat(modules.size()).isEqualTo(2); + assertThat(modules).hasSize(2); // Module 1 ProjectDefinition module1 = modules.get(0); diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-sources/sonar-project.properties b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-sources/sonar-project.properties new file mode 100644 index 00000000000..30e8f87d632 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-sources/sonar-project.properties @@ -0,0 +1,6 @@ +sonar.projectKey=com.foo.project +sonar.projectName=Foo Project +sonar.projectVersion=1.0-SNAPSHOT +sonar.projectDescription=Description of Foo Project + +sonar.sources=**/sources/* diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-tests/sonar-project.properties b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-tests/sonar-project.properties new file mode 100644 index 00000000000..a254575a235 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/ProjectReactorBuilderTest/simple-project-with-asterisks-in-tests/sonar-project.properties @@ -0,0 +1,7 @@ +sonar.projectKey=com.foo.project +sonar.projectName=Foo Project +sonar.projectVersion=1.0-SNAPSHOT +sonar.projectDescription=Description of Foo Project + +sonar.sources=sources +sonar.tests=**/tests/* -- 2.39.5