]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6457 Feed dependencies in batch report 280/head
authorJulien HENRY <julien.henry@sonarsource.com>
Mon, 4 May 2015 17:45:03 +0000 (19:45 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 5 May 2015 09:23:41 +0000 (11:23 +0200)
20 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/CountUnresolvedIssuesDecorator.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ManualMeasureDecorator.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/ProtobufUtil.java
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/output/BatchReportWriter.java
sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/dependency/package-info.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java
sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java

index afe895137bf92cd262e1b2d2dc166079a90743c9..1606b3aeaca8bd9482e5065711ef90c57563a3e0 100644 (file)
@@ -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;
index 3825b13348f90c1d51001f70904c3c00f9acc3db..a62c1af9748f45ba83966aaced0d3248bab7a6b2 100644 (file)
@@ -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;
index 169246a096fb7da0c6b0864ae76d6f86c4a5e4aa..49473602e35018e9d75e5a6cbb4eefe45fb28bc7 100644 (file)
  */
 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;
index a997423aa37721865086af5a2bab630f2031b2fb..36e525ecfb10575bfbffbe0dfd7f097eb894642f 100644 (file)
  */
 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<PastSnapshot> projectPastSnapshots;
index a2579c079373e953ac3258dbbc96688507f516a5..3b85d604365a4760f5f0716418481499d8add1ef 100644 (file)
@@ -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 <MESSAGE extends Message> void writeMessagesToFile(Iterable<MESSAGE> messages, File file) {
     try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {
       for (MESSAGE message : messages) {
index 33f651ace44055a5d363ae57a9b575592b731a70..9bfa1e5cad09cfe57e2dcc11d968251b9672413f 100644 (file)
@@ -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<BatchReport.ModuleDependencies.ModuleDependency> 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 (file)
index 6dd1202..0000000
+++ /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 (file)
index 50ce757..0000000
+++ /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<DefaultDependency> cache;
-
-  public DependencyCache(Caches caches) {
-    caches.registerValueCoder(DefaultDependency.class, new DefaultDependencyValueCoder());
-    cache = caches.createCache("dependencies");
-  }
-
-  public Iterable<Entry<DefaultDependency>> 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 (file)
index 56e93fe..0000000
+++ /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;
-
index c882eb9ef68b2bc64aa35be5de891adfa0a69176..5c4195bb7192a83fd0eaf38df2d5e3b88b674ea6 100644 (file)
  */
 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) {
index 13aa50590ca0cbd87d20f7406796287b176f4e7a..8aa0a88a5748508deb970db32ca28eb7e07b4368 100644 (file)
@@ -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<String, InputFile> inputFiles = new HashMap<>();
   private Map<String, Component> reportComponents = new HashMap<>();
   private Map<String, InputDir> inputDirs = new HashMap<>();
-  private Map<String, Map<String, Integer>> 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<DefaultDependency> entry : dependencyCache.entries()) {
-      String fromKey = entry.key()[1].toString();
-      String toKey = entry.key()[2].toString();
-      if (!dependencies.containsKey(fromKey)) {
-        dependencies.put(fromKey, new HashMap<String, Integer>());
-      }
-      dependencies.get(fromKey).put(toKey, entry.value().weight());
-    }
-  }
-
   public List<Issue> 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;
-  }
 }
index b555f76ded9737d62a4974b50f11c3cd935af2dc..69bc2daad89933849195ea9a107e181466753e4c 100644 (file)
  */
 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<Decorator> decorators = decoratorsSelector.select(project);
     eventBus.fireEvent(new DecoratorsPhaseEvent(Lists.newArrayList(decorators), true));
     ((DefaultDecoratorContext) decorateResource(project, decorators, true)).end();
index b157c30b64189bb7a541d97318b5766f2254f96d..ebf3d5c2d876140f35e5342fc5ff0f6bf1ab141f 100644 (file)
@@ -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(),
index e7a08a4a37cb30b9e5a081ce478aa797dcda5f0c..b09883aef7c4a50b77349d79df6cdbbe5d36ee28 100644 (file)
@@ -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.<String, String>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);
+
+  }
 }
index 530606f84baeb0d2fa2b47fe0ca1fc154eb95666..000c64140d0ec728cf2142fcb4d771dc450d5d3d 100644 (file)
@@ -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<Integer>()
       .forMetric(CoreMetrics.LINES)
index 066d11f0c19d8e00dab72d60fd86bf5b60b83742..7b6d86c8f11df573fe243a32af31d741b47d0aec 100644 (file)
@@ -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();
   }
 
 }
index 7b644d27530c4d326728a22309b3fbdc64d0b772..6ee9a66aab313a7f95193fe84b365f624607a52a 100644 (file)
@@ -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");
index 661135d15874594f40a5bc36bf6c5deec0cbfeec..b3f2792b5075ade7887244ff298091841c7b7001 100644 (file)
@@ -25,7 +25,6 @@ import org.sonar.api.resources.Resource;
 /**
  * @since 1.10
  */
-@RequiresDB
 public interface Decorator extends BatchExtension, CheckProject {
 
   /**
index ea6f38cc371c040de836525fa7bfa671f7a03891..8e42b40ab1e4ee078a4e89799e22a957f498ec62 100644 (file)
@@ -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)
index 59b2eb350b58aad6370b0fdb95b94889736e3685..3ea8f9ef4d31120abbc582b32f3458212947a08c 100644 (file)
@@ -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;
   }