]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11459 move dir and module issues to root
authorMichal Duda <michalno1@gmail.com>
Tue, 13 Nov 2018 10:00:42 +0000 (11:00 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 16 Jan 2019 08:43:00 +0000 (09:43 +0100)
13 files changed:
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/AbstractDefaultIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssueTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/TaskResult.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java

index a316dc2fbe8a40c911b88454cfd672b72d5e0967..58286e136e7030b949054a62cd4530bd5296eee5 100644 (file)
@@ -108,7 +108,7 @@ public class SensorContextTester implements SensorContext {
   private DefaultFileSystem fs;
   private ActiveRules activeRules;
   private InMemorySensorStorage sensorStorage;
-  private InputModule module;
+  private DefaultInputModule module;
   private SonarRuntime runtime;
   private boolean cancelled;
 
@@ -220,7 +220,7 @@ public class SensorContextTester implements SensorContext {
 
   @Override
   public NewIssue newIssue() {
-    return new DefaultIssue(sensorStorage);
+    return new DefaultIssue(module, sensorStorage);
   }
 
   public Collection<Issue> allIssues() {
@@ -229,7 +229,7 @@ public class SensorContextTester implements SensorContext {
 
   @Override
   public NewExternalIssue newExternalIssue() {
-    return new DefaultExternalIssue(sensorStorage);
+    return new DefaultExternalIssue(module, sensorStorage);
   }
 
   @Override
index 79a62e03cc46f03215ea1f0f82301cce264fb8d1..c993ee62d07d29d0019afa5ca7c5a280d46b3606 100644 (file)
 package org.sonar.api.batch.sensor.issue.internal;
 
 import com.google.common.base.Preconditions;
+import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
 import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.sensor.internal.DefaultStorable;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.Issue.Flow;
 import org.sonar.api.batch.sensor.issue.IssueLocation;
 import org.sonar.api.batch.sensor.issue.NewIssueLocation;
+import org.sonar.api.utils.PathUtils;
 
 import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Strings.isNullOrEmpty;
 import static java.util.Collections.unmodifiableList;
 import static java.util.stream.Collectors.toList;
 
-public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue>  extends DefaultStorable {
+public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> extends DefaultStorable {
   protected IssueLocation primaryLocation;
   protected List<List<IssueLocation>> flows = new ArrayList<>();
-  
-  protected AbstractDefaultIssue() {
-    super(null);
+  protected DefaultInputModule projectRoot;
+
+  protected AbstractDefaultIssue(DefaultInputModule projectRoot) {
+    this(projectRoot, null);
   }
-  
-  public AbstractDefaultIssue(@Nullable SensorStorage storage) {
+
+  public AbstractDefaultIssue(DefaultInputModule projectRoot, @Nullable SensorStorage storage) {
     super(storage);
+    this.projectRoot = projectRoot;
   }
-  
+
   public IssueLocation primaryLocation() {
     return primaryLocation;
   }
@@ -55,7 +65,7 @@ public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue>  exte
       .<Flow>map(l -> () -> unmodifiableList(new ArrayList<>(l)))
       .collect(toList());
   }
-  
+
   public NewIssueLocation newLocation() {
     return new DefaultIssueLocation();
   }
@@ -63,23 +73,50 @@ public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue>  exte
   public T at(NewIssueLocation primaryLocation) {
     Preconditions.checkArgument(primaryLocation != null, "Cannot use a location that is null");
     checkState(this.primaryLocation == null, "at() already called");
-    this.primaryLocation = (DefaultIssueLocation) primaryLocation;
+    this.primaryLocation = rewriteLocation((DefaultIssueLocation) primaryLocation);
     Preconditions.checkArgument(this.primaryLocation.inputComponent() != null, "Cannot use a location with no input component");
     return (T) this;
   }
 
   public T addLocation(NewIssueLocation secondaryLocation) {
-    flows.add(Arrays.asList((IssueLocation) secondaryLocation));
+    flows.add(Collections.singletonList(rewriteLocation((DefaultIssueLocation) secondaryLocation)));
     return (T) this;
   }
 
   public T addFlow(Iterable<NewIssueLocation> locations) {
     List<IssueLocation> flowAsList = new ArrayList<>();
     for (NewIssueLocation issueLocation : locations) {
-      flowAsList.add((DefaultIssueLocation) issueLocation);
+      flowAsList.add(rewriteLocation((DefaultIssueLocation) issueLocation));
     }
     flows.add(flowAsList);
     return (T) this;
   }
-  
+
+  private DefaultIssueLocation rewriteLocation(DefaultIssueLocation location) {
+    InputComponent component = location.inputComponent();
+    Optional<Path> dirOrModulePath = Optional.empty();
+
+    if (component instanceof DefaultInputDir) {
+      DefaultInputDir dirComponent = (DefaultInputDir) component;
+      dirOrModulePath = Optional.of(projectRoot.getBaseDir().relativize(dirComponent.path()));
+    } else if (component instanceof DefaultInputModule && !Objects.equals(projectRoot.key(), component.key())) {
+      DefaultInputModule moduleComponent = (DefaultInputModule) component;
+      dirOrModulePath = Optional.of(projectRoot.getBaseDir().relativize(moduleComponent.getBaseDir()));
+    }
+
+    if (dirOrModulePath.isPresent()) {
+      String path = PathUtils.sanitize(dirOrModulePath.get().toString());
+      DefaultIssueLocation fixedLocation = new DefaultIssueLocation();
+      fixedLocation.on(projectRoot);
+      StringBuilder fullMessage = new StringBuilder();
+      if (!isNullOrEmpty(path)) {
+        fullMessage.append("[").append(path).append("] ");
+      }
+      fullMessage.append(location.message());
+      fixedLocation.message(fullMessage.toString());
+      return fixedLocation;
+    } else {
+      return location;
+    }
+  }
 }
index facceda9c6cf1ed9c4fd2cbb5bdeaceae9bb40d7..a9b9cc1051da32ffc4799213cd77921ab4d5f425 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.api.batch.sensor.issue.internal;
 
 import com.google.common.base.Preconditions;
 import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.ExternalIssue;
@@ -39,12 +40,12 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs
   private String engineId;
   private String ruleId;
 
-  public DefaultExternalIssue() {
-    super(null);
+  public DefaultExternalIssue(DefaultInputModule projectRoot) {
+    this(projectRoot, null);
   }
 
-  public DefaultExternalIssue(@Nullable SensorStorage storage) {
-    super(storage);
+  public DefaultExternalIssue(DefaultInputModule projectRoot, @Nullable SensorStorage storage) {
+    super(projectRoot, storage);
   }
 
   @Override
index d936ba0937126968c3cc2d814e184b79a5dc19c7..1b7de9d9ab0c0d1fde44e57455c831c24b3b37d3 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.api.batch.sensor.issue.internal;
 
 import com.google.common.base.Preconditions;
 import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.Issue;
@@ -37,12 +38,12 @@ public class DefaultIssue extends AbstractDefaultIssue<DefaultIssue> implements
   private Double gap;
   private Severity overriddenSeverity;
 
-  public DefaultIssue() {
-    super(null);
+  public DefaultIssue(DefaultInputModule projectRoot) {
+    this(projectRoot, null);
   }
 
-  public DefaultIssue(@Nullable SensorStorage storage) {
-    super(storage);
+  public DefaultIssue(DefaultInputModule projectRoot, @Nullable SensorStorage storage) {
+    super(projectRoot, storage);
   }
 
   public DefaultIssue forRule(RuleKey ruleKey) {
@@ -54,7 +55,6 @@ public class DefaultIssue extends AbstractDefaultIssue<DefaultIssue> implements
     return this.ruleKey;
   }
 
-
   @Override
   public DefaultIssue gap(@Nullable Double gap) {
     Preconditions.checkArgument(gap == null || gap >= 0, format("Gap must be greater than or equal 0 (got %s)", gap));
index 33da8b1a2c15a68605577370d9671b79c7a9302d..6ef27d97f3cd2cd3ecf97d9dd0e4145999719da1 100644 (file)
  */
 package org.sonar.api.batch.sensor.issue.internal;
 
+import java.io.IOException;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
@@ -35,6 +40,20 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 public class DefaultExternalIssueTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  private DefaultInputModule projectRoot;
+
+  @Before
+  public void setup() throws IOException {
+    projectRoot = new DefaultInputModule(ProjectDefinition.create()
+      .setKey("foo")
+      .setBaseDir(temp.newFolder())
+      .setWorkDir(temp.newFolder()));
+  }
+
   @Rule
   public ExpectedException exception = ExpectedException.none();
 
@@ -45,7 +64,7 @@ public class DefaultExternalIssueTest {
   @Test
   public void build_file_issue() {
     SensorStorage storage = mock(SensorStorage.class);
-    DefaultExternalIssue issue = new DefaultExternalIssue(storage)
+    DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
         .on(inputFile)
         .at(inputFile.selectLine(1))
@@ -73,7 +92,7 @@ public class DefaultExternalIssueTest {
   @Test
   public void fail_to_store_if_no_type() {
     SensorStorage storage = mock(SensorStorage.class);
-    DefaultExternalIssue issue = new DefaultExternalIssue(storage)
+    DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
         .on(inputFile)
         .at(inputFile.selectLine(1))
@@ -90,7 +109,7 @@ public class DefaultExternalIssueTest {
   @Test
   public void fail_to_store_if_primary_location_is_not_a_file() {
     SensorStorage storage = mock(SensorStorage.class);
-    DefaultExternalIssue issue = new DefaultExternalIssue(storage)
+    DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
         .on(mock(InputComponent.class))
         .message("Wrong way!"))
@@ -102,11 +121,11 @@ public class DefaultExternalIssueTest {
     exception.expectMessage("External issues must be located in files");
     issue.save();
   }
-  
+
   @Test
   public void fail_to_store_if_primary_location_has_no_message() {
     SensorStorage storage = mock(SensorStorage.class);
-    DefaultExternalIssue issue = new DefaultExternalIssue(storage)
+    DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
         .on(inputFile)
         .at(inputFile.selectLine(1)))
@@ -123,7 +142,7 @@ public class DefaultExternalIssueTest {
   @Test
   public void fail_to_store_if_no_severity() {
     SensorStorage storage = mock(SensorStorage.class);
-    DefaultExternalIssue issue = new DefaultExternalIssue(storage)
+    DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
         .on(inputFile)
         .at(inputFile.selectLine(1))
index 37664b90cc3edc1ffed408392f8eb2515c9ffc36..5d36dcd2a9c88be2911232cf8c281372638755df 100644 (file)
@@ -19,7 +19,9 @@
  */
 package org.sonar.api.batch.sensor.issue.internal;
 
+import java.io.File;
 import java.io.IOException;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -41,14 +43,24 @@ public class DefaultIssueTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
+  private DefaultInputModule projectRoot;
+
   private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php")
     .initMetadata("Foo\nBar\n")
     .build();
 
+  @Before
+  public void prepare() throws IOException {
+    projectRoot = new DefaultInputModule(ProjectDefinition.create()
+      .setKey("foo")
+      .setBaseDir(temp.newFolder())
+      .setWorkDir(temp.newFolder()));
+  }
+
   @Test
   public void build_file_issue() {
     SensorStorage storage = mock(SensorStorage.class);
-    DefaultIssue issue = new DefaultIssue(storage)
+    DefaultIssue issue = new DefaultIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
         .on(inputFile)
         .at(inputFile.selectLine(1))
@@ -68,19 +80,50 @@ public class DefaultIssueTest {
   }
 
   @Test
-  public void build_directory_issue() {
+  public void move_directory_issue_to_project_root() {
     SensorStorage storage = mock(SensorStorage.class);
-    DefaultIssue issue = new DefaultIssue(storage)
+    DefaultIssue issue = new DefaultIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
-        .on(new DefaultInputDir("foo", "src"))
+        .on(new DefaultInputDir("foo", "src/main").setModuleBaseDir(projectRoot.getBaseDir()))
         .message("Wrong way!"))
       .forRule(RuleKey.of("repo", "rule"))
       .overrideSeverity(Severity.BLOCKER);
 
-    assertThat(issue.primaryLocation().inputComponent()).isEqualTo(new DefaultInputDir("foo", "src"));
+    assertThat(issue.primaryLocation().inputComponent()).isEqualTo(projectRoot);
     assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule"));
     assertThat(issue.primaryLocation().textRange()).isNull();
-    assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!");
+    assertThat(issue.primaryLocation().message()).isEqualTo("[src/main] Wrong way!");
+    assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER);
+
+    issue.save();
+
+    verify(storage).store(issue);
+  }
+
+  @Test
+  public void move_submodule_issue_to_project_root() {
+    File subModuleDirectory = new File(projectRoot.getBaseDir().toString(), "bar");
+    subModuleDirectory.mkdir();
+
+    ProjectDefinition subModuleDefinition = ProjectDefinition.create()
+      .setKey("foo/bar")
+      .setBaseDir(subModuleDirectory)
+      .setWorkDir(subModuleDirectory);
+    projectRoot.definition().addSubProject(subModuleDefinition);
+    DefaultInputModule subModule = new DefaultInputModule(subModuleDefinition);
+
+    SensorStorage storage = mock(SensorStorage.class);
+    DefaultIssue issue = new DefaultIssue(projectRoot, storage)
+      .at(new DefaultIssueLocation()
+        .on(subModule)
+        .message("Wrong way!"))
+      .forRule(RuleKey.of("repo", "rule"))
+      .overrideSeverity(Severity.BLOCKER);
+
+    assertThat(issue.primaryLocation().inputComponent()).isEqualTo(projectRoot);
+    assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule"));
+    assertThat(issue.primaryLocation().textRange()).isNull();
+    assertThat(issue.primaryLocation().message()).isEqualTo("[bar] Wrong way!");
     assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER);
 
     issue.save();
@@ -92,7 +135,7 @@ public class DefaultIssueTest {
   public void build_project_issue() throws IOException {
     SensorStorage storage = mock(SensorStorage.class);
     DefaultInputModule inputModule = new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-    DefaultIssue issue = new DefaultIssue(storage)
+    DefaultIssue issue = new DefaultIssue(projectRoot, storage)
       .at(new DefaultIssueLocation()
         .on(inputModule)
         .message("Wrong way!"))
index b510f895a51923a491c7be827229d76faf9023a9..d2ea968143351eaf779bd8abea6a16c1d3884341 100644 (file)
@@ -36,6 +36,7 @@ import org.sonar.api.batch.AnalysisMode;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputDir;
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
 import org.sonar.api.batch.fs.TextPointer;
 import org.sonar.api.batch.fs.TextRange;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
@@ -63,6 +64,7 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver
   private Map<String, InputFile> inputFiles = new HashMap<>();
   private Map<String, Component> reportComponents = new HashMap<>();
   private Map<String, InputDir> inputDirs = new HashMap<>();
+  private InputModule root;
   private ScannerReportReader reader;
 
   @Override
@@ -78,6 +80,8 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver
       Metadata readMetadata = getReportReader().readMetadata();
       int rootComponentRef = readMetadata.getRootComponentRef();
       storeReportComponents(rootComponentRef, null);
+      InputComponentStore inputFileCache = container.getComponentByType(InputComponentStore.class);
+      root = inputFileCache.root();
     }
 
     storeFs(container);
@@ -154,6 +158,10 @@ public class TaskResult implements org.sonar.scanner.mediumtest.ScanTaskObserver
     return result;
   }
 
+  public InputModule root() {
+    return root;
+  }
+
   public Collection<InputFile> inputFiles() {
     return inputFiles.values();
   }
index 1df2834b0ebc8a7ddd02e348ad146408f182f8f9..ed8640d773223f245cead3f1f7ce4e84a7d4144d 100644 (file)
@@ -27,6 +27,7 @@ import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputModule;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.code.NewSignificantCode;
@@ -79,9 +80,10 @@ public class DefaultSensorContext implements SensorContext {
   private final InputModule module;
   private final SonarRuntime sonarRuntime;
   private final Configuration config;
+  private final InputModuleHierarchy hierarchy;
 
   public DefaultSensorContext(InputModule module, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules,
-    AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime) {
+    AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime, InputModuleHierarchy hierarchy) {
     this.module = module;
     this.config = config;
     this.mutableSettings = mutableSettings;
@@ -90,6 +92,7 @@ public class DefaultSensorContext implements SensorContext {
     this.analysisMode = analysisMode;
     this.sensorStorage = sensorStorage;
     this.sonarRuntime = sonarRuntime;
+    this.hierarchy = hierarchy;
   }
 
   @Override
@@ -134,7 +137,7 @@ public class DefaultSensorContext implements SensorContext {
 
   @Override
   public NewIssue newIssue() {
-    return new DefaultIssue(sensorStorage);
+    return new DefaultIssue(hierarchy.root(), sensorStorage);
   }
 
   @Override
@@ -142,7 +145,7 @@ public class DefaultSensorContext implements SensorContext {
     if (analysisMode.isIssues()) {
       return NO_OP_NEW_EXTERNAL_ISSUE;
     }
-    return new DefaultExternalIssue(sensorStorage);
+    return new DefaultExternalIssue(hierarchy.root(), sensorStorage);
   }
 
   @Override
index ab8dd62ce5280e6e416e3197771cd27363da0273..f001bfc555d79ce51670eb39d5dc275c3850c059 100644 (file)
  */
 package org.sonar.scanner.issue;
 
+import java.io.IOException;
 import java.util.Collections;
 import java.util.HashSet;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.rule.internal.NewActiveRule;
@@ -57,6 +63,11 @@ public class ModuleIssuesTest {
   static final String SQUID_RULE_NAME = "Avoid Cycle";
   private static final RuleKey NOSONAR_RULE_KEY = RuleKey.of("squid", "NoSonarCheck");
 
+  private DefaultInputModule projectRoot;
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
   @Mock
   ModuleIssueFilters filters;
 
@@ -68,11 +79,19 @@ public class ModuleIssuesTest {
   DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.php").initMetadata("Foo\nBar\nBiz\n").build();
   ReportPublisher reportPublisher = mock(ReportPublisher.class, RETURNS_DEEP_STUBS);
 
+  @Before
+  public void prepare() throws IOException {
+    projectRoot = new DefaultInputModule(ProjectDefinition.create()
+      .setKey("foo")
+      .setBaseDir(temp.newFolder())
+      .setWorkDir(temp.newFolder()));
+  }
+
   @Test
   public void ignore_null_active_rule() {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
     initModuleIssues();
-    DefaultIssue issue = new DefaultIssue()
+    DefaultIssue issue = new DefaultIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo"))
       .forRule(SQUID_RULE_KEY);
     boolean added = moduleIssues.initAndAddIssue(issue);
@@ -87,7 +106,7 @@ public class ModuleIssuesTest {
     activeRulesBuilder.addRule(new NewActiveRule.Builder().setRuleKey(SQUID_RULE_KEY).setQProfileKey("qp-1").build());
     initModuleIssues();
 
-    DefaultIssue issue = new DefaultIssue()
+    DefaultIssue issue = new DefaultIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo"))
       .forRule(SQUID_RULE_KEY);
     boolean added = moduleIssues.initAndAddIssue(issue);
@@ -106,7 +125,7 @@ public class ModuleIssuesTest {
       .build());
     initModuleIssues();
 
-    DefaultIssue issue = new DefaultIssue()
+    DefaultIssue issue = new DefaultIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo"))
       .forRule(SQUID_RULE_KEY)
       .overrideSeverity(org.sonar.api.batch.rule.Severity.CRITICAL);
@@ -126,7 +145,7 @@ public class ModuleIssuesTest {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
     initModuleIssues();
 
-    DefaultExternalIssue issue = new DefaultExternalIssue()
+    DefaultExternalIssue issue = new DefaultExternalIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo"))
       .type(RuleType.BUG)
       .forRule(SQUID_RULE_KEY)
@@ -149,7 +168,7 @@ public class ModuleIssuesTest {
       .build());
     initModuleIssues();
 
-    DefaultIssue issue = new DefaultIssue()
+    DefaultIssue issue = new DefaultIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message("Foo"))
       .forRule(SQUID_RULE_KEY);
     when(filters.accept(anyString(), any(ScannerReport.Issue.class))).thenReturn(true);
@@ -170,7 +189,7 @@ public class ModuleIssuesTest {
       .build());
     initModuleIssues();
 
-    DefaultIssue issue = new DefaultIssue()
+    DefaultIssue issue = new DefaultIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message(""))
       .forRule(SQUID_RULE_KEY);
 
@@ -185,10 +204,14 @@ public class ModuleIssuesTest {
   @Test
   public void should_ignore_lines_commented_with_nosonar() {
     ruleBuilder.add(SQUID_RULE_KEY).setName(SQUID_RULE_NAME);
-    activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
+    activeRulesBuilder.addRule(new NewActiveRule.Builder()
+      .setRuleKey(SQUID_RULE_KEY)
+      .setSeverity(Severity.INFO)
+      .setQProfileKey("qp-1")
+      .build());
     initModuleIssues();
 
-    DefaultIssue issue = new DefaultIssue()
+    DefaultIssue issue = new DefaultIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message(""))
       .forRule(SQUID_RULE_KEY);
 
@@ -204,12 +227,16 @@ public class ModuleIssuesTest {
   public void should_accept_issues_on_no_sonar_rules() {
     // The "No Sonar" rule logs violations on the lines that are flagged with "NOSONAR" !!
     ruleBuilder.add(NOSONAR_RULE_KEY).setName("No Sonar");
-    activeRulesBuilder.create(NOSONAR_RULE_KEY).setSeverity(Severity.INFO).activate();
+    activeRulesBuilder.addRule(new NewActiveRule.Builder()
+      .setRuleKey(NOSONAR_RULE_KEY)
+      .setSeverity(Severity.INFO)
+      .setQProfileKey("qp-1")
+      .build());
     initModuleIssues();
 
     file.noSonarAt(new HashSet<>(Collections.singletonList(3)));
 
-    DefaultIssue issue = new DefaultIssue()
+    DefaultIssue issue = new DefaultIssue(projectRoot)
       .at(new DefaultIssueLocation().on(file).at(file.selectLine(3)).message(""))
       .forRule(NOSONAR_RULE_KEY);
 
index 674fcc347a7b10744d0ffe2cf1a5c170c71fb338..d30beea2c532e838efd43092ce6dfa312bc417f9 100644 (file)
@@ -36,6 +36,7 @@ import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.InputDir;
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputModule;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.utils.MessageException;
 import org.sonar.api.utils.System2;
@@ -432,9 +433,10 @@ public class FileSystemMediumTest {
       .execute();
 
     DefaultInputFile unknownInputFile = (DefaultInputFile) result.inputFile("src/unknown/file.notanalyzed");
-    InputDir unknownInputDir = result.inputDir("src/unknown");
+    InputModule root = result.root();
+
     assertThat(unknownInputFile.isPublished()).isFalse();
-    assertThat(result.getReportComponent(unknownInputDir.key())).isNotNull();
+    assertThat(result.getReportComponent(root.key())).isNotNull();
 
     // no issues on empty dir
     InputDir emptyInputDir = result.inputDir(emptyDirRelative.toString());
index 36bd841552c4a00838f5c31c7deea72849020853..95b92faf565560d857f5431c0ba37d4d73ca4e7b 100644 (file)
@@ -70,7 +70,8 @@ public class IssuesOnDirMediumTest {
         .build())
       .execute();
 
-    assertThat(result.issuesFor(result.inputDir("src"))).hasSize(2);
+    assertThat(result.issuesFor(result.inputDir("src"))).hasSize(0);
+    assertThat(result.issuesFor(result.root())).hasSize(2);
   }
 
   @Test
@@ -96,7 +97,8 @@ public class IssuesOnDirMediumTest {
         .build())
       .execute();
 
-    assertThat(result.issuesFor(result.inputDir(""))).hasSize(2);
+    assertThat(result.issuesFor(result.inputDir(""))).hasSize(0);
+    assertThat(result.issuesFor(result.root())).hasSize(2);
   }
 
 }
index 83ac5e1a97720cc36266736c876e98c8f291218d..9747021d1d99509336b3ac605454f69b95c2f449 100644 (file)
@@ -27,8 +27,11 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.SonarQubeSide;
 import org.sonar.api.SonarRuntime;
 import org.sonar.api.batch.AnalysisMode;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.InputModule;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
@@ -37,6 +40,7 @@ import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.internal.SonarRuntimeImpl;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.utils.Version;
+import org.sonar.scanner.scan.DefaultInputModuleHierarchy;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -57,6 +61,7 @@ public class DefaultSensorContextTest {
   private SensorStorage sensorStorage;
   private AnalysisMode analysisMode;
   private SonarRuntime runtime;
+  private InputModuleHierarchy hierarchy;
 
   @Before
   public void prepare() throws Exception {
@@ -69,7 +74,10 @@ public class DefaultSensorContextTest {
     sensorStorage = mock(SensorStorage.class);
     analysisMode = mock(AnalysisMode.class);
     runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER);
-    adaptor = new DefaultSensorContext(mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, analysisMode, sensorStorage, runtime);
+    hierarchy = new DefaultInputModuleHierarchy(new DefaultInputModule(ProjectDefinition.create()
+      .setWorkDir(temp.newFolder())
+      .setBaseDir(temp.newFolder()).setKey("foo")));
+    adaptor = new DefaultSensorContext(mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, analysisMode, sensorStorage, runtime, hierarchy);
   }
 
   @Test
index 1d05cfeb8f87ffaf7ff302d3c1dcaeed13ea4dee..a270f8076118510d004e2ee59550ce8d7e1ed6c9 100644 (file)
@@ -80,6 +80,7 @@ public class DefaultSensorStorageTest {
   private ScannerReportWriter reportWriter;
   private ContextPropertiesCache contextPropertiesCache = new ContextPropertiesCache();
   private BranchConfiguration branchConfiguration;
+  private DefaultInputModule projectRoot;
 
   @Before
   public void prepare() throws Exception {
@@ -101,6 +102,11 @@ public class DefaultSensorStorageTest {
     underTest = new DefaultSensorStorage(metricFinder,
       moduleIssues, settings.asConfig(), reportPublisher, measureCache,
       mock(SonarCpdBlockIndex.class), contextPropertiesCache, new ScannerMetrics(), branchConfiguration);
+
+    projectRoot = new DefaultInputModule(ProjectDefinition.create()
+      .setKey("foo")
+      .setBaseDir(temp.newFolder())
+      .setWorkDir(temp.newFolder()));
   }
 
   @Test
@@ -120,7 +126,7 @@ public class DefaultSensorStorageTest {
   public void should_save_issue() {
     InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build();
 
-    DefaultIssue issue = new DefaultIssue().at(new DefaultIssueLocation().on(file));
+    DefaultIssue issue = new DefaultIssue(projectRoot).at(new DefaultIssueLocation().on(file));
     underTest.store(issue);
 
     ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
@@ -132,7 +138,7 @@ public class DefaultSensorStorageTest {
   public void should_save_external_issue() {
     InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build();
 
-    DefaultExternalIssue externalIssue = new DefaultExternalIssue().at(new DefaultIssueLocation().on(file));
+    DefaultExternalIssue externalIssue = new DefaultExternalIssue(projectRoot).at(new DefaultIssueLocation().on(file));
     underTest.store(externalIssue);
 
     ArgumentCaptor<ExternalIssue> argumentCaptor = ArgumentCaptor.forClass(ExternalIssue.class);
@@ -145,7 +151,7 @@ public class DefaultSensorStorageTest {
     InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").setStatus(InputFile.Status.SAME).build();
     when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
 
-    DefaultIssue issue = new DefaultIssue().at(new DefaultIssueLocation().on(file));
+    DefaultIssue issue = new DefaultIssue(projectRoot).at(new DefaultIssueLocation().on(file));
     underTest.store(issue);
 
     verifyZeroInteractions(moduleIssues);