diff options
author | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-04-09 02:19:28 +0400 |
---|---|---|
committer | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-04-26 13:00:11 +0400 |
commit | e174628696636f74808f61c76a44da994edcadc7 (patch) | |
tree | 06af7a9e94d17294cce72ddded48a84c8b2b3f1f | |
parent | 4eb630d0ff939898efdd9ef29330736ca4e50ebc (diff) | |
download | sonarqube-e174628696636f74808f61c76a44da994edcadc7.tar.gz sonarqube-e174628696636f74808f61c76a44da994edcadc7.zip |
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
22 files changed, 683 insertions, 541 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java index c9ef33368dc..5f0ace5847f 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java @@ -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"; diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectClasspath.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectClasspath.java new file mode 100644 index 00000000000..978acf4b5d5 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectClasspath.java @@ -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; + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java new file mode 100644 index 00000000000..82302af4973 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java @@ -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(); + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/InMemoryPomCreator.java b/sonar-batch/src/main/java/org/sonar/batch/InMemoryPomCreator.java deleted file mode 100644 index 73c79ad8548..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/InMemoryPomCreator.java +++ /dev/null @@ -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; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java index 0086f1015c0..48bc41730b0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java @@ -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) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java new file mode 100644 index 00000000000..450509870be --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java @@ -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); + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectFileSystem.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectFileSystem.java deleted file mode 100644 index 39ac4ad7c18..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectFileSystem.java +++ /dev/null @@ -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); - } - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenReactor.java b/sonar-batch/src/main/java/org/sonar/batch/MavenReactor.java deleted file mode 100644 index fff85d35e34..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/MavenReactor.java +++ /dev/null @@ -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; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java index 95355bc08ef..7a6ea61b454 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java @@ -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 diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java index ddae656f1d8..f89e9d644fa 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java @@ -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); } } - diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java index 4a03586a2e8..ac2db745ec3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java @@ -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"); } -}
\ No newline at end of file + + 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(); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java index b632feb60ac..907f30940ac 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java @@ -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; } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java b/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java index 49560b6126e..ab6c9915123 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPluginsConfigurator.java @@ -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); + } } } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/InMemoryPomCreatorTest.java b/sonar-batch/src/test/java/org/sonar/batch/InMemoryPomCreatorTest.java deleted file mode 100644 index e7787f5e05b..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/InMemoryPomCreatorTest.java +++ /dev/null @@ -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(); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java new file mode 100644 index 00000000000..c9a2c4124fb --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java @@ -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")); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java index ef3b087ffac..c494dfb02bc 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java @@ -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 { diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/ProjectDefinitionTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/ProjectDefinitionTest.java new file mode 100644 index 00000000000..df584f312b6 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrapper/ProjectDefinitionTest.java @@ -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])); + } + } +} diff --git a/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java b/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java index 075dfe9110a..f979a24944d 100644 --- a/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java +++ b/sonar-core-maven-plugin/src/main/java/org/sonar/maven2/BatchMojo.java @@ -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, diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java index ab0123210f5..eb57053ba8a 100644 --- a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java +++ b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java @@ -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, diff --git a/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java b/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java index baca606b874..7bb5e3e5f69 100644 --- a/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java +++ b/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java @@ -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, diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java index 9fffa244dbf..130ad3c29fe 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java @@ -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; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java index 9670a437af9..6b3737ac39d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java @@ -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; |