]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4069 ability to configure the phases to be executed
authorSimon Brandhof <simon.brandhof@gmail.com>
Fri, 15 Mar 2013 11:38:52 +0000 (12:38 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Fri, 15 Mar 2013 11:39:05 +0000 (12:39 +0100)
sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/Phases.java
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/scan/ScanTask.java
sonar-batch/src/test/java/org/sonar/batch/phases/PhaseExecutorTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/phases/PhasesTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ScanTaskTest.java

diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java
new file mode 100644 (file)
index 0000000..49091a2
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.phases;
+
+import com.google.common.collect.Lists;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.Project;
+import org.sonar.batch.events.EventBus;
+import org.sonar.batch.index.DefaultIndex;
+import org.sonar.batch.index.PersistenceManager;
+import org.sonar.batch.scan.filesystem.FileSystemLogger;
+import org.sonar.batch.scan.maven.MavenPhaseExecutor;
+import org.sonar.batch.scan.maven.MavenPluginsConfigurator;
+import org.sonar.core.component.ScanGraphStore;
+
+import java.util.Collection;
+
+public final class PhaseExecutor {
+
+  public static Collection<Class> getPhaseClasses() {
+    return Lists.<Class>newArrayList(DecoratorsExecutor.class, MavenPhaseExecutor.class, MavenPluginsConfigurator.class,
+      PostJobsExecutor.class, SensorsExecutor.class,
+      InitializersExecutor.class, ProjectInitializer.class, UpdateStatusJob.class);
+  }
+
+  private EventBus eventBus;
+  private Phases phases;
+  private DecoratorsExecutor decoratorsExecutor;
+  private MavenPhaseExecutor mavenPhaseExecutor;
+  private MavenPluginsConfigurator mavenPluginsConfigurator;
+  private PostJobsExecutor postJobsExecutor;
+  private InitializersExecutor initializersExecutor;
+  private SensorsExecutor sensorsExecutor;
+  private UpdateStatusJob updateStatusJob;
+  private PersistenceManager persistenceManager;
+  private SensorContext sensorContext;
+  private DefaultIndex index;
+  private ProjectInitializer pi;
+  private ScanGraphStore graphStorage;
+  private FileSystemLogger fsLogger;
+
+  public PhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
+                       MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
+                       PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
+                       PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
+                       EventBus eventBus, UpdateStatusJob updateStatusJob, ProjectInitializer pi,
+                       ScanGraphStore graphStorage, FileSystemLogger fsLogger) {
+    this.phases = phases;
+    this.decoratorsExecutor = decoratorsExecutor;
+    this.mavenPhaseExecutor = mavenPhaseExecutor;
+    this.mavenPluginsConfigurator = mavenPluginsConfigurator;
+    this.postJobsExecutor = postJobsExecutor;
+    this.initializersExecutor = initializersExecutor;
+    this.sensorsExecutor = sensorsExecutor;
+    this.persistenceManager = persistenceManager;
+    this.sensorContext = sensorContext;
+    this.index = index;
+    this.eventBus = eventBus;
+    this.updateStatusJob = updateStatusJob;
+    this.pi = pi;
+    this.graphStorage = graphStorage;
+    this.fsLogger = fsLogger;
+  }
+
+  public PhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
+                       MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
+                       PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
+                       PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
+                       EventBus eventBus, ProjectInitializer pi, ScanGraphStore graphStorage, FileSystemLogger fsLogger) {
+    this(phases, decoratorsExecutor, mavenPhaseExecutor, mavenPluginsConfigurator, initializersExecutor, postJobsExecutor,
+      sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi, graphStorage, fsLogger);
+  }
+
+  /**
+   * Executed on each module
+   */
+  public void execute(Project module) {
+    pi.execute(module);
+    eventBus.fireEvent(new ProjectAnalysisEvent(module, true));
+    if (phases.isEnabled(Phases.Phase.MAVEN)) {
+      mavenPluginsConfigurator.execute(module);
+      mavenPhaseExecutor.execute(module);
+    }
+    if (phases.isEnabled(Phases.Phase.INIT)) {
+      initializersExecutor.execute();
+      fsLogger.log();
+    }
+
+    persistenceManager.setDelayedMode(true);
+    if (phases.isEnabled(Phases.Phase.SENSOR)) {
+      sensorsExecutor.execute(sensorContext);
+    }
+    if (phases.isEnabled(Phases.Phase.DECORATOR)) {
+      decoratorsExecutor.execute();
+    }
+    persistenceManager.dump();
+    persistenceManager.setDelayedMode(false);
+
+    if (module.isRoot()) {
+      graphStorage.save();
+      if (updateStatusJob != null) {
+        updateStatusJob.execute();
+      }
+      if (phases.isEnabled(Phases.Phase.POSTJOB)) {
+        postJobsExecutor.execute(sensorContext);
+      }
+    }
+    cleanMemory();
+    eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
+  }
+
+  private void cleanMemory() {
+    persistenceManager.clear();
+    index.clear();
+  }
+}
index 2ad607cd0dc327e1272f7129eac84afeeef63bd1..2ccb0da0d053d638cfd79a42c57b1df5c688c2f5 100644 (file)
  */
 package org.sonar.batch.phases;
 
-import com.google.common.collect.Lists;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.resources.Project;
-import org.sonar.batch.events.EventBus;
-import org.sonar.batch.index.DefaultIndex;
-import org.sonar.batch.index.PersistenceManager;
-import org.sonar.batch.scan.filesystem.FileSystemLogger;
-import org.sonar.batch.scan.maven.MavenPhaseExecutor;
-import org.sonar.batch.scan.maven.MavenPluginsConfigurator;
-import org.sonar.core.component.ScanGraphStore;
+import com.google.common.collect.Sets;
 
-import java.util.Collection;
+import java.util.Arrays;
+import java.util.Set;
 
-public final class Phases {
+public class Phases {
 
-  public static Collection<Class> getPhaseClasses() {
-    return Lists.<Class>newArrayList(DecoratorsExecutor.class, MavenPhaseExecutor.class, MavenPluginsConfigurator.class,
-      PostJobsExecutor.class, SensorsExecutor.class,
-      InitializersExecutor.class, ProjectInitializer.class, UpdateStatusJob.class);
+  public static enum Phase {
+    MAVEN, INIT, SENSOR, DECORATOR, POSTJOB
   }
 
-  private EventBus eventBus;
-  private DecoratorsExecutor decoratorsExecutor;
-  private MavenPhaseExecutor mavenPhaseExecutor;
-  private MavenPluginsConfigurator mavenPluginsConfigurator;
-  private PostJobsExecutor postJobsExecutor;
-  private InitializersExecutor initializersExecutor;
-  private SensorsExecutor sensorsExecutor;
-  private UpdateStatusJob updateStatusJob;
-  private PersistenceManager persistenceManager;
-  private SensorContext sensorContext;
-  private DefaultIndex index;
-  private ProjectInitializer pi;
-  private ScanGraphStore graphStorage;
-  private FileSystemLogger fsLogger;
+  private final Set<Phase> enabled = Sets.newHashSet();
 
-  public Phases(DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
-                MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
-                PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
-                PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
-                EventBus eventBus, UpdateStatusJob updateStatusJob, ProjectInitializer pi,
-                ScanGraphStore graphStorage, FileSystemLogger fsLogger) {
-    this.decoratorsExecutor = decoratorsExecutor;
-    this.mavenPhaseExecutor = mavenPhaseExecutor;
-    this.mavenPluginsConfigurator = mavenPluginsConfigurator;
-    this.postJobsExecutor = postJobsExecutor;
-    this.initializersExecutor = initializersExecutor;
-    this.sensorsExecutor = sensorsExecutor;
-    this.persistenceManager = persistenceManager;
-    this.sensorContext = sensorContext;
-    this.index = index;
-    this.eventBus = eventBus;
-    this.updateStatusJob = updateStatusJob;
-    this.pi = pi;
-    this.graphStorage = graphStorage;
-    this.fsLogger = fsLogger;
+  public Phases enable(Phase... phases) {
+    enabled.addAll(Arrays.asList(phases));
+    return this;
   }
 
-  public Phases(DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
-                MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
-                PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
-                PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
-                EventBus eventBus, ProjectInitializer pi, ScanGraphStore graphStorage, FileSystemLogger fsLogger) {
-    this(decoratorsExecutor, mavenPhaseExecutor, mavenPluginsConfigurator, initializersExecutor, postJobsExecutor,
-      sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi, graphStorage, fsLogger);
+  public boolean isEnabled(Phase phase) {
+    return enabled.contains(phase);
   }
 
-  /**
-   * Executed on each module
-   */
-  public void execute(Project module) {
-    pi.execute(module);
-    eventBus.fireEvent(new ProjectAnalysisEvent(module, true));
-    mavenPluginsConfigurator.execute(module);
-    mavenPhaseExecutor.execute(module);
-    initializersExecutor.execute();
-    fsLogger.log();
-
-    persistenceManager.setDelayedMode(true);
-    sensorsExecutor.execute(sensorContext);
-    decoratorsExecutor.execute();
-    persistenceManager.dump();
-    persistenceManager.setDelayedMode(false);
-
-    if (module.isRoot()) {
-      graphStorage.save();
-      if (updateStatusJob != null) {
-        updateStatusJob.execute();
-      }
-      postJobsExecutor.execute(sensorContext);
-    }
-    cleanMemory();
-    eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
-  }
-
-  private void cleanMemory() {
-    persistenceManager.clear();
-    index.clear();
+  public boolean isFullyEnabled() {
+    return enabled.containsAll(Arrays.asList(Phase.values()));
   }
 }
index 0e001d1c3b735005970854686d3bf63626ed7291..8fdb47f966847b8c129043ab16936805d77afea6 100644 (file)
@@ -46,7 +46,7 @@ import org.sonar.batch.events.EventBus;
 import org.sonar.batch.index.DefaultIndex;
 import org.sonar.batch.index.ResourcePersister;
 import org.sonar.batch.local.DryRunExporter;
-import org.sonar.batch.phases.Phases;
+import org.sonar.batch.phases.PhaseExecutor;
 import org.sonar.batch.phases.PhasesTimeProfiler;
 import org.sonar.batch.scan.filesystem.DeprecatedFileSystemAdapter;
 import org.sonar.batch.scan.filesystem.ExclusionFilters;
@@ -83,10 +83,10 @@ public class ModuleScanContainer extends ComponentContainer {
 
     add(
       EventBus.class,
-      Phases.class,
+      PhaseExecutor.class,
       PhasesTimeProfiler.class,
       UnsupportedProperties.class,
-      Phases.getPhaseClasses(),
+      PhaseExecutor.getPhaseClasses(),
       moduleDefinition.getContainerExtensions(),
 
       // TODO move outside project, but not possible yet because of dependency of project settings (cf plsql)
@@ -140,7 +140,7 @@ public class ModuleScanContainer extends ComponentContainer {
       getComponentByType(ViolationFilters.class),
       getComponentByType(RulesProfile.class));
 
-    getComponentByType(Phases.class).execute(module);
+    getComponentByType(PhaseExecutor.class).execute(module);
   }
 
 }
index 01e6ad7b9b997744559a03fa25aaa15d8320b2d2..a6df4b096be79067811bc4ce0cd70a5786b6bfbf 100644 (file)
@@ -24,9 +24,9 @@ import org.sonar.api.platform.ComponentContainer;
 import org.sonar.api.task.Task;
 import org.sonar.api.task.TaskDefinition;
 import org.sonar.batch.bootstrap.TaskContainer;
+import org.sonar.batch.phases.Phases;
 
 public class ScanTask implements Task {
-
   public static final TaskDefinition DEFINITION = TaskDefinition.builder()
     .description("Scan project")
     .key(CoreProperties.SCAN_TASK)
@@ -40,7 +40,11 @@ public class ScanTask implements Task {
   }
 
   public void execute() {
-    new ProjectScanContainer(taskContainer).execute();
+    scan(new ProjectScanContainer(taskContainer));
   }
 
+  void scan(ComponentContainer scanContainer) {
+    scanContainer.add(new Phases().enable(Phases.Phase.values()));
+    scanContainer.execute();
+  }
 }
diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/PhaseExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/PhaseExecutorTest.java
new file mode 100644 (file)
index 0000000..47784cb
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.phases;
+
+import org.junit.Test;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PhaseExecutorTest {
+
+  @Test
+  public void shouldDefinePhaseClasses() {
+    assertThat(PhaseExecutor.getPhaseClasses().size()).isGreaterThan(4);
+  }
+
+}
index 0e4d0157a7ad521f111ddb1911c9f7a2647610eb..c7d4a558819035a30e35a50e7b5921e793d74015 100644 (file)
@@ -21,14 +21,36 @@ package org.sonar.batch.phases;
 
 import org.junit.Test;
 
-import static org.hamcrest.number.OrderingComparisons.greaterThan;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
 
 public class PhasesTest {
+  @Test
+  public void no_phase_should_be_enabled_by_default() {
+    Phases phases = new Phases();
+    assertThat(phases.isEnabled(Phases.Phase.DECORATOR)).isFalse();
+  }
 
   @Test
-  public void shouldDefinePhaseClasses() {
-    assertThat(Phases.getPhaseClasses().size(), greaterThan(4));
+  public void phase_should_be_enabled() {
+    Phases phases = new Phases();
+    phases.enable(Phases.Phase.SENSOR, Phases.Phase.DECORATOR);
+
+    assertThat(phases.isEnabled(Phases.Phase.DECORATOR)).isTrue();
+    assertThat(phases.isEnabled(Phases.Phase.SENSOR)).isTrue();
+    assertThat(phases.isEnabled(Phases.Phase.POSTJOB)).isFalse();
+    assertThat(phases.isFullyEnabled()).isFalse();
   }
 
+  @Test
+  public void all_phases_should_be_enabled() {
+    Phases phases = new Phases();
+    phases.enable(Phases.Phase.values());
+
+    assertThat(phases.isEnabled(Phases.Phase.INIT)).isTrue();
+    assertThat(phases.isEnabled(Phases.Phase.MAVEN)).isTrue();
+    assertThat(phases.isEnabled(Phases.Phase.DECORATOR)).isTrue();
+    assertThat(phases.isEnabled(Phases.Phase.SENSOR)).isTrue();
+    assertThat(phases.isEnabled(Phases.Phase.POSTJOB)).isTrue();
+    assertThat(phases.isFullyEnabled()).isTrue();
+  }
 }
index fcf4c52244a5a58e29c5feb4a3eb5b0fb8f5a51c..7f5b71697f4512add55e6298bd48f765e02021fa 100644 (file)
@@ -21,8 +21,12 @@ package org.sonar.batch.scan;
 
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
+import org.sonar.api.platform.ComponentContainer;
+import org.sonar.batch.bootstrap.TaskContainer;
+import org.sonar.batch.phases.Phases;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
 
 public class ScanTaskTest {
   @Test
@@ -30,4 +34,14 @@ public class ScanTaskTest {
     assertThat(ScanTask.DEFINITION).isNotNull();
     assertThat(ScanTask.DEFINITION.key()).isEqualTo(CoreProperties.SCAN_TASK);
   }
+
+  @Test
+  public void should_enable_all_phases() {
+    ScanTask task = new ScanTask(mock(TaskContainer.class));
+    ComponentContainer projectScanContainer = new ComponentContainer();
+    task.scan(projectScanContainer);
+
+    Phases phases = projectScanContainer.getComponentByType(Phases.class);
+    assertThat(phases.isFullyEnabled()).isTrue();
+  }
 }