@@ -20,6 +20,7 @@ | |||
package org.sonar.batch; | |||
import org.apache.maven.project.MavenProject; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.MavenPlugin; | |||
import org.sonar.api.batch.maven.MavenPluginHandler; | |||
import org.sonar.api.resources.Project; | |||
@@ -31,11 +32,16 @@ import org.sonar.api.utils.TimeProfiler; | |||
*/ | |||
public abstract class AbstractMavenPluginExecutor implements MavenPluginExecutor { | |||
public final MavenPluginHandler execute(Project project, MavenPluginHandler handler) { | |||
public final MavenPluginHandler execute(Project project, ProjectDefinition projectDefinition, MavenPluginHandler handler) { | |||
for (String goal : handler.getGoals()) { | |||
MavenPlugin plugin = MavenPlugin.getPlugin(project.getPom(), handler.getGroupId(), handler.getArtifactId()); | |||
execute(project, getGoal(handler.getGroupId(), handler.getArtifactId(), plugin.getPlugin().getVersion(), goal)); | |||
execute(project, getGoal(handler.getGroupId(), handler.getArtifactId(), (plugin!=null && plugin.getPlugin()!=null ? plugin.getPlugin().getVersion() : null), goal)); | |||
} | |||
if (project.getPom()!=null) { | |||
MavenProjectConverter.synchronizeFileSystem(project.getPom(), projectDefinition); | |||
} | |||
return handler; | |||
} | |||
@@ -21,7 +21,6 @@ package org.sonar.batch; | |||
import com.google.common.collect.ImmutableList; | |||
import com.google.common.collect.Iterables; | |||
import com.google.common.collect.Lists; | |||
import org.apache.commons.io.FileUtils; | |||
import org.apache.maven.project.MavenProject; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
@@ -32,7 +31,6 @@ import org.sonar.api.utils.SonarException; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Collections; | |||
import java.util.List; | |||
/** | |||
@@ -57,11 +55,7 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem { | |||
} | |||
public File getBasedir() { | |||
if (pom != null) { | |||
return pom.getBasedir(); | |||
} else { | |||
return def.getBaseDir(); | |||
} | |||
return def.getBaseDir(); | |||
} | |||
public File getBuildDir() { | |||
@@ -88,13 +82,7 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem { | |||
@Override | |||
public List<File> getSourceDirs() { | |||
List<File> unfiltered; | |||
if (pom != null) { | |||
// Maven can modify source directories during Sonar execution - see MavenPhaseExecutor. | |||
unfiltered = resolvePaths(pom.getCompileSourceRoots()); | |||
} else { | |||
unfiltered = resolvePaths(def.getSourceDirs()); | |||
} | |||
List<File> unfiltered = resolvePaths(def.getSourceDirs()); | |||
return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS)); | |||
} | |||
@@ -108,9 +96,8 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem { | |||
} | |||
if (pom != null) { | |||
pom.getCompileSourceRoots().add(0, dir.getAbsolutePath()); | |||
} else { | |||
def.addSourceDirs(dir.getAbsolutePath()); | |||
} | |||
def.addSourceDirs(dir.getAbsolutePath()); | |||
return this; | |||
} | |||
@@ -119,13 +106,7 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem { | |||
*/ | |||
@Override | |||
public List<File> getTestDirs() { | |||
List<File> unfiltered; | |||
if (pom != null) { | |||
// Maven can modify test directories during Sonar execution - see MavenPhaseExecutor. | |||
unfiltered = resolvePaths(pom.getTestCompileSourceRoots()); | |||
} else { | |||
unfiltered = resolvePaths(def.getTestDirs()); | |||
} | |||
List<File> unfiltered = resolvePaths(def.getTestDirs()); | |||
return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS)); | |||
} | |||
@@ -139,9 +120,8 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem { | |||
} | |||
if (pom != null) { | |||
pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath()); | |||
} else { | |||
def.addTestDirs(dir.getAbsolutePath()); | |||
} | |||
def.addTestDirs(dir.getAbsolutePath()); | |||
return this; | |||
} | |||
@@ -158,18 +138,12 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem { | |||
@Override | |||
public File getSonarWorkingDirectory() { | |||
File dir; | |||
if (pom != null) { | |||
dir = new File(getBuildDir(), "sonar"); | |||
} else { | |||
dir = def.getWorkDir(); | |||
} | |||
try { | |||
FileUtils.forceMkdir(dir); | |||
FileUtils.forceMkdir(def.getWorkDir()); | |||
return def.getWorkDir(); | |||
} catch (IOException e) { | |||
throw new SonarException("Unable to retrieve Sonar working directory.", e); | |||
} | |||
return dir; | |||
} | |||
@Override |
@@ -19,15 +19,16 @@ | |||
*/ | |||
package org.sonar.batch; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.MavenPluginHandler; | |||
import org.sonar.api.resources.Project; | |||
public class FakeMavenPluginExecutor implements MavenPluginExecutor { | |||
public final class FakeMavenPluginExecutor implements MavenPluginExecutor { | |||
public void execute(Project project, String goal) { | |||
// do nothing | |||
} | |||
public MavenPluginHandler execute(Project project, MavenPluginHandler handler) { | |||
public MavenPluginHandler execute(Project project, ProjectDefinition projectDefinition, MavenPluginHandler handler) { | |||
// do nothing | |||
return handler; | |||
} |
@@ -20,6 +20,7 @@ | |||
package org.sonar.batch; | |||
import org.sonar.api.BatchComponent; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.MavenPluginHandler; | |||
import org.sonar.api.resources.Project; | |||
@@ -27,6 +28,6 @@ public interface MavenPluginExecutor extends BatchComponent { | |||
void execute(Project project, String goal); | |||
MavenPluginHandler execute(Project project, MavenPluginHandler handler); | |||
MavenPluginHandler execute(Project project, ProjectDefinition def, MavenPluginHandler handler); | |||
} |
@@ -66,11 +66,33 @@ public final class MavenProjectConverter { | |||
*/ | |||
static ProjectDefinition convert(MavenProject pom) { | |||
String key = new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString(); | |||
return new ProjectDefinition(pom.getBasedir(), null, pom.getModel().getProperties()) // TODO work directory ? | |||
ProjectDefinition definition = ProjectDefinition.create(); | |||
definition.setProperties(pom.getModel().getProperties()) | |||
.setKey(key) | |||
.setVersion(pom.getVersion()) | |||
.setName(pom.getName()) | |||
.setDescription(pom.getDescription()) | |||
.addContainerExtension(pom); | |||
synchronizeFileSystem(pom, definition); | |||
return definition; | |||
} | |||
public static void synchronizeFileSystem(MavenProject pom, ProjectDefinition into) { | |||
into.setBaseDir(pom.getBasedir()); | |||
into.setWorkDir(new File(resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), "sonar")); | |||
into.setSourceDirs((String[]) pom.getCompileSourceRoots().toArray(new String[pom.getCompileSourceRoots().size()])); | |||
into.setTestDirs((String[]) pom.getTestCompileSourceRoots().toArray(new String[pom.getTestCompileSourceRoots().size()])); | |||
} | |||
static File resolvePath(String path, File basedir) { | |||
File file = new File(path); | |||
if (!file.isAbsolute()) { | |||
try { | |||
file = new File(basedir, path).getCanonicalFile(); | |||
} catch (IOException e) { | |||
throw new SonarException("Unable to resolve path '" + path + "'", e); | |||
} | |||
} | |||
return file; | |||
} | |||
} |
@@ -27,7 +27,7 @@ import java.util.Properties; | |||
/** | |||
* Describes project in a form suitable to bootstrap Sonar batch. | |||
* We assume that project is just a set of configuration properties and directories. | |||
* | |||
* | |||
* @since 2.6 | |||
* @deprecated since 2.9. Move into org.sonar.api.batch.bootstrap | |||
*/ | |||
@@ -38,11 +38,14 @@ public class ProjectDefinition { | |||
private List<ProjectDefinition> children = new ArrayList<ProjectDefinition>(); | |||
/** | |||
* @param baseDir project base directory | |||
* @param baseDir project base directory | |||
* @param properties project properties | |||
*/ | |||
public ProjectDefinition(File baseDir, File workDir, Properties properties) { | |||
target = new org.sonar.api.batch.bootstrap.ProjectDefinition(baseDir, workDir, properties); | |||
target = org.sonar.api.batch.bootstrap.ProjectDefinition.create() | |||
.setBaseDir(baseDir) | |||
.setWorkDir(workDir) | |||
.setProperties(properties); | |||
} | |||
public File getBaseDir() { | |||
@@ -71,7 +74,7 @@ public class ProjectDefinition { | |||
/** | |||
* @param path path to directory with test sources. | |||
* It can be absolute or relative to project directory. | |||
* It can be absolute or relative to project directory. | |||
*/ | |||
public void addTestDir(String path) { | |||
target.addTestDirs(path); | |||
@@ -83,7 +86,7 @@ public class ProjectDefinition { | |||
/** | |||
* @param path path to directory with compiled source. In case of Java this is directory with class files. | |||
* It can be absolute or relative to project directory. | |||
* It can be absolute or relative to project directory. | |||
* @TODO currently Sonar supports only one such directory due to dependency on MavenProject | |||
*/ | |||
public void addBinaryDir(String path) { | |||
@@ -96,7 +99,7 @@ public class ProjectDefinition { | |||
/** | |||
* @param path path to file with third-party library. In case of Java this is path to jar file. | |||
* It can be absolute or relative to project directory. | |||
* It can be absolute or relative to project directory. | |||
*/ | |||
public void addLibrary(String path) { | |||
target.addLibrary(path); | |||
@@ -104,7 +107,7 @@ public class ProjectDefinition { | |||
/** | |||
* Adds an extension, which would be available in PicoContainer during analysis of this project. | |||
* | |||
* | |||
* @since 2.8 | |||
*/ | |||
public void addContainerExtension(Object extension) { |
@@ -40,14 +40,16 @@ public class DecoratorsExecutor implements BatchComponent { | |||
private DecoratorsSelector decoratorsSelector; | |||
private SonarIndex index; | |||
private EventBus eventBus; | |||
private Project project; | |||
public DecoratorsExecutor(BatchExtensionDictionnary extensionDictionnary, SonarIndex index, EventBus eventBus) { | |||
public DecoratorsExecutor(BatchExtensionDictionnary extensionDictionnary, Project project, SonarIndex index, EventBus eventBus) { | |||
this.decoratorsSelector = new DecoratorsSelector(extensionDictionnary); | |||
this.index = index; | |||
this.eventBus = eventBus; | |||
this.project = project; | |||
} | |||
public void execute(Project project) { | |||
public void execute() { | |||
Collection<Decorator> decorators = decoratorsSelector.select(project); | |||
eventBus.fireEvent(new DecoratorsPhaseEvent(Lists.newArrayList(decorators), true)); | |||
decorateResource(project, decorators, true); |
@@ -19,19 +19,20 @@ | |||
*/ | |||
package org.sonar.batch.phases; | |||
import java.util.Collection; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.batch.BatchExtensionDictionnary; | |||
import org.sonar.api.batch.Initializer; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.DependsUponMavenPlugin; | |||
import org.sonar.api.batch.maven.MavenPluginHandler; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.utils.TimeProfiler; | |||
import org.sonar.batch.MavenPluginExecutor; | |||
import java.util.Collection; | |||
public class InitializersExecutor { | |||
private static final Logger logger = LoggerFactory.getLogger(SensorsExecutor.class); | |||
@@ -39,19 +40,23 @@ public class InitializersExecutor { | |||
private MavenPluginExecutor mavenExecutor; | |||
private Collection<Initializer> initializers; | |||
private ProjectDefinition projectDef; | |||
private Project project; | |||
public InitializersExecutor(BatchExtensionDictionnary selector, Project project, MavenPluginExecutor mavenExecutor) { | |||
public InitializersExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDef, MavenPluginExecutor mavenExecutor) { | |||
this.initializers = selector.select(Initializer.class, project, true); | |||
this.mavenExecutor = mavenExecutor; | |||
this.project = project; | |||
this.projectDef = projectDef; | |||
} | |||
public void execute(Project project) { | |||
public void execute() { | |||
if (logger.isDebugEnabled()) { | |||
logger.debug("Initializers : {}", StringUtils.join(initializers, " -> ")); | |||
} | |||
for (Initializer initializer : initializers) { | |||
executeMavenPlugin(project, initializer); | |||
executeMavenPlugin(initializer); | |||
TimeProfiler profiler = new TimeProfiler(logger).start("Initializer " + initializer); | |||
initializer.execute(project); | |||
@@ -59,12 +64,12 @@ public class InitializersExecutor { | |||
} | |||
} | |||
private void executeMavenPlugin(Project project, Initializer sensor) { | |||
private void executeMavenPlugin(Initializer sensor) { | |||
if (sensor instanceof DependsUponMavenPlugin) { | |||
MavenPluginHandler handler = ((DependsUponMavenPlugin) sensor).getMavenPluginHandler(project); | |||
if (handler != null) { | |||
TimeProfiler profiler = new TimeProfiler(logger).start("Execute maven plugin " + handler.getArtifactId()); | |||
mavenExecutor.execute(project, handler); | |||
mavenExecutor.execute(project, projectDef, handler); | |||
profiler.stop(); | |||
} | |||
} |
@@ -74,17 +74,17 @@ public final class Phases { | |||
eventBus.fireEvent(new ProjectAnalysisEvent(project, true)); | |||
mavenPluginsConfigurator.execute(project); | |||
mavenPhaseExecutor.execute(project); | |||
initializersExecutor.execute(project); | |||
initializersExecutor.execute(); | |||
persistenceManager.setDelayedMode(true); | |||
sensorsExecutor.execute(project, sensorContext); | |||
decoratorsExecutor.execute(project); | |||
sensorsExecutor.execute(sensorContext); | |||
decoratorsExecutor.execute(); | |||
persistenceManager.dump(); | |||
persistenceManager.setDelayedMode(false); | |||
if (project.isRoot()) { | |||
updateStatusJob.execute(); | |||
postJobsExecutor.execute(project, sensorContext); | |||
postJobsExecutor.execute(sensorContext); | |||
} | |||
cleanMemory(); | |||
eventBus.fireEvent(new ProjectAnalysisEvent(project, false)); |
@@ -26,35 +26,40 @@ import org.sonar.api.BatchComponent; | |||
import org.sonar.api.batch.BatchExtensionDictionnary; | |||
import org.sonar.api.batch.PostJob; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.DependsUponMavenPlugin; | |||
import org.sonar.api.batch.maven.MavenPluginHandler; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.batch.MavenPluginExecutor; | |||
import java.util.Collection; | |||
import java.util.List; | |||
public class PostJobsExecutor implements BatchComponent { | |||
private static final Logger LOG = LoggerFactory.getLogger(PostJobsExecutor.class); | |||
private Collection<PostJob> postJobs; | |||
private MavenPluginExecutor mavenExecutor; | |||
private ProjectDefinition projectDefinition; | |||
private Project project; | |||
public PostJobsExecutor(Project project, BatchExtensionDictionnary selector, MavenPluginExecutor mavenExecutor) { | |||
postJobs = selector.select(PostJob.class, project, true); | |||
this.mavenExecutor = mavenExecutor; | |||
public PostJobsExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDefinition, MavenPluginExecutor mavenExecutor) { | |||
this(selector.select(PostJob.class, project, true), project, projectDefinition, mavenExecutor); | |||
} | |||
protected PostJobsExecutor(Collection<PostJob> postJobs, MavenPluginExecutor mavenExecutor) { | |||
this.postJobs = postJobs; | |||
PostJobsExecutor(Collection<PostJob> jobs, Project project, ProjectDefinition projectDefinition, MavenPluginExecutor mavenExecutor) { | |||
this.postJobs = jobs; | |||
this.mavenExecutor = mavenExecutor; | |||
this.project = project; | |||
this.projectDefinition = projectDefinition; | |||
} | |||
public void execute(Project project, SensorContext context) { | |||
public void execute(SensorContext context) { | |||
logPostJobs(); | |||
for (PostJob postJob : postJobs) { | |||
LOG.info("Executing post-job {}", postJob.getClass()); | |||
executeMavenPlugin(project, postJob); | |||
executeMavenPlugin(postJob); | |||
postJob.executeOn(project, context); | |||
} | |||
} | |||
@@ -65,11 +70,11 @@ public class PostJobsExecutor implements BatchComponent { | |||
} | |||
} | |||
private void executeMavenPlugin(Project project, PostJob job) { | |||
private void executeMavenPlugin(PostJob job) { | |||
if (job instanceof DependsUponMavenPlugin) { | |||
MavenPluginHandler handler = ((DependsUponMavenPlugin) job).getMavenPluginHandler(project); | |||
if (handler != null) { | |||
mavenExecutor.execute(project, handler); | |||
mavenExecutor.execute(project, projectDefinition, handler); | |||
} | |||
} | |||
} |
@@ -26,6 +26,7 @@ import org.sonar.api.BatchComponent; | |||
import org.sonar.api.batch.BatchExtensionDictionnary; | |||
import org.sonar.api.batch.Sensor; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.DependsUponMavenPlugin; | |||
import org.sonar.api.batch.maven.MavenPluginHandler; | |||
import org.sonar.api.resources.Project; | |||
@@ -41,18 +42,22 @@ public class SensorsExecutor implements BatchComponent { | |||
private Collection<Sensor> sensors; | |||
private MavenPluginExecutor mavenExecutor; | |||
private EventBus eventBus; | |||
private Project project; | |||
private ProjectDefinition projectDefinition; | |||
public SensorsExecutor(BatchExtensionDictionnary selector, Project project, MavenPluginExecutor mavenExecutor, EventBus eventBus) { | |||
public SensorsExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDefinition, MavenPluginExecutor mavenExecutor, EventBus eventBus) { | |||
this.sensors = selector.select(Sensor.class, project, true); | |||
this.mavenExecutor = mavenExecutor; | |||
this.eventBus = eventBus; | |||
this.project = project; | |||
this.projectDefinition = projectDefinition; | |||
} | |||
public void execute(Project project, SensorContext context) { | |||
public void execute(SensorContext context) { | |||
eventBus.fireEvent(new SensorsPhaseEvent(Lists.newArrayList(sensors), true)); | |||
for (Sensor sensor : sensors) { | |||
executeMavenPlugin(project, sensor); | |||
executeMavenPlugin(sensor); | |||
eventBus.fireEvent(new SensorExecutionEvent(sensor, true)); | |||
sensor.analyse(project, context); | |||
@@ -62,12 +67,12 @@ public class SensorsExecutor implements BatchComponent { | |||
eventBus.fireEvent(new SensorsPhaseEvent(Lists.newArrayList(sensors), false)); | |||
} | |||
private void executeMavenPlugin(Project project, Sensor sensor) { | |||
private void executeMavenPlugin(Sensor sensor) { | |||
if (sensor instanceof DependsUponMavenPlugin) { | |||
MavenPluginHandler handler = ((DependsUponMavenPlugin) sensor).getMavenPluginHandler(project); | |||
if (handler != null) { | |||
TimeProfiler profiler = new TimeProfiler(LOG).start("Execute maven plugin " + handler.getArtifactId()); | |||
mavenExecutor.execute(project, handler); | |||
mavenExecutor.execute(project, projectDefinition, handler); | |||
profiler.stop(); | |||
} | |||
} |
@@ -19,13 +19,18 @@ | |||
*/ | |||
package org.sonar.batch; | |||
import org.apache.maven.project.MavenProject; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.maven.MavenPlugin; | |||
import org.sonar.api.batch.maven.MavenPluginHandler; | |||
import org.sonar.api.resources.Project; | |||
import java.io.File; | |||
import static org.hamcrest.CoreMatchers.is; | |||
import static org.junit.Assert.assertThat; | |||
import static org.junit.internal.matchers.IsCollectionContaining.hasItem; | |||
public class AbstractMavenPluginExecutorTest { | |||
@@ -34,13 +39,36 @@ public class AbstractMavenPluginExecutorTest { | |||
assertThat(AbstractMavenPluginExecutor.getGoal("group", "artifact", null, "goal"), is("group:artifact::goal")); | |||
} | |||
static class FakeCheckstyleMavenPluginHandler implements MavenPluginHandler { | |||
/** | |||
* The maven plugin sometimes changes the project structure (for example mvn build-helper:add-source). These changes | |||
* must be applied to the internal structure. | |||
*/ | |||
@Test | |||
public void shouldUpdateProjectAfterExecution() { | |||
AbstractMavenPluginExecutor executor = new AbstractMavenPluginExecutor() { | |||
@Override | |||
public void concreteExecute(MavenProject pom, String goal) throws Exception { | |||
pom.addCompileSourceRoot("src/java"); | |||
} | |||
}; | |||
MavenProject pom = new MavenProject(); | |||
pom.setFile(new File("target/AbstractMavenPluginExecutorTest/pom.xml")); | |||
pom.getBuild().setDirectory("target"); | |||
Project foo = new Project("foo"); | |||
foo.setPom(pom); | |||
ProjectDefinition definition = ProjectDefinition.create(); | |||
executor.execute(foo, definition, new AddSourceMavenPluginHandler()); | |||
assertThat(definition.getSourceDirs(), hasItem("src/java")); | |||
} | |||
static class AddSourceMavenPluginHandler implements MavenPluginHandler { | |||
public String getGroupId() { | |||
return "org.apache.maven.plugins"; | |||
return "fake"; | |||
} | |||
public String getArtifactId() { | |||
return "maven-checkstyle-plugin"; | |||
return "fake"; | |||
} | |||
public String getVersion() { | |||
@@ -52,7 +80,7 @@ public class AbstractMavenPluginExecutorTest { | |||
} | |||
public String[] getGoals() { | |||
return new String[] { "checkstyle" }; | |||
return new String[] { "fake" }; | |||
} | |||
public void configure(Project project, MavenPlugin plugin) { |
@@ -0,0 +1,47 @@ | |||
/* | |||
* 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.hamcrest.core.Is; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.resources.Languages; | |||
import org.sonar.api.resources.Project; | |||
import java.io.File; | |||
import static org.junit.Assert.assertThat; | |||
import static org.junit.internal.matchers.IsCollectionContaining.hasItem; | |||
public class DefaultProjectFileSystem2Test { | |||
@Test | |||
public void shouldIgnoreInexistingSourceDirs() { | |||
File exists = FileUtils.toFile(getClass().getResource("/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs")); | |||
File notExists = new File("target/unknown"); | |||
ProjectDefinition definition = ProjectDefinition.create().addSourceDirs(exists, notExists); | |||
DefaultProjectFileSystem2 fs = new DefaultProjectFileSystem2(new Project("foo"), new Languages(), definition); | |||
assertThat(fs.getSourceDirs().size(), Is.is(1)); | |||
assertThat(fs.getSourceDirs(), hasItem(exists)); | |||
} | |||
} |
@@ -45,9 +45,11 @@ public class MavenProjectConverterTest { | |||
public void shouldConvertModules() { | |||
MavenProject root = new MavenProject(); | |||
root.setFile(new File("/foo/pom.xml")); | |||
root.getBuild().setDirectory("target"); | |||
root.getModules().add("module"); | |||
MavenProject module = new MavenProject(); | |||
module.setFile(new File("/foo/module/pom.xml")); | |||
module.getBuild().setDirectory("target"); | |||
ProjectDefinition project = MavenProjectConverter.convert(Arrays.asList(root, module), root); | |||
assertThat(project.getSubProjects().size(), is(1)); | |||
@@ -61,6 +63,8 @@ public class MavenProjectConverterTest { | |||
pom.setVersion("1.0.1"); | |||
pom.setName("Test"); | |||
pom.setDescription("just test"); | |||
pom.setFile(new File("/foo/pom.xml")); | |||
pom.getBuild().setDirectory("target"); | |||
ProjectDefinition project = MavenProjectConverter.convert(pom); | |||
Properties properties = project.getProperties(); | |||
@@ -130,6 +134,7 @@ public class MavenProjectConverterTest { | |||
Model model = new MavenXpp3Reader().read(new StringReader(FileUtils.readFileToString(pomFile))); | |||
MavenProject pom = new MavenProject(model); | |||
pom.setFile(pomFile); | |||
pom.getBuild().setDirectory("target"); | |||
pom.setExecutionRoot(isRoot); | |||
return pom; | |||
} |
@@ -35,7 +35,7 @@ public class BootstrapModuleTest { | |||
public void execute(Project project, String goal) { | |||
} | |||
public MavenPluginHandler execute(Project project, MavenPluginHandler handler) { | |||
public MavenPluginHandler execute(Project project, ProjectDefinition projectDef, MavenPluginHandler handler) { | |||
return handler; | |||
} | |||
} |
@@ -66,7 +66,7 @@ public class DecoratorsExecutorTest { | |||
Decorator decorator = mock(Decorator.class); | |||
doThrow(new SonarException()).when(decorator).decorate(any(Resource.class), any(DecoratorContext.class)); | |||
DecoratorsExecutor executor = new DecoratorsExecutor(mock(BatchExtensionDictionnary.class), mock(SonarIndex.class), mock(EventBus.class)); | |||
DecoratorsExecutor executor = new DecoratorsExecutor(mock(BatchExtensionDictionnary.class), new Project("key"), mock(SonarIndex.class), mock(EventBus.class)); | |||
try { | |||
executor.executeDecorator(decorator, mock(DefaultDecoratorContext.class), new File("org/foo/Bar.java")); | |||
fail("Exception has not been thrown"); |
@@ -22,6 +22,7 @@ package org.sonar.batch.phases; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.PostJob; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.batch.MavenPluginExecutor; | |||
@@ -39,10 +40,11 @@ public class PostJobsExecutorTest { | |||
PostJob job2 = mock(PostJob.class); | |||
List<PostJob> jobs = Arrays.asList(job1, job2); | |||
PostJobsExecutor executor = new PostJobsExecutor(jobs, mock(MavenPluginExecutor.class)); | |||
Project project = new Project("project"); | |||
ProjectDefinition projectDefinition = ProjectDefinition.create(); | |||
PostJobsExecutor executor = new PostJobsExecutor(jobs, project, projectDefinition, mock(MavenPluginExecutor.class)); | |||
SensorContext context = mock(SensorContext.class); | |||
executor.execute(project, context); | |||
executor.execute(context); | |||
verify(job1).executeOn(project, context); | |||
verify(job2).executeOn(project, context); |
@@ -0,0 +1 @@ | |||
fake |
@@ -31,7 +31,8 @@ import java.util.Properties; | |||
/** | |||
* Defines project metadata (key, name, source directories, ...). It's generally used by the | |||
* {@link org.sonar.api.batch.bootstrap.ProjectBuilder extension point} | |||
* {@link org.sonar.api.batch.bootstrap.ProjectBuilder extension point} and must not be used | |||
* by other standard extensions. | |||
* | |||
* @since 2.9 | |||
*/ | |||
@@ -48,17 +49,11 @@ public final class ProjectDefinition implements BatchComponent { | |||
private File baseDir; | |||
private File workDir; | |||
private Properties properties; | |||
private Properties properties = new Properties(); | |||
private ProjectDefinition parent = null; | |||
private List<ProjectDefinition> subProjects = Lists.newArrayList(); | |||
private List<Object> containerExtensions = Lists.newArrayList(); | |||
public ProjectDefinition(File baseDir, File workDir, Properties properties) { | |||
this.baseDir = baseDir; | |||
this.workDir = workDir; | |||
this.properties = properties; | |||
} | |||
private ProjectDefinition() { | |||
} | |||
@@ -66,6 +61,11 @@ public final class ProjectDefinition implements BatchComponent { | |||
return new ProjectDefinition(); | |||
} | |||
public ProjectDefinition setProperties(Properties p) { | |||
this.properties = p; | |||
return this; | |||
} | |||
public File getBaseDir() { | |||
return baseDir; | |||
} | |||
@@ -151,24 +151,24 @@ public final class ProjectDefinition implements BatchComponent { | |||
public ProjectDefinition addSourceDirs(File... dirs) { | |||
for (File dir : dirs) { | |||
addSourceDirs(dir); | |||
addSourceDirs(dir.getAbsolutePath()); | |||
} | |||
return this; | |||
} | |||
public ProjectDefinition setSourceDir(String path) { | |||
properties.setProperty(SOURCE_DIRS_PROPERTY, path); | |||
return this; | |||
} | |||
public ProjectDefinition resetSourceDirs() { | |||
properties.remove(SOURCE_DIRS_PROPERTY); | |||
return this; | |||
} | |||
public ProjectDefinition setSourceDir(File path) { | |||
setSourceDir(path.getAbsolutePath()); | |||
return this; | |||
public ProjectDefinition setSourceDirs(String... paths) { | |||
resetSourceDirs(); | |||
return addSourceDirs(paths); | |||
} | |||
public ProjectDefinition setSourceDirs(File... dirs) { | |||
resetSourceDirs(); | |||
return setSourceDirs(dirs); | |||
} | |||
/** | |||
@@ -221,6 +221,16 @@ public final class ProjectDefinition implements BatchComponent { | |||
return this; | |||
} | |||
public ProjectDefinition setTestDirs(String... paths) { | |||
resetTestDirs(); | |||
return addTestDirs(paths); | |||
} | |||
public ProjectDefinition setTestDirs(File... dirs) { | |||
resetTestDirs(); | |||
return setTestDirs(dirs); | |||
} | |||
public ProjectDefinition resetTestDirs() { | |||
properties.remove(TEST_DIRS_PROPERTY); | |||
return this; | |||
@@ -269,6 +279,11 @@ public final class ProjectDefinition implements BatchComponent { | |||
return this; | |||
} | |||
public ProjectDefinition addBinaryDir(File f) { | |||
return addBinaryDir(f.getAbsolutePath()); | |||
} | |||
public List<String> getLibraries() { | |||
String sources = properties.getProperty(LIBRARIES_PROPERTY, ""); | |||
return Arrays.asList(StringUtils.split(sources, SEPARATOR)); |
@@ -35,7 +35,7 @@ public class ProjectBuilderTest { | |||
@Test | |||
public void shouldChangeProject() { | |||
// this reactor is created and injected by Sonar | |||
ProjectReactor projectReactor = new ProjectReactor(new ProjectDefinition(new File("."), new File("."), new Properties())); | |||
ProjectReactor projectReactor = new ProjectReactor(ProjectDefinition.create()); | |||
ProjectBuilder builder = new ProjectBuilderSample(projectReactor, new PropertiesConfiguration()); | |||
builder.start(); | |||
@@ -65,11 +65,13 @@ public class ProjectBuilderTest { | |||
// add sub-project | |||
File baseDir = new File(root.getBaseDir(), "path/to/subproject"); | |||
ProjectDefinition subProject = new ProjectDefinition(baseDir, new File(baseDir, "target/.sonar"), new Properties()); | |||
ProjectDefinition subProject = ProjectDefinition.create(); | |||
subProject.setBaseDir(baseDir); | |||
subProject.setWorkDir(new File(baseDir, "target/.sonar")); | |||
subProject.setKey("groupId:subProjectId"); | |||
subProject.setVersion(root.getVersion()); | |||
subProject.setName("Sub Project"); | |||
subProject.setSourceDir("src"); | |||
subProject.setSourceDirs("src"); | |||
root.addSubProject(subProject); | |||
} | |||
} |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.api.batch.bootstrap; | |||
import org.hamcrest.CoreMatchers; | |||
import org.junit.Test; | |||
import org.sonar.api.CoreProperties; | |||
@@ -29,19 +30,20 @@ import java.util.Properties; | |||
import static org.hamcrest.CoreMatchers.nullValue; | |||
import static org.hamcrest.Matchers.is; | |||
import static org.junit.Assert.assertThat; | |||
import static org.junit.matchers.JUnitMatchers.hasItem; | |||
public class ProjectDefinitionTest { | |||
@Test | |||
public void shouldSetKey() { | |||
ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
def.setKey("mykey"); | |||
assertThat(def.getKey(), is("mykey")); | |||
} | |||
@Test | |||
public void shouldSetOptionalFields() { | |||
ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
def.setName("myname"); | |||
def.setDescription("desc"); | |||
assertThat(def.getName(), is("myname")); | |||
@@ -50,7 +52,7 @@ public class ProjectDefinitionTest { | |||
@Test | |||
public void shouldSupportDefaultName() { | |||
ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
def.setKey("myKey"); | |||
assertThat(def.getName(), is("Unnamed - myKey")); | |||
} | |||
@@ -58,13 +60,14 @@ public class ProjectDefinitionTest { | |||
public void shouldGetKeyFromProperties() { | |||
Properties props = new Properties(); | |||
props.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo"); | |||
ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), props); | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
def.setProperties(props); | |||
assertThat(def.getKey(), is("foo")); | |||
} | |||
@Test | |||
public void testDefaultValues() { | |||
ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
assertThat(def.getSourceDirs().size(), is(0)); | |||
assertThat(def.getTestDirs().size(), is(0)); | |||
assertThat(def.getBinaries().size(), is(0)); | |||
@@ -72,8 +75,8 @@ public class ProjectDefinitionTest { | |||
} | |||
@Test | |||
public void shouldAddDirectories() { | |||
ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
public void shouldAddDirectoriesAsPath() { | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
def.addSourceDirs("src/main/java", "src/main/java2"); | |||
def.addTestDirs("src/test/java"); | |||
def.addTestDirs("src/test/java2"); | |||
@@ -88,9 +91,21 @@ public class ProjectDefinitionTest { | |||
assertFiles(def.getLibraries(), "junit.jar", "mockito.jar"); | |||
} | |||
@Test | |||
public void shouldAddDirectories() { | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
def.addSourceDirs(new File("src/main/java"), new File("src/main/java2")); | |||
def.addTestDirs(new File("src/test/java"), new File("src/test/java2")); | |||
def.addBinaryDir(new File("target/classes")); | |||
assertThat(def.getSourceDirs().size(), is(2)); | |||
assertThat(def.getTestDirs().size(), CoreMatchers.is(2)); | |||
assertThat(def.getBinaries().size(), CoreMatchers.is(1)); | |||
} | |||
@Test | |||
public void shouldAddFiles() { | |||
ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
def.addSourceFiles("src/main/java/foo/Bar.java", "src/main/java/hello/World.java"); | |||
def.addTestFiles("src/test/java/foo/BarTest.java", "src/test/java/hello/WorldTest.java"); | |||
@@ -101,8 +116,8 @@ public class ProjectDefinitionTest { | |||
@Test | |||
public void shouldManageRelationships() { | |||
ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition child = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition root = ProjectDefinition.create(); | |||
ProjectDefinition child = ProjectDefinition.create(); | |||
root.addSubProject(child); | |||
assertThat(root.getSubProjects().size(), is(1)); | |||
@@ -114,7 +129,7 @@ public class ProjectDefinitionTest { | |||
@Test | |||
public void shouldResetSourceDirs() { | |||
ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition root = ProjectDefinition.create(); | |||
root.addSourceDirs("src", "src2/main"); | |||
assertThat(root.getSourceDirs().size(), is(2)); | |||
@@ -124,7 +139,7 @@ public class ProjectDefinitionTest { | |||
@Test | |||
public void shouldResetTestDirs() { | |||
ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition root = ProjectDefinition.create(); | |||
root.addTestDirs("src", "src2/test"); | |||
assertThat(root.getTestDirs().size(), is(2)); | |||
@@ -31,8 +31,8 @@ public class ProjectReactorTest { | |||
@Test | |||
public void shouldSupportMultipleProjects() { | |||
ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition child = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition root = ProjectDefinition.create(); | |||
ProjectDefinition child = ProjectDefinition.create(); | |||
root.addSubProject(child); | |||
ProjectReactor reactor = new ProjectReactor(root); | |||
@@ -42,8 +42,8 @@ public class ProjectReactorTest { | |||
@Test(expected = IllegalArgumentException.class) | |||
public void shouldFailIfNotRoot() { | |||
ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition child = new ProjectDefinition(new File("."), new File("."), new Properties()); | |||
ProjectDefinition root = ProjectDefinition.create(); | |||
ProjectDefinition child = ProjectDefinition.create(); | |||
root.addSubProject(child); | |||
new ProjectReactor(child); |