Browse Source

SONAR-4876 Allow the user to specify the key to be used for a module

tags/4.1-RC1
Julien HENRY 10 years ago
parent
commit
5c63b1e2a1

+ 15
- 16
sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java View File

@@ -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);
}
}


+ 28
- 18
sonar-batch/src/test/java/org/sonar/batch/scan/DefaultProjectBootstrapperTest.java View File

@@ -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");
@@ -562,15 +581,6 @@ public class DefaultProjectBootstrapperTest {
assertThat(workDir).isEqualTo(new File("src").getAbsoluteFile());
}

@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();
@@ -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));

+ 1
- 0
sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module1/sources/Fake.java View File

@@ -0,0 +1 @@
Fake

+ 1
- 0
sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/module2/src/Fake.java View File

@@ -0,0 +1 @@
Fake

+ 19
- 0
sonar-batch/src/test/resources/org/sonar/batch/scan/DefaultProjectBootstrapperTest/multi-module-definitions-moduleKey/sonar-project.properties View File

@@ -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

+ 5
- 0
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java View File

@@ -136,6 +136,11 @@ public interface CoreProperties {
*/
String PROJECT_KEY_PROPERTY = "sonar.projectKey";

/**
* @since 4.1
*/
String MODULE_KEY_PROPERTY = "sonar.moduleKey";

/**
* @since 2.6
*/

Loading…
Cancel
Save