mirror of
https://github.com/SonarSource/sonarqube.git
synced 2024-08-03 08:18:00 +02:00
SONAR-2298 Add support for multi-modules for non-Maven projects
* Use ProjectDefinition in ProjectTree instead of MavenProject * Allow to specify extensions for project's container via ProjectDefinition, so MavenProject not passed directly to batch in mojos * ProjectDefinition should store all information in properties * Replace DefaultProjectFileSystem by DefaultProjectFileSystem2, which works not only for Maven projects * Add DefaultProjectClasspath, which works not only for Maven projects * Enable ProjectLinksSensor only for Maven
This commit is contained in:
parent
4eb630d0ff
commit
e174628696
@ -26,9 +26,11 @@ import org.apache.maven.model.Scm;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.batch.Sensor;
|
||||
import org.sonar.api.batch.SensorContext;
|
||||
import org.sonar.api.batch.SupportedEnvironment;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.ProjectLink;
|
||||
|
||||
@SupportedEnvironment("maven")
|
||||
public class ProjectLinksSensor implements Sensor {
|
||||
|
||||
public static final String KEY_HOME = "homepage";
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.batch.ProjectClasspath;
|
||||
import org.sonar.api.resources.ProjectFileSystem;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultProjectClasspath extends ProjectClasspath {
|
||||
|
||||
private ProjectDefinition def;
|
||||
private ProjectFileSystem projectFileSystem;
|
||||
|
||||
public DefaultProjectClasspath(ProjectDefinition def, ProjectFileSystem projectFileSystem) {
|
||||
this(def, projectFileSystem, null);
|
||||
}
|
||||
|
||||
public DefaultProjectClasspath(ProjectDefinition def, ProjectFileSystem projectFileSystem, MavenProject pom) {
|
||||
super(pom);
|
||||
this.def = def;
|
||||
this.projectFileSystem = projectFileSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<File> createElements() {
|
||||
if (pom != null) {
|
||||
return super.createElements();
|
||||
} else {
|
||||
List<File> elements = Lists.newArrayList();
|
||||
for (String path : def.getBinaries()) {
|
||||
elements.add(projectFileSystem.resolvePath(path));
|
||||
}
|
||||
for (String path : def.getLibraries()) {
|
||||
elements.add(projectFileSystem.resolvePath(path));
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.resources.DefaultProjectFileSystem;
|
||||
import org.sonar.api.resources.Languages;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.ProjectFileSystem;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ProjectFileSystem} based on {@link ProjectDefinition} and {@link MavenProject}.
|
||||
*/
|
||||
public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
|
||||
|
||||
private ProjectDefinition def;
|
||||
private MavenProject pom;
|
||||
|
||||
public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def) {
|
||||
super(project, languages);
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
/**
|
||||
* For Maven.
|
||||
*/
|
||||
public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom) {
|
||||
this(project, languages, def);
|
||||
this.pom = pom;
|
||||
}
|
||||
|
||||
public File getBasedir() {
|
||||
if (pom != null) {
|
||||
return pom.getBasedir();
|
||||
} else {
|
||||
return def.getBaseDir();
|
||||
}
|
||||
}
|
||||
|
||||
public File getBuildDir() {
|
||||
if (pom != null) {
|
||||
return resolvePath(pom.getBuild().getDirectory());
|
||||
} else {
|
||||
// TODO workaround
|
||||
return new File(getSonarWorkingDirectory(), "target");
|
||||
}
|
||||
}
|
||||
|
||||
public File getBuildOutputDir() {
|
||||
if (pom != null) {
|
||||
return resolvePath(pom.getBuild().getOutputDirectory());
|
||||
} else {
|
||||
if (def.getBinaries().isEmpty()) {
|
||||
// workaround for IndexOutOfBoundsException
|
||||
return new File(getBuildDir(), "classes");
|
||||
}
|
||||
// TODO we assume that there is only one directory which contains compiled code
|
||||
return resolvePath(def.getBinaries().get(0));
|
||||
}
|
||||
}
|
||||
|
||||
public List<File> getSourceDirs() {
|
||||
if (pom != null) {
|
||||
// Maven can modify source directories during Sonar execution - see MavenPhaseExecutor.
|
||||
return resolvePaths(pom.getCompileSourceRoots());
|
||||
} else {
|
||||
return resolvePaths(def.getSourceDirs());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.6, because should be immutable
|
||||
*/
|
||||
@Deprecated
|
||||
public DefaultProjectFileSystem addSourceDir(File dir) {
|
||||
if (dir == null) {
|
||||
throw new IllegalArgumentException("Can not add null to project source dirs");
|
||||
}
|
||||
if (pom != null) {
|
||||
pom.getCompileSourceRoots().add(0, dir.getAbsolutePath());
|
||||
} else {
|
||||
def.addSourceDir(dir.getAbsolutePath());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
|
||||
*/
|
||||
public List<File> getTestDirs() {
|
||||
if (pom != null) {
|
||||
// Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
|
||||
return resolvePaths(pom.getTestCompileSourceRoots());
|
||||
} else {
|
||||
return resolvePaths(def.getTestDirs());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.6, because should be immutable
|
||||
*/
|
||||
@Deprecated
|
||||
public DefaultProjectFileSystem addTestDir(File dir) {
|
||||
if (dir == null) {
|
||||
throw new IllegalArgumentException("Can not add null to project test dirs");
|
||||
}
|
||||
if (pom != null) {
|
||||
pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
|
||||
} else {
|
||||
def.addTestDir(dir.getAbsolutePath());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO Godin: seems that used only by Cobertura and Clover
|
||||
*/
|
||||
public File getReportOutputDir() {
|
||||
if (pom != null) {
|
||||
return resolvePath(pom.getReporting().getOutputDirectory());
|
||||
} else {
|
||||
return new File(getBuildDir(), "site");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getSonarWorkingDirectory() {
|
||||
if (pom != null) {
|
||||
try {
|
||||
File dir = new File(getBuildDir(), "sonar");
|
||||
FileUtils.forceMkdir(dir);
|
||||
return dir;
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new SonarException("Unable to retrieve Sonar working directory.", e);
|
||||
}
|
||||
} else {
|
||||
return def.getWorkDir();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.maven.artifact.DependencyResolutionRequiredException;
|
||||
import org.apache.maven.model.Reporting;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.CoreProperties;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* This is a dirty hack for for non-Maven environments,
|
||||
* which allows to create {@link MavenProject} based on {@link ProjectDefinition}.
|
||||
*/
|
||||
public class InMemoryPomCreator {
|
||||
|
||||
private ProjectDefinition project;
|
||||
|
||||
public InMemoryPomCreator(ProjectDefinition project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public MavenProject create() {
|
||||
File workDir = project.getWorkDir();
|
||||
String buildDirectory = workDir.getAbsolutePath() + "/target";
|
||||
Properties properties = project.getProperties();
|
||||
|
||||
if (project.getBinaries().size() == 0) {
|
||||
project.addBinaryDir(buildDirectory + "/classes");
|
||||
}
|
||||
|
||||
final MavenProject pom = new MavenProject() {
|
||||
/**
|
||||
* This allows to specify base directory without specifying location of a pom.xml
|
||||
*/
|
||||
@Override
|
||||
public File getBasedir() {
|
||||
return project.getBaseDir();
|
||||
};
|
||||
|
||||
/**
|
||||
* This allows to specify project classpath (binaries + libraries).
|
||||
*/
|
||||
@Override
|
||||
public List<String> getCompileClasspathElements() throws DependencyResolutionRequiredException {
|
||||
List<String> cp = new ArrayList<String>();
|
||||
cp.addAll(project.getBinaries());
|
||||
cp.addAll(project.getLibraries());
|
||||
return cp;
|
||||
}
|
||||
};
|
||||
|
||||
String key = getPropertyOrDie(properties, CoreProperties.PROJECT_KEY_PROPERTY);
|
||||
String[] keys = key.split(":");
|
||||
pom.setGroupId(keys[0]);
|
||||
pom.setArtifactId(keys[1]);
|
||||
pom.setVersion(getPropertyOrDie(properties, CoreProperties.PROJECT_VERSION_PROPERTY));
|
||||
|
||||
pom.setName(properties.getProperty(CoreProperties.PROJECT_NAME_PROPERTY, "Unnamed - " + key));
|
||||
pom.setDescription(properties.getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, ""));
|
||||
|
||||
pom.getModel().setProperties(properties);
|
||||
|
||||
pom.setArtifacts(Collections.EMPTY_SET);
|
||||
|
||||
// Configure fake directories
|
||||
pom.getBuild().setDirectory(buildDirectory);
|
||||
pom.getBuild().setOutputDirectory(project.getBinaries().get(0));
|
||||
Reporting reporting = new Reporting();
|
||||
String reportingOutputDirectory = buildDirectory + "/site";
|
||||
reporting.setOutputDirectory(reportingOutputDirectory);
|
||||
pom.setReporting(reporting);
|
||||
|
||||
// Configure source directories
|
||||
for (String dir : project.getSourceDirs()) {
|
||||
pom.addCompileSourceRoot(dir);
|
||||
}
|
||||
|
||||
// Configure test directories
|
||||
for (String dir : project.getTestDirs()) {
|
||||
pom.addTestCompileSourceRoot(dir);
|
||||
}
|
||||
|
||||
return pom;
|
||||
}
|
||||
|
||||
private static String getPropertyOrDie(Properties properties, String key) {
|
||||
String value = properties.getProperty(key);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
throw new SonarException("Property '" + key + "' must be specified");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@ -19,14 +19,9 @@
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.configuration.*;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.time.DateUtils;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.CoreProperties;
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
import org.sonar.api.database.model.ResourceModel;
|
||||
@ -34,7 +29,14 @@ import org.sonar.api.database.model.Snapshot;
|
||||
import org.sonar.api.resources.Java;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
// TODO Godin: rename to ProjectBuilder ?
|
||||
public class MavenProjectBuilder {
|
||||
|
||||
private DatabaseSession databaseSession;
|
||||
@ -43,43 +45,55 @@ public class MavenProjectBuilder {
|
||||
this.databaseSession = databaseSession;
|
||||
}
|
||||
|
||||
public Project create(MavenProject pom) {
|
||||
Configuration configuration = getStartupConfiguration(pom);
|
||||
return new Project(loadProjectKey(pom), loadProjectBranch(configuration), pom.getName())
|
||||
.setPom(pom)
|
||||
.setDescription(pom.getDescription())
|
||||
.setPackaging(pom.getPackaging());
|
||||
public Project create(ProjectDefinition project) {
|
||||
Configuration configuration = getStartupConfiguration(project);
|
||||
return new Project(loadProjectKey(project), loadProjectBranch(configuration), loadProjectName(project))
|
||||
.setDescription(project.getProperties().getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY))
|
||||
.setPackaging("jar"); // FIXME http://jira.codehaus.org/browse/SONAR-2341
|
||||
}
|
||||
|
||||
Configuration getStartupConfiguration(MavenProject pom) {
|
||||
Configuration getStartupConfiguration(ProjectDefinition project) {
|
||||
CompositeConfiguration configuration = new CompositeConfiguration();
|
||||
configuration.addConfiguration(new SystemConfiguration());
|
||||
configuration.addConfiguration(new EnvironmentConfiguration());
|
||||
configuration.addConfiguration(new MapConfiguration(pom.getModel().getProperties()));
|
||||
configuration.addConfiguration(new MapConfiguration(project.getProperties()));
|
||||
return configuration;
|
||||
}
|
||||
|
||||
String loadProjectKey(MavenProject pom) {
|
||||
return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString();
|
||||
private String getPropertyOrDie(ProjectDefinition project, String key) {
|
||||
String value = project.getProperties().getProperty(key);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
throw new SonarException("Property '" + key + "' must be specified");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
String loadProjectKey(ProjectDefinition projectDefinition) {
|
||||
return getPropertyOrDie(projectDefinition, CoreProperties.PROJECT_KEY_PROPERTY);
|
||||
}
|
||||
|
||||
String loadProjectName(ProjectDefinition projectDefinition) {
|
||||
return projectDefinition.getProperties().getProperty(
|
||||
CoreProperties.PROJECT_NAME_PROPERTY,
|
||||
"Unnamed - " + loadProjectKey(projectDefinition));
|
||||
}
|
||||
|
||||
String loadProjectBranch(Configuration configuration) {
|
||||
return configuration.getString(CoreProperties.PROJECT_BRANCH_PROPERTY, configuration.getString("branch" /* deprecated property */));
|
||||
}
|
||||
|
||||
public void configure(Project project) {
|
||||
ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project);
|
||||
public void configure(Project project, ProjectDefinition def) {
|
||||
ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project, def.getProperties());
|
||||
configure(project, projectConfiguration);
|
||||
}
|
||||
|
||||
void configure(Project project, Configuration projectConfiguration) {
|
||||
Date analysisDate = loadAnalysisDate(projectConfiguration);
|
||||
MavenProject pom = project.getPom();
|
||||
project.setConfiguration(projectConfiguration)
|
||||
.setExclusionPatterns(loadExclusionPatterns(projectConfiguration))
|
||||
.setAnalysisDate(analysisDate)
|
||||
.setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate))
|
||||
.setAnalysisVersion(loadAnalysisVersion(projectConfiguration, pom))
|
||||
.setAnalysisVersion(loadAnalysisVersion(projectConfiguration))
|
||||
.setAnalysisType(loadAnalysisType(projectConfiguration))
|
||||
.setLanguageKey(loadLanguageKey(projectConfiguration));
|
||||
}
|
||||
@ -133,12 +147,8 @@ public class MavenProjectBuilder {
|
||||
return Project.AnalysisType.STATIC;
|
||||
}
|
||||
|
||||
String loadAnalysisVersion(Configuration configuration, MavenProject pom) {
|
||||
String version = configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY);
|
||||
if (version == null && pom != null) {
|
||||
version = pom.getVersion();
|
||||
}
|
||||
return version;
|
||||
String loadAnalysisVersion(Configuration configuration) {
|
||||
return configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY);
|
||||
}
|
||||
|
||||
String loadLanguageKey(Configuration configuration) {
|
||||
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.CoreProperties;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenProjectConverter {
|
||||
|
||||
private MavenProjectConverter() {
|
||||
}
|
||||
|
||||
public static ProjectDefinition convert(List<MavenProject> poms) {
|
||||
Map<String, MavenProject> paths = Maps.newHashMap(); // projects by canonical path
|
||||
Map<MavenProject, ProjectDefinition> defs = Maps.newHashMap();
|
||||
|
||||
try {
|
||||
for (MavenProject pom : poms) {
|
||||
String basedir = pom.getBasedir().getCanonicalPath();
|
||||
paths.put(basedir, pom);
|
||||
defs.put(pom, convert(pom));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, MavenProject> entry : paths.entrySet()) {
|
||||
MavenProject pom = entry.getValue();
|
||||
for (Object moduleId : pom.getModules()) {
|
||||
File modulePath = new File(pom.getBasedir(), (String) moduleId);
|
||||
MavenProject module = paths.get(modulePath.getCanonicalPath());
|
||||
defs.get(pom).addModule(defs.get(module));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new SonarException(e);
|
||||
}
|
||||
|
||||
return defs.get(poms.get(0));
|
||||
}
|
||||
|
||||
public static ProjectDefinition convert(MavenProject pom) {
|
||||
Properties properties = new Properties();
|
||||
|
||||
String key = new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString();
|
||||
setProperty(properties, CoreProperties.PROJECT_KEY_PROPERTY, key);
|
||||
setProperty(properties, CoreProperties.PROJECT_VERSION_PROPERTY, pom.getVersion());
|
||||
setProperty(properties, CoreProperties.PROJECT_NAME_PROPERTY, pom.getName());
|
||||
setProperty(properties, CoreProperties.PROJECT_DESCRIPTION_PROPERTY, pom.getDescription());
|
||||
properties.putAll(pom.getModel().getProperties());
|
||||
|
||||
ProjectDefinition def = new ProjectDefinition(pom.getBasedir(), null, properties); // TODO work directory ?
|
||||
def.addContainerExtension(pom);
|
||||
return def;
|
||||
}
|
||||
|
||||
private static void setProperty(Properties properties, String key, String value) {
|
||||
if (value != null) {
|
||||
properties.setProperty(key, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.resources.DefaultProjectFileSystem;
|
||||
import org.sonar.api.resources.Languages;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.ProjectFileSystem;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ProjectFileSystem} based on {@link MavenProject}.
|
||||
*/
|
||||
public class MavenProjectFileSystem extends DefaultProjectFileSystem {
|
||||
|
||||
private MavenProject pom;
|
||||
|
||||
public MavenProjectFileSystem(Project project, Languages languages) {
|
||||
super(project, languages);
|
||||
this.pom = project.getPom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getBasedir() {
|
||||
return pom.getBasedir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getBuildDir() {
|
||||
return resolvePath(pom.getBuild().getDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getBuildOutputDir() {
|
||||
return resolvePath(pom.getBuild().getOutputDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Maven can modify source directories during Sonar execution - see MavenPhaseExecutor.
|
||||
*/
|
||||
@Override
|
||||
public List<File> getSourceDirs() {
|
||||
return resolvePaths(pom.getCompileSourceRoots());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultProjectFileSystem addSourceDir(File dir) {
|
||||
if (dir == null) {
|
||||
throw new IllegalArgumentException("Can not add null to project source dirs");
|
||||
}
|
||||
pom.getCompileSourceRoots().add(0, dir.getAbsolutePath());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
|
||||
*/
|
||||
@Override
|
||||
public List<File> getTestDirs() {
|
||||
return resolvePaths(pom.getTestCompileSourceRoots());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.6, because should be immutable
|
||||
*/
|
||||
@Override
|
||||
public DefaultProjectFileSystem addTestDir(File dir) {
|
||||
if (dir == null) {
|
||||
throw new IllegalArgumentException("Can not add null to project test dirs");
|
||||
}
|
||||
pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getReportOutputDir() {
|
||||
return resolvePath(pom.getReporting().getOutputDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getSonarWorkingDirectory() {
|
||||
try {
|
||||
File dir = new File(getBuildDir(), "sonar");
|
||||
FileUtils.forceMkdir(dir);
|
||||
return dir;
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new SonarException("Unable to retrieve Sonar working directory.", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MavenReactor {
|
||||
|
||||
private List<MavenProject> sortedProjects;
|
||||
|
||||
public MavenReactor(MavenSession mavenSession) {
|
||||
this.sortedProjects = mavenSession.getSortedProjects();
|
||||
}
|
||||
|
||||
public MavenReactor(List<MavenProject> sortedProjects) {
|
||||
this.sortedProjects = sortedProjects;
|
||||
}
|
||||
|
||||
public List<MavenProject> getSortedProjects() {
|
||||
return sortedProjects;
|
||||
}
|
||||
|
||||
}
|
@ -19,8 +19,8 @@
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.batch.BatchExtensionDictionnary;
|
||||
import org.sonar.api.batch.ProjectClasspath;
|
||||
import org.sonar.api.measures.CoreMetrics;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.measures.Metrics;
|
||||
@ -32,6 +32,7 @@ import org.sonar.api.resources.ProjectFileSystem;
|
||||
import org.sonar.api.rules.DefaultRulesManager;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.bootstrap.BatchPluginRepository;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
import org.sonar.batch.components.PastViolationsLoader;
|
||||
import org.sonar.batch.components.TimeMachineConfiguration;
|
||||
import org.sonar.batch.events.EventBus;
|
||||
@ -103,10 +104,21 @@ public class ProjectBatch {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
ProjectDefinition projectDefinition = getComponent(ProjectTree.class).getProjectDefinition(project.getKey());
|
||||
addComponent(projectDefinition);
|
||||
for (Object component : projectDefinition.getContainerExtensions()) {
|
||||
addComponent(component);
|
||||
if (component instanceof MavenProject) {
|
||||
// For backward compatibility we must set POM and actual packaging
|
||||
MavenProject pom = (MavenProject) component;
|
||||
project.setPom(pom);
|
||||
project.setPackaging(pom.getPackaging());
|
||||
}
|
||||
}
|
||||
|
||||
addComponent(project);
|
||||
addComponent(project.getPom());
|
||||
addComponent(ProjectClasspath.class);
|
||||
addComponent(MavenProjectFileSystem.class);
|
||||
addComponent(DefaultProjectClasspath.class);
|
||||
addComponent(DefaultProjectFileSystem2.class);
|
||||
addComponent(project.getConfiguration());
|
||||
|
||||
// need to be registered after the Configuration
|
||||
|
@ -20,20 +20,26 @@
|
||||
package org.sonar.batch;
|
||||
|
||||
import org.apache.commons.configuration.*;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
import org.sonar.api.resources.Project;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class ProjectConfiguration extends CompositeConfiguration {
|
||||
private PropertiesConfiguration runtimeConfiguration;
|
||||
|
||||
// FIXME remove
|
||||
public ProjectConfiguration(DatabaseSession session, Project project) {
|
||||
this(session, project, project.getPom().getProperties());
|
||||
}
|
||||
|
||||
public ProjectConfiguration(DatabaseSession session, Project project, Properties properties) {
|
||||
runtimeConfiguration = new PropertiesConfiguration();
|
||||
addConfiguration(runtimeConfiguration);
|
||||
|
||||
loadSystemSettings();
|
||||
loadProjectDatabaseSettings(session, project);
|
||||
loadMavenSettings(project.getPom());
|
||||
addConfiguration(new MapConfiguration(properties));
|
||||
loadGlobalDatabaseSettings(session);
|
||||
}
|
||||
|
||||
@ -56,13 +62,8 @@ public class ProjectConfiguration extends CompositeConfiguration {
|
||||
addConfiguration(new EnvironmentConfiguration());
|
||||
}
|
||||
|
||||
private void loadMavenSettings(MavenProject pom) {
|
||||
addConfiguration(new MapConfiguration(pom.getModel().getProperties()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String s, Object o) {
|
||||
runtimeConfiguration.setProperty(s, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,42 +21,30 @@ package org.sonar.batch;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonar.api.CoreProperties;
|
||||
import org.sonar.api.database.DatabaseSession;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
import org.sonar.batch.bootstrapper.Reactor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class ProjectTree {
|
||||
|
||||
private List<Project> projects;
|
||||
private List<MavenProject> poms;
|
||||
private MavenProjectBuilder projectBuilder;
|
||||
private List<ProjectDefinition> definitions;
|
||||
|
||||
public ProjectTree(MavenReactor mavenReactor, DatabaseSession databaseSession) {
|
||||
this.poms = mavenReactor.getSortedProjects();
|
||||
this.projectBuilder = new MavenProjectBuilder(databaseSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hack for non-Maven environments.
|
||||
*/
|
||||
public ProjectTree(Reactor sonarReactor, DatabaseSession databaseSession) {
|
||||
this(createMavenReactor(sonarReactor), databaseSession);
|
||||
}
|
||||
|
||||
private static MavenReactor createMavenReactor(Reactor sonarReactor) {
|
||||
List<ProjectDefinition> sonarProjects = sonarReactor.getSortedProjects();
|
||||
List<MavenProject> mavenProjects = Lists.newArrayList();
|
||||
for (ProjectDefinition project : sonarProjects) {
|
||||
mavenProjects.add(new InMemoryPomCreator(project).create());
|
||||
this.projectBuilder = new MavenProjectBuilder(databaseSession);
|
||||
definitions = Lists.newArrayList();
|
||||
for (ProjectDefinition project : sonarReactor.getSortedProjects()) {
|
||||
collectProjects(project, definitions);
|
||||
}
|
||||
return new MavenReactor(mavenProjects);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +52,8 @@ public class ProjectTree {
|
||||
*/
|
||||
protected ProjectTree(MavenProjectBuilder projectBuilder, List<MavenProject> poms) {
|
||||
this.projectBuilder = projectBuilder;
|
||||
this.poms = poms;
|
||||
definitions = Lists.newArrayList();
|
||||
collectProjects(MavenProjectConverter.convert(poms), definitions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,36 +63,40 @@ public class ProjectTree {
|
||||
this.projects = new ArrayList<Project>(projects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates list of projects from hierarchy.
|
||||
*/
|
||||
private static void collectProjects(ProjectDefinition root, List<ProjectDefinition> collected) {
|
||||
collected.add(root);
|
||||
for (ProjectDefinition module : root.getModules()) {
|
||||
collectProjects(module, collected);
|
||||
}
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
projects = Lists.newArrayList();
|
||||
Map<String, Project> paths = Maps.newHashMap(); // projects by canonical path
|
||||
Map<ProjectDefinition, Project> map = Maps.newHashMap();
|
||||
|
||||
for (MavenProject pom : poms) {
|
||||
Project project = projectBuilder.create(pom);
|
||||
for (ProjectDefinition def : definitions) {
|
||||
Project project = projectBuilder.create(def);
|
||||
map.put(def, project);
|
||||
projects.add(project);
|
||||
paths.put(pom.getBasedir().getCanonicalPath(), project);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Project> entry : paths.entrySet()) {
|
||||
for (Map.Entry<ProjectDefinition, Project> entry : map.entrySet()) {
|
||||
ProjectDefinition def = entry.getKey();
|
||||
Project project = entry.getValue();
|
||||
MavenProject pom = project.getPom();
|
||||
for (Object moduleId : pom.getModules()) {
|
||||
File modulePath = new File(pom.getBasedir(), (String) moduleId);
|
||||
Project module = paths.get(modulePath.getCanonicalPath());
|
||||
if (module != null) {
|
||||
module.setParent(project);
|
||||
}
|
||||
for (ProjectDefinition module : def.getModules()) {
|
||||
map.get(module).setParent(project);
|
||||
}
|
||||
}
|
||||
|
||||
configureProjects();
|
||||
applyModuleExclusions();
|
||||
}
|
||||
|
||||
private void configureProjects() {
|
||||
for (Project project : projects) {
|
||||
projectBuilder.configure(project);
|
||||
// Configure
|
||||
for (Map.Entry<ProjectDefinition, Project> entry : map.entrySet()) {
|
||||
projectBuilder.configure(entry.getValue(), entry.getKey());
|
||||
}
|
||||
|
||||
applyModuleExclusions();
|
||||
}
|
||||
|
||||
void applyModuleExclusions() {
|
||||
@ -125,7 +118,7 @@ public class ProjectTree {
|
||||
|
||||
if (!includedModulesIdSet.isEmpty()) {
|
||||
for (Project currentProject : projects) {
|
||||
if (!includedModulesIdSet.contains(currentProject.getPom().getArtifactId())) {
|
||||
if (!includedModulesIdSet.contains(getArtifactId(currentProject))) {
|
||||
exclude(currentProject);
|
||||
}
|
||||
}
|
||||
@ -160,9 +153,19 @@ public class ProjectTree {
|
||||
return projects;
|
||||
}
|
||||
|
||||
private String getArtifactId(Project project) {
|
||||
String key = project.getKey();
|
||||
if (StringUtils.isNotBlank(project.getBranch())) {
|
||||
// remove branch part
|
||||
key = StringUtils.removeEnd(project.getKey(), ":" + project.getBranch());
|
||||
}
|
||||
return StringUtils.substringAfterLast(key, ":");
|
||||
}
|
||||
|
||||
public Project getProjectByArtifactId(String artifactId) {
|
||||
for (Project project : projects) {
|
||||
if (project.getPom().getArtifactId().equals(artifactId)) {
|
||||
// TODO see http://jira.codehaus.org/browse/SONAR-2324
|
||||
if (StringUtils.equals(getArtifactId(project), artifactId)) {
|
||||
return project;
|
||||
}
|
||||
}
|
||||
@ -177,4 +180,27 @@ public class ProjectTree {
|
||||
}
|
||||
throw new IllegalStateException("Can not find the root project from the list of Maven modules");
|
||||
}
|
||||
}
|
||||
|
||||
private String getProjectKey(ProjectDefinition def) {
|
||||
String key = def.getProperties().getProperty(CoreProperties.PROJECT_KEY_PROPERTY);
|
||||
String branch = def.getProperties().getProperty(CoreProperties.PROJECT_BRANCH_PROPERTY);
|
||||
if (StringUtils.isNotBlank(branch)) {
|
||||
return key + ":" + branch;
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public ProjectDefinition getProjectDefinition(String key) {
|
||||
for (ProjectDefinition def : definitions) {
|
||||
if (StringUtils.equals(key, getProjectKey(def))) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Object> getProjectExtensions(String key) {
|
||||
return getProjectDefinition(key).getContainerExtensions();
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,14 @@
|
||||
*/
|
||||
package org.sonar.batch.bootstrapper;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Describes project in a form suitable to bootstrap Sonar batch.
|
||||
* We assume that project is just a set of configuration properties and directories.
|
||||
@ -33,13 +35,19 @@ import com.google.common.collect.Lists;
|
||||
*/
|
||||
public class ProjectDefinition {
|
||||
|
||||
private static final String PROJECT_SOURCES_PROPERTY = "sonar.sources";
|
||||
private static final String PROJECT_TESTS_PROPERTY = "sonar.tests";
|
||||
private static final String PROJECT_BINARIES_PROPERTY = "sonar.binaries";
|
||||
private static final String PROJECT_LIBRARIES_PROPERTY = "sonar.libraries";
|
||||
|
||||
private static final char SEPARATOR = ',';
|
||||
|
||||
private File baseDir;
|
||||
private File workDir;
|
||||
private Properties properties;
|
||||
private List<String> sourceDirs = Lists.newArrayList();
|
||||
private List<String> testDirs = Lists.newArrayList();
|
||||
private List<String> binaries = Lists.newArrayList();
|
||||
private List<String> libraries = Lists.newArrayList();
|
||||
private List<ProjectDefinition> modules = Lists.newArrayList();
|
||||
|
||||
private List<Object> containerExtensions = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* @param baseDir project base directory
|
||||
@ -63,8 +71,14 @@ public class ProjectDefinition {
|
||||
return properties;
|
||||
}
|
||||
|
||||
private void appendProperty(String key, String value) {
|
||||
String newValue = properties.getProperty(key, "") + SEPARATOR + value;
|
||||
properties.put(key, newValue);
|
||||
}
|
||||
|
||||
public List<String> getSourceDirs() {
|
||||
return sourceDirs;
|
||||
String sources = properties.getProperty(PROJECT_SOURCES_PROPERTY, "");
|
||||
return Arrays.asList(StringUtils.split(sources, SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,11 +86,12 @@ public class ProjectDefinition {
|
||||
* It can be absolute or relative to project directory.
|
||||
*/
|
||||
public void addSourceDir(String path) {
|
||||
sourceDirs.add(path);
|
||||
appendProperty(PROJECT_SOURCES_PROPERTY, path);
|
||||
}
|
||||
|
||||
public List<String> getTestDirs() {
|
||||
return testDirs;
|
||||
String sources = properties.getProperty(PROJECT_TESTS_PROPERTY, "");
|
||||
return Arrays.asList(StringUtils.split(sources, SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,11 +99,12 @@ public class ProjectDefinition {
|
||||
* It can be absolute or relative to project directory.
|
||||
*/
|
||||
public void addTestDir(String path) {
|
||||
testDirs.add(path);
|
||||
appendProperty(PROJECT_TESTS_PROPERTY, path);
|
||||
}
|
||||
|
||||
public List<String> getBinaries() {
|
||||
return binaries;
|
||||
String sources = properties.getProperty(PROJECT_BINARIES_PROPERTY, "");
|
||||
return Arrays.asList(StringUtils.split(sources, SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,11 +113,12 @@ public class ProjectDefinition {
|
||||
* @TODO currently Sonar supports only one such directory due to dependency on MavenProject
|
||||
*/
|
||||
public void addBinaryDir(String path) {
|
||||
binaries.add(path);
|
||||
appendProperty(PROJECT_BINARIES_PROPERTY, path);
|
||||
}
|
||||
|
||||
public List<String> getLibraries() {
|
||||
return libraries;
|
||||
String sources = properties.getProperty(PROJECT_LIBRARIES_PROPERTY, "");
|
||||
return Arrays.asList(StringUtils.split(sources, SEPARATOR));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,6 +126,36 @@ public class ProjectDefinition {
|
||||
* It can be absolute or relative to project directory.
|
||||
*/
|
||||
public void addLibrary(String path) {
|
||||
libraries.add(path);
|
||||
appendProperty(PROJECT_LIBRARIES_PROPERTY, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an extension, which would be available in PicoContainer during analysis of this project.
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public void addContainerExtension(Object extension) {
|
||||
containerExtensions.add(extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8
|
||||
*/
|
||||
public List<Object> getContainerExtensions() {
|
||||
return containerExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8
|
||||
*/
|
||||
public void addModule(ProjectDefinition projectDefinition) {
|
||||
modules.add(projectDefinition);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8
|
||||
*/
|
||||
public List<ProjectDefinition> getModules() {
|
||||
return modules;
|
||||
}
|
||||
}
|
||||
|
@ -60,16 +60,18 @@ public class MavenPluginsConfigurator implements BatchComponent {
|
||||
|
||||
protected void savePom(Project project) {
|
||||
MavenProject pom = project.getPom();
|
||||
File targetPom = new File(project.getFileSystem().getSonarWorkingDirectory(), "sonar-pom.xml");
|
||||
FileWriter fileWriter = null;
|
||||
try {
|
||||
fileWriter = new FileWriter(targetPom, false);
|
||||
pom.writeModel(fileWriter);
|
||||
if (pom != null) {
|
||||
File targetPom = new File(project.getFileSystem().getSonarWorkingDirectory(), "sonar-pom.xml");
|
||||
FileWriter fileWriter = null;
|
||||
try {
|
||||
fileWriter = new FileWriter(targetPom, false);
|
||||
pom.writeModel(fileWriter);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new SonarException("Can not save pom to " + targetPom, e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(fileWriter);
|
||||
} catch (IOException e) {
|
||||
throw new SonarException("Can not save pom to " + targetPom, e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(fileWriter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.CoreProperties;
|
||||
import org.sonar.api.utils.SonarException;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class InMemoryPomCreatorTest {
|
||||
|
||||
private Properties properties;
|
||||
private ProjectDefinition project;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
properties = new Properties();
|
||||
File baseDir = new File(".");
|
||||
File workDir = new File(baseDir, "sonar");
|
||||
project = new ProjectDefinition(baseDir, workDir, properties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minimal() {
|
||||
createRequiredProperties();
|
||||
|
||||
MavenProject pom = create();
|
||||
|
||||
assertThat(pom.getBasedir(), is(project.getBaseDir()));
|
||||
assertThat(pom.getGroupId(), is("org.example"));
|
||||
assertThat(pom.getArtifactId(), is("example"));
|
||||
assertThat(pom.getName(), is("Unnamed - org.example:example"));
|
||||
assertThat(pom.getDescription(), is(""));
|
||||
assertThat(pom.getProperties(), is(project.getProperties()));
|
||||
assertThat(pom.getBasedir(), is(project.getBaseDir()));
|
||||
String buildDirectory = project.getWorkDir().getAbsolutePath() + "/target";
|
||||
assertThat(pom.getBuild().getDirectory(), is(buildDirectory));
|
||||
assertThat(pom.getBuild().getOutputDirectory(), is(buildDirectory + "/classes"));
|
||||
assertThat(pom.getReporting().getOutputDirectory(), is(buildDirectory + "/site"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameAndDescription() {
|
||||
createRequiredProperties();
|
||||
|
||||
properties.setProperty(CoreProperties.PROJECT_NAME_PROPERTY, "Foo");
|
||||
properties.setProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, "Bar");
|
||||
|
||||
MavenProject pom = create();
|
||||
|
||||
assertThat(pom.getName(), is("Foo"));
|
||||
assertThat(pom.getDescription(), is("Bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceDirectories() {
|
||||
createRequiredProperties();
|
||||
project.addSourceDir("src");
|
||||
project.addTestDir("test");
|
||||
|
||||
MavenProject pom = create();
|
||||
|
||||
assertThat(pom.getCompileSourceRoots().size(), is(1));
|
||||
assertThat((String) pom.getCompileSourceRoots().get(0), is("src"));
|
||||
|
||||
assertThat(pom.getTestCompileSourceRoots().size(), is(1));
|
||||
assertThat((String) pom.getTestCompileSourceRoots().get(0), is("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classpath() throws Exception {
|
||||
createRequiredProperties();
|
||||
project.addBinaryDir("/classes");
|
||||
project.addLibrary("junit.jar");
|
||||
|
||||
MavenProject pom = create();
|
||||
|
||||
List<String> cp = pom.getCompileClasspathElements();
|
||||
assertThat(cp.size(), is(2));
|
||||
assertThat(cp.get(0), is("/classes"));
|
||||
assertThat(cp.get(1), is("junit.jar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotFailIfNoBinaries() throws Exception {
|
||||
createRequiredProperties();
|
||||
|
||||
MavenProject pom = create();
|
||||
assertThat(pom.getCompileClasspathElements().size(), is(1));
|
||||
}
|
||||
|
||||
private void createRequiredProperties() {
|
||||
properties.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "org.example:example");
|
||||
properties.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test(expected = SonarException.class)
|
||||
public void shouldFailWhenKeyNotSpecified() {
|
||||
create();
|
||||
}
|
||||
|
||||
@Test(expected = SonarException.class)
|
||||
public void shouldFailWhenVersionNotSpecified() {
|
||||
properties.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "org.example:example");
|
||||
create();
|
||||
}
|
||||
|
||||
private MavenProject create() {
|
||||
return new InMemoryPomCreator(project).create();
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.CoreProperties;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenProjectConverterTest {
|
||||
@Test
|
||||
public void test2() {
|
||||
MavenProject root = new MavenProject();
|
||||
root.setFile(new File("/foo/pom.xml"));
|
||||
root.getModules().add("module");
|
||||
MavenProject module = new MavenProject();
|
||||
module.setFile(new File("/foo/module/pom.xml"));
|
||||
ProjectDefinition project = MavenProjectConverter.convert(Arrays.asList(root, module));
|
||||
|
||||
assertThat(project.getModules().size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
MavenProject pom = new MavenProject();
|
||||
pom.setGroupId("foo");
|
||||
pom.setArtifactId("bar");
|
||||
pom.setVersion("1.0.1");
|
||||
pom.setName("Test");
|
||||
pom.setDescription("just test");
|
||||
ProjectDefinition project = MavenProjectConverter.convert(pom);
|
||||
|
||||
Properties properties = project.getProperties();
|
||||
assertThat(properties.getProperty(CoreProperties.PROJECT_KEY_PROPERTY), is("foo:bar"));
|
||||
assertThat(properties.getProperty(CoreProperties.PROJECT_VERSION_PROPERTY), is("1.0.1"));
|
||||
assertThat(properties.getProperty(CoreProperties.PROJECT_NAME_PROPERTY), is("Test"));
|
||||
assertThat(properties.getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY), is("just test"));
|
||||
}
|
||||
}
|
@ -19,6 +19,11 @@
|
||||
*/
|
||||
package org.sonar.batch;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
|
||||
|
||||
import org.apache.commons.configuration.PropertiesConfiguration;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.maven.model.Model;
|
||||
@ -26,8 +31,8 @@ import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
import org.junit.Test;
|
||||
import org.sonar.jpa.test.AbstractDbUnitTestCase;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.jpa.test.AbstractDbUnitTestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -35,12 +40,6 @@ import java.io.StringReader;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
|
||||
|
||||
|
||||
public class ProjectTreeTest extends AbstractDbUnitTestCase {
|
||||
|
||||
@Test
|
||||
@ -71,7 +70,6 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
|
||||
ProjectTree tree = new ProjectTree(newProjectBuilder(), Arrays.asList(parent, module1, module2));
|
||||
tree.start();
|
||||
|
||||
|
||||
Project root = tree.getRootProject();
|
||||
assertThat(root.getModules().size(), is(2));
|
||||
assertThat(root.getKey(), is("org.test:parent"));
|
||||
@ -105,7 +103,6 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
|
||||
assertThat(tree.getRootProject().getName(), is("Project BRANCH-1.X"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void keyIncludesDeprecatedBranch() throws IOException, XmlPullParserException, URISyntaxException {
|
||||
MavenProject pom = loadProject("/org/sonar/batch/ProjectTreeTest/keyIncludesDeprecatedBranch/pom.xml", true);
|
||||
@ -130,7 +127,7 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skipModule() {
|
||||
public void skipModule() throws IOException {
|
||||
Project root = newProjectWithArtifactId("root");
|
||||
root.getConfiguration().setProperty("sonar.skippedModules", "sub1");
|
||||
Project sub1 = newProjectWithArtifactId("sub1");
|
||||
@ -191,7 +188,7 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase {
|
||||
private Project newProjectWithArtifactId(String artifactId) {
|
||||
MavenProject pom = new MavenProject();
|
||||
pom.setArtifactId(artifactId);
|
||||
return new Project(artifactId).setPom(pom).setConfiguration(new PropertiesConfiguration());
|
||||
return new Project("org.example:" + artifactId).setPom(pom).setConfiguration(new PropertiesConfiguration());
|
||||
}
|
||||
|
||||
private MavenProject loadProject(String pomPath, boolean isRoot) throws URISyntaxException, IOException, XmlPullParserException {
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2011 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.batch.bootstrapper;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ProjectDefinitionTest {
|
||||
private ProjectDefinition def;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
def = new ProjectDefinition(new File("."), new File("."), new Properties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultValues() {
|
||||
assertThat(def.getSourceDirs().size(), is(0));
|
||||
assertThat(def.getTestDirs().size(), is(0));
|
||||
assertThat(def.getBinaries().size(), is(0));
|
||||
assertThat(def.getLibraries().size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddDirectories() {
|
||||
def.addSourceDir("src/main/java");
|
||||
def.addSourceDir("src/main/java2");
|
||||
def.addTestDir("src/test/java");
|
||||
def.addTestDir("src/test/java2");
|
||||
def.addBinaryDir("target/classes");
|
||||
def.addBinaryDir("target/classes2");
|
||||
def.addLibrary("junit.jar");
|
||||
def.addLibrary("mockito.jar");
|
||||
|
||||
assertDirs(def.getSourceDirs(), "src/main/java", "src/main/java2");
|
||||
assertDirs(def.getTestDirs(), "src/test/java", "src/test/java2");
|
||||
assertDirs(def.getBinaries(), "target/classes", "target/classes2");
|
||||
assertDirs(def.getLibraries(), "junit.jar", "mockito.jar");
|
||||
}
|
||||
|
||||
private static void assertDirs(List<String> dirs, String... values) {
|
||||
assertThat(dirs.size(), is(values.length));
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
assertThat(dirs.get(i), is(values[i]));
|
||||
}
|
||||
}
|
||||
}
|
@ -19,8 +19,6 @@
|
||||
*/
|
||||
package org.sonar.maven2;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||
import ch.qos.logback.core.joran.spi.JoranException;
|
||||
@ -42,8 +40,12 @@ import org.apache.maven.project.MavenProjectBuilder;
|
||||
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonar.batch.Batch;
|
||||
import org.sonar.batch.MavenReactor;
|
||||
import org.sonar.batch.MavenProjectConverter;
|
||||
import org.sonar.batch.bootstrapper.EnvironmentInformation;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
import org.sonar.batch.bootstrapper.Reactor;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @goal internal
|
||||
@ -143,7 +145,9 @@ public final class BatchMojo extends AbstractMojo {
|
||||
}
|
||||
|
||||
private void executeBatch() throws MojoExecutionException {
|
||||
MavenReactor reactor = new MavenReactor(session);
|
||||
ProjectDefinition def = MavenProjectConverter.convert(session.getSortedProjects());
|
||||
Reactor reactor = new Reactor(def);
|
||||
|
||||
Batch batch = new Batch(getInitialConfiguration(), reactor, session, project,
|
||||
getLog(), lifecycleExecutor, pluginManager, artifactFactory,
|
||||
localRepository, artifactMetadataSource, artifactCollector,
|
||||
|
@ -19,8 +19,6 @@
|
||||
*/
|
||||
package org.sonar.maven;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||
import ch.qos.logback.core.joran.spi.JoranException;
|
||||
@ -42,8 +40,12 @@ import org.apache.maven.project.MavenProjectBuilder;
|
||||
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonar.batch.Batch;
|
||||
import org.sonar.batch.MavenReactor;
|
||||
import org.sonar.batch.MavenProjectConverter;
|
||||
import org.sonar.batch.bootstrapper.EnvironmentInformation;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
import org.sonar.batch.bootstrapper.Reactor;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @goal sonar
|
||||
@ -143,7 +145,9 @@ public final class SonarMojo extends AbstractMojo {
|
||||
}
|
||||
|
||||
private void executeBatch() throws MojoExecutionException {
|
||||
MavenReactor reactor = new MavenReactor(session);
|
||||
ProjectDefinition def = MavenProjectConverter.convert(session.getSortedProjects());
|
||||
Reactor reactor = new Reactor(def);
|
||||
|
||||
Batch batch = new Batch(getInitialConfiguration(),
|
||||
reactor, session, project, getLog(), lifecycleExecutor, pluginManager, artifactFactory,
|
||||
localRepository, artifactMetadataSource, artifactCollector, dependencyTreeBuilder,
|
||||
|
@ -19,8 +19,6 @@
|
||||
*/
|
||||
package org.sonar.maven3;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||
import ch.qos.logback.core.joran.spi.JoranException;
|
||||
@ -41,8 +39,12 @@ import org.apache.maven.project.MavenProjectBuilder;
|
||||
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonar.batch.Batch;
|
||||
import org.sonar.batch.MavenReactor;
|
||||
import org.sonar.batch.MavenProjectConverter;
|
||||
import org.sonar.batch.bootstrapper.EnvironmentInformation;
|
||||
import org.sonar.batch.bootstrapper.ProjectDefinition;
|
||||
import org.sonar.batch.bootstrapper.Reactor;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @goal sonar
|
||||
@ -136,7 +138,9 @@ public final class SonarMojo extends AbstractMojo {
|
||||
}
|
||||
|
||||
private void executeBatch() throws MojoExecutionException {
|
||||
MavenReactor reactor = new MavenReactor(session);
|
||||
ProjectDefinition def = MavenProjectConverter.convert(session.getSortedProjects());
|
||||
Reactor reactor = new Reactor(def);
|
||||
|
||||
Batch batch = new Batch(getInitialConfiguration(),
|
||||
reactor, session, project, getLog(), lifecycleExecutor, artifactFactory,
|
||||
localRepository, artifactMetadataSource, artifactCollector, dependencyTreeBuilder,
|
||||
|
@ -36,7 +36,7 @@ import java.util.List;
|
||||
*/
|
||||
public class ProjectClasspath implements BatchComponent {
|
||||
|
||||
private MavenProject pom;
|
||||
protected MavenProject pom;
|
||||
private List<File> elements;
|
||||
private URLClassLoader classloader;
|
||||
|
||||
|
@ -43,8 +43,9 @@ import java.util.List;
|
||||
* For internal use only.
|
||||
*
|
||||
* @since 1.10
|
||||
* @TODO in fact this class should not be located in sonar-plugin-api
|
||||
* @deprecated in 2.8. In fact this class should not be located in sonar-plugin-api and most of the methods were overridden by a component in sonar-batch.
|
||||
*/
|
||||
@Deprecated
|
||||
public class DefaultProjectFileSystem implements ProjectFileSystem {
|
||||
|
||||
private Project project;
|
||||
|
Loading…
Reference in New Issue
Block a user