]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5190 Make default bootstrapper support Maven
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 2 Apr 2014 09:58:22 +0000 (11:58 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 2 Apr 2014 13:26:12 +0000 (15:26 +0200)
plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectBootstrapper.java
plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenProjectConverter.java
sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/test/java/org/sonar/batch/scan/DefaultProjectBootstrapperTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectBootstrapper.java

index 178ab748607dae41ddb5288260472f63532612ef..1bb3ea37d21829e8812fc64a0551b2773723b829 100644 (file)
@@ -27,6 +27,10 @@ import org.sonar.api.batch.bootstrap.ProjectReactor;
 
 import java.util.List;
 
+/**
+ * @deprecated since 4.3 kept only to support old version of SonarQube Mojo
+ */
+@Deprecated
 @SupportedEnvironment("maven")
 public class MavenProjectBootstrapper implements ProjectBootstrapper {
 
index 47082d40b2a689aafb144fc65e22e635ee2acfab..3162b0953615e950e2391fbd272a79637851b891 100644 (file)
@@ -48,6 +48,10 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+/**
+ * @deprecated since 4.3 kept only to support old version of SonarQube Mojo
+ */
+@Deprecated
 @SupportedEnvironment("maven")
 public class MavenProjectConverter implements TaskExtension {
 
index 528891fadc8c92b84974e76352c22585d294413c..69807164d75f634987c2fa10a60438bed23f7525 100644 (file)
@@ -28,6 +28,8 @@ import org.apache.commons.io.filefilter.FileFileFilter;
 import org.apache.commons.io.filefilter.IOFileFilter;
 import org.apache.commons.io.filefilter.WildcardFileFilter;
 import org.apache.commons.lang.StringUtils;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.MavenProject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
@@ -37,6 +39,8 @@ import org.sonar.api.batch.bootstrap.ProjectReactor;
 import org.sonar.batch.bootstrap.BootstrapSettings;
 import org.sonar.core.component.ComponentKeys;
 
+import javax.annotation.Nullable;
+
 import java.io.File;
 import java.io.FileFilter;
 import java.io.FileInputStream;
@@ -113,9 +117,11 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper {
 
   private BootstrapSettings settings;
   private File rootProjectWorkDir;
+  private MavenSession mavenSession;
 
-  DefaultProjectBootstrapper(BootstrapSettings settings) {
+  DefaultProjectBootstrapper(BootstrapSettings settings, @Nullable MavenSession mavenSession) {
     this.settings = settings;
+    this.mavenSession = mavenSession;
   }
 
   @Override
@@ -149,9 +155,28 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper {
     ProjectDefinition definition = ProjectDefinition.create().setProperties(properties)
       .setBaseDir(baseDir)
       .setWorkDir(workDir);
+    setMavenProjectIfApplicable(definition);
     return definition;
   }
 
+  private void setMavenProjectIfApplicable(ProjectDefinition definition) {
+    if (mavenSession != null) {
+      String moduleKey = definition.getKey();
+      MavenProject foundMavenModule = null;
+      for (MavenProject mavenModule : (List<MavenProject>) mavenSession.getSortedProjects()) {
+        String mavenModuleKey = mavenModule.getGroupId() + ":" + mavenModule.getArtifactId();
+        if (mavenModuleKey.equals(moduleKey)) {
+          foundMavenModule = mavenModule;
+          break;
+        }
+      }
+      if (foundMavenModule == null) {
+        throw new IllegalStateException("Unable to find Maven project in reactor with key " + moduleKey);
+      }
+      definition.addContainerExtension(foundMavenModule);
+    }
+  }
+
   private void checkProjectKeyValid(String projectKey) {
     if (!ComponentKeys.isValidModuleKey(projectKey)) {
       throw new IllegalStateException(String.format(
index d0820064349c0887d7f0f8f2275e07ffeedbeb38..c837a2f8df118d9c05af8365694809e6e9e54a85 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.batch.scan;
 
 import com.google.common.annotations.VisibleForTesting;
+import org.apache.maven.execution.MavenSession;
 import org.sonar.api.BatchExtension;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.InstantiationStrategy;
@@ -35,12 +36,34 @@ import org.sonar.batch.DefaultFileLinesContextFactory;
 import org.sonar.batch.DefaultResourceCreationLock;
 import org.sonar.batch.ProjectConfigurator;
 import org.sonar.batch.ProjectTree;
-import org.sonar.batch.bootstrap.*;
+import org.sonar.batch.bootstrap.BootstrapSettings;
+import org.sonar.batch.bootstrap.ExtensionInstaller;
+import org.sonar.batch.bootstrap.ExtensionMatcher;
+import org.sonar.batch.bootstrap.ExtensionUtils;
+import org.sonar.batch.bootstrap.MetricProvider;
 import org.sonar.batch.components.PeriodsDefinition;
 import org.sonar.batch.debt.DebtModelProvider;
 import org.sonar.batch.debt.IssueChangelogDebtCalculator;
-import org.sonar.batch.index.*;
-import org.sonar.batch.issue.*;
+import org.sonar.batch.index.Caches;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.batch.index.ComponentDataPersister;
+import org.sonar.batch.index.DefaultIndex;
+import org.sonar.batch.index.DefaultPersistenceManager;
+import org.sonar.batch.index.DefaultResourcePersister;
+import org.sonar.batch.index.DependencyPersister;
+import org.sonar.batch.index.EventPersister;
+import org.sonar.batch.index.LinkPersister;
+import org.sonar.batch.index.MeasurePersister;
+import org.sonar.batch.index.MemoryOptimizer;
+import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.index.ResourceKeyMigration;
+import org.sonar.batch.index.SnapshotCache;
+import org.sonar.batch.index.SourcePersister;
+import org.sonar.batch.issue.DefaultProjectIssues;
+import org.sonar.batch.issue.DeprecatedViolations;
+import org.sonar.batch.issue.IssueCache;
+import org.sonar.batch.issue.IssuePersister;
+import org.sonar.batch.issue.ScanIssueStorage;
 import org.sonar.batch.phases.GraphPersister;
 import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
 import org.sonar.batch.rule.RulesProvider;
@@ -85,10 +108,12 @@ public class ProjectScanContainer extends ComponentContainer {
     if (reactor == null) {
       // OK, not present, so look for a custom ProjectBootstrapper
       ProjectBootstrapper bootstrapper = getComponentByType(ProjectBootstrapper.class);
-      if (bootstrapper == null) {
+      BootstrapSettings settings = getComponentByType(BootstrapSettings.class);
+      if (bootstrapper == null
+        // Starting from Maven plugin 2.3 then only DefaultProjectBootstrapper should be used.
+        || "true".equals(settings.property("sonar.mojoUseRunner"))) {
         // Use default SonarRunner project bootstrapper
-        BootstrapSettings settings = getComponentByType(BootstrapSettings.class);
-        bootstrapper = new DefaultProjectBootstrapper(settings);
+        bootstrapper = new DefaultProjectBootstrapper(settings, getComponentByType(MavenSession.class));
       }
       reactor = bootstrapper.bootstrap();
       if (reactor == null) {
@@ -162,8 +187,7 @@ public class ProjectScanContainer extends ComponentContainer {
       // Differential periods
       PeriodsDefinition.class,
 
-      ProjectSettingsReady.class
-    );
+      ProjectSettingsReady.class);
   }
 
   private void fixMavenExecutor() {
index c96a789ff9f6ce26d41af097dff037c9194ca36d..f84724557cd9bca7122d6aa8871bc48e5c7e7271 100644 (file)
@@ -471,7 +471,7 @@ public class DefaultProjectBootstrapperTest {
     thrown.expect(IllegalStateException.class);
     thrown.expectMessage("You must define the following mandatory properties for 'Unknown': foo2, foo3");
 
-    DefaultProjectBootstrapper.checkMandatoryProperties(props, new String[]{"foo1", "foo2", "foo3"});
+    DefaultProjectBootstrapper.checkMandatoryProperties(props, new String[] {"foo1", "foo2", "foo3"});
   }
 
   @Test
@@ -483,7 +483,7 @@ public class DefaultProjectBootstrapperTest {
     thrown.expect(IllegalStateException.class);
     thrown.expectMessage("You must define the following mandatory properties for 'my-project': foo2, foo3");
 
-    DefaultProjectBootstrapper.checkMandatoryProperties(props, new String[]{"foo1", "foo2", "foo3"});
+    DefaultProjectBootstrapper.checkMandatoryProperties(props, new String[] {"foo1", "foo2", "foo3"});
   }
 
   @Test
@@ -492,7 +492,7 @@ public class DefaultProjectBootstrapperTest {
     props.setProperty("foo1", "bla");
     props.setProperty("foo4", "bla");
 
-    DefaultProjectBootstrapper.checkMandatoryProperties(props, new String[]{"foo1"});
+    DefaultProjectBootstrapper.checkMandatoryProperties(props, new String[] {"foo1"});
 
     // No exception should be thrown
   }
@@ -555,7 +555,7 @@ public class DefaultProjectBootstrapperTest {
 
   @Test
   public void shouldInitRootWorkDir() {
-    DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(Maps.<String, String>newHashMap())));
+    DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(Maps.<String, String>newHashMap())), null);
     File baseDir = new File("target/tmp/baseDir");
 
     File workDir = builder.initRootProjectWorkDir(baseDir);
@@ -567,7 +567,7 @@ public class DefaultProjectBootstrapperTest {
   public void shouldInitWorkDirWithCustomRelativeFolder() {
     Map<String, String> props = Maps.<String, String>newHashMap();
     props.put("sonar.working.directory", ".foo");
-    DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(props)));
+    DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(props)), null);
     File baseDir = new File("target/tmp/baseDir");
 
     File workDir = builder.initRootProjectWorkDir(baseDir);
@@ -579,7 +579,7 @@ public class DefaultProjectBootstrapperTest {
   public void shouldInitRootWorkDirWithCustomAbsoluteFolder() {
     Map<String, String> props = Maps.<String, String>newHashMap();
     props.put("sonar.working.directory", new File("src").getAbsolutePath());
-    DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(props)));
+    DefaultProjectBootstrapper builder = new DefaultProjectBootstrapper(new BootstrapSettings(new BootstrapProperties(props)), null);
     File baseDir = new File("target/tmp/baseDir");
 
     File workDir = builder.initRootProjectWorkDir(baseDir);
@@ -644,7 +644,7 @@ public class DefaultProjectBootstrapperTest {
     }
     props.put("sonar.projectBaseDir", TestUtils.getResource(this.getClass(), projectFolder).getAbsolutePath());
     BootstrapProperties bootstrapProps = new BootstrapProperties(props);
-    ProjectReactor projectReactor = new DefaultProjectBootstrapper(new BootstrapSettings(bootstrapProps)).bootstrap();
+    ProjectReactor projectReactor = new DefaultProjectBootstrapper(new BootstrapSettings(bootstrapProps), null).bootstrap();
     return projectReactor.getRoot();
   }
 
index 5f926c4538c45b2a991a4d0c5ab36a12a5e17404..66657c5054b5c261a9f9c439f3644ef06a8e6dba 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.batch.scan;
 
+import com.google.common.collect.Maps;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.BatchExtension;
@@ -31,6 +32,8 @@ import org.sonar.api.batch.bootstrap.ProjectReactor;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.task.TaskExtension;
+import org.sonar.batch.bootstrap.BootstrapProperties;
+import org.sonar.batch.bootstrap.BootstrapSettings;
 import org.sonar.batch.bootstrap.ExtensionInstaller;
 import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
 import org.sonar.batch.scan.maven.MavenPluginExecutor;
@@ -42,17 +45,19 @@ import static org.mockito.Mockito.when;
 public class ProjectScanContainerTest {
 
   private ProjectBootstrapper projectBootstrapper;
+  private BootstrapSettings bootstrapSettings;
 
   @Before
   public void prepare() {
     projectBootstrapper = mock(ProjectBootstrapper.class);
     when(projectBootstrapper.bootstrap()).thenReturn(new ProjectReactor(ProjectDefinition.create()));
+    bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Maps.<String, String>newHashMap()));
   }
 
   @Test
   public void should_add_fake_maven_executor_on_non_maven_env() {
     ProjectScanContainer container = new ProjectScanContainer(new ComponentContainer());
-    container.add(mock(ExtensionInstaller.class), projectBootstrapper);
+    container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings);
     container.doBeforeStart();
 
     assertThat(container.getComponentByType(MavenPluginExecutor.class)).isNotNull();
@@ -61,7 +66,7 @@ public class ProjectScanContainerTest {
   @Test
   public void should_use_maven_executor_provided_by_maven() {
     ProjectScanContainer container = new ProjectScanContainer(new ComponentContainer());
-    container.add(mock(ExtensionInstaller.class), projectBootstrapper);
+    container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings);
     MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class);
     container.add(mavenPluginExecutor);
     container.doBeforeStart();
@@ -76,7 +81,7 @@ public class ProjectScanContainerTest {
     Settings settings = new Settings();
     parentContainer.add(settings);
     ProjectScanContainer container = new ProjectScanContainer(parentContainer);
-    container.add(mock(ExtensionInstaller.class), projectBootstrapper);
+    container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings);
     container.doBeforeStart();
 
     assertThat(container.getComponentsByType(PhasesSumUpTimeProfiler.class)).hasSize(0);
@@ -84,7 +89,7 @@ public class ProjectScanContainerTest {
     settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, "true");
 
     container = new ProjectScanContainer(parentContainer);
-    container.add(mock(ExtensionInstaller.class), projectBootstrapper);
+    container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings);
     container.doBeforeStart();
 
     assertThat(container.getComponentsByType(PhasesSumUpTimeProfiler.class)).hasSize(1);
index 076b04180afcacddacd3383d5bd3c70a2997e11b..fd3266f27a392a04b32d1dcfa854158dada93114 100644 (file)
@@ -32,7 +32,9 @@ import org.sonar.api.task.TaskExtension;
  * Only one instance is allowed per environment.
  *
  * @since 3.7
+ * @deprecated since 4.3 All bootstrappers should use SQ Runner API and provide a set of properties
  */
+@Deprecated
 public interface ProjectBootstrapper extends TaskExtension {
 
   /**