From: Julien HENRY Date: Thu, 19 Jun 2014 06:59:17 +0000 (+0200) Subject: SONAR-5389 Skipe execution of Analyzers according to provided metadata X-Git-Tag: 4.4-RC1~322 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e62ad022b7a4d608066eb2496e9f8c9767cb829b;p=sonarqube.git SONAR-5389 Skipe execution of Analyzers according to provided metadata --- diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java index fca38c4a4ce..622a7ef92b9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java @@ -29,6 +29,7 @@ import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.batch.scan.SensorWrapper; +import org.sonar.batch.scan2.AnalyzerOptimizer; import javax.annotation.Nullable; @@ -42,11 +43,13 @@ public class BatchExtensionDictionnary extends org.sonar.api.batch.BatchExtensio private FileSystem fs; private AnalyzerContext context; + private AnalyzerOptimizer analyzerOptimizer; - public BatchExtensionDictionnary(ComponentContainer componentContainer, FileSystem fs, AnalyzerContext context) { + public BatchExtensionDictionnary(ComponentContainer componentContainer, FileSystem fs, AnalyzerContext context, AnalyzerOptimizer analyzerOptimizer) { super(componentContainer); this.fs = fs; this.context = context; + this.analyzerOptimizer = analyzerOptimizer; } public Collection select(Class type, @Nullable Project project, boolean sort, @Nullable ExtensionMatcher matcher) { @@ -61,7 +64,7 @@ public class BatchExtensionDictionnary extends org.sonar.api.batch.BatchExtensio List result = Lists.newArrayList(); for (Object extension : getExtensions(type)) { if (type == Sensor.class && extension instanceof Analyzer) { - extension = new SensorWrapper((Analyzer) extension, context, fs); + extension = new SensorWrapper((Analyzer) extension, context, fs, analyzerOptimizer); } if (shouldKeep(type, extension, project, matcher)) { result.add((T) extension); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index a0584e490d9..0935b576062 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -81,6 +81,7 @@ import org.sonar.batch.scan.filesystem.PreviousFileHashLoader; import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter; import org.sonar.batch.scan.filesystem.StatusDetectionFactory; import org.sonar.batch.scan.report.JsonReport; +import org.sonar.batch.scan2.AnalyzerOptimizer; import org.sonar.core.component.ScanPerspectives; import org.sonar.core.measure.MeasurementFilters; @@ -137,6 +138,8 @@ public class ModuleScanContainer extends ComponentContainer { ProjectFileSystemAdapter.class, QProfileVerifier.class, + AnalyzerOptimizer.class, + // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor) getComponentByType(ResourcePersister.class).getSnapshot(module), diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java index ac53dbec1db..6f2e09acc3f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java @@ -29,6 +29,7 @@ import org.sonar.api.batch.analyzer.internal.DefaultAnalyzerDescriptor; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.measures.Metric; import org.sonar.api.resources.Project; +import org.sonar.batch.scan2.AnalyzerOptimizer; import java.util.Arrays; import java.util.List; @@ -39,9 +40,11 @@ public class SensorWrapper implements Sensor { private AnalyzerContext adaptor; private FileSystem fs; private DefaultAnalyzerDescriptor descriptor; + private AnalyzerOptimizer optimizer; - public SensorWrapper(Analyzer analyzer, AnalyzerContext adaptor, FileSystem fs) { + public SensorWrapper(Analyzer analyzer, AnalyzerContext adaptor, FileSystem fs, AnalyzerOptimizer optimizer) { this.analyzer = analyzer; + this.optimizer = optimizer; descriptor = new DefaultAnalyzerDescriptor(); analyzer.describe(descriptor); this.adaptor = adaptor; @@ -60,19 +63,7 @@ public class SensorWrapper implements Sensor { @Override public boolean shouldExecuteOnProject(Project project) { - if (!descriptor.languages().isEmpty()) { - if (project.getLanguageKey() != null && !descriptor.languages().contains(project.getLanguageKey())) { - return false; - } - boolean hasFile = false; - for (String languageKey : descriptor.languages()) { - hasFile |= fs.hasFiles(fs.predicates().hasLanguage(languageKey)); - } - if (!hasFile) { - return false; - } - } - return true; + return optimizer.shouldExecute(descriptor); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java new file mode 100644 index 00000000000..3ad0a29aa76 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java @@ -0,0 +1,49 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.scan2; + +import org.sonar.api.BatchComponent; +import org.sonar.api.batch.analyzer.internal.DefaultAnalyzerDescriptor; +import org.sonar.api.batch.fs.FilePredicate; +import org.sonar.api.batch.fs.FileSystem; + +public class AnalyzerOptimizer implements BatchComponent { + + private FileSystem fs; + + public AnalyzerOptimizer(FileSystem fs) { + this.fs = fs; + } + + /** + * Decide if the given Analyzer should be executed. + */ + public boolean shouldExecute(DefaultAnalyzerDescriptor descriptor) { + FilePredicate predicate = fs.predicates().hasLanguages(descriptor.languages()); + if (descriptor.types().size() == 1) { + // Size = 0 or Size = 2 means both main and test type + predicate = fs.predicates().and( + predicate, + fs.predicates().hasType(descriptor.types().iterator().next())); + } + return fs.hasFiles(predicate); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzersExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzersExecutor.java index f90cb5ad4a4..7bb802e301c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzersExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzersExecutor.java @@ -34,9 +34,11 @@ public class AnalyzersExecutor implements BatchComponent { private static final Logger LOG = LoggerFactory.getLogger(AnalyzersExecutor.class); private BatchExtensionDictionnary selector; + private AnalyzerOptimizer optimizer; - public AnalyzersExecutor(BatchExtensionDictionnary selector) { + public AnalyzersExecutor(BatchExtensionDictionnary selector, AnalyzerOptimizer optimizer) { this.selector = selector; + this.optimizer = optimizer; } public void execute(AnalyzerContext context) { @@ -47,6 +49,11 @@ public class AnalyzersExecutor implements BatchComponent { DefaultAnalyzerDescriptor descriptor = new DefaultAnalyzerDescriptor(); analyzer.describe(descriptor); + if (!optimizer.shouldExecute(descriptor)) { + LOG.debug("Analyzer skipped: " + descriptor.name()); + continue; + } + LOG.info("Execute analyzer: " + descriptor.name()); executeSensor(context, analyzer); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java index 6982d3da3b2..fc6c0e85b3b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java @@ -98,6 +98,8 @@ public class ModuleScanContainer extends ComponentContainer { ModuleFileSystemInitializer.class, QProfileVerifier.class, + AnalyzerOptimizer.class, + DefaultAnalyzerContext.class, BatchExtensionDictionnary.class, IssueFilters.class, diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java index ff878582c68..55518ac42d2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java @@ -19,15 +19,15 @@ */ package org.sonar.batch.bootstrap; -import org.sonar.api.batch.analyzer.AnalyzerContext; - import org.junit.Test; import org.sonar.api.BatchExtension; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.analyzer.AnalyzerContext; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; +import org.sonar.batch.scan2.AnalyzerOptimizer; import java.util.Collection; @@ -43,7 +43,7 @@ public class BatchExtensionDictionnaryTest { for (BatchExtension extension : extensions) { iocContainer.addSingleton(extension); } - return new BatchExtensionDictionnary(iocContainer, mock(FileSystem.class), mock(AnalyzerContext.class)); + return new BatchExtensionDictionnary(iocContainer, mock(FileSystem.class), mock(AnalyzerContext.class), mock(AnalyzerOptimizer.class)); } @Test diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/internal/DefaultAnalyzerDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/internal/DefaultAnalyzerDescriptor.java index 29fb8730fc1..9fc41b65dd0 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/internal/DefaultAnalyzerDescriptor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/internal/DefaultAnalyzerDescriptor.java @@ -50,8 +50,8 @@ public class DefaultAnalyzerDescriptor implements AnalyzerDescriptor { return Arrays.asList(languages); } - public InputFile.Type[] types() { - return types; + public Collection types() { + return Arrays.asList(types); } @Override