From: Julien HENRY Date: Mon, 4 May 2015 17:45:03 +0000 (+0200) Subject: SONAR-6457 Feed dependencies in batch report X-Git-Tag: 5.2-RC1~2054^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fpull%2F280%2Fhead;p=sonarqube.git SONAR-6457 Feed dependencies in batch report --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java index afe895137bf..1606b3aeaca 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java @@ -19,9 +19,6 @@ */ package org.sonar.plugins.core.issue; -import org.sonar.batch.components.Period; - -import org.sonar.batch.components.TimeMachineConfiguration; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.*; import org.apache.commons.lang.time.DateUtils; @@ -35,6 +32,8 @@ import org.sonar.api.resources.Resource; import org.sonar.api.resources.ResourceUtils; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RulePriority; +import org.sonar.batch.components.Period; +import org.sonar.batch.components.TimeMachineConfiguration; import javax.annotation.Nullable; @@ -46,6 +45,7 @@ import java.util.*; * @since 3.6 */ @DependsUpon(DecoratorBarriers.ISSUES_TRACKED) +@RequiresDB public class CountUnresolvedIssuesDecorator implements Decorator { private final ResourcePerspectives perspectives; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java index 3825b13348f..a62c1af9748 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java @@ -22,6 +22,7 @@ package org.sonar.plugins.core.sensors; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.Phase; +import org.sonar.api.batch.RequiresDB; import org.sonar.api.database.DatabaseSession; import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; @@ -35,6 +36,7 @@ import java.util.List; import static com.google.common.base.Preconditions.checkState; @Phase(name = Phase.Name.PRE) +@RequiresDB public class ManualMeasureDecorator implements Decorator { private DatabaseSession session; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java index 169246a096f..49473602e35 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java @@ -19,10 +19,7 @@ */ package org.sonar.plugins.core.timemachine; -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DecoratorBarriers; -import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.*; import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.Snapshot; import org.sonar.api.resources.Project; @@ -37,6 +34,7 @@ import java.util.List; import static org.sonar.api.utils.DateUtils.dateToLong; @DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) +@RequiresDB public final class TimeMachineConfigurationPersister implements Decorator { private final TimeMachineConfiguration timeMachineConfiguration; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java index a997423aa37..36e525ecfb1 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java @@ -19,22 +19,10 @@ */ package org.sonar.plugins.core.timemachine; -import org.sonar.batch.components.TimeMachineConfiguration; - -import org.sonar.batch.components.PastSnapshot; -import org.sonar.batch.components.PastMeasuresLoader; import com.google.common.collect.Maps; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DecoratorBarriers; -import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.DependedUpon; -import org.sonar.api.batch.DependsUpon; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.MeasuresFilters; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.MetricFinder; -import org.sonar.api.measures.RuleMeasure; +import org.sonar.api.batch.*; +import org.sonar.api.measures.*; import org.sonar.api.resources.Project; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; @@ -42,6 +30,9 @@ import org.sonar.api.resources.Scopes; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.technicaldebt.batch.Characteristic; +import org.sonar.batch.components.PastMeasuresLoader; +import org.sonar.batch.components.PastSnapshot; +import org.sonar.batch.components.TimeMachineConfiguration; import javax.annotation.Nullable; @@ -50,6 +41,7 @@ import java.util.List; import java.util.Map; @DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) +@RequiresDB public class VariationDecorator implements Decorator { private List projectPastSnapshots; diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/ProtobufUtil.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/ProtobufUtil.java index a2579c07937..3b85d604365 100644 --- a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/ProtobufUtil.java +++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/ProtobufUtil.java @@ -45,6 +45,14 @@ public class ProtobufUtil { } } + public static void appendToFile(Message message, File toFile) { + try (OutputStream out = new BufferedOutputStream(new FileOutputStream(toFile, true))) { + message.writeDelimitedTo(out); + } catch (IOException e) { + throw new IllegalStateException("Unable to append protocol buffer data to file " + toFile, e); + } + } + public static void writeMessagesToFile(Iterable messages, File file) { try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) { for (MESSAGE message : messages) { diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportWriter.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportWriter.java index 33f651ace44..9bfa1e5cad0 100644 --- a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportWriter.java +++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportWriter.java @@ -130,6 +130,11 @@ public class BatchReportWriter { ProtobufUtil.writeMessagesToFile(fileDependencies, file); } + public void appendFileDependency(int componentRef, BatchReport.FileDependency fileDependency) { + File file = fileStructure.fileFor(FileStructure.Domain.FILE_DEPENDENCIES, componentRef); + ProtobufUtil.appendToFile(fileDependency, file); + } + public void writeModuleDependencies(int componentRef, Iterable dependencies) { BatchReport.ModuleDependencies.Builder builder = BatchReport.ModuleDependencies.newBuilder(); builder.addAllDep(dependencies); diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java deleted file mode 100644 index 6dd1202dc42..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.dependency; - -import com.persistit.Value; -import com.persistit.encoding.CoderContext; -import com.persistit.encoding.ValueCoder; -import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; - -class DefaultDependencyValueCoder implements ValueCoder { - - @Override - public void put(Value value, Object object, CoderContext context) { - DefaultDependency dep = (DefaultDependency) object; - value.putUTF(dep.fromKey()); - value.putUTF(dep.toKey()); - value.put(dep.weight()); - } - - @Override - public Object get(Value value, Class clazz, CoderContext context) { - String fromKey = value.getString(); - String toKey = value.getString(); - int weight = value.getInt(); - return new DefaultDependency() - .setFromKey(fromKey) - .setToKey(toKey) - .setWeight(weight); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java deleted file mode 100644 index 50ce7577c7b..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.dependency; - -import com.google.common.base.Preconditions; -import org.sonar.api.BatchComponent; -import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; -import org.sonar.batch.index.Cache; -import org.sonar.batch.index.Cache.Entry; -import org.sonar.batch.index.Caches; - -import javax.annotation.CheckForNull; - -/** - * Cache of all dependencies. This cache is shared amongst all project modules. - * module key -> from key -> to key -> Dependency - */ -public class DependencyCache implements BatchComponent { - - private final Cache cache; - - public DependencyCache(Caches caches) { - caches.registerValueCoder(DefaultDependency.class, new DefaultDependencyValueCoder()); - cache = caches.createCache("dependencies"); - } - - public Iterable> entries() { - return cache.entries(); - } - - @CheckForNull - public DefaultDependency get(String moduleKey, String fromKey, String toKey) { - Preconditions.checkNotNull(moduleKey); - Preconditions.checkNotNull(fromKey); - Preconditions.checkNotNull(toKey); - return cache.get(moduleKey, fromKey, toKey); - } - - public DependencyCache put(String moduleKey, DefaultDependency dependency) { - Preconditions.checkNotNull(moduleKey); - Preconditions.checkNotNull(dependency); - cache.put(moduleKey, dependency.fromKey(), dependency.toKey(), dependency); - return this; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/package-info.java deleted file mode 100644 index 56e93fec2f3..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/dependency/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.batch.dependency; - -import javax.annotation.ParametersAreNonnullByDefault; - diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java index c882eb9ef68..5c4195bb719 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java @@ -19,12 +19,12 @@ */ package org.sonar.batch.index; -import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.api.database.DatabaseSession; import org.sonar.api.design.Dependency; import org.sonar.api.design.DependencyDto; import org.sonar.api.resources.Project; -import org.sonar.batch.dependency.DependencyCache; +import org.sonar.batch.protocol.output.BatchReport; +import org.sonar.batch.report.ReportPublisher; import javax.annotation.Nullable; @@ -32,16 +32,17 @@ public final class DependencyPersister { private final ResourceCache resourceCache; private final DatabaseSession session; - private final DependencyCache dependencyCache; + private final ReportPublisher reportPublisher; + private final BatchReport.FileDependency.Builder builder = BatchReport.FileDependency.newBuilder(); - public DependencyPersister(ResourceCache resourceCache, DependencyCache dependencyCache, @Nullable DatabaseSession session) { + public DependencyPersister(ResourceCache resourceCache, ReportPublisher reportPublisher, @Nullable DatabaseSession session) { this.resourceCache = resourceCache; - this.dependencyCache = dependencyCache; + this.reportPublisher = reportPublisher; this.session = session; } - public DependencyPersister(ResourceCache resourceCache, DependencyCache dependencyCache) { - this(resourceCache, dependencyCache, null); + public DependencyPersister(ResourceCache resourceCache, ReportPublisher reportPublisher) { + this(resourceCache, reportPublisher, null); } public void saveDependency(Project project, Dependency dependency) { @@ -50,7 +51,8 @@ public final class DependencyPersister { BatchResource projectResource = resourceCache.get(project); if (fromResource.isFile() && toResource.isFile()) { - dependencyCache.put(project.getEffectiveKey(), new DefaultDependency().setFromKey(fromResource.key()).setToKey(toResource.key()).setWeight(dependency.getWeight())); + builder.clear(); + reportPublisher.getWriter().appendFileDependency(fromResource.batchId(), builder.setToFileRef(toResource.batchId()).setWeight(dependency.getWeight()).build()); } if (session != null) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java index 13aa50590ca..8aa0a88a574 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java @@ -29,14 +29,12 @@ import org.slf4j.LoggerFactory; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.*; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.api.batch.sensor.duplication.Duplication; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.issue.Issue; import org.sonar.api.issue.internal.DefaultIssue; import org.sonar.api.measures.Measure; -import org.sonar.batch.dependency.DependencyCache; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.Cache.Entry; import org.sonar.batch.index.ResourceCache; @@ -70,7 +68,6 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { private Map inputFiles = new HashMap<>(); private Map reportComponents = new HashMap<>(); private Map inputDirs = new HashMap<>(); - private Map> dependencies = new HashMap<>(); private BatchReportReader reader; @Override @@ -93,7 +90,6 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { storeMeasures(container); storeDuplication(container); - storeDependencies(container); } private void storeReportComponents(int componentRef, String parentModuleKey, @Nullable String branch) { @@ -152,18 +148,6 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { } } - private void storeDependencies(ProjectScanContainer container) { - DependencyCache dependencyCache = container.getComponentByType(DependencyCache.class); - for (Entry entry : dependencyCache.entries()) { - String fromKey = entry.key()[1].toString(); - String toKey = entry.key()[2].toString(); - if (!dependencies.containsKey(fromKey)) { - dependencies.put(fromKey, new HashMap()); - } - dependencies.get(fromKey).put(toKey, entry.value().weight()); - } - } - public List issues() { return issues; } @@ -288,6 +272,23 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { return null; } + public BatchReport.FileDependency fileDependencyFor(InputFile file, InputFile anotherFile) { + int ref = reportComponents.get(((DefaultInputFile) file).key()).getRef(); + int otherRef = reportComponents.get(((DefaultInputFile) anotherFile).key()).getRef(); + try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readFileDependencies(ref))) { + BatchReport.FileDependency dep = BatchReport.FileDependency.PARSER.parseDelimitedFrom(inputStream); + while (dep != null) { + if (dep.getToFileRef() == otherRef) { + return dep; + } + dep = BatchReport.FileDependency.PARSER.parseDelimitedFrom(inputStream); + } + } catch (Exception e) { + throw new IllegalStateException(e); + } + return null; + } + public BatchReport.CoverageDetail coveragePerTestFor(InputFile testFile, String testName) { int ref = reportComponents.get(((DefaultInputFile) testFile).key()).getRef(); try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readCoverageDetails(ref))) { @@ -303,14 +304,4 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { } return null; } - - /** - * @return null if no dependency else return dependency weight. - */ - @CheckForNull - public Integer dependencyWeight(InputFile from, InputFile to) { - String fromKey = ((DefaultInputFile) from).key(); - String toKey = ((DefaultInputFile) to).key(); - return dependencies.containsKey(fromKey) ? dependencies.get(fromKey).get(toKey) : null; - } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java index b555f76ded9..69bc2daad89 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java @@ -19,11 +19,9 @@ */ package org.sonar.batch.phases; -import org.sonar.batch.deprecated.decorator.DefaultDecoratorContext; - -import org.sonar.batch.deprecated.decorator.DecoratorsSelector; import com.google.common.collect.Lists; import org.sonar.api.BatchComponent; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.SonarIndex; @@ -33,6 +31,8 @@ import org.sonar.api.resources.Resource; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.SonarException; import org.sonar.batch.bootstrap.BatchExtensionDictionnary; +import org.sonar.batch.deprecated.decorator.DecoratorsSelector; +import org.sonar.batch.deprecated.decorator.DefaultDecoratorContext; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.events.EventBus; import org.sonar.batch.scan.measure.MeasureCache; @@ -43,21 +43,23 @@ import java.util.List; public class DecoratorsExecutor implements BatchComponent { - private DecoratorsSelector decoratorsSelector; - private SonarIndex index; - private EventBus eventBus; - private Project project; - private CoverageExclusions coverageFilter; - private MeasureCache measureCache; - private MetricFinder metricFinder; + private final DecoratorsSelector decoratorsSelector; + private final SonarIndex index; + private final EventBus eventBus; + private final Project project; + private final CoverageExclusions coverageFilter; + private final MeasureCache measureCache; + private final MetricFinder metricFinder; private final DuplicationCache duplicationCache; + private final AnalysisMode analysisMode; public DecoratorsExecutor(BatchExtensionDictionnary batchExtDictionnary, Project project, SonarIndex index, EventBus eventBus, CoverageExclusions coverageFilter, MeasureCache measureCache, MetricFinder metricFinder, - DuplicationCache duplicationCache) { + DuplicationCache duplicationCache, AnalysisMode analysisMode) { this.measureCache = measureCache; this.metricFinder = metricFinder; this.duplicationCache = duplicationCache; + this.analysisMode = analysisMode; this.decoratorsSelector = new DecoratorsSelector(batchExtDictionnary); this.index = index; this.eventBus = eventBus; @@ -66,6 +68,10 @@ public class DecoratorsExecutor implements BatchComponent { } public void execute() { + if (analysisMode.isPreview()) { + // Decorators are not executed in preview mode + return; + } Collection decorators = decoratorsSelector.select(project); eventBus.fireEvent(new DecoratorsPhaseEvent(Lists.newArrayList(decorators), true)); ((DefaultDecoratorContext) decorateResource(project, decorators, true)).end(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index b157c30b641..ebf3d5c2d87 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -37,7 +37,6 @@ import org.sonar.batch.ProjectTree; import org.sonar.batch.bootstrap.*; import org.sonar.batch.debt.DebtModelProvider; import org.sonar.batch.debt.IssueChangelogDebtCalculator; -import org.sonar.batch.dependency.DependencyCache; import org.sonar.batch.deprecated.components.DefaultResourceCreationLock; import org.sonar.batch.deprecated.components.PeriodsDefinition; import org.sonar.batch.duplication.DuplicationCache; @@ -169,7 +168,6 @@ public class ProjectScanContainer extends ComponentContainer { // Dependencies DependencyPersister.class, - DependencyCache.class, // Quality Gate new QualityGateProvider(), diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java index e7a08a4a37c..b09883aef7c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java @@ -19,6 +19,7 @@ */ package org.sonar.batch.mediumtest.dependency; +import com.google.common.base.Charsets; import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -87,8 +88,42 @@ public class DependencyMediumTest { .build()) .start(); - assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/sample2.xoo"))).isEqualTo(3); - assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/foo/sample3.xoo"))).isEqualTo(6); + assertThat(result.fileDependencyFor(result.inputFile("src/sample.xoo"), result.inputFile("src/sample2.xoo")).getWeight()).isEqualTo(3); + assertThat(result.fileDependencyFor(result.inputFile("src/sample.xoo"), result.inputFile("src/foo/sample3.xoo")).getWeight()).isEqualTo(6); } + @Test + public void manyDependenciesNoCycle() throws IOException { + + File baseDir = temp.newFolder(); + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + int nbFiles = 100; + for (int nb = 1; nb <= nbFiles; nb++) { + File xooFile = new File(srcDir, "dir1/sample" + nb + ".xoo"); + FileUtils.write(xooFile, "foo"); + File xooFile2 = new File(srcDir, "dir2/sample" + nb + ".xoo"); + FileUtils.write(xooFile2, "foo"); + File xooDepFile = new File(srcDir, "dir1/sample" + nb + ".xoo.deps"); + for (int otherId = 1; otherId <= nbFiles; otherId++) { + FileUtils.write(xooDepFile, "src/dir2/sample" + otherId + ".xoo:1\n", Charsets.UTF_8, true); + } + } + + TaskResult result = tester.newTask() + .properties(ImmutableMap.builder() + .put("sonar.task", "scan") + .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) + .put("sonar.projectKey", "com.foo.project") + .put("sonar.projectName", "Foo Project") + .put("sonar.projectVersion", "1.0-SNAPSHOT") + .put("sonar.projectDescription", "Description of Foo Project") + .put("sonar.sources", "src") + .build()) + .start(); + + assertThat(result.fileDependencyFor(result.inputFile("src/dir1/sample1.xoo"), result.inputFile("src/dir2/sample1.xoo")).getWeight()).isEqualTo(1); + + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java index 530606f84ba..000c64140d0 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java @@ -66,7 +66,7 @@ public class MeasuresMediumTest { .newScanTask(new File(projectDir, "sonar-project.properties")) .start(); - assertThat(result.allMeasures()).hasSize(20); + assertThat(result.allMeasures()).hasSize(58); } @Test @@ -93,7 +93,7 @@ public class MeasuresMediumTest { .build()) .start(); - assertThat(result.allMeasures()).hasSize(4); + assertThat(result.allMeasures()).hasSize(28); assertThat(result.allMeasures()).contains(new DefaultMeasure() .forMetric(CoreMetrics.LINES) diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java index 066d11f0c19..7b6d86c8f11 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java @@ -288,10 +288,12 @@ public class ScmMediumTest { .put("sonar.sources", "src") .put("sonar.scm.disabled", "true") .put("sonar.scm.provider", "xoo") + .put("sonar.cpd.xoo.skip", "true") .build()) .start(); - assertThat(result.allMeasures()).extracting("metric.key").containsOnly("lines", "quality_profiles"); + BatchReport.Changesets changesets = getChangesets(baseDir, 0); + assertThat(changesets).isNull(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java index 7b644d27530..6ee9a66aab3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java @@ -20,6 +20,7 @@ package org.sonar.batch.phases; import org.junit.Test; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.SonarIndex; @@ -67,7 +68,7 @@ public class DecoratorsExecutorTest { doThrow(new SonarException()).when(decorator).decorate(any(Resource.class), any(DecoratorContext.class)); DecoratorsExecutor executor = new DecoratorsExecutor(mock(BatchExtensionDictionnary.class), new Project("key"), mock(SonarIndex.class), - mock(EventBus.class), mock(CoverageExclusions.class), mock(MeasureCache.class), mock(MetricFinder.class), mock(DuplicationCache.class)); + mock(EventBus.class), mock(CoverageExclusions.class), mock(MeasureCache.class), mock(MetricFinder.class), mock(DuplicationCache.class), mock(AnalysisMode.class)); try { executor.executeDecorator(decorator, mock(DefaultDecoratorContext.class), File.create("src/org/foo/Bar.java", null, false)); fail("Exception has not been thrown"); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java index 661135d1587..b3f2792b507 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java @@ -25,7 +25,6 @@ import org.sonar.api.resources.Resource; /** * @since 1.10 */ -@RequiresDB public interface Decorator extends BatchExtension, CheckProject { /** diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java index ea6f38cc371..8e42b40ab1e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; * requires database access. As a result such extension will be disabled in preview mode. * * - * @since 3.4 + * @since 5.1 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java index 59b2eb350b5..3ea8f9ef4d3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java @@ -19,8 +19,6 @@ */ package org.sonar.api.batch.sensor.dependency.internal; -import org.sonar.api.batch.sensor.internal.SensorStorage; - import com.google.common.base.Preconditions; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; @@ -29,6 +27,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.dependency.Dependency; import org.sonar.api.batch.sensor.dependency.NewDependency; import org.sonar.api.batch.sensor.internal.DefaultStorable; +import org.sonar.api.batch.sensor.internal.SensorStorage; import javax.annotation.Nullable; @@ -62,7 +61,7 @@ public class DefaultDependency extends DefaultStorable implements Dependency, Ne @Override public DefaultDependency weight(int weight) { - Preconditions.checkArgument(weight > 1, "weight should be greater than 1"); + Preconditions.checkArgument(weight >= 1, "weight should be greater than 0"); this.weight = weight; return this; }