diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2013-11-26 17:55:38 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2013-11-26 17:55:38 +0100 |
commit | 5c63b1e2a17983f2db4130cd7ad7a567cb6889a9 (patch) | |
tree | fa9c884c87e6c9bc8613775c856922acbabe457a /sonar-batch | |
parent | b2a041d11f29681ec988ff4ce3a63010e1b84724 (diff) | |
download | sonarqube-5c63b1e2a17983f2db4130cd7ad7a567cb6889a9.tar.gz sonarqube-5c63b1e2a17983f2db4130cd7ad7a567cb6889a9.zip |
SONAR-4876 Allow the user to specify the key to be used for a module
Diffstat (limited to 'sonar-batch')
5 files changed, 64 insertions, 34 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java b/sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java index 5ca8e682c65..4c00baf33ff 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java @@ -97,7 +97,7 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper { /** * Array of all mandatory properties required for a child project before its properties get merged with its parent ones. */ - private static final String[] MANDATORY_PROPERTIES_FOR_CHILD = {CoreProperties.PROJECT_KEY_PROPERTY, CoreProperties.PROJECT_NAME_PROPERTY}; + private static final String[] MANDATORY_PROPERTIES_FOR_CHILD = {CoreProperties.MODULE_KEY_PROPERTY, CoreProperties.PROJECT_NAME_PROPERTY}; /** * Properties that must not be passed from the parent project to its children. @@ -181,8 +181,6 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper { } private ProjectDefinition loadChildProject(ProjectDefinition parentProject, Properties moduleProps, String moduleId) { - setProjectKeyAndNameIfNotDefined(moduleProps, moduleId); - final File baseDir; if (moduleProps.containsKey(PROPERTY_PROJECT_BASEDIR)) { baseDir = getFileFromPath(moduleProps.getProperty(PROPERTY_PROJECT_BASEDIR), parentProject.getBaseDir()); @@ -202,14 +200,14 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper { tryToFindAndLoadPropsFile(baseDir, moduleProps, moduleId); } + setModuleKeyAndNameIfNotDefined(moduleProps, moduleId, parentProject.getKey()); + // and finish checkMandatoryProperties(moduleProps, MANDATORY_PROPERTIES_FOR_CHILD); validateDirectories(moduleProps, baseDir, moduleId); mergeParentProperties(moduleProps, parentProject.getProperties()); - prefixProjectKeyWithParentKey(moduleProps, parentProject.getKey()); - return defineProject(moduleProps, parentProject); } @@ -266,13 +264,20 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper { } @VisibleForTesting - protected static void setProjectKeyAndNameIfNotDefined(Properties childProps, String moduleId) { - if (!childProps.containsKey(CoreProperties.PROJECT_KEY_PROPERTY)) { - childProps.put(CoreProperties.PROJECT_KEY_PROPERTY, moduleId); + protected static void setModuleKeyAndNameIfNotDefined(Properties childProps, String moduleId, String parentKey) { + if (!childProps.containsKey(CoreProperties.MODULE_KEY_PROPERTY)) { + if (!childProps.containsKey(CoreProperties.PROJECT_KEY_PROPERTY)) { + childProps.put(CoreProperties.MODULE_KEY_PROPERTY, parentKey + ":" + moduleId); + } else { + String childKey = childProps.getProperty(CoreProperties.PROJECT_KEY_PROPERTY); + childProps.put(CoreProperties.MODULE_KEY_PROPERTY, parentKey + ":" + childKey); + } } if (!childProps.containsKey(CoreProperties.PROJECT_NAME_PROPERTY)) { childProps.put(CoreProperties.PROJECT_NAME_PROPERTY, moduleId); } + // For backward compatibility with ProjectDefinition + childProps.put(CoreProperties.PROJECT_KEY_PROPERTY, childProps.getProperty(CoreProperties.MODULE_KEY_PROPERTY)); } @VisibleForTesting @@ -284,12 +289,6 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper { } } - @VisibleForTesting - protected static void prefixProjectKeyWithParentKey(Properties childProps, String parentKey) { - String childKey = childProps.getProperty(CoreProperties.PROJECT_KEY_PROPERTY); - childProps.put(CoreProperties.PROJECT_KEY_PROPERTY, parentKey + ":" + childKey); - } - private static void setProjectBaseDir(File baseDir, Properties childProps, String moduleId) { if (!baseDir.isDirectory()) { throw new IllegalStateException("The base directory of the module '" + moduleId + "' does not exist: " + baseDir.getAbsolutePath()); @@ -309,9 +308,9 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper { missing.append(mandatoryProperty); } } - String projectKey = props.getProperty(CoreProperties.PROJECT_KEY_PROPERTY); + String moduleKey = StringUtils.defaultIfBlank(props.getProperty(CoreProperties.MODULE_KEY_PROPERTY), props.getProperty(CoreProperties.PROJECT_KEY_PROPERTY)); if (missing.length() != 0) { - throw new IllegalStateException("You must define the following mandatory properties for '" + (projectKey == null ? "Unknown" : projectKey) + "': " + missing); + throw new IllegalStateException("You must define the following mandatory properties for '" + (moduleKey == null ? "Unknown" : moduleKey) + "': " + missing); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/DefaultProjectBootstrapperTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/DefaultProjectBootstrapperTest.java index f42129fdc22..caedb3c46a1 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/DefaultProjectBootstrapperTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/DefaultProjectBootstrapperTest.java @@ -207,6 +207,25 @@ public class DefaultProjectBootstrapperTest { assertThat(module2.getProperties().getProperty("module2.sonar.projectKey")).isNull(); } + // SONAR-4876 + @Test + public void shouldDefineMultiModuleProjectWithModuleKey() throws IOException { + ProjectDefinition rootProject = loadProjectDefinition("multi-module-definitions-moduleKey"); + + // CHECK ROOT + // module properties must have been cleaned + assertThat(rootProject.getProperties().getProperty("module1.sonar.moduleKey")).isNull(); + assertThat(rootProject.getProperties().getProperty("module2.sonar.moduleKey")).isNull(); + + // CHECK MODULES + List<ProjectDefinition> modules = rootProject.getSubProjects(); + assertThat(modules.size()).isEqualTo(2); + + // Module 2 + ProjectDefinition module2 = modules.get(1); + assertThat(module2.getKey()).isEqualTo("com.foo.project.module2"); + } + @Test public void shouldDefineMultiModuleProjectWithDefinitionsModule1Inherited() throws IOException { ProjectDefinition rootProject = loadProjectDefinition("multi-module-definitions-in-each-module-inherited"); @@ -530,7 +549,7 @@ public class DefaultProjectBootstrapperTest { @Test public void shouldInitRootWorkDir() { - DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(Maps.<String, String> newHashMap()))); + DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(Maps.<String, String>newHashMap()))); File baseDir = new File("target/tmp/baseDir"); File workDir = builder.initRootProjectWorkDir(baseDir); @@ -540,7 +559,7 @@ public class DefaultProjectBootstrapperTest { @Test public void shouldInitWorkDirWithCustomRelativeFolder() { - Map<String, String> props = Maps.<String, String> newHashMap(); + Map<String, String> props = Maps.<String, String>newHashMap(); props.put("sonar.working.directory", ".foo"); DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(props))); File baseDir = new File("target/tmp/baseDir"); @@ -552,7 +571,7 @@ public class DefaultProjectBootstrapperTest { @Test public void shouldInitRootWorkDirWithCustomAbsoluteFolder() { - Map<String, String> props = Maps.<String, String> newHashMap(); + Map<String, String> props = Maps.<String, String>newHashMap(); props.put("sonar.working.directory", new File("src").getAbsolutePath()); DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(props))); File baseDir = new File("target/tmp/baseDir"); @@ -563,15 +582,6 @@ public class DefaultProjectBootstrapperTest { } @Test - public void shouldReturnPrefixedKey() { - Properties props = new Properties(); - props.put("sonar.projectKey", "my-module-key"); - - DefaultProjectBootstrapper.prefixProjectKeyWithParentKey(props, "my-parent-key"); - assertThat(props.getProperty("sonar.projectKey")).isEqualTo("my-parent-key:my-module-key"); - } - - @Test public void shouldFailIf2ModulesWithSameKey() { Properties props = new Properties(); props.put("sonar.projectKey", "root"); @@ -597,18 +607,18 @@ public class DefaultProjectBootstrapperTest { } @Test - public void shouldSetProjectKeyIfNotPresent() { + public void shouldSetModuleKeyIfNotPresent() { Properties props = new Properties(); props.put("sonar.projectVersion", "1.0"); // should be set - DefaultProjectBootstrapper.setProjectKeyAndNameIfNotDefined(props, "foo"); - assertThat(props.getProperty("sonar.projectKey")).isEqualTo("foo"); + DefaultProjectBootstrapper.setModuleKeyAndNameIfNotDefined(props, "foo", "parent"); + assertThat(props.getProperty("sonar.moduleKey")).isEqualTo("parent:foo"); assertThat(props.getProperty("sonar.projectName")).isEqualTo("foo"); // but not this 2nd time - DefaultProjectBootstrapper.setProjectKeyAndNameIfNotDefined(props, "bar"); - assertThat(props.getProperty("sonar.projectKey")).isEqualTo("foo"); + DefaultProjectBootstrapper.setModuleKeyAndNameIfNotDefined(props, "bar", "parent"); + assertThat(props.getProperty("sonar.moduleKey")).isEqualTo("parent:foo"); assertThat(props.getProperty("sonar.projectName")).isEqualTo("foo"); } @@ -621,7 +631,7 @@ public class DefaultProjectBootstrapperTest { } private ProjectDefinition loadProjectDefinition(String projectFolder) throws IOException { - Map<String, String> props = Maps.<String, String> newHashMap(); + Map<String, String> props = Maps.<String, String>newHashMap(); Properties runnerProps = DefaultProjectBootstrapper.toProperties(TestUtils.getResource(this.getClass(), projectFolder + "/sonar-project.properties")); for (final String name : runnerProps.stringPropertyNames()) { props.put(name, runnerProps.getProperty(name)); diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module1/sources/Fake.java b/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module1/sources/Fake.java new file mode 100644 index 00000000000..b2e6462a3f9 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module1/sources/Fake.java @@ -0,0 +1 @@ +Fake diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module2/src/Fake.java b/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module2/src/Fake.java new file mode 100644 index 00000000000..b2e6462a3f9 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module2/src/Fake.java @@ -0,0 +1 @@ +Fake diff --git a/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/sonar-project.properties b/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/sonar-project.properties new file mode 100644 index 00000000000..6def8070d6f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/sonar-project.properties @@ -0,0 +1,19 @@ +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 +sonar.binaries=target/classes + +sonar.modules=module1,\ + module2 + +# Mandatory properties for module1 are all inferred from the module ID + +module2.sonar.moduleKey=com.foo.project.module2 +module2.sonar.projectName=Foo Module 2 +# redefine some properties +module2.sonar.projectDescription=Description of Module 2 +module2.sonar.sources=src |