]> source.dussan.org Git - sonarqube.git/commitdiff
Allow the extension ProjectBuilder to change the source directories of root module
authorSimon Brandhof <simon.brandhof@gmail.com>
Mon, 6 Jun 2011 12:27:49 +0000 (14:27 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Mon, 6 Jun 2011 12:28:04 +0000 (14:28 +0200)
22 files changed:
sonar-batch/src/main/java/org/sonar/batch/AbstractMavenPluginExecutor.java
sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java
sonar-batch/src/main/java/org/sonar/batch/FakeMavenPluginExecutor.java
sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java
sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java
sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/InitializersExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/Phases.java
sonar-batch/src/main/java/org/sonar/batch/phases/PostJobsExecutor.java
sonar-batch/src/main/java/org/sonar/batch/phases/SensorsExecutor.java
sonar-batch/src/test/java/org/sonar/batch/AbstractMavenPluginExecutorTest.java
sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapModuleTest.java
sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java
sonar-batch/src/test/java/org/sonar/batch/phases/PostJobsExecutorTest.java
sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectDefinitionTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectReactorTest.java

index 85e5614c0d7745ada7947b761c32e42b3e08744b..2c4c0d12ed823d1996362d0ce69025f774373880 100644 (file)
@@ -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;
   }
 
index 632ee139c8ca52836797458e6ea4ec41ad3b7512..941ff57269ec94235213d07c03b77b35dff0a5f7 100644 (file)
@@ -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
index a10a74012b0066e780f7cd551ed7353a67813e85..539d2962ec2302020e96e78c1a75d24981077eb4 100644 (file)
  */
 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;
   }
index dd16c99d89eecf9d30fb0bde18271972e0c4548d..891c9fd1c4b1419280a226ba7a176ea8b735c8b7 100644 (file)
@@ -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);
 
 }
index be0ac861cd77de4e48fb557ec5425ccba27ec11a..ec3104f755c01f919c75ab01152cb77e8becffed 100644 (file)
@@ -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;
   }
 }
index f3fbe726c9fd00f68e12ab21df12131d57f7118e..0c59c79993505e0da66008f1ca1e3d1a91ac669e 100644 (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) {
index 1605a1623d410c160947bc472126bcfc3df72de4..ef3738dda3f4ba7e6c62944e32c5a454e00f341d 100644 (file)
@@ -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);
index e84d4527edea72ceb2d3b3769e7581021ea73d17..c205df16034cdf9c195b254c0947a000818e065d 100644 (file)
  */
 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();
       }
     }
index 5ca5be54a8e8f3554124fa01c42014db183ad835..a9d69e72a23d6567648950d10b4b70f4593db829 100644 (file)
@@ -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));
index 9c42b329378485106d91c95b514e50bb727c1362..3f6b6433cbcd2e43d8fb974794206c5d0198885b 100644 (file)
@@ -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);
       }
     }
   }
index 474f53be1736ddd5c9aba69526340780c396aa8e..f59d9c5fe55f0a2592862a0fe408e7fcf390477f 100644 (file)
@@ -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();
       }
     }
index 687ccbbbc6b9dd9c47f00d361447ef730394092c..eecec7e0113b803748bc0d32fdc76487b15144ac 100644 (file)
  */
 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) {
diff --git a/sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java b/sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java
new file mode 100644 (file)
index 0000000..7fd4cb0
--- /dev/null
@@ -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));
+
+  }
+}
index 279645cb3a29937695bda741880579e0b22c928f..7077ddde5287394c5baba01548932536d30afc21 100644 (file)
@@ -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;
   }
index dd765b0e1007fabe649f9473554cf0fa81fefa23..ff62f837bbd121e8498c93e94c5a6f17ab60c70b 100644 (file)
@@ -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;
     }
   }
index fc86a6d4c275c27f026a8847a6b6fdc717bdcdb1..181abf7308186f9541cbf8f1247fe27f85f10ccf 100644 (file)
@@ -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");
index 2231bea710add36affdfe7ecdbb97157de62ce63..60efff9650989b72b878d83633addebe5c675f56 100644 (file)
@@ -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);
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt b/sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt
new file mode 100644 (file)
index 0000000..f0f877c
--- /dev/null
@@ -0,0 +1 @@
+fake
\ No newline at end of file
index 1b062bc81313ce66c358743bbed8941eb24baa9f..cec0930c949969f06b2e7502ca23df44bb228988 100644 (file)
@@ -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));
index 4a5d80b899f05c9f907e3e4c14702e8e59eb847a..af6ae6d93b8fca19fdda9f3b7e698c0e94a2cca2 100644 (file)
@@ -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);
     }
   }
index ed13c6a719c9d4a2d49ae82c848b2be55b5723c6..93b9bcdfefa14ba5425181c2dec72932d4dbdb03 100644 (file)
@@ -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));
 
index 4385cb1455afe7c339523cbd56f6bef105dfa2bc..59035cd4dd486c0e256240332e63d2764b8a181b 100644 (file)
@@ -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);