
org.sonar.runner.internal.batch.SonarProjectBuilder Maven / Gradle / Ivy
The newest version!
/*
* Sonar Runner
* Copyright (C) 2011 SonarSource
* [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.runner.internal.batch;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.FileFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.runner.RunnerException;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
/**
* Class that creates a Sonar project definition based on a set of properties.
*
* @since 1.5
*/
public final class SonarProjectBuilder {
private static final Logger LOG = LoggerFactory.getLogger(SonarProjectBuilder.class);
private static final String PROPERTY_PROJECT_BASEDIR = "sonar.projectBaseDir";
private static final String PROPERTY_PROJECT_CONFIG_FILE = "sonar.projectConfigFile";
private static final String PROPERTY_PROJECT_KEY = "sonar.projectKey";
private static final String PROPERTY_PROJECT_NAME = "sonar.projectName";
private static final String PROPERTY_PROJECT_DESCRIPTION = "sonar.projectDescription";
private static final String PROPERTY_PROJECT_VERSION = "sonar.projectVersion";
private static final String PROPERTY_MODULES = "sonar.modules";
/**
* New properties, to be consistent with Sonar naming conventions
* @since 1.5
*/
private static final String PROPERTY_SOURCES = "sonar.sources";
private static final String PROPERTY_TESTS = "sonar.tests";
private static final String PROPERTY_BINARIES = "sonar.binaries";
private static final String PROPERTY_LIBRARIES = "sonar.libraries";
/**
* Old deprecated properties, replaced by the same ones preceded by "sonar."
*/
private static final String PROPERTY_OLD_SOURCES = "sources";
private static final String PROPERTY_OLD_TESTS = "tests";
private static final String PROPERTY_OLD_BINARIES = "binaries";
private static final String PROPERTY_OLD_LIBRARIES = "libraries";
private static final Map DEPRECATED_PROPS_TO_NEW_PROPS = new HashMap() {
{
put(PROPERTY_OLD_SOURCES, PROPERTY_SOURCES);
put(PROPERTY_OLD_TESTS, PROPERTY_TESTS);
put(PROPERTY_OLD_BINARIES, PROPERTY_BINARIES);
put(PROPERTY_OLD_LIBRARIES, PROPERTY_LIBRARIES);
}
};
/**
* @since 1.4
*/
private static final String PROPERTY_WORK_DIRECTORY = "sonar.working.directory";
private static final String DEF_VALUE_WORK_DIRECTORY = ".sonar";
/**
* Array of all mandatory properties required for a project.
*/
private static final String[] MANDATORY_PROPERTIES_FOR_PROJECT = {PROPERTY_PROJECT_BASEDIR, PROPERTY_PROJECT_KEY, PROPERTY_PROJECT_NAME, PROPERTY_PROJECT_VERSION,
PROPERTY_SOURCES};
/**
* 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 = {PROPERTY_PROJECT_KEY, PROPERTY_PROJECT_NAME};
/**
* Properties that must not be passed from the parent project to its children.
*/
private static final List NON_HERITED_PROPERTIES_FOR_CHILD = Lists.newArrayList(PROPERTY_PROJECT_BASEDIR, PROPERTY_MODULES, PROPERTY_PROJECT_DESCRIPTION);
private Properties properties;
private File rootProjectWorkDir;
private SonarProjectBuilder(Properties properties) {
this.properties = properties;
}
public static SonarProjectBuilder create(Properties properties) {
return new SonarProjectBuilder(properties);
}
public ProjectDefinition generateProjectDefinition() {
ProjectDefinition rootProject = defineProject(properties, null);
rootProjectWorkDir = rootProject.getWorkDir();
defineChildren(rootProject);
cleanAndCheckProjectDefinitions(rootProject);
return rootProject;
}
private ProjectDefinition defineProject(Properties properties, ProjectDefinition parent) {
checkMandatoryProperties(properties, MANDATORY_PROPERTIES_FOR_PROJECT);
File baseDir = new File(properties.getProperty(PROPERTY_PROJECT_BASEDIR));
File workDir = null;
if (parent == null) {
workDir = initRootProjectWorkDir(baseDir);
} else {
workDir = initModuleWorkDir(properties);
}
ProjectDefinition definition = ProjectDefinition.create((Properties) properties.clone())
.setBaseDir(baseDir)
.setWorkDir(workDir);
return definition;
}
@VisibleForTesting
protected File initRootProjectWorkDir(File baseDir) {
String workDir = properties.getProperty(PROPERTY_WORK_DIRECTORY);
if (StringUtils.isBlank(workDir)) {
return new File(baseDir, DEF_VALUE_WORK_DIRECTORY);
}
File customWorkDir = new File(workDir);
if (customWorkDir.isAbsolute()) {
return customWorkDir;
}
return new File(baseDir, customWorkDir.getPath());
}
@VisibleForTesting
protected File initModuleWorkDir(Properties properties) {
String cleanKey = StringUtils.deleteWhitespace(properties.getProperty(PROPERTY_PROJECT_KEY));
cleanKey = StringUtils.replace(cleanKey, ":", "_");
return new File(rootProjectWorkDir, cleanKey);
}
private void defineChildren(ProjectDefinition parentProject) {
Properties parentProps = parentProject.getProperties();
if (parentProps.containsKey(PROPERTY_MODULES)) {
for (String module : SonarRunnerUtils.getListFromProperty(parentProps, PROPERTY_MODULES)) {
Properties moduleProps = extractModuleProperties(module, parentProps);
ProjectDefinition childProject = loadChildProject(parentProject, moduleProps, module);
// check the unicity of the child key
checkUnicityOfChildKey(childProject, parentProject);
// the child project may have children as well
defineChildren(childProject);
// and finally add this child project to its parent
parentProject.addSubProject(childProject);
}
}
}
private ProjectDefinition loadChildProject(ProjectDefinition parentProject, Properties moduleProps, String moduleId) {
setProjectKeyAndNameIfNotDefined(moduleProps, moduleId);
if (moduleProps.containsKey(PROPERTY_PROJECT_BASEDIR)) {
File baseDir = getFileFromPath(moduleProps.getProperty(PROPERTY_PROJECT_BASEDIR), parentProject.getBaseDir());
setProjectBaseDir(baseDir, moduleProps, moduleId);
tryToFindAndLoadPropsFile(baseDir, moduleProps, moduleId);
} else if (moduleProps.containsKey(PROPERTY_PROJECT_CONFIG_FILE)) {
loadPropsFile(parentProject, moduleProps, moduleId);
} else {
File baseDir = new File(parentProject.getBaseDir(), moduleId);
setProjectBaseDir(baseDir, moduleProps, moduleId);
tryToFindAndLoadPropsFile(baseDir, moduleProps, moduleId);
}
// and finish
checkMandatoryProperties(moduleProps, MANDATORY_PROPERTIES_FOR_CHILD);
mergeParentProperties(moduleProps, parentProject.getProperties());
prefixProjectKeyWithParentKey(moduleProps, parentProject.getKey());
return defineProject(moduleProps, parentProject);
}
protected void loadPropsFile(ProjectDefinition parentProject, Properties moduleProps, String moduleId) {
File propertyFile = getFileFromPath(moduleProps.getProperty(PROPERTY_PROJECT_CONFIG_FILE), parentProject.getBaseDir());
if (propertyFile.isFile()) {
Properties propsFromFile = toProperties(propertyFile);
for (Entry
© 2015 - 2025 Weber Informatics LLC | Privacy Policy