]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11459 Stop publishing modules and folders in the scanner report
authorJulien HENRY <julien.henry@sonarsource.com>
Fri, 16 Nov 2018 14:19:14 +0000 (15:19 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 16 Jan 2019 08:43:02 +0000 (09:43 +0100)
49 files changed:
server/sonar-server-common/src/main/java/org/sonar/server/config/ConfigurationProvider.java
sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java
sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputComponentTree.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/cpd/CpdMediumTest.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/mediumtest/issues/IssuesOnModuleMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultComponentTreeTest.java [deleted file]
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java
sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report-without-resolved-issues.json
sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report.json
sonar-scanner-protocol/src/main/protobuf/scanner_report.proto

index 237b4443460a71557421c93b197188022a92a78d..bd3ff03f8f88e517f8ff45c0a2db146c899a6073 100644 (file)
@@ -28,7 +28,7 @@ import org.sonar.api.config.PropertyDefinition;
 import org.sonar.api.config.Settings;
 
 import static java.util.function.Function.identity;
-import static org.sonar.core.config.MultivalueProperty.parseAsCsv;
+import static org.sonar.api.config.internal.MultivalueProperty.parseAsCsv;
 
 public class ConfigurationProvider extends ProviderAdapter {
 
index 0b2285aaaae1e9c19369320aca4e0b22dd4ded8f..440f7339f1f04037a1bf8f98f82d32ffc59cafc8 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.core.component;
 
 import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
-import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
@@ -46,8 +46,8 @@ public final class ComponentKeys {
     // only static stuff
   }
 
-  public static String createEffectiveKey(String projectKey, InputPath inputPath) {
-    return createEffectiveKey(projectKey, inputPath.relativePath());
+  public static String createEffectiveKey(String projectKey, DefaultInputFile inputPath) {
+    return createEffectiveKey(projectKey, inputPath.getProjectRelativePath());
   }
 
   public static String createEffectiveKey(String projectKey, @Nullable String path) {
index 954c016b0102968fd7833cafb2e00b3ccb75776f..f2104fbcab459c71fb91110b4014e1f29354e534 100644 (file)
  */
 package org.sonar.core.component;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class ComponentKeysTest {
   @Rule
@@ -34,8 +34,8 @@ public class ComponentKeysTest {
 
   @Test
   public void create_effective_key() {
-    InputFile file = mock(InputFile.class);
-    when(file.relativePath()).thenReturn("foo/Bar.php");
+    DefaultInputFile file = mock(DefaultInputFile.class);
+    when(file.getProjectRelativePath()).thenReturn("foo/Bar.php");
     assertThat(ComponentKeys.createEffectiveKey("my_project", file)).isEqualTo("my_project:foo/Bar.php");
   }
 
index 705934458b44c9e653cce6bf7d13421dbed30d43..433c87c57bbce1798abeedb9ddffb18e6c72f531 100644 (file)
@@ -165,9 +165,6 @@ public interface FileSystem {
     @CheckForNull
     InputFile inputFile(String relativePath);
 
-    @CheckForNull
-    InputDir inputDir(String relativePath);
-
     /**
      * @since 6.3
      */
index 096d0eb5d0334d2b9052f5c0f6b4f71975b48722..ee90497714da21fb299781eb2dae86da01b39928 100644 (file)
@@ -172,7 +172,8 @@ public class DefaultFileSystem implements FileSystem {
     if (relativePath == null) {
       return null;
     }
-    return cache.inputDir(relativePath);
+    // Issues on InputDir are moved to the project, so we just return a fake InputDir for backward compatibility
+    return new DefaultInputDir("unused", relativePath).setModuleBaseDir(baseDir);
   }
 
   public DefaultFileSystem add(InputFile inputFile) {
@@ -180,11 +181,6 @@ public class DefaultFileSystem implements FileSystem {
     return this;
   }
 
-  public DefaultFileSystem add(DefaultInputDir inputDir) {
-    cache.add(inputDir);
-    return this;
-  }
-
   @Override
   public SortedSet<String> languages() {
     return cache.languages();
@@ -199,16 +195,10 @@ public class DefaultFileSystem implements FileSystem {
 
     protected abstract void doAdd(InputFile inputFile);
 
-    protected abstract void doAdd(InputDir inputDir);
-
     final void add(InputFile inputFile) {
       doAdd(inputFile);
     }
 
-    public void add(InputDir inputDir) {
-      doAdd(inputDir);
-    }
-
     protected abstract SortedSet<String> languages();
   }
 
@@ -217,7 +207,6 @@ public class DefaultFileSystem implements FileSystem {
    */
   private static class MapCache extends Cache {
     private final Map<String, InputFile> fileMap = new HashMap<>();
-    private final Map<String, InputDir> dirMap = new HashMap<>();
     private final SetMultimap<String, InputFile> filesByNameCache = LinkedHashMultimap.create();
     private final SetMultimap<String, InputFile> filesByExtensionCache = LinkedHashMultimap.create();
     private SortedSet<String> languages = new TreeSet<>();
@@ -232,11 +221,6 @@ public class DefaultFileSystem implements FileSystem {
       return fileMap.get(relativePath);
     }
 
-    @Override
-    public InputDir inputDir(String relativePath) {
-      return dirMap.get(relativePath);
-    }
-
     @Override
     public Iterable<InputFile> getFilesByName(String filename) {
       return filesByNameCache.get(filename);
@@ -257,11 +241,6 @@ public class DefaultFileSystem implements FileSystem {
       filesByExtensionCache.put(FileExtensionPredicate.getExtension(inputFile), inputFile);
     }
 
-    @Override
-    protected void doAdd(InputDir inputDir) {
-      dirMap.put(inputDir.relativePath(), inputDir);
-    }
-
     @Override
     protected SortedSet<String> languages() {
       return languages;
index 5b3bdf7a67190b917e0d44e4448b416dd436c1f9..1488121129c79463cfc08261ea47a6deefa22aa3 100644 (file)
@@ -39,7 +39,7 @@ import org.sonar.api.utils.PathUtils;
 public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile {
   private final String projectRelativePath;
   private final String moduleRelativePath;
-  private final String moduleKey;
+  private final String projectKey;
   private final String language;
   private final Type type;
   private final Path absolutePath;
@@ -48,15 +48,15 @@ public class DefaultIndexedFile extends DefaultInputComponent implements Indexed
   /**
    * Testing purposes only!
    */
-  public DefaultIndexedFile(String moduleKey, Path baseDir, String relativePath, @Nullable String language) {
-    this(baseDir.resolve(relativePath), moduleKey, relativePath, relativePath, Type.MAIN, language, TestInputFileBuilder.nextBatchId(),
+  public DefaultIndexedFile(String projectKey, Path baseDir, String relativePath, @Nullable String language) {
+    this(baseDir.resolve(relativePath), projectKey, relativePath, relativePath, Type.MAIN, language, TestInputFileBuilder.nextBatchId(),
       new SensorStrategy());
   }
 
-  public DefaultIndexedFile(Path absolutePath, String moduleKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId,
+  public DefaultIndexedFile(Path absolutePath, String projectKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId,
     SensorStrategy sensorStrategy) {
     super(batchId);
-    this.moduleKey = moduleKey;
+    this.projectKey = projectKey;
     this.projectRelativePath = PathUtils.sanitize(projectRelativePath);
     this.moduleRelativePath = PathUtils.sanitize(moduleRelativePath);
     this.type = type;
@@ -114,11 +114,7 @@ public class DefaultIndexedFile extends DefaultInputComponent implements Indexed
    */
   @Override
   public String key() {
-    return new StringBuilder().append(moduleKey).append(":").append(moduleRelativePath).toString();
-  }
-
-  public String moduleKey() {
-    return moduleKey;
+    return new StringBuilder().append(projectKey).append(":").append(projectRelativePath).toString();
   }
 
   @Override
index 7138f95adcc7ccbe91c0836af6eb3a49d66cb3bd..9908523fc9ab5a24807176094a354d6377453074 100644 (file)
@@ -27,8 +27,8 @@ import org.sonar.api.batch.fs.InputComponent;
 public abstract class DefaultInputComponent implements InputComponent {
   private int id;
 
-  public DefaultInputComponent(int batchId) {
-    this.id = batchId;
+  public DefaultInputComponent(int scannerId) {
+    this.id = scannerId;
   }
 
   @Override
index 32b8ad6cb23f08d9f79ec82d6850900a24c26b92..14a39ee1b32953cf088630a9ef58081a99e5a865 100644 (file)
@@ -36,11 +36,7 @@ public class DefaultInputDir extends DefaultInputComponent implements InputDir {
   private Path moduleBaseDir;
 
   public DefaultInputDir(String moduleKey, String relativePath) {
-    this(moduleKey, relativePath, TestInputFileBuilder.nextBatchId());
-  }
-
-  public DefaultInputDir(String moduleKey, String relativePath, int batchId) {
-    super(batchId);
+    super(-1);
     this.moduleKey = moduleKey;
     this.relativePath = PathUtils.sanitize(relativePath);
   }
index efa7804d512f774960a8c2d1b47c1f433b4f155a..01316b2ad30bf460cd0118ef382d04ad40023185 100644 (file)
@@ -174,10 +174,6 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
     return indexedFile.key();
   }
 
-  public String moduleKey() {
-    return indexedFile.moduleKey();
-  }
-
   @Override
   public int hashCode() {
     return indexedFile.hashCode();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputComponentTree.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputComponentTree.java
deleted file mode 100644 (file)
index ddb76b8..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.api.batch.fs.internal;
-
-import java.util.Collection;
-
-import org.sonar.api.batch.fs.InputComponent;
-
-public interface InputComponentTree {
-  Collection<InputComponent> getChildren(InputComponent module);
-
-  InputComponent getParent(InputComponent module);
-}
index d84961b76c52b959307969da3c16cd91f64df170..00f9319c2d466e6bba7b48c3c2b972d6d89ef3c5 100644 (file)
@@ -36,19 +36,19 @@ import org.sonar.api.utils.PathUtils;
 /**
  * Intended to be used in unit tests that need to create {@link InputFile}s.
  * An InputFile is unambiguously identified by a <b>module key</b> and a <b>relative path</b>, so these parameters are mandatory.
- * 
+ * <p>
  * A module base directory is only needed to construct absolute paths.
- * 
+ * <p>
  * Examples of usage of the constructors:
- * 
+ *
  * <pre>
  * InputFile file1 = TestInputFileBuilder.create("module1", "myfile.java").build();
  * InputFile file2 = TestInputFileBuilder.create("", fs.baseDir(), myfile).build();
  * </pre>
- * 
+ * <p>
  * file1 will have the "module1" as both module key and module base directory.
  * file2 has an empty string as module key, and a relative path which is the path from the filesystem base directory to myfile.
- * 
+ *
  * @since 6.3
  */
 public class TestInputFileBuilder {
@@ -56,7 +56,7 @@ public class TestInputFileBuilder {
 
   private final int id;
   private final String relativePath;
-  private final String moduleKey;
+  private final String projectKey;
   @CheckForNull
   private Path projectBaseDir;
   private Path moduleBaseDir;
@@ -74,29 +74,28 @@ public class TestInputFileBuilder {
   private String contents;
 
   /**
-   * Create a InputFile identified by the given module key and relative path.
-   * The module key will also be used as the module's base directory. 
+   * Create a InputFile identified by the given project key and relative path.
    */
-  public TestInputFileBuilder(String moduleKey, String relativePath) {
-    this(moduleKey, relativePath, batchId++);
+  public TestInputFileBuilder(String projectKey, String relativePath) {
+    this(projectKey, relativePath, batchId++);
   }
 
   /**
    * Create a InputFile with a given module key and module base directory.
-   * The relative path is generated comparing the file path to the module base directory. 
+   * The relative path is generated comparing the file path to the module base directory.
    * filePath must point to a file that is within the module base directory.
    */
-  public TestInputFileBuilder(String moduleKey, File moduleBaseDir, File filePath) {
+  public TestInputFileBuilder(String projectKey, File moduleBaseDir, File filePath) {
     String relativePath = moduleBaseDir.toPath().relativize(filePath.toPath()).toString();
-    this.moduleKey = moduleKey;
+    this.projectKey = projectKey;
     setModuleBaseDir(moduleBaseDir.toPath());
     this.relativePath = PathUtils.sanitize(relativePath);
     this.id = batchId++;
   }
 
-  public TestInputFileBuilder(String moduleKey, String relativePath, int id) {
-    this.moduleKey = moduleKey;
-    setModuleBaseDir(Paths.get(moduleKey));
+  public TestInputFileBuilder(String projectKey, String relativePath, int id) {
+    this.projectKey = projectKey;
+    setModuleBaseDir(Paths.get(projectKey));
     this.relativePath = PathUtils.sanitize(relativePath);
     this.id = id;
   }
@@ -217,7 +216,7 @@ public class TestInputFileBuilder {
       projectBaseDir = moduleBaseDir;
     }
     String projectRelativePath = projectBaseDir.relativize(absolutePath).toString();
-    DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, moduleKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy());
+    DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, projectKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy());
     DefaultInputFile inputFile = new DefaultInputFile(indexedFile,
       f -> f.setMetadata(new Metadata(lines, nonBlankLines, hash, originalLineStartOffsets, originalLineEndOffsets, lastValidOffset)),
       contents);
index aa6ed4c7d974ad741aafa109474810ebe5260c28..cc2d186da447ac59546b9bfeb4fbd1e6666dfc40 100644 (file)
@@ -33,11 +33,11 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class PathPatternTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
-  private Path moduleBasePath;
+  private Path baseDir;
 
   @Before
   public void setUp() throws IOException {
-    moduleBasePath = temp.newFolder().toPath();
+    baseDir = temp.newFolder().toPath();
   }
 
   @Test
@@ -45,14 +45,14 @@ public class PathPatternTest {
     PathPattern pattern = PathPattern.create("**/*Foo.java");
     assertThat(pattern.toString()).isEqualTo("**/*Foo.java");
 
-    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.java", null);
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/MyFoo.java", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()))).isTrue();
 
     // case sensitive by default
-    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA", null);
+    indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/MyFoo.JAVA", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()))).isFalse();
 
-    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java", null);
+    indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/Other.java", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()))).isFalse();
   }
 
@@ -60,10 +60,10 @@ public class PathPatternTest {
   public void match_relative_path_and_insensitive_file_extension() throws Exception {
     PathPattern pattern = PathPattern.create("**/*Foo.java");
 
-    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA", null);
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/MyFoo.JAVA", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()), false)).isTrue();
 
-    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java", null);
+    indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/Other.java", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()), false)).isFalse();
   }
 
@@ -72,14 +72,14 @@ public class PathPatternTest {
     PathPattern pattern = PathPattern.create("file:**/src/main/**Foo.java");
     assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java");
 
-    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.java", null);
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/MyFoo.java", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()))).isTrue();
 
     // case sensitive by default
-    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA", null);
+    indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/MyFoo.JAVA", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()))).isFalse();
 
-    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.java", null);
+    indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/Other.java", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()))).isFalse();
   }
 
@@ -88,10 +88,10 @@ public class PathPatternTest {
     PathPattern pattern = PathPattern.create("file:**/src/main/**Foo.java");
     assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java");
 
-    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/MyFoo.JAVA", null);
+    IndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/MyFoo.JAVA", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()), false)).isTrue();
 
-    indexedFile = new DefaultIndexedFile("ABCDE", moduleBasePath, "src/main/java/org/Other.JAVA", null);
+    indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/main/java/org/Other.JAVA", null);
     assertThat(pattern.match(indexedFile.path(), Paths.get(indexedFile.relativePath()), false)).isFalse();
   }
 
index bf0264252058574d011a854e7bc2ef8e8ffd8d92..7e496fd478b0f6e9eb6140ef5655a097d7598601 100644 (file)
@@ -31,14 +31,12 @@ import java.util.Map;
 import java.util.stream.Stream;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import org.sonar.api.batch.ScannerSide;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.api.batch.fs.InputModule;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.AbstractProjectOrModule;
-import org.sonar.api.batch.fs.internal.InputComponentTree;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
 import org.sonar.api.batch.rule.ActiveRule;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.core.issue.tracking.Input;
@@ -49,22 +47,21 @@ import org.sonar.scanner.issue.IssueTransformer;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.scanner.repository.ProjectRepositories;
 
-@ScannerSide
 public class LocalIssueTracking {
+  private final DefaultInputProject project;
   private final Tracker<TrackedIssue, ServerIssueFromWs> tracker;
   private final ServerLineHashesLoader lastLineHashes;
   private final ActiveRules activeRules;
   private final ServerIssueRepository serverIssueRepository;
   private final DefaultAnalysisMode mode;
-  private final InputComponentTree componentTree;
 
   private boolean hasServerAnalysis;
 
-  public LocalIssueTracking(Tracker<TrackedIssue, ServerIssueFromWs> tracker, ServerLineHashesLoader lastLineHashes, InputComponentTree componentTree,
-    ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) {
+  public LocalIssueTracking(DefaultInputProject project, Tracker<TrackedIssue, ServerIssueFromWs> tracker, ServerLineHashesLoader lastLineHashes,
+                            ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) {
+    this.project = project;
     this.tracker = tracker;
     this.lastLineHashes = lastLineHashes;
-    this.componentTree = componentTree;
     this.serverIssueRepository = serverIssueRepository;
     this.mode = mode;
     this.activeRules = activeRules;
@@ -102,7 +99,7 @@ public class LocalIssueTracking {
       }
     }
 
-    if (hasServerAnalysis && componentTree.getParent(component) == null) {
+    if (hasServerAnalysis && !component.isFile()) {
       Preconditions.checkState(component instanceof InputModule, "Object without parent is of type: " + component.getClass());
       // issues that relate to deleted components
       addIssuesOnDeletedComponents(trackedIssues, component.key());
@@ -165,9 +162,8 @@ public class LocalIssueTracking {
   private SourceHashHolder loadSourceHashes(InputComponent component) {
     SourceHashHolder sourceHashHolder = null;
     if (component.isFile()) {
-      AbstractProjectOrModule module = (AbstractProjectOrModule) componentTree.getParent(componentTree.getParent(component));
       DefaultInputFile file = (DefaultInputFile) component;
-      sourceHashHolder = new SourceHashHolder(module, file, lastLineHashes);
+      sourceHashHolder = new SourceHashHolder(project, file, lastLineHashes);
     }
     return sourceHashHolder;
   }
index b1b56be89a8660ea3382a4040d42f2662d78620e..48721f3cbdd37ee89480531d86d37f98dddb8034 100644 (file)
  */
 package org.sonar.scanner.issue.tracking;
 
-import java.util.Collection;
-import java.util.Collections;
 import javax.annotation.CheckForNull;
 import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.AbstractProjectOrModule;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
 import org.sonar.core.component.ComponentKeys;
 
 public class SourceHashHolder {
 
-  private final AbstractProjectOrModule module;
+  private final DefaultInputProject project;
   private final DefaultInputFile inputFile;
   private final ServerLineHashesLoader lastSnapshots;
 
   private FileHashes hashedReference;
   private FileHashes hashedSource;
 
-  public SourceHashHolder(AbstractProjectOrModule module, DefaultInputFile inputFile, ServerLineHashesLoader lastSnapshots) {
-    this.module = module;
+  public SourceHashHolder(DefaultInputProject project, DefaultInputFile inputFile, ServerLineHashesLoader lastSnapshots) {
+    this.project = project;
     this.inputFile = inputFile;
     this.lastSnapshots = lastSnapshots;
   }
@@ -52,7 +50,7 @@ public class SourceHashHolder {
         hashedReference = hashedSource;
       } else {
         // Need key with branch
-        String serverSideKey = ComponentKeys.createEffectiveKey(module.definition().getKeyWithBranch(), inputFile);
+        String serverSideKey = ComponentKeys.createEffectiveKey(project.getKeyWithBranch(), inputFile);
         String[] lineHashes = lastSnapshots.getLineHashes(serverSideKey);
         hashedReference = lineHashes != null ? FileHashes.create(lineHashes) : null;
       }
@@ -69,13 +67,4 @@ public class SourceHashHolder {
     initHashes();
     return hashedSource;
   }
-
-  public Collection<Integer> getNewLinesMatching(Integer originLine) {
-    FileHashes reference = getHashedReference();
-    if (reference == null) {
-      return Collections.emptySet();
-    } else {
-      return getHashedSource().getLinesForHash(reference.getHash(originLine));
-    }
-  }
 }
index 4c2cff60a32d10d9d1fa2b51c1f9ce8139a8dd9a..db4f0787172ffa0d68fd2768876aaff3d1d55fdd 100644 (file)
@@ -32,12 +32,11 @@ import javax.annotation.CheckForNull;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-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.TextPointer;
 import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.scanner.fs.InputProject;
@@ -46,7 +45,6 @@ import org.sonar.scanner.issue.IssueCache;
 import org.sonar.scanner.issue.tracking.TrackedIssue;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.scanner.protocol.output.ScannerReport.Component;
-import org.sonar.scanner.protocol.output.ScannerReport.Metadata;
 import org.sonar.scanner.protocol.output.ScannerReport.Symbol;
 import org.sonar.scanner.protocol.output.ScannerReportReader;
 import org.sonar.scanner.report.ReportPublisher;
@@ -54,16 +52,12 @@ import org.sonar.scanner.report.ScannerReportUtils;
 import org.sonar.scanner.scan.ProjectScanContainer;
 import org.sonar.scanner.scan.filesystem.InputComponentStore;
 
-import static org.apache.commons.lang.StringUtils.isNotEmpty;
-
 public class AnalysisResult implements AnalysisObserver {
 
   private static final Logger LOG = LoggerFactory.getLogger(AnalysisResult.class);
 
   private List<TrackedIssue> issues = new ArrayList<>();
-  private Map<String, InputFile> inputFiles = new HashMap<>();
-  private Map<String, Component> reportComponents = new HashMap<>();
-  private Map<String, InputDir> inputDirs = new HashMap<>();
+  private Map<String, InputFile> inputFilesByKeys = new HashMap<>();
   private InputProject project;
   private ScannerReportReader reader;
 
@@ -76,30 +70,12 @@ public class AnalysisResult implements AnalysisObserver {
 
     ReportPublisher reportPublisher = container.getComponentByType(ReportPublisher.class);
     reader = new ScannerReportReader(reportPublisher.getReportDir().toFile());
-    if (!container.getComponentByType(AnalysisMode.class).isIssues()) {
-      Metadata readMetadata = getReportReader().readMetadata();
-      int rootComponentRef = readMetadata.getRootComponentRef();
-      storeReportComponents(rootComponentRef, null);
-      project = container.getComponentByType(InputProject.class);
-    }
+    project = container.getComponentByType(InputProject.class);
 
     storeFs(container);
 
   }
 
-  private void storeReportComponents(int componentRef, String parentModuleKey) {
-    Component component = getReportReader().readComponent(componentRef);
-    if (isNotEmpty(component.getKey())) {
-      reportComponents.put(component.getKey(), component);
-    } else {
-      reportComponents.put(parentModuleKey + ":" + component.getPath(), component);
-    }
-    for (int childId : component.getChildRefList()) {
-      storeReportComponents(childId, isNotEmpty(component.getKey()) ? component.getKey() : parentModuleKey);
-    }
-
-  }
-
   public ScannerReportReader getReportReader() {
     return reader;
   }
@@ -107,10 +83,7 @@ public class AnalysisResult implements AnalysisObserver {
   private void storeFs(ProjectScanContainer container) {
     InputComponentStore inputFileCache = container.getComponentByType(InputComponentStore.class);
     for (InputFile inputPath : inputFileCache.allFiles()) {
-      inputFiles.put(((DefaultInputFile) inputPath).getProjectRelativePath(), inputPath);
-    }
-    for (InputDir inputPath : inputFileCache.allDirs()) {
-      inputDirs.put(inputPath.relativePath(), inputPath);
+      inputFilesByKeys.put(((DefaultInputFile) inputPath).getProjectRelativePath(), inputPath);
     }
   }
 
@@ -118,18 +91,20 @@ public class AnalysisResult implements AnalysisObserver {
     return issues;
   }
 
-  public Component getReportComponent(String key) {
-    return reportComponents.get(key);
+  public Component getReportComponent(InputComponent inputComponent) {
+    return getReportReader().readComponent(((DefaultInputComponent) inputComponent).scannerId());
+  }
+
+  public Component getReportComponent(int scannerId) {
+    return getReportReader().readComponent(scannerId);
   }
 
   public List<ScannerReport.Issue> issuesFor(InputComponent inputComponent) {
-    int ref = reportComponents.get(inputComponent.key()).getRef();
-    return issuesFor(ref);
+    return issuesFor(((DefaultInputComponent) inputComponent).scannerId());
   }
-  
+
   public List<ScannerReport.ExternalIssue> externalIssuesFor(InputComponent inputComponent) {
-    int ref = reportComponents.get(inputComponent.key()).getRef();
-    return externalIssuesFor(ref);
+    return externalIssuesFor(((DefaultInputComponent) inputComponent).scannerId());
   }
 
   public List<ScannerReport.Issue> issuesFor(Component reportComponent) {
@@ -146,7 +121,7 @@ public class AnalysisResult implements AnalysisObserver {
     }
     return result;
   }
-  
+
   private List<ScannerReport.ExternalIssue> externalIssuesFor(int ref) {
     List<ScannerReport.ExternalIssue> result = Lists.newArrayList();
     try (CloseableIterator<ScannerReport.ExternalIssue> it = reader.readComponentExternalIssues(ref)) {
@@ -162,41 +137,38 @@ public class AnalysisResult implements AnalysisObserver {
   }
 
   public Collection<InputFile> inputFiles() {
-    return inputFiles.values();
+    return inputFilesByKeys.values();
   }
 
   @CheckForNull
   public InputFile inputFile(String relativePath) {
-    return inputFiles.get(relativePath);
-  }
-
-  public Collection<InputDir> inputDirs() {
-    return inputDirs.values();
-  }
-
-  @CheckForNull
-  public InputDir inputDir(String relativePath) {
-    return inputDirs.get(relativePath);
+    return inputFilesByKeys.get(relativePath);
   }
 
   public Map<String, List<ScannerReport.Measure>> allMeasures() {
     Map<String, List<ScannerReport.Measure>> result = new HashMap<>();
-    for (Map.Entry<String, Component> component : reportComponents.entrySet()) {
+    List<ScannerReport.Measure> projectMeasures = new ArrayList<>();
+    try (CloseableIterator<ScannerReport.Measure> it = reader.readComponentMeasures(((DefaultInputComponent) project).scannerId())) {
+      Iterators.addAll(projectMeasures, it);
+    }
+    result.put(project.key(), projectMeasures);
+    for (InputFile inputFile : inputFilesByKeys.values()) {
       List<ScannerReport.Measure> measures = new ArrayList<>();
-      try (CloseableIterator<ScannerReport.Measure> it = reader.readComponentMeasures(component.getValue().getRef())) {
+      try (CloseableIterator<ScannerReport.Measure> it = reader.readComponentMeasures(((DefaultInputComponent) inputFile).scannerId())) {
         Iterators.addAll(measures, it);
       }
-      result.put(component.getKey(), measures);
+      result.put(inputFile.key(), measures);
     }
     return result;
   }
 
   /**
    * Get highlighting types at a given position in an inputfile
+   *
    * @param lineOffset 0-based offset in file
    */
   public List<TypeOfText> highlightingTypeFor(InputFile file, int line, int lineOffset) {
-    int ref = reportComponents.get(file.key()).getRef();
+    int ref = ((DefaultInputComponent) file).scannerId();
     if (!reader.hasSyntaxHighlighting(ref)) {
       return Collections.emptyList();
     }
@@ -222,12 +194,13 @@ public class AnalysisResult implements AnalysisObserver {
 
   /**
    * Get list of all start positions of a symbol in an inputfile
-   * @param symbolStartLine 0-based start offset for the symbol in file
+   *
+   * @param symbolStartLine       0-based start offset for the symbol in file
    * @param symbolStartLineOffset 0-based end offset for the symbol in file
    */
   @CheckForNull
   public List<ScannerReport.TextRange> symbolReferencesFor(InputFile file, int symbolStartLine, int symbolStartLineOffset) {
-    int ref = reportComponents.get(file.key()).getRef();
+    int ref = ((DefaultInputComponent) file).scannerId();
     try (CloseableIterator<Symbol> symbols = getReportReader().readComponentSymbols(ref)) {
       while (symbols.hasNext()) {
         Symbol symbol = symbols.next();
@@ -241,7 +214,7 @@ public class AnalysisResult implements AnalysisObserver {
 
   public List<ScannerReport.Duplication> duplicationsFor(InputFile file) {
     List<ScannerReport.Duplication> result = new ArrayList<>();
-    int ref = reportComponents.get(file.key()).getRef();
+    int ref = ((DefaultInputComponent) file).scannerId();
     try (CloseableIterator<ScannerReport.Duplication> it = getReportReader().readComponentDuplications(ref)) {
       while (it.hasNext()) {
         result.add(it.next());
@@ -254,7 +227,7 @@ public class AnalysisResult implements AnalysisObserver {
 
   public List<ScannerReport.CpdTextBlock> duplicationBlocksFor(InputFile file) {
     List<ScannerReport.CpdTextBlock> result = new ArrayList<>();
-    int ref = reportComponents.get(file.key()).getRef();
+    int ref = ((DefaultInputComponent) file).scannerId();
     try (CloseableIterator<ScannerReport.CpdTextBlock> it = getReportReader().readCpdTextBlocks(ref)) {
       while (it.hasNext()) {
         result.add(it.next());
@@ -267,7 +240,7 @@ public class AnalysisResult implements AnalysisObserver {
 
   @CheckForNull
   public ScannerReport.LineCoverage coverageFor(InputFile file, int line) {
-    int ref = reportComponents.get(file.key()).getRef();
+    int ref = ((DefaultInputComponent) file).scannerId();
     try (CloseableIterator<ScannerReport.LineCoverage> it = getReportReader().readComponentCoverage(ref)) {
       while (it.hasNext()) {
         ScannerReport.LineCoverage coverage = it.next();
@@ -282,7 +255,7 @@ public class AnalysisResult implements AnalysisObserver {
   }
 
   public ScannerReport.Test firstTestExecutionForName(InputFile testFile, String testName) {
-    int ref = reportComponents.get(testFile.key()).getRef();
+    int ref = ((DefaultInputComponent) testFile).scannerId();
     try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readTests(ref))) {
       ScannerReport.Test test = ScannerReport.Test.parser().parseDelimitedFrom(inputStream);
       while (test != null) {
@@ -298,7 +271,7 @@ public class AnalysisResult implements AnalysisObserver {
   }
 
   public ScannerReport.CoverageDetail coveragePerTestFor(InputFile testFile, String testName) {
-    int ref = reportComponents.get(testFile.key()).getRef();
+    int ref = ((DefaultInputComponent) testFile).scannerId();
     try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readCoverageDetails(ref))) {
       ScannerReport.CoverageDetail details = ScannerReport.CoverageDetail.parser().parseDelimitedFrom(inputStream);
       while (details != null) {
index 7902bcde70681621c0ef66146809ddd8bf725d87..a9d042489b93c46642828960f71d45c38ae6a2da 100644 (file)
  */
 package org.sonar.scanner.report;
 
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.stream.Collectors;
+import java.util.Map;
 import javax.annotation.CheckForNull;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-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.InputFile.Status;
-import org.sonar.api.batch.fs.InputModule;
-import org.sonar.api.batch.fs.internal.DefaultInputComponent;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.AbstractProjectOrModule;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.batch.fs.internal.InputComponentTree;
-import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
-import org.sonar.api.utils.PathUtils;
-import org.sonar.core.util.CloseableIterator;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType;
 import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus;
 import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink;
 import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink.ComponentLinkType;
-import org.sonar.scanner.protocol.output.ScannerReport.Issue;
-import org.sonar.scanner.protocol.output.ScannerReportReader;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
-import org.sonar.scanner.scan.branch.BranchConfiguration;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
 
 /**
  * Adds components and analysis metadata to output report
  */
 public class ComponentsPublisher implements ReportPublisherStep {
 
-  private final InputComponentTree componentTree;
-  private final InputModuleHierarchy moduleHierarchy;
-  private final BranchConfiguration branchConfiguration;
+  private final InputComponentStore inputComponentStore;
+  private final DefaultInputProject project;
 
-  private ScannerReportReader reader;
-  private ScannerReportWriter writer;
 
-  public ComponentsPublisher(InputModuleHierarchy moduleHierarchy, InputComponentTree inputComponentTree, BranchConfiguration branchConfiguration) {
-    this.moduleHierarchy = moduleHierarchy;
-    this.componentTree = inputComponentTree;
-    this.branchConfiguration = branchConfiguration;
+  public ComponentsPublisher(DefaultInputProject project, InputComponentStore inputComponentStore) {
+    this.project = project;
+    this.inputComponentStore = inputComponentStore;
   }
 
   @Override
   public void publish(ScannerReportWriter writer) {
-    this.reader = new ScannerReportReader(writer.getFileStructure().root());
-    this.writer = writer;
-    recursiveWriteComponent(moduleHierarchy.root());
-  }
-
-  /**
-   * Writes the tree of components recursively, deep-first.
-   *
-   * @return true if component was written (not skipped)
-   */
-  private boolean recursiveWriteComponent(DefaultInputComponent component) {
-    Collection<InputComponent> children = componentTree.getChildren(component).stream()
-      .filter(c -> recursiveWriteComponent((DefaultInputComponent) c))
-      .collect(Collectors.toList());
-
-    if (shouldSkipComponent(component, children)) {
-      return false;
-    }
+    ScannerReport.Component.Builder projectBuilder = prepareProjectBuilder();
 
-    ScannerReport.Component.Builder builder = ScannerReport.Component.newBuilder();
+    ScannerReport.Component.Builder fileBuilder = ScannerReport.Component.newBuilder();
+    for (DefaultInputFile file : inputComponentStore.allFilesToPublish()) {
+      projectBuilder.addChildRef(file.scannerId());
 
-    // non-null fields
-    builder.setRef(component.scannerId());
-    builder.setType(getType(component));
+      fileBuilder.clear();
 
-    // Don't set key on directories and files to save space since it can be deduced from path
-    if (component instanceof InputModule) {
-      DefaultInputModule inputModule = (DefaultInputModule) component;
-      // Here we want key without branch
-      builder.setKey(inputModule.key());
+      // non-null fields
+      fileBuilder.setRef(file.scannerId());
+      fileBuilder.setType(ComponentType.FILE);
 
-      // protocol buffers does not accept null values
-      String name = getName(inputModule);
-      if (name != null) {
-        builder.setName(name);
-      }
-      String description = getDescription(inputModule);
-      if (description != null) {
-        builder.setDescription(description);
-      }
-
-      writeVersion(inputModule, builder);
-    } else if (component.isFile()) {
-      DefaultInputFile file = (DefaultInputFile) component;
-      builder.setIsTest(file.type() == InputFile.Type.TEST);
-      builder.setLines(file.lines());
-      builder.setStatus(convert(file.status()));
+      fileBuilder.setIsTest(file.type() == InputFile.Type.TEST);
+      fileBuilder.setLines(file.lines());
+      fileBuilder.setStatus(convert(file.status()));
 
       String lang = getLanguageKey(file);
       if (lang != null) {
-        builder.setLanguage(lang);
+        fileBuilder.setLanguage(lang);
       }
+      fileBuilder.setProjectRelativePath(file.getProjectRelativePath());
+      writer.writeComponent(fileBuilder.build());
     }
 
-    String path = getPath(component);
-    if (path != null) {
-      builder.setPath(path);
-    }
+    writer.writeComponent(projectBuilder.build());
+  }
+
+  private ScannerReport.Component.Builder prepareProjectBuilder() {
+    ScannerReport.Component.Builder projectBuilder = ScannerReport.Component.newBuilder();
+    projectBuilder.setRef(project.scannerId());
+    projectBuilder.setType(ComponentType.PROJECT);
+    // Here we want key without branch
+    projectBuilder.setKey(project.key());
 
-    String projectRelativePath = getProjectRelativePath(component);
-    if (projectRelativePath != null) {
-      builder.setProjectRelativePath(projectRelativePath);
+    // protocol buffers does not accept null values
+    String name = getName(project);
+    if (name != null) {
+      projectBuilder.setName(name);
+    }
+    String description = getDescription(project);
+    if (description != null) {
+      projectBuilder.setDescription(description);
     }
 
-    for (InputComponent child : children) {
-      builder.addChildRef(((DefaultInputComponent) child).scannerId());
+    String version = project.getOriginalVersion();
+    if (version != null) {
+      projectBuilder.setVersion(version);
     }
-    writeLinks(component, builder);
-    writer.writeComponent(builder.build());
-    return true;
+
+    writeLinks(project, projectBuilder);
+    return projectBuilder;
   }
 
-  private FileStatus convert(Status status) {
+  private static FileStatus convert(Status status) {
     switch (status) {
       case ADDED:
         return FileStatus.ADDED;
@@ -154,97 +118,18 @@ public class ComponentsPublisher implements ReportPublisherStep {
     }
   }
 
-  private boolean shouldSkipComponent(DefaultInputComponent component, Collection<InputComponent> children) {
-    if (component instanceof InputModule && children.isEmpty() && (branchConfiguration.isShortOrPullRequest())) {
-      // no children on a module in short branch analysis -> skip it (except root)
-      return !moduleHierarchy.isRoot((DefaultInputModule) component);
-    } else if (component instanceof InputDir && children.isEmpty()) {
-      try (CloseableIterator<Issue> componentIssuesIt = reader.readComponentIssues(component.scannerId())) {
-        if (!componentIssuesIt.hasNext()) {
-          // no files to publish on a directory without issues -> skip it
-          return true;
-        }
-      }
-    } else if (component instanceof DefaultInputFile) {
-      // skip files not marked for publishing
-      DefaultInputFile inputFile = (DefaultInputFile) component;
-      return !inputFile.isPublished();
-    }
-    return false;
-  }
+  private static void writeLinks(DefaultInputProject project, ScannerReport.Component.Builder builder) {
+    ComponentLink.Builder linkBuilder = ComponentLink.newBuilder();
 
-  private void writeVersion(DefaultInputModule module, ScannerReport.Component.Builder builder) {
-    String version = getVersion(module);
-    if (version != null) {
-      builder.setVersion(version);
-    }
+    writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_HOME_PAGE, ComponentLinkType.HOME);
+    writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_CI, ComponentLinkType.CI);
+    writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_ISSUE_TRACKER, ComponentLinkType.ISSUE);
+    writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_SOURCES, ComponentLinkType.SCM);
   }
 
-  @CheckForNull
-  private String getPath(InputComponent component) {
-    if (component instanceof InputFile) {
-      DefaultInputFile inputPath = (DefaultInputFile) component;
-      return inputPath.getModuleRelativePath();
-    } else if (component instanceof InputDir) {
-      InputDir inputPath = (InputDir) component;
-      if (StringUtils.isEmpty(inputPath.relativePath())) {
-        return "/";
-      } else {
-        return inputPath.relativePath();
-      }
-    } else if (component instanceof InputModule) {
-      DefaultInputModule module = (DefaultInputModule) component;
-      return moduleHierarchy.relativePath(module);
-    }
-    throw new IllegalStateException("Unknown component: " + component.getClass());
-  }
-
-  @CheckForNull
-  private String getProjectRelativePath(DefaultInputComponent component) {
-    if (component instanceof InputFile) {
-      DefaultInputFile inputFile = (DefaultInputFile) component;
-      return inputFile.getProjectRelativePath();
-    }
-
-    Path projectBaseDir = moduleHierarchy.root().getBaseDir();
-    if (component instanceof InputDir) {
-      InputDir inputDir = (InputDir) component;
-      return PathUtils.sanitize(projectBaseDir.relativize(inputDir.path()).toString());
-    }
-    if (component instanceof InputModule) {
-      AbstractProjectOrModule module = (AbstractProjectOrModule) component;
-      return PathUtils.sanitize(projectBaseDir.relativize(module.getBaseDir()).toString());
-    }
-    throw new IllegalStateException("Unknown component: " + component.getClass());
-  }
-
-  private String getVersion(DefaultInputModule module) {
-    String version = module.getOriginalVersion();
-    if (StringUtils.isNotBlank(version)) {
-      return version;
-    }
-
-    DefaultInputModule parent = moduleHierarchy.parent(module);
-
-    return parent != null ? getVersion(parent) : null;
-  }
-
-  private static void writeLinks(InputComponent c, ScannerReport.Component.Builder builder) {
-    if (c instanceof InputModule) {
-      AbstractProjectOrModule inputModule = (AbstractProjectOrModule) c;
-      ProjectDefinition def = inputModule.definition();
-      ComponentLink.Builder linkBuilder = ComponentLink.newBuilder();
-
-      writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_HOME_PAGE, ComponentLinkType.HOME);
-      writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_CI, ComponentLinkType.CI);
-      writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_ISSUE_TRACKER, ComponentLinkType.ISSUE);
-      writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES, ComponentLinkType.SCM);
-    }
-  }
-
-  private static void writeProjectLink(ScannerReport.Component.Builder componentBuilder, ProjectDefinition def, ComponentLink.Builder linkBuilder, String linkProp,
-    ComponentLinkType linkType) {
-    String link = def.properties().get(linkProp);
+  private static void writeProjectLink(ScannerReport.Component.Builder componentBuilder, Map<String, String> properties, ComponentLink.Builder linkBuilder, String linkProp,
+                                       ComponentLinkType linkType) {
+    String link = properties.get(linkProp);
     if (StringUtils.isNotBlank(link)) {
       linkBuilder.setType(linkType);
       linkBuilder.setHref(link);
@@ -272,18 +157,4 @@ public class ComponentsPublisher implements ReportPublisherStep {
     return module.definition().getDescription();
   }
 
-  private ComponentType getType(InputComponent r) {
-    if (r instanceof InputFile) {
-      return ComponentType.FILE;
-    } else if (r instanceof InputDir) {
-      return ComponentType.DIRECTORY;
-    } else if ((r instanceof InputModule) && moduleHierarchy.isRoot((DefaultInputModule) r)) {
-      return ComponentType.PROJECT;
-    } else if (r instanceof InputModule) {
-      return ComponentType.MODULE;
-    }
-
-    throw new IllegalArgumentException("Unknown resource type: " + r);
-  }
-
 }
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java
deleted file mode 100644 (file)
index 7da8990..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.scan;
-
-import com.google.common.base.Preconditions;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import org.sonar.api.batch.fs.InputComponent;
-import org.sonar.api.batch.fs.internal.InputComponentTree;
-
-public class DefaultComponentTree implements InputComponentTree {
-  private Map<InputComponent, InputComponent> parents = new HashMap<>();
-  private Map<InputComponent, Set<InputComponent>> children = new HashMap<>();
-
-  public void index(InputComponent component, InputComponent parent) {
-    Preconditions.checkNotNull(component);
-    Preconditions.checkNotNull(parent);
-    parents.put(component, parent);
-    children.computeIfAbsent(parent, k -> new LinkedHashSet<>()).add(component);
-  }
-
-  @Override
-  public Collection<InputComponent> getChildren(InputComponent component) {
-    return children.getOrDefault(component, Collections.emptySet());
-  }
-
-  @CheckForNull
-  @Override
-  public InputComponent getParent(InputComponent component) {
-    return parents.get(component);
-  }
-}
index 60baccdfa5ad7d1cb758e695d0e3b7dee9c1f1ed..4b85e732f663eb8fc3c1b94b0eaba06fb2d0ca98 100644 (file)
@@ -30,12 +30,10 @@ import org.sonar.scanner.scan.filesystem.InputComponentStore;
  * project definitions provided by the {@link ImmutableProjectReactor}.
  */
 public class ModuleIndexer implements Startable {
-  private final DefaultComponentTree componentTree;
   private final InputModuleHierarchy moduleHierarchy;
   private final InputComponentStore componentStore;
 
-  public ModuleIndexer(DefaultComponentTree componentTree, InputComponentStore componentStore, InputModuleHierarchy moduleHierarchy) {
-    this.componentTree = componentTree;
+  public ModuleIndexer(InputComponentStore componentStore, InputModuleHierarchy moduleHierarchy) {
     this.componentStore = componentStore;
     this.moduleHierarchy = moduleHierarchy;
   }
@@ -49,7 +47,6 @@ public class ModuleIndexer implements Startable {
 
   private void indexChildren(DefaultInputModule parent) {
     for (DefaultInputModule module : moduleHierarchy.children(parent)) {
-      componentTree.index(module, parent);
       componentStore.put(module);
       indexChildren(module);
     }
index eb33fe12f42d402c0b5c485262ac66da3cf11d2d..7e595179de1f57295836e791a0a329197383f009 100644 (file)
@@ -160,7 +160,6 @@ public class ProjectScanContainer extends ComponentContainer {
       PathResolver.class,
       new InputProjectProvider(),
       new InputModuleHierarchyProvider(),
-      DefaultComponentTree.class,
       ScannerComponentIdGenerator.class,
       new ScmChangedFilesProvider(),
       StatusDetection.class,
index 5294797c67cbce52c0c634e403a7b79ef47b011f..20a1d8036884a7757aa2431fd66cb9426db3c4be 100644 (file)
@@ -44,12 +44,9 @@ import org.sonar.api.batch.ScannerSide;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputFile.Type;
 import org.sonar.api.batch.fs.InputFileFilter;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.scan.DefaultComponentTree;
 import org.sonar.scanner.util.ProgressReport;
 
 /**
@@ -62,7 +59,6 @@ public class FileIndexer {
   private final InputFileFilter[] filters;
   private final ExclusionFilters exclusionFilters;
   private final InputFileBuilder inputFileBuilder;
-  private final DefaultComponentTree componentTree;
   private final DefaultInputModule module;
   private final ScannerComponentIdGenerator scannerComponentIdGenerator;
   private final InputComponentStore componentStore;
@@ -74,13 +70,12 @@ public class FileIndexer {
   private ProgressReport progressReport;
 
   public FileIndexer(ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters,
-                     DefaultComponentTree componentTree, InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem,
+                     InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem,
                      LanguageDetection languageDetection,
                      InputFileFilter[] filters) {
     this.scannerComponentIdGenerator = scannerComponentIdGenerator;
     this.componentStore = componentStore;
     this.module = module;
-    this.componentTree = componentTree;
     this.inputFileBuilder = inputFileBuilder;
     this.defaultModuleFileSystem = defaultModuleFileSystem;
     this.langDetection = languageDetection;
@@ -90,9 +85,9 @@ public class FileIndexer {
   }
 
   public FileIndexer(ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters,
-                     DefaultComponentTree componentTree, InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem,
+                     InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem,
                      LanguageDetection languageDetection) {
-    this(scannerComponentIdGenerator, componentStore, module, exclusionFilters, componentTree, inputFileBuilder, defaultModuleFileSystem, languageDetection,
+    this(scannerComponentIdGenerator, componentStore, module, exclusionFilters, inputFileBuilder, defaultModuleFileSystem, languageDetection,
       new InputFileFilter[0]);
   }
 
@@ -192,34 +187,15 @@ public class FileIndexer {
       progress.increaseExcludedByPatternsCount();
       return null;
     }
-    String parentRelativePath = getParentRelativePath(realAbsoluteFile);
     synchronized (this) {
       progress.markAsIndexed(inputFile);
-      indexFileAndParentDir(inputFile, parentRelativePath);
+      defaultModuleFileSystem.add(inputFile);
     }
     LOG.debug("'{}' indexed {}with language '{}'", relativePath, type == Type.TEST ? "as test " : "", inputFile.language());
     inputFileBuilder.checkMetadata(inputFile);
     return null;
   }
 
-  private String getParentRelativePath(Path filePath) {
-    Path parentDir = filePath.getParent();
-    return PathResolver.relativize(module.getBaseDir(), parentDir)
-      .orElseThrow(() -> new IllegalStateException("Failed to compute relative path of file: " + parentDir));
-  }
-
-  private void indexFileAndParentDir(InputFile inputFile, String parentRelativePath) {
-    DefaultInputDir inputDir = (DefaultInputDir) componentStore.getDir(module.key(), parentRelativePath);
-    if (inputDir == null) {
-      inputDir = new DefaultInputDir(module.key(), parentRelativePath, scannerComponentIdGenerator.getAsInt());
-      inputDir.setModuleBaseDir(module.getBaseDir());
-      componentTree.index(inputDir, module);
-      defaultModuleFileSystem.add(inputDir);
-    }
-    componentTree.index(inputFile, inputDir);
-    defaultModuleFileSystem.add(inputFile);
-  }
-
   private boolean accept(InputFile indexedFile) {
     // InputFileFilter extensions. Might trigger generation of metadata
     for (InputFileFilter filter : filters) {
index 15eb4f6b0a0cc7f87480b833c1e5149222dae798..8d1071b172cc4ca58c2f1bd5f51eaa82b40588db 100644 (file)
@@ -24,7 +24,6 @@ import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Table;
 import com.google.common.collect.TreeBasedTable;
-import java.nio.file.Path;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -34,13 +33,10 @@ import java.util.TreeSet;
 import java.util.stream.Stream;
 import javax.annotation.CheckForNull;
 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.internal.AbstractProjectOrModule;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.FileExtensionPredicate;
-import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.scanner.fs.InputProject;
 import org.sonar.scanner.scan.branch.BranchConfiguration;
 
@@ -53,9 +49,7 @@ public class InputComponentStore {
   private final SortedSet<String> globalLanguagesCache = new TreeSet<>();
   private final Map<String, SortedSet<String>> languagesCache = new HashMap<>();
   private final Map<String, InputFile> globalInputFileCache = new HashMap<>();
-  private final Table<String, String, InputFile> inputFileCache = TreeBasedTable.create();
-  private final Map<String, InputDir> globalInputDirCache = new HashMap<>();
-  private final Table<String, String, InputDir> inputDirCache = TreeBasedTable.create();
+  private final Table<String, String, InputFile> inputFileByModuleCache = TreeBasedTable.create();
   // indexed by key with branch
   private final Map<String, AbstractProjectOrModule> inputModuleCache = new HashMap<>();
   private final Map<String, InputComponent> inputComponents = new HashMap<>();
@@ -74,7 +68,7 @@ public class InputComponentStore {
   }
 
   private Stream<DefaultInputFile> allFilesToPublishStream() {
-    return inputFileCache.values().stream()
+    return inputFileByModuleCache.values().stream()
       .map(f -> (DefaultInputFile) f)
       .filter(DefaultInputFile::isPublished);
   }
@@ -90,11 +84,7 @@ public class InputComponentStore {
   }
 
   public Iterable<InputFile> allFiles() {
-    return inputFileCache.values();
-  }
-
-  public Iterable<InputDir> allDirs() {
-    return inputDirCache.values();
+    return globalInputFileCache.values();
   }
 
   public InputComponent getByKey(String key) {
@@ -102,35 +92,13 @@ public class InputComponentStore {
   }
 
   public Iterable<InputFile> filesByModule(String moduleKey) {
-    return inputFileCache.row(moduleKey).values();
-  }
-
-  public Iterable<InputDir> dirsByModule(String moduleKey) {
-    return inputDirCache.row(moduleKey).values();
-  }
-
-  public InputComponentStore removeModule(String moduleKey) {
-    inputFileCache.row(moduleKey).clear();
-    inputDirCache.row(moduleKey).clear();
-    return this;
-  }
-
-  public InputComponentStore remove(InputFile inputFile) {
-    DefaultInputFile file = (DefaultInputFile) inputFile;
-    inputFileCache.remove(file.moduleKey(), file.getModuleRelativePath());
-    return this;
-  }
-
-  public InputComponentStore remove(InputDir inputDir) {
-    DefaultInputDir dir = (DefaultInputDir) inputDir;
-    inputDirCache.remove(dir.moduleKey(), inputDir.relativePath());
-    return this;
+    return inputFileByModuleCache.row(moduleKey).values();
   }
 
-  public InputComponentStore put(InputFile inputFile) {
+  public InputComponentStore put(String moduleKey, InputFile inputFile) {
     DefaultInputFile file = (DefaultInputFile) inputFile;
-    addToLanguageCache(file);
-    inputFileCache.put(file.moduleKey(), file.getModuleRelativePath(), inputFile);
+    addToLanguageCache(moduleKey, file);
+    inputFileByModuleCache.put(moduleKey, file.getModuleRelativePath(), inputFile);
     globalInputFileCache.put(file.getProjectRelativePath(), inputFile);
     inputComponents.put(inputFile.key(), inputFile);
     filesByNameCache.put(inputFile.filename(), inputFile);
@@ -138,34 +106,17 @@ public class InputComponentStore {
     return this;
   }
 
-  private void addToLanguageCache(DefaultInputFile inputFile) {
+  private void addToLanguageCache(String moduleKey, DefaultInputFile inputFile) {
     String language = inputFile.language();
     if (language != null) {
       globalLanguagesCache.add(language);
-      languagesCache.computeIfAbsent(inputFile.moduleKey(), k -> new TreeSet<>()).add(language);
+      languagesCache.computeIfAbsent(moduleKey, k -> new TreeSet<>()).add(language);
     }
   }
 
-  public InputComponentStore put(InputDir inputDir) {
-    DefaultInputDir dir = (DefaultInputDir) inputDir;
-    inputDirCache.put(dir.moduleKey(), inputDir.relativePath(), inputDir);
-    // FIXME an InputDir can be already indexed by another module
-    globalInputDirCache.put(getProjectRelativePath(dir), inputDir);
-    inputComponents.put(inputDir.key(), inputDir);
-    return this;
-  }
-
-  private String getProjectRelativePath(DefaultInputDir dir) {
-    return PathResolver.relativize(getProjectBaseDir(), dir.path()).orElseThrow(() -> new IllegalStateException("Dir " + dir.path() + " should be relative to project baseDir"));
-  }
-
-  private Path getProjectBaseDir() {
-    return ((AbstractProjectOrModule) project).getBaseDir();
-  }
-
   @CheckForNull
   public InputFile getFile(String moduleKey, String relativePath) {
-    return inputFileCache.get(moduleKey, relativePath);
+    return inputFileByModuleCache.get(moduleKey, relativePath);
   }
 
   @CheckForNull
@@ -173,16 +124,6 @@ public class InputComponentStore {
     return globalInputFileCache.get(relativePath);
   }
 
-  @CheckForNull
-  public InputDir getDir(String moduleKey, String relativePath) {
-    return inputDirCache.get(moduleKey, relativePath);
-  }
-
-  @CheckForNull
-  public InputDir getDir(String relativePath) {
-    return globalInputDirCache.get(relativePath);
-  }
-
   @CheckForNull
   public AbstractProjectOrModule getModule(String moduleKeyWithBranch) {
     return inputModuleCache.get(moduleKeyWithBranch);
index 4de7d1bf07e837a32cc5c107a0830e40d5657f76..438a0edd44bf10769c7c9faefe7913700bc3f5c4 100644 (file)
@@ -30,6 +30,7 @@ import org.sonar.api.batch.fs.internal.SensorStrategy;
 import org.sonar.scanner.scan.ScanProperties;
 
 public class InputFileBuilder {
+  private final DefaultInputProject project;
   private final DefaultInputModule module;
   private final ScannerComponentIdGenerator idGenerator;
   private final MetadataGenerator metadataGenerator;
@@ -42,6 +43,7 @@ public class InputFileBuilder {
                           SensorStrategy sensorStrategy) {
     this.sensorStrategy = sensorStrategy;
     this.projectBaseDir = project.getBaseDir();
+    this.project = project;
     this.module = module;
     this.metadataGenerator = metadataGenerator;
     this.idGenerator = idGenerator;
@@ -49,7 +51,7 @@ public class InputFileBuilder {
   }
 
   DefaultInputFile create(InputFile.Type type, Path absolutePath, @Nullable String language) {
-    DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, module.key(),
+    DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, project.key(),
       projectBaseDir.relativize(absolutePath).toString(),
       module.getBaseDir().relativize(absolutePath).toString(),
       type, language, idGenerator.getAsInt(), sensorStrategy);
index 8d694756fb97e43c830b99b8c0e66750c820fc01..6bb17759043805c7b341f71d5c30e06d42ef0dfa 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.scanner.scan.filesystem;
 
 import java.util.SortedSet;
 import org.sonar.api.batch.ScannerSide;
-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.DefaultFileSystem;
@@ -58,15 +57,6 @@ public class ModuleInputComponentStore extends DefaultFileSystem.Cache {
     }
   }
 
-  @Override
-  public InputDir inputDir(String relativePath) {
-    if (strategy.isGlobal()) {
-      return inputComponentStore.getDir(relativePath);
-    } else {
-      return inputComponentStore.getDir(moduleKey, relativePath);
-    }
-  }
-
   @Override
   public SortedSet<String> languages() {
     if (strategy.isGlobal()) {
@@ -78,12 +68,7 @@ public class ModuleInputComponentStore extends DefaultFileSystem.Cache {
 
   @Override
   protected void doAdd(InputFile inputFile) {
-    inputComponentStore.put(inputFile);
-  }
-
-  @Override
-  protected void doAdd(InputDir inputDir) {
-    inputComponentStore.put(inputDir);
+    inputComponentStore.put(moduleKey, inputFile);
   }
 
   @Override
index b302742bf7b5ff12584d2f2b08745ee16cda93c7..d965bb3e90859467abd479d18bf6cff74450e632 100644 (file)
@@ -38,13 +38,8 @@ import org.sonar.api.Property;
 import org.sonar.api.PropertyType;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputComponent;
-import org.sonar.api.batch.fs.InputDir;
-import org.sonar.api.batch.fs.InputPath;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.AbstractProjectOrModule;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.batch.fs.internal.InputComponentTree;
-import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
 import org.sonar.api.batch.rule.Rule;
 import org.sonar.api.batch.rule.Rules;
 import org.sonar.api.config.Configuration;
@@ -72,21 +67,17 @@ public class JSONReport implements Reporter {
   private final Rules rules;
   private final IssueCache issueCache;
   private final InputComponentStore componentStore;
-  private final DefaultInputModule rootModule;
-  private final InputModuleHierarchy moduleHierarchy;
-  private final InputComponentTree inputComponentTree;
+  private final DefaultInputProject project;
 
-  public JSONReport(InputModuleHierarchy moduleHierarchy, Configuration settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache,
-                    DefaultInputModule rootModule, InputComponentStore componentStore, InputComponentTree inputComponentTree) {
-    this.moduleHierarchy = moduleHierarchy;
+  public JSONReport(Configuration settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache,
+                    DefaultInputProject project, InputComponentStore componentStore) {
     this.settings = settings;
     this.fileSystem = fileSystem;
     this.server = server;
     this.rules = rules;
     this.issueCache = issueCache;
-    this.rootModule = rootModule;
+    this.project = project;
     this.componentStore = componentStore;
-    this.inputComponentTree = inputComponentTree;
   }
 
   @Override
@@ -126,14 +117,14 @@ public class JSONReport implements Reporter {
     for (TrackedIssue issue : getIssues()) {
       if (issue.resolution() == null) {
         InputComponent component = componentStore.getByKey(issue.componentKey());
-        String componentKey = getModule(component).definition().getKeyWithBranch();
-        if (component instanceof InputPath) {
-          componentKey = ComponentKeys.createEffectiveKey(componentKey, (InputPath) component);
+        String componentKeyWithBranch = project.getKeyWithBranch();
+        if (component.isFile()) {
+          componentKeyWithBranch = ComponentKeys.createEffectiveKey(componentKeyWithBranch, (DefaultInputFile) component);
         }
         json
           .beginObject()
           .prop("key", issue.key())
-          .prop("component", componentKey)
+          .prop("component", componentKeyWithBranch)
           .prop("line", issue.startLine())
           .prop("startLine", issue.startLine())
           .prop("startOffset", issue.startLineOffset())
@@ -158,54 +149,28 @@ public class JSONReport implements Reporter {
     json.endArray();
   }
 
-  private AbstractProjectOrModule getModule(InputComponent component) {
-    if (component.isFile()) {
-      return (AbstractProjectOrModule) inputComponentTree.getParent(inputComponentTree.getParent(component));
-    }
-    if (component instanceof InputDir) {
-      return (AbstractProjectOrModule) inputComponentTree.getParent(component);
-    }
-    return (AbstractProjectOrModule) component;
-  }
-
   private void writeJsonComponents(JsonWriter json) {
     json.name("components").beginArray();
     // Dump modules
-    writeJsonModuleComponents(json, rootModule);
+    writeJsonProject(json);
     for (DefaultInputFile inputFile : componentStore.allFilesToPublish()) {
-      String moduleKey = getModule(inputFile).definition().getKeyWithBranch();
-      String key = ComponentKeys.createEffectiveKey(moduleKey, inputFile);
+      String projectKey = project.getKeyWithBranch();
+      String key = ComponentKeys.createEffectiveKey(projectKey, inputFile);
       json
         .beginObject()
         .prop("key", key)
         .prop("path", inputFile.relativePath())
-        .prop("moduleKey", moduleKey)
         .prop("status", inputFile.status().name())
         .endObject();
     }
-    for (InputDir inputDir : componentStore.allDirs()) {
-      String moduleKey = getModule(inputDir).definition().getKeyWithBranch();
-      String key = ComponentKeys.createEffectiveKey(moduleKey, inputDir);
-      json
-        .beginObject()
-        .prop("key", key)
-        .prop("path", inputDir.relativePath())
-        .prop("moduleKey", moduleKey)
-        .endObject();
-
-    }
     json.endArray();
   }
 
-  private void writeJsonModuleComponents(JsonWriter json, DefaultInputModule moduleOrProject) {
+  private void writeJsonProject(JsonWriter json) {
     json
       .beginObject()
-      .prop("key", moduleOrProject.definition().getKeyWithBranch())
-      .prop("path", moduleHierarchy.relativePath(moduleOrProject))
+      .prop("key", project.definition().getKeyWithBranch())
       .endObject();
-    for (DefaultInputModule subModule : moduleHierarchy.children(moduleOrProject)) {
-      writeJsonModuleComponents(json, subModule);
-    }
   }
 
   private void writeJsonRules(JsonWriter json, Set<RuleKey> ruleKeys) {
index 611e42c779395f65ee175caf1f44993a477e4037..6588f2e3c0aadaf4802747c80208dab62c213d4a 100644 (file)
@@ -234,7 +234,7 @@ public class CpdExecutorTest {
       .setLines(lines);
     config.accept(fileBuilder);
     DefaultInputFile file = fileBuilder.build();
-    componentStore.put(file);
+    componentStore.put("foo", file);
     return file;
   }
 
index 6aa8686690ff63e5d02f3b453231609ca01472cb..590d4119282f33c0ece676c852fb6e2fb9d80d3c 100644 (file)
@@ -28,11 +28,9 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.mockito.Mockito;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
 
 import static org.apache.commons.codec.digest.DigestUtils.md5Hex;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -51,11 +49,10 @@ public class SourceHashHolderTest {
   DefaultInputFile file;
 
   private File ioFile;
-  private ProjectDefinition def;
+  private DefaultInputProject project;
 
   @Before
   public void setUp() throws Exception {
-    def = ProjectDefinition.create().setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder());
     lastSnapshots = mock(ServerLineHashesLoader.class);
     file = mock(DefaultInputFile.class);
     ioFile = temp.newFile();
@@ -65,7 +62,8 @@ public class SourceHashHolderTest {
     when(file.lines()).thenReturn(1);
     when(file.charset()).thenReturn(StandardCharsets.UTF_8);
 
-    sourceHashHolder = new SourceHashHolder(new DefaultInputModule(def, 1), file, lastSnapshots);
+    project = mock(DefaultInputProject.class);
+    sourceHashHolder = new SourceHashHolder(project, file, lastSnapshots);
   }
 
   @Test
@@ -84,8 +82,8 @@ public class SourceHashHolderTest {
   public void should_lazy_load_reference_hashes_when_status_changed() throws Exception {
     final String source = "source";
     FileUtils.write(ioFile, source, StandardCharsets.UTF_8);
-    def.setKey("foo");
-    when(file.relativePath()).thenReturn("src/Foo.java");
+    when(project.getKeyWithBranch()).thenReturn("foo");
+    when(file.getProjectRelativePath()).thenReturn("src/Foo.java");
     String key = "foo:src/Foo.java";
     when(file.status()).thenReturn(InputFile.Status.CHANGED);
     when(lastSnapshots.getLineHashes(key)).thenReturn(new String[] {md5Hex(source)});
@@ -101,9 +99,8 @@ public class SourceHashHolderTest {
   public void should_lazy_load_reference_hashes_when_status_changed_on_branch() throws Exception {
     final String source = "source";
     FileUtils.write(ioFile, source, StandardCharsets.UTF_8);
-    def.setKey("foo");
-    def.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "myBranch");
-    when(file.relativePath()).thenReturn("src/Foo.java");
+    when(project.getKeyWithBranch()).thenReturn("foo:myBranch");
+    when(file.getProjectRelativePath()).thenReturn("src/Foo.java");
     String key = "foo:myBranch:src/Foo.java";
     when(file.status()).thenReturn(InputFile.Status.CHANGED);
     when(lastSnapshots.getLineHashes(key)).thenReturn(new String[] {md5Hex(source)});
index 21d88ed6f5de93bcab4b675e455fc2123240cdc6..62899cf17f12f9fb126f37d0cb6da354a3f73c08 100644 (file)
@@ -73,7 +73,7 @@ public class BranchMediumTest {
   public void should_not_skip_report_for_unchanged_files_in_short_branch() {
     // sanity check, normally report gets generated
     AnalysisResult result = getResult(tester);
-    assertThat(getResult(tester).getReportComponent(result.inputFile(FILE_PATH).key())).isNotNull();
+    assertThat(getResult(tester).getReportComponent(result.inputFile(FILE_PATH))).isNotNull();
     int fileId = 2;
     assertThat(result.getReportReader().readChangesets(fileId)).isNotNull();
     assertThat(result.getReportReader().hasCoverage(fileId)).isTrue();
@@ -81,7 +81,7 @@ public class BranchMediumTest {
 
     // file is not skipped for short branches (need coverage, duplications coming soon)
     AnalysisResult result2 = getResult(tester.setBranchType(BranchType.SHORT));
-    assertThat(result2.getReportComponent(result2.inputFile(FILE_PATH).key())).isNotNull();
+    assertThat(result2.getReportComponent(result2.inputFile(FILE_PATH))).isNotNull();
     assertThat(result2.getReportReader().readChangesets(fileId)).isNull();
     assertThat(result2.getReportReader().hasCoverage(fileId)).isTrue();
     assertThat(result2.getReportReader().readFileSource(fileId)).isNull();
index bcc46d488d4b85030eaace65fb71c22675f8532f..41ea161bc72d773df39d139fd5caf96159d54f77 100644 (file)
@@ -93,7 +93,7 @@ public class DeprecatedBranchMediumTest {
     assertThat(result.inputFile("src/sample.xoo").key()).isEqualTo("com.foo.project:src/sample.xoo");
 
     DefaultInputFile inputfile = (DefaultInputFile) result.inputFile("src/sample.xoo");
-    assertThat(result.getReportReader().readComponent(inputfile.scannerId()).getPath()).isEqualTo("src/sample.xoo");
+    assertThat(result.getReportReader().readComponent(inputfile.scannerId()).getProjectRelativePath()).isEqualTo("src/sample.xoo");
 
     assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
 
@@ -125,14 +125,11 @@ public class DeprecatedBranchMediumTest {
       .execute();
 
     assertThat(result.inputFiles()).hasSize(1);
-    assertThat(result.inputFile("moduleA/src/sample.xoo").key()).isEqualTo("com.foo.project:moduleA:src/sample.xoo");
+    assertThat(result.inputFile("moduleA/src/sample.xoo").key()).isEqualTo("com.foo.project:moduleA/src/sample.xoo");
 
     // no branch in the report
     DefaultInputFile inputfile = (DefaultInputFile) result.inputFile("moduleA/src/sample.xoo");
-    assertThat(result.getReportReader().readComponent(inputfile.scannerId()).getPath()).isEqualTo("src/sample.xoo");
-
-    // no branch in InputModule's key or in report
-    assertThat(result.getReportComponent("com.foo.project:moduleA").getKey()).isEqualTo("com.foo.project:moduleA");
+    assertThat(result.getReportReader().readComponent(inputfile.scannerId()).getProjectRelativePath()).isEqualTo("moduleA/src/sample.xoo");
 
     assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
 
@@ -145,7 +142,7 @@ public class DeprecatedBranchMediumTest {
       .execute();
 
     assertThat(result.inputFiles()).hasSize(1);
-    assertThat(result.inputFile("moduleA/src/sample.xoo").key()).isEqualTo("com.foo.project:moduleA:src/sample.xoo");
+    assertThat(result.inputFile("moduleA/src/sample.xoo").key()).isEqualTo("com.foo.project:moduleA/src/sample.xoo");
   }
 
 }
index f230f2b8bf8e03cb73dc174e29d96dbf9ad56c6a..1417262c3f94beedddca5bfbff9983ab03071896 100644 (file)
@@ -330,14 +330,14 @@ public class CoverageMediumTest {
 
     Map<String, List<org.sonar.scanner.protocol.output.ScannerReport.Measure>> allMeasures = result.allMeasures();
 
-    assertThat(allMeasures.get("com.foo.project:module1:src/sample1.xoo")).extracting("metricKey", "intValue.value")
+    assertThat(allMeasures.get("com.foo.project:module1/src/sample1.xoo")).extracting("metricKey", "intValue.value")
       .contains(tuple(CoreMetrics.LINES_TO_COVER_KEY, 2),
         tuple(CoreMetrics.UNCOVERED_LINES_KEY, 2));
 
-    assertThat(allMeasures.get("com.foo.project:module1:src/sample1.xoo")).extracting("metricKey").doesNotContain(CoreMetrics.CONDITIONS_TO_COVER_KEY,
+    assertThat(allMeasures.get("com.foo.project:module1/src/sample1.xoo")).extracting("metricKey").doesNotContain(CoreMetrics.CONDITIONS_TO_COVER_KEY,
       CoreMetrics.UNCOVERED_CONDITIONS_KEY);
 
-    assertThat(allMeasures.get("com.foo.project:module1:src/sample2.xoo")).extracting("metricKey").doesNotContain(CoreMetrics.LINES_TO_COVER_KEY,
+    assertThat(allMeasures.get("com.foo.project:module1/src/sample2.xoo")).extracting("metricKey").doesNotContain(CoreMetrics.LINES_TO_COVER_KEY,
       CoreMetrics.CONDITIONS_TO_COVER_KEY,
       CoreMetrics.UNCOVERED_CONDITIONS_KEY, CoreMetrics.UNCOVERED_LINES_KEY);
   }
index 6ce98f526ac195acb2681597948fa35770909214..e31dfbb1b4e3e2bc2063191011d39f99c22444a2 100644 (file)
@@ -125,7 +125,7 @@ public class CpdMediumTest {
     assertThat(cloneGroupFile1.getOriginPosition().getStartLine()).isEqualTo(1);
     assertThat(cloneGroupFile1.getOriginPosition().getEndLine()).isEqualTo(17);
     assertThat(cloneGroupFile1.getDuplicateList()).hasSize(1);
-    assertThat(cloneGroupFile1.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent((inputFile2).key()).getRef());
+    assertThat(cloneGroupFile1.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile2).getRef());
 
     List<ScannerReport.Duplication> duplicationGroupsFile2 = result.duplicationsFor(inputFile2);
     assertThat(duplicationGroupsFile2).hasSize(1);
@@ -134,7 +134,7 @@ public class CpdMediumTest {
     assertThat(cloneGroupFile2.getOriginPosition().getStartLine()).isEqualTo(1);
     assertThat(cloneGroupFile2.getOriginPosition().getEndLine()).isEqualTo(17);
     assertThat(cloneGroupFile2.getDuplicateList()).hasSize(1);
-    assertThat(cloneGroupFile2.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent((inputFile1).key()).getRef());
+    assertThat(cloneGroupFile2.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile1).getRef());
 
     assertThat(result.duplicationBlocksFor(inputFile1)).isEmpty();
   }
@@ -177,7 +177,7 @@ public class CpdMediumTest {
     assertThat(cloneGroupFile1.getOriginPosition().getStartLine()).isEqualTo(1);
     assertThat(cloneGroupFile1.getOriginPosition().getEndLine()).isEqualTo(17);
     assertThat(cloneGroupFile1.getDuplicateList()).hasSize(1);
-    assertThat(cloneGroupFile1.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent((inputFile2).key()).getRef());
+    assertThat(cloneGroupFile1.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile2).getRef());
 
     List<ScannerReport.Duplication> duplicationGroupsFile2 = result.duplicationsFor(inputFile2);
     assertThat(duplicationGroupsFile2).hasSize(1);
@@ -186,7 +186,7 @@ public class CpdMediumTest {
     assertThat(cloneGroupFile2.getOriginPosition().getStartLine()).isEqualTo(1);
     assertThat(cloneGroupFile2.getOriginPosition().getEndLine()).isEqualTo(17);
     assertThat(cloneGroupFile2.getDuplicateList()).hasSize(1);
-    assertThat(cloneGroupFile2.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent((inputFile1).key()).getRef());
+    assertThat(cloneGroupFile2.getDuplicate(0).getOtherFileRef()).isEqualTo(result.getReportComponent(inputFile1).getRef());
 
     assertThat(result.duplicationBlocksFor(inputFile1)).isEmpty();
   }
index a8e84a6faf20c94a5238ede96f4b3d450a587db4..705692a6777fc34ad90afbf1fbd8bb5c5504e095 100644 (file)
@@ -25,7 +25,6 @@ import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Random;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
@@ -34,10 +33,8 @@ import org.junit.Rule;
 import org.junit.Test;
 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.internal.DefaultInputFile;
-import org.sonar.api.scanner.fs.InputProject;
 import org.sonar.api.utils.MessageException;
 import org.sonar.api.utils.System2;
 import org.sonar.scanner.mediumtest.AnalysisResult;
@@ -112,19 +109,15 @@ public class FileSystemMediumTest {
     int ref = result.getReportReader().readMetadata().getRootComponentRef();
     assertThat(result.getReportReader().readComponent(ref).getName()).isEmpty();
     assertThat(result.inputFiles()).hasSize(1);
-    assertThat(result.inputDirs()).hasSize(1);
 
     DefaultInputFile file = (DefaultInputFile) result.inputFile("src/sample.xoo");
-    InputDir dir = result.inputDir("src");
     assertThat(file.type()).isEqualTo(InputFile.Type.MAIN);
     assertThat(file.relativePath()).isEqualTo("src/sample.xoo");
     assertThat(file.language()).isEqualTo("xoo");
-    assertThat(dir.relativePath()).isEqualTo("src");
 
-    // file and dirs were published, since language matched xoo
+    // file was published, since language matched xoo
     assertThat(file.isPublished()).isTrue();
-    assertThat(result.getReportComponent(dir.key())).isNotNull();
-    assertThat(result.getReportComponent(file.key())).isNotNull();
+    assertThat(result.getReportComponent(file.scannerId())).isNotNull();
   }
 
   @Test
@@ -290,7 +283,11 @@ public class FileSystemMediumTest {
     assertThat(logs.getAllAsString()).doesNotContain("'src/main/sample.java' generated metadata");
     assertThat(logs.getAllAsString()).doesNotContain("'src/test/sample.java' generated metadata");
     DefaultInputFile javaInputFile = (DefaultInputFile) result.inputFile("src/main/sample.java");
-    assertThat(result.getReportComponent(javaInputFile.key())).isNull();
+
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Unable to find report for component");
+
+    result.getReportComponent(javaInputFile);
   }
 
   @Test
@@ -317,7 +314,7 @@ public class FileSystemMediumTest {
     assertThat(logs.getAllAsString()).contains("'src" + File.separator + "sample.unknown' indexed with language 'null'");
     assertThat(logs.getAllAsString()).contains("'src/sample.unknown' generated metadata");
     DefaultInputFile inputFile = (DefaultInputFile) result.inputFile("src/sample.unknown");
-    assertThat(result.getReportComponent(inputFile.key())).isNotNull();
+    assertThat(result.getReportComponent(inputFile)).isNotNull();
   }
 
   @Test
@@ -397,54 +394,9 @@ public class FileSystemMediumTest {
       .execute();
 
     DefaultInputFile file = (DefaultInputFile) result.inputFile("src/sample.xoo");
-    InputDir dir = result.inputDir("src");
 
     assertThat(file.isPublished()).isTrue();
-    assertThat(result.getReportComponent(dir.key())).isNotNull();
-    assertThat(result.getReportComponent(file.key())).isNotNull();
-  }
-
-  @Test
-  public void publishDirsWithIssues() throws IOException {
-    tester
-      .addRules(new XooRulesDefinition())
-      .addActiveRule("xoo", "OneIssuePerDirectory", null, "OneIssuePerDirectory", "MAJOR", null, "xoo");
-
-    builder = ImmutableMap.<String, String>builder()
-      .put("sonar.task", "scan")
-      .put("sonar.verbose", "true")
-      .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
-      .put("sonar.projectKey", "com.foo.project")
-      .put("sonar.projectVersion", "1.0-SNAPSHOT")
-      .put("sonar.projectDescription", "Description of Foo Project");
-
-    Path unknownRelative = Paths.get("src", "unknown", "file.notanalyzed");
-    Path unknown = baseDir.toPath().resolve(unknownRelative);
-    Files.createDirectories(unknown.getParent());
-    Files.write(unknown, "dummy content".getBytes());
-
-    Path emptyDirRelative = Paths.get("src", "emptydir");
-    Files.createDirectories(emptyDirRelative);
-
-    AnalysisResult result = tester.newAnalysis()
-      .properties(builder
-        .put("sonar.sources", "src")
-        .build())
-      .execute();
-
-    DefaultInputFile unknownInputFile = (DefaultInputFile) result.inputFile("src/unknown/file.notanalyzed");
-    InputProject project = result.project();
-
-    assertThat(unknownInputFile.isPublished()).isFalse();
-    assertThat(result.getReportComponent(project.key())).isNotNull();
-
-    // no issues on empty dir
-    InputDir emptyInputDir = result.inputDir(emptyDirRelative.toString());
-    assertThat(emptyInputDir).isNull();
-
-    // no issues on parent dir
-    InputDir parentInputDir = result.inputDir(unknownRelative.getParent().getParent().toString());
-    assertThat(parentInputDir).isNull();
+    assertThat(result.getReportComponent(file)).isNotNull();
   }
 
   @Test
@@ -462,10 +414,8 @@ public class FileSystemMediumTest {
       .execute();
 
     assertThat(result.inputFiles()).hasSize(1);
-    assertThat(result.inputDirs()).hasSize(1);
     assertThat(result.inputFile("src/sample.xoo").type()).isEqualTo(InputFile.Type.MAIN);
     assertThat(result.inputFile("src/sample.xoo").relativePath()).isEqualTo("src/sample.xoo");
-    assertThat(result.inputDir("src").relativePath()).isEqualTo("src");
   }
 
   @Test
@@ -487,7 +437,6 @@ public class FileSystemMediumTest {
       .execute();
 
     assertThat(result.inputFiles()).hasSize(100);
-    assertThat(result.inputDirs()).hasSize(1);
   }
 
   @Test
@@ -540,7 +489,6 @@ public class FileSystemMediumTest {
       .execute();
 
     assertThat(result.inputFiles()).hasSize(4);
-    assertThat(result.inputDirs()).hasSize(3);
   }
 
   @Test
@@ -680,7 +628,6 @@ public class FileSystemMediumTest {
       .execute();
 
     assertThat(result.inputFiles()).hasSize(4);
-    assertThat(result.inputDirs()).hasSize(4);
   }
 
   @Test
@@ -727,7 +674,6 @@ public class FileSystemMediumTest {
       .execute();
 
     assertThat(result.inputFiles()).hasSize(4);
-    assertThat(result.inputDirs()).hasSize(3);
   }
 
   @Test
index ed76bba6c251800623e07f29feefbe882b324999..e09f0b42967aa603d7aedb0cecf12497c604ada3 100644 (file)
@@ -70,7 +70,6 @@ public class IssuesOnDirMediumTest {
         .build())
       .execute();
 
-    assertThat(result.issuesFor(result.inputDir("src"))).hasSize(0);
     assertThat(result.issuesFor(result.project())).hasSize(2);
   }
 
@@ -97,7 +96,6 @@ public class IssuesOnDirMediumTest {
         .build())
       .execute();
 
-    assertThat(result.issuesFor(result.inputDir(""))).hasSize(0);
     assertThat(result.issuesFor(result.project())).hasSize(2);
   }
 
index 48561c72e0a6c34fb7f054449441d874acc95368..5c8fa0d92e1b79fbbf4489327c2eacba2107c159 100644 (file)
@@ -67,7 +67,7 @@ public class IssuesOnModuleMediumTest {
         .build())
       .execute();
 
-    assertThat(result.issuesFor(result.getReportComponent("com.foo.project"))).hasSize(1);
+    assertThat(result.issuesFor(result.project())).hasSize(1);
   }
 
 }
index cb29125779c564dae7f5c4e0734eee7a88a9ea63..2e58d57728816cd59d5b5326bb5be621fd0f32c3 100644 (file)
@@ -147,7 +147,7 @@ public class IssueModeAndReportsMediumTest {
     String logs = StringUtils.join(logTester.logs(LoggerLevel.INFO), "\n");
 
     assertThat(logs).contains("Performing issue tracking");
-    assertThat(logs).contains("6/6 components tracked");
+    assertThat(logs).contains("4/4 components tracked");
 
     // assert that original fields of a matched issue are kept
     assertThat(result.trackedIssues()).haveExactly(1, new Condition<TrackedIssue>() {
index 5b42f3e016c1d14b1f35448f1485aa7bc5365c03..94f6030b3e6eb319cac9a7d5d2b9e2197de1383e 100644 (file)
@@ -116,10 +116,9 @@ public class ScmMediumTest {
     ScannerReportReader reader = new ScannerReportReader(reportDir);
 
     Component project = reader.readComponent(reader.readMetadata().getRootComponentRef());
-    Component dir = reader.readComponent(project.getChildRef(0));
-    for (Integer fileRef : dir.getChildRefList()) {
+    for (Integer fileRef : project.getChildRefList()) {
       Component file = reader.readComponent(fileRef);
-      if (file.getPath().equals(path)) {
+      if (file.getProjectRelativePath().equals(path)) {
         return reader.readChangesets(file.getRef());
       }
     }
index 245fe2cefc1a4cb9e4bebf731376ca08105bbabb..3d45aa214d83cdb0ca852848b7a825ecd16b6a32 100644 (file)
@@ -87,7 +87,7 @@ public class DefaultPostJobContextTest {
     assertThat(issue.inputComponent()).isNull();
 
     String moduleKey = "foo";
-    componentStore.put(new TestInputFileBuilder(moduleKey, "src/Foo.php").build());
+    componentStore.put(moduleKey, new TestInputFileBuilder(moduleKey, "src/Foo.php").build());
     assertThat(issue.inputComponent()).isNotNull();
 
   }
index 4b27f676ae92a337fa0d5777bfeda3a2fe8e664f..e13bc24a9d076489f1b86f837b5fa469118b9947 100644 (file)
@@ -21,12 +21,8 @@ package org.sonar.scanner.report;
 
 import java.io.File;
 import java.io.IOException;
-import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -35,10 +31,8 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputFile.Type;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
 import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.scanner.ProjectAnalysisInfo;
@@ -49,24 +43,17 @@ import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus;
 import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink.ComponentLinkType;
 import org.sonar.scanner.protocol.output.ScannerReportReader;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
-import org.sonar.scanner.scan.DefaultComponentTree;
-import org.sonar.scanner.scan.DefaultInputModuleHierarchy;
 import org.sonar.scanner.scan.branch.BranchConfiguration;
-import org.sonar.scanner.scan.branch.BranchType;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-import static org.sonar.api.batch.fs.internal.TestInputFileBuilder.newDefaultInputDir;
-import static org.sonar.api.batch.fs.internal.TestInputFileBuilder.newDefaultInputFile;
-import static org.sonar.api.batch.fs.internal.TestInputFileBuilder.newDefaultInputModule;
 
 public class ComponentsPublisherTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
-  private DefaultComponentTree tree;
-  private InputModuleHierarchy moduleHierarchy;
   private File outputDir;
   private ScannerReportWriter writer;
   private ScannerReportReader reader;
@@ -75,7 +62,6 @@ public class ComponentsPublisherTest {
   @Before
   public void setUp() throws IOException {
     branchConfiguration = mock(BranchConfiguration.class);
-    tree = new DefaultComponentTree();
     outputDir = temp.newFolder();
     writer = new ScannerReportWriter(outputDir);
     reader = new ScannerReportReader(outputDir);
@@ -97,7 +83,9 @@ public class ComponentsPublisherTest {
       .setDescription("Root description")
       .setBaseDir(temp.newFolder())
       .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
+    DefaultInputProject project = new DefaultInputProject(rootDef, 1);
+
+    InputComponentStore store = new InputComponentStore(project, branchConfiguration);
 
     Path moduleBaseDir = temp.newFolder().toPath();
     ProjectDefinition module1Def = ProjectDefinition.create()
@@ -108,43 +96,25 @@ public class ComponentsPublisherTest {
       .setWorkDir(temp.newFolder());
     rootDef.addSubProject(module1Def);
 
-    DefaultInputModule module1 = new DefaultInputModule(module1Def, 2);
-
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
-    when(moduleHierarchy.children(root)).thenReturn(Collections.singleton(module1));
-    when(moduleHierarchy.parent(module1)).thenReturn(root);
-    tree.index(module1, root);
-
-    DefaultInputDir dir = new DefaultInputDir("module1", "src", 3)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir, module1);
-
-    DefaultInputDir dir2 = new DefaultInputDir("module1", "src2", 17)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir2, module1);
+    DefaultInputFile file = new TestInputFileBuilder("foo", "module1/src/Foo.java", 4).setLines(2).setStatus(InputFile.Status.SAME).build();
+    store.put("module1", file);
 
-    DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).setStatus(InputFile.Status.SAME).build();
-    tree.index(file, dir);
+    DefaultInputFile file18 = new TestInputFileBuilder("foo", "module1/src2/Foo.java", 18).setLines(2).setStatus(InputFile.Status.SAME).build();
+    store.put("module1", file18);
 
-    DefaultInputFile file18 = new TestInputFileBuilder("module1", "src2/Foo.java", 18).setLines(2).setStatus(InputFile.Status.SAME).build();
-    tree.index(file18, dir2);
+    DefaultInputFile file2 = new TestInputFileBuilder("foo", "module1/src/Foo2.java", 5).setPublish(false).setLines(2).build();
+    store.put("module1", file2);
 
-    DefaultInputFile file2 = new TestInputFileBuilder("module1", "src/Foo2.java", 5).setPublish(false).setLines(2).build();
-    tree.index(file2, dir);
+    DefaultInputFile fileWithoutLang = new TestInputFileBuilder("foo", "module1/src/make", 6).setLines(10).setStatus(InputFile.Status.CHANGED).build();
+    store.put("module1", fileWithoutLang);
 
-    DefaultInputFile fileWithoutLang = new TestInputFileBuilder("module1", "src/make", 6).setLines(10).setStatus(InputFile.Status.CHANGED).build();
-    tree.index(fileWithoutLang, dir);
+    DefaultInputFile testFile = new TestInputFileBuilder("foo", "module1/test/FooTest.java", 7).setType(Type.TEST).setStatus(InputFile.Status.ADDED).setLines(4).build();
+    store.put("module1", testFile);
 
-    DefaultInputFile testFile = new TestInputFileBuilder("module1", "test/FooTest.java", 7).setType(Type.TEST).setStatus(InputFile.Status.ADDED).setLines(4).build();
-    tree.index(testFile, dir);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
+    ComponentsPublisher publisher = new ComponentsPublisher(project, store);
     publisher.publish(writer);
 
     assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isTrue();
     assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
     assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isTrue();
     assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isTrue();
@@ -161,11 +131,6 @@ public class ComponentsPublisherTest {
     assertThat(rootProtobuf.getVersion()).isEqualTo("1.0");
     assertThat(rootProtobuf.getLinkCount()).isEqualTo(0);
 
-    Component module1Protobuf = reader.readComponent(2);
-    assertThat(module1Protobuf.getKey()).isEqualTo("module1");
-    assertThat(module1Protobuf.getDescription()).isEqualTo("Module description");
-    assertThat(module1Protobuf.getVersion()).isEqualTo("1.0");
-
     assertThat(reader.readComponent(4).getStatus()).isEqualTo(FileStatus.SAME);
     assertThat(reader.readComponent(6).getStatus()).isEqualTo(FileStatus.CHANGED);
     assertThat(reader.readComponent(7).getStatus()).isEqualTo(FileStatus.ADDED);
@@ -183,12 +148,11 @@ public class ComponentsPublisherTest {
       .setWorkDir(temp.newFolder())
       .setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "my_branch");
 
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
+    DefaultInputProject project = new DefaultInputProject(rootDef, 1);
 
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
+    InputComponentStore store = new InputComponentStore(project, branchConfiguration);
 
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
+    ComponentsPublisher publisher = new ComponentsPublisher(project, store);
     publisher.publish(writer);
     Component rootProtobuf = reader.readComponent(1);
     assertThat(rootProtobuf.getKey()).isEqualTo("foo");
@@ -196,311 +160,48 @@ public class ComponentsPublisherTest {
   }
 
   @Test
-  public void should_write_relative_path_to_root_for_modules_in_flat_hierarchy() throws IOException {
-    Path rootBaseDir = temp.newFolder().toPath();
-    Path module1BaseDir = rootBaseDir.resolve("module1");
-    Path module2BaseDir = rootBaseDir.resolve("module2");
-    Files.createDirectories(module1BaseDir);
-    Files.createDirectories(module2BaseDir);
-
-    ProjectDefinition rootDef = ProjectDefinition.create()
-      .setKey("foo")
-      .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
-      .setName("Root project")
-      .setDescription("Root description")
-      .setBaseDir(rootBaseDir.toFile())
-      .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
-
-    ProjectDefinition module1Def = ProjectDefinition.create()
-      .setKey("module1k")
-      .setName("Module1")
-      .setDescription("Module description")
-      .setBaseDir(module1BaseDir.toFile())
-      .setWorkDir(temp.newFolder());
-    rootDef.addSubProject(module1Def);
-    DefaultInputModule module1 = new DefaultInputModule(module1Def, 2);
-
-    ProjectDefinition module2Def = ProjectDefinition.create()
-      .setKey("module2k")
-      .setName("Module2")
-      .setDescription("Module description")
-      .setBaseDir(module2BaseDir.toFile())
-      .setWorkDir(temp.newFolder());
-    module1Def.addSubProject(module2Def);
-    DefaultInputModule module2 = new DefaultInputModule(module2Def, 3);
-
-    Map<DefaultInputModule, DefaultInputModule> modules = new HashMap<>();
-    modules.put(module2, module1);
-    modules.put(module1, root);
-    moduleHierarchy = new DefaultInputModuleHierarchy(root, modules);
-    tree.index(module2, module1);
-    tree.index(module1, root);
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
-    publisher.publish(writer);
-
-    assertThat(reader.readComponent(2).getProjectRelativePath()).isEqualTo("module1");
-    assertThat(reader.readComponent(3).getProjectRelativePath()).isEqualTo("module2");
-  }
-
-  @Test
-  public void should_skip_dir_without_published_files() throws IOException {
-    ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
-    when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
-
-    Path moduleBaseDir = temp.newFolder().toPath();
-    ProjectDefinition rootDef = ProjectDefinition.create()
-      .setKey("foo")
-      .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
-      .setName("Root project")
-      .setDescription("Root description")
-      .setBaseDir(moduleBaseDir.toFile())
-      .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
-
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
-    when(moduleHierarchy.children(root)).thenReturn(Collections.emptyList());
-
-    // dir with files
-    DefaultInputDir dir = new DefaultInputDir("module1", "src", 2)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir, root);
-
-    // dir without files and issues
-    DefaultInputDir dir2 = new DefaultInputDir("module1", "src2", 3)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir2, root);
-
-    // dir without files but has issues
-    DefaultInputDir dir3 = new DefaultInputDir("module1", "src3", 4)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir3, root);
-    writeIssue(4);
-
-    DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 5).setLines(2).setStatus(InputFile.Status.SAME).build();
-    tree.index(file, dir);
-
-    DefaultInputFile file2 = new TestInputFileBuilder("module1", "src2/Foo2.java", 6).setPublish(false).setLines(2).build();
-    tree.index(file2, dir2);
-
-    DefaultInputFile file3 = new TestInputFileBuilder("module1", "src2/Foo3.java", 7).setPublish(false).setLines(2).build();
-    tree.index(file3, dir3);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
-    publisher.publish(writer);
-
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
-
-    // file was not marked for publishing and directory doesn't contain issues, so directory won't be included as well
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isFalse();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isFalse();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isFalse();
-  }
-
-  @Test
-  public void should_skip_empty_modules_for_short_living_branches() throws IOException {
-    ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
-    when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
-
-    ProjectDefinition rootDef = ProjectDefinition.create()
-      .setKey("foo")
-      .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
-      .setName("Root project")
-      .setDescription("Root description")
-      .setBaseDir(temp.newFolder())
-      .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
-
-    ProjectDefinition emptyModuleDef = ProjectDefinition.create()
-      .setKey("modEmpty")
-      .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
-      .setName("Empty module")
-      .setDescription("Empty module")
-      .setBaseDir(temp.newFolder())
-      .setWorkDir(temp.newFolder());
-    DefaultInputModule emptyModule = new DefaultInputModule(emptyModuleDef, 2);
-
-    ProjectDefinition notEmptyModuleDef = ProjectDefinition.create()
-      .setKey("modNotEmpty")
-      .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
-      .setName("Module")
-      .setDescription("Module")
-      .setBaseDir(temp.newFolder())
-      .setWorkDir(temp.newFolder());
-    DefaultInputModule notEmptyModule = new DefaultInputModule(notEmptyModuleDef, 3);
-
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
-    when(moduleHierarchy.isRoot(root)).thenReturn(true);
-    when(moduleHierarchy.children(root)).thenReturn(Arrays.asList(emptyModule, notEmptyModule));
-    when(moduleHierarchy.children(emptyModule)).thenReturn(Collections.emptyList());
-    when(moduleHierarchy.children(notEmptyModule)).thenReturn(Collections.emptyList());
-    when(branchConfiguration.branchType()).thenReturn(BranchType.SHORT);
-
-    // dir with files
-    DefaultInputDir dir = new DefaultInputDir("modNotEmpty", "src", 4);
-    tree.index(dir, notEmptyModule);
-
-    // Only an unchanged file, so module should also be skipped
-    DefaultInputFile file = new TestInputFileBuilder("modNotEmpty", "src/Foo.java", 5).setLines(2).setStatus(InputFile.Status.SAME).build();
-    tree.index(file, dir);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
-    publisher.publish(writer);
-
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isFalse();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isFalse();
-  }
-
-  @Test
-  public void do_not_skip_unchanged_components_in_short_branches() throws IOException {
-    when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
-    ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
-    when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
-
-    Path moduleBaseDir = temp.newFolder().toPath();
-    ProjectDefinition rootDef = ProjectDefinition.create()
-      .setKey("foo")
-      .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
-      .setName("Root project")
-      .setDescription("Root description")
-      .setBaseDir(moduleBaseDir.toFile())
-      .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
-
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
-    when(moduleHierarchy.children(root)).thenReturn(Collections.emptyList());
-
-    // dir with changed files
-    DefaultInputDir dir = new DefaultInputDir("module1", "src", 2)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir, root);
-
-    // dir without changed files or issues
-    DefaultInputDir dir2 = new DefaultInputDir("module1", "src2", 3)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir2, root);
-
-    // dir without changed files but has issues
-    DefaultInputDir dir3 = new DefaultInputDir("module1", "src3", 4)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir3, root);
-    writeIssue(4);
-
-    DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 5)
-      .setLines(2)
-      .setPublish(true)
-      .setStatus(InputFile.Status.ADDED)
-      .build();
-    tree.index(file, dir);
-
-    DefaultInputFile file2 = new TestInputFileBuilder("module1", "src2/Foo2.java", 6)
-      .setPublish(true)
-      .setStatus(InputFile.Status.SAME)
-      .setLines(2)
-      .build();
-    tree.index(file2, dir2);
-
-    DefaultInputFile file3 = new TestInputFileBuilder("module1", "src3/Foo3.java", 7)
-      .setPublish(true)
-      .setStatus(InputFile.Status.SAME)
-      .setLines(2)
-      .build();
-    tree.index(file3, dir3);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
-    publisher.publish(writer);
-
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
-
-    // do not skip, needed for computing overall coverage
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isTrue();
-  }
-
-  @Test
-  public void do_not_skip_unchanged_components_in_pull_requests() throws IOException {
+  public void publish_unchanged_components_even_in_short_branches() throws IOException {
     when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
     ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
     when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
 
-    Path moduleBaseDir = temp.newFolder().toPath();
+    Path baseDir = temp.newFolder().toPath();
     ProjectDefinition rootDef = ProjectDefinition.create()
       .setKey("foo")
       .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
       .setName("Root project")
       .setDescription("Root description")
-      .setBaseDir(moduleBaseDir.toFile())
+      .setBaseDir(baseDir.toFile())
       .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
-
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
-    when(moduleHierarchy.children(root)).thenReturn(Collections.emptyList());
-
-    // dir with changed files
-    DefaultInputDir dir = new DefaultInputDir("module1", "src", 2)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir, root);
-
-    // dir without changed files or issues
-    DefaultInputDir dir2 = new DefaultInputDir("module1", "src2", 3)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir2, root);
+    DefaultInputProject project = new DefaultInputProject(rootDef, 1);
 
-    // dir without changed files but has issues
-    DefaultInputDir dir3 = new DefaultInputDir("module1", "src3", 4)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir3, root);
-    writeIssue(4);
+    InputComponentStore store = new InputComponentStore(project, branchConfiguration);
 
-    DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 5)
+    DefaultInputFile file = new TestInputFileBuilder("foo", "src/Foo.java", 5)
       .setLines(2)
       .setPublish(true)
       .setStatus(InputFile.Status.ADDED)
       .build();
-    tree.index(file, dir);
+    store.put("foo", file);
 
-    DefaultInputFile file2 = new TestInputFileBuilder("module1", "src2/Foo2.java", 6)
+    DefaultInputFile file2 = new TestInputFileBuilder("foo", "src2/Foo2.java", 6)
       .setPublish(true)
       .setStatus(InputFile.Status.SAME)
       .setLines(2)
       .build();
-    tree.index(file2, dir2);
+    store.put("foo", file2);
 
-    DefaultInputFile file3 = new TestInputFileBuilder("module1", "src3/Foo3.java", 7)
-      .setPublish(true)
-      .setStatus(InputFile.Status.SAME)
-      .setLines(2)
-      .build();
-    tree.index(file3, dir3);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
+    ComponentsPublisher publisher = new ComponentsPublisher(project, store);
     publisher.publish(writer);
 
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
     assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
 
     // do not skip, needed for computing overall coverage
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isTrue();
     assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isTrue();
   }
 
   @Test
-  public void add_components_without_version_and_name() throws IOException {
+  public void publish_project_without_version_and_name() throws IOException {
     ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
     when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
 
@@ -509,47 +210,13 @@ public class ComponentsPublisherTest {
       .setDescription("Root description")
       .setBaseDir(temp.newFolder())
       .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
-
-    Path moduleBaseDir = temp.newFolder().toPath();
-    ProjectDefinition module1Def = ProjectDefinition.create()
-      .setKey("module1")
-      .setDescription("Module description")
-      .setBaseDir(moduleBaseDir.toFile())
-      .setWorkDir(temp.newFolder());
-    rootDef.addSubProject(module1Def);
-    DefaultInputModule module1 = new DefaultInputModule(module1Def, 2);
-
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
-    when(moduleHierarchy.children(root)).thenReturn(Collections.singleton(module1));
-    tree.index(module1, root);
-
-    DefaultInputDir dir = new DefaultInputDir("module1", "src", 3)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir, module1);
-
-    DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).setStatus(InputFile.Status.SAME).build();
-    tree.index(file, dir);
-
-    DefaultInputFile fileWithoutLang = new TestInputFileBuilder("module1", "src/make", 5).setLines(10).setStatus(InputFile.Status.SAME).build();
-    tree.index(fileWithoutLang, dir);
+    DefaultInputProject project = new DefaultInputProject(rootDef, 1);
 
-    DefaultInputFile testFile = new TestInputFileBuilder("module1", "test/FooTest.java", 6).setType(Type.TEST).setStatus(InputFile.Status.SAME).setLines(4).build();
-    tree.index(testFile, dir);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
+    InputComponentStore store = new InputComponentStore(project, branchConfiguration);
+    ComponentsPublisher publisher = new ComponentsPublisher(project, store);
     publisher.publish(writer);
 
     assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isTrue();
-
-    // no such reference
-    assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isFalse();
 
     ScannerReportReader reader = new ScannerReportReader(outputDir);
     Component rootProtobuf = reader.readComponent(1);
@@ -558,16 +225,10 @@ public class ComponentsPublisherTest {
     assertThat(rootProtobuf.getDescription()).isEqualTo("Root description");
     assertThat(rootProtobuf.getVersion()).isEqualTo("");
     assertThat(rootProtobuf.getLinkCount()).isEqualTo(0);
-
-    Component module1Protobuf = reader.readComponent(2);
-    assertThat(module1Protobuf.getKey()).isEqualTo("module1");
-    assertThat(module1Protobuf.getName()).isEqualTo("");
-    assertThat(module1Protobuf.getDescription()).isEqualTo("Module description");
-    assertThat(module1Protobuf.getVersion()).isEqualTo("");
   }
 
   @Test
-  public void add_components_with_links_and_branch() throws Exception {
+  public void publish_project_with_links_and_branch() throws Exception {
     ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
     when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
 
@@ -577,156 +238,23 @@ public class ComponentsPublisherTest {
       .setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "my_branch")
       .setName("Root project")
       .setProperty(CoreProperties.LINKS_HOME_PAGE, "http://home")
+      .setProperty(CoreProperties.LINKS_CI, "http://ci")
       .setDescription("Root description")
       .setBaseDir(temp.newFolder())
       .setWorkDir(temp.newFolder());
-    DefaultInputModule root = new DefaultInputModule(rootDef, 1);
-
-    Path moduleBaseDir = temp.newFolder().toPath();
-    ProjectDefinition module1Def = ProjectDefinition.create()
-      .setKey("module1")
-      .setName("Module1")
-      .setProperty(CoreProperties.LINKS_CI, "http://ci")
-      .setDescription("Module description")
-      .setBaseDir(moduleBaseDir.toFile())
-      .setWorkDir(temp.newFolder());
-    rootDef.addSubProject(module1Def);
-    DefaultInputModule module1 = new DefaultInputModule(module1Def, 2);
-
-    moduleHierarchy = mock(InputModuleHierarchy.class);
-    when(moduleHierarchy.root()).thenReturn(root);
-    when(moduleHierarchy.children(root)).thenReturn(Collections.singleton(module1));
-    when(moduleHierarchy.parent(module1)).thenReturn(root);
-    tree.index(module1, root);
+    DefaultInputProject project = new DefaultInputProject(rootDef, 1);
 
-    DefaultInputDir dir = new DefaultInputDir("module1", "src", 3)
-      .setModuleBaseDir(moduleBaseDir);
-    tree.index(dir, module1);
-
-    DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).setStatus(InputFile.Status.SAME).build();
-    tree.index(file, dir);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
+    InputComponentStore store = new InputComponentStore(project, branchConfiguration);
+    ComponentsPublisher publisher = new ComponentsPublisher(project, store);
     publisher.publish(writer);
 
     ScannerReportReader reader = new ScannerReportReader(outputDir);
     Component rootProtobuf = reader.readComponent(1);
     assertThat(rootProtobuf.getVersion()).isEqualTo("1.0");
-    assertThat(rootProtobuf.getLinkCount()).isEqualTo(1);
+    assertThat(rootProtobuf.getLinkCount()).isEqualTo(2);
     assertThat(rootProtobuf.getLink(0).getType()).isEqualTo(ComponentLinkType.HOME);
     assertThat(rootProtobuf.getLink(0).getHref()).isEqualTo("http://home");
-
-    Component module1Protobuf = reader.readComponent(2);
-    assertThat(module1Protobuf.getVersion()).isEqualTo("1.0");
-    assertThat(module1Protobuf.getLinkCount()).isEqualTo(1);
-    assertThat(module1Protobuf.getLink(0).getType()).isEqualTo(ComponentLinkType.CI);
-    assertThat(module1Protobuf.getLink(0).getHref()).isEqualTo("http://ci");
-  }
-
-  @Test
-  public void add_components_with_correct_project_relative_path() throws Exception {
-    Map<DefaultInputModule, DefaultInputModule> parents = new HashMap<>();
-
-    DefaultInputModule root = newDefaultInputModule("foo", temp.newFolder());
-
-    DefaultInputFile file = newDefaultInputFile(root.getBaseDir(), root, "Foo.java");
-    tree.index(file, root);
-
-    DefaultInputDir dir1 = newDefaultInputDir(root, "dir1");
-    tree.index(dir1, root);
-
-    DefaultInputFile dir1_file = newDefaultInputFile(root.getBaseDir(), root, "dir1/Foo.java");
-    tree.index(dir1_file, dir1);
-
-    DefaultInputDir dir1_dir1 = newDefaultInputDir(root, "dir1/dir1");
-    tree.index(dir1_dir1, dir1);
-
-    DefaultInputFile dir1_dir1_file = newDefaultInputFile(root.getBaseDir(), root, "dir1/dir1/Foo.java");
-    tree.index(dir1_dir1_file, dir1_dir1);
-
-    // module in root
-
-    DefaultInputModule mod1 = newDefaultInputModule(root, "mod1");
-    parents.put(mod1, root);
-    tree.index(mod1, root);
-
-    DefaultInputFile mod1_file = newDefaultInputFile(root.getBaseDir(), mod1, "Foo.java");
-    tree.index(mod1_file, mod1);
-
-    DefaultInputDir mod1_dir2 = newDefaultInputDir(mod1, "dir2");
-    tree.index(mod1_dir2, mod1);
-
-    DefaultInputFile mod1_dir2_file = newDefaultInputFile(root.getBaseDir(), mod1, "dir2/Foo.java");
-    tree.index(mod1_dir2_file, mod1_dir2);
-
-    // module in module
-
-    DefaultInputModule mod1_mod2 = newDefaultInputModule(mod1, "mod2");
-    parents.put(mod1_mod2, mod1);
-    tree.index(mod1_mod2, mod1);
-
-    DefaultInputFile mod1_mod2_file = newDefaultInputFile(root.getBaseDir(), mod1_mod2, "Foo.java");
-    tree.index(mod1_mod2_file, mod1_mod2);
-
-    DefaultInputDir mod1_mod2_dir = newDefaultInputDir(mod1_mod2, "dir");
-    tree.index(mod1_mod2_dir, mod1_mod2);
-
-    DefaultInputFile mod1_mod2_dir_file = newDefaultInputFile(root.getBaseDir(), mod1_mod2, "dir/Foo.java");
-    tree.index(mod1_mod2_dir_file, mod1_mod2_dir);
-
-    moduleHierarchy = new DefaultInputModuleHierarchy(root, parents);
-
-    ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree, branchConfiguration);
-    publisher.publish(writer);
-
-    ScannerReportReader reader = new ScannerReportReader(outputDir);
-
-    // project root
-    assertThat(reader.readComponent(root.scannerId()).getPath()).isEmpty();
-    assertThat(reader.readComponent(root.scannerId()).getProjectRelativePath()).isEmpty();
-
-    // file in root
-    assertThat(reader.readComponent(file.scannerId()).getPath()).isEqualTo("Foo.java");
-    assertThat(reader.readComponent(file.scannerId()).getProjectRelativePath()).isEqualTo("Foo.java");
-
-    // dir in root
-    assertThat(reader.readComponent(dir1.scannerId()).getPath()).isEqualTo("dir1");
-    assertThat(reader.readComponent(dir1.scannerId()).getProjectRelativePath()).isEqualTo("dir1");
-
-    // file in dir in root
-    assertThat(reader.readComponent(dir1_file.scannerId()).getPath()).isEqualTo("dir1/Foo.java");
-    assertThat(reader.readComponent(dir1_file.scannerId()).getProjectRelativePath()).isEqualTo("dir1/Foo.java");
-
-    // dir in dir in root
-    assertThat(reader.readComponent(dir1_dir1.scannerId()).getPath()).isEqualTo("dir1/dir1");
-    assertThat(reader.readComponent(dir1_dir1.scannerId()).getProjectRelativePath()).isEqualTo("dir1/dir1");
-
-    // module in root
-    assertThat(reader.readComponent(mod1.scannerId()).getPath()).isEqualTo("mod1");
-    assertThat(reader.readComponent(mod1.scannerId()).getProjectRelativePath()).isEqualTo("mod1");
-
-    // dir in module in root
-    assertThat(reader.readComponent(mod1_dir2.scannerId()).getPath()).isEqualTo("dir2");
-    assertThat(reader.readComponent(mod1_dir2.scannerId()).getProjectRelativePath()).isEqualTo("mod1/dir2");
-
-    // file in dir in module in root
-    assertThat(reader.readComponent(mod1_dir2_file.scannerId()).getPath()).isEqualTo("dir2/Foo.java");
-    assertThat(reader.readComponent(mod1_dir2_file.scannerId()).getProjectRelativePath()).isEqualTo("mod1/dir2/Foo.java");
-
-    // module in module
-    assertThat(reader.readComponent(mod1_mod2.scannerId()).getPath()).isEqualTo("mod2");
-    assertThat(reader.readComponent(mod1_mod2.scannerId()).getProjectRelativePath()).isEqualTo("mod1/mod2");
-
-    // file in module in module
-    assertThat(reader.readComponent(mod1_mod2_file.scannerId()).getPath()).isEqualTo("Foo.java");
-    assertThat(reader.readComponent(mod1_mod2_file.scannerId()).getProjectRelativePath()).isEqualTo("mod1/mod2/Foo.java");
-
-    // dir in module in module
-    assertThat(reader.readComponent(mod1_mod2_dir.scannerId()).getPath()).isEqualTo("dir");
-    assertThat(reader.readComponent(mod1_mod2_dir.scannerId()).getProjectRelativePath()).isEqualTo("mod1/mod2/dir");
-
-    // file in dir in module in module
-    assertThat(reader.readComponent(mod1_mod2_dir_file.scannerId()).getPath()).isEqualTo("dir/Foo.java");
-    assertThat(reader.readComponent(mod1_mod2_dir_file.scannerId()).getProjectRelativePath()).isEqualTo("mod1/mod2/dir/Foo.java");
+    assertThat(rootProtobuf.getLink(1).getType()).isEqualTo(ComponentLinkType.CI);
+    assertThat(rootProtobuf.getLink(1).getHref()).isEqualTo("http://ci");
   }
 }
index d2cc7ac178d66fcfd7c7a6e4200f0af5c225f2d7..93663f7f57bd5044ec9a99292eb41d8038c31630 100644 (file)
@@ -59,7 +59,7 @@ public class CoveragePublisherTest {
     inputFile = new TestInputFileBuilder(moduleKey, "src/Foo.php").setLines(5).build();
     DefaultInputProject rootModule = TestInputFileBuilder.newDefaultInputProject(moduleKey, temp.newFolder());
     InputComponentStore componentCache = new InputComponentStore(rootModule, mock(BranchConfiguration.class));
-    componentCache.put(inputFile);
+    componentCache.put(moduleKey, inputFile);
 
     measureCache = mock(MeasureCache.class);
     when(measureCache.byMetric(anyString(), anyString())).thenReturn(null);
index 08cb3b61e3c0b877ba81bf063a03bd256fe35e8a..7583eac09714cff61bcdc5f7aeac705891bf43dd 100644 (file)
@@ -70,7 +70,7 @@ public class MeasuresPublisherTest {
     project = TestInputFileBuilder.newDefaultInputProject(projectKey, temp.newFolder());
     inputFile = new TestInputFileBuilder(projectKey, "src/Foo.php").setPublish(true).build();
     InputComponentStore componentCache = new InputComponentStore(project, mock(BranchConfiguration.class));
-    componentCache.put(inputFile);
+    componentCache.put(projectKey, inputFile);
     measureCache = mock(MeasureCache.class);
     when(measureCache.byComponentKey(anyString())).thenReturn(Collections.<DefaultMeasure<?>>emptyList());
     publisher = new MeasuresPublisher(componentCache, measureCache, mock(TestPlanBuilder.class));
index f6840f3b1754b25b3f224191439ee8e7a3ab1b55..da37398e387df4d51ce6b28763c0913fb52f0ddd 100644 (file)
@@ -59,7 +59,7 @@ public class SourcePublisherTest {
 
     DefaultInputProject rootProject = TestInputFileBuilder.newDefaultInputProject(moduleKey, baseDir);
     InputComponentStore componentStore = new InputComponentStore(rootProject, mock(BranchConfiguration.class));
-    componentStore.put(inputFile);
+    componentStore.put(moduleKey, inputFile);
 
     publisher = new SourcePublisher(componentStore);
     File outputDir = temp.newFolder();
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultComponentTreeTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultComponentTreeTest.java
deleted file mode 100644 (file)
index 930f5ee..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.scanner.scan;
-
-import java.io.IOException;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.batch.fs.internal.DefaultInputProject;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class DefaultComponentTreeTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  private DefaultComponentTree tree;
-
-  @Before
-  public void setUp() {
-    tree = new DefaultComponentTree();
-  }
-
-  @Test
-  public void test() throws IOException {
-    DefaultInputProject root = new DefaultInputProject(ProjectDefinition.create().setKey("root").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-    DefaultInputModule mod1 = new DefaultInputModule(ProjectDefinition.create().setKey("mod1").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-    DefaultInputModule mod2 = new DefaultInputModule(ProjectDefinition.create().setKey("mod2").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-    DefaultInputModule mod3 = new DefaultInputModule(ProjectDefinition.create().setKey("mod3").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-    DefaultInputModule mod4 = new DefaultInputModule(ProjectDefinition.create().setKey("mod4").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-
-    tree.index(mod1, root);
-    tree.index(mod2, mod1);
-    tree.index(mod3, root);
-    tree.index(mod4, root);
-
-    assertThat(tree.getChildren(root)).containsOnly(mod1, mod3, mod4);
-    assertThat(tree.getChildren(mod4)).isEmpty();
-    assertThat(tree.getChildren(mod1)).containsOnly(mod2);
-
-    assertThat(tree.getParent(mod4)).isEqualTo(root);
-    assertThat(tree.getParent(mod2)).isEqualTo(mod1);
-    assertThat(tree.getParent(mod1)).isEqualTo(root);
-    assertThat(tree.getParent(root)).isNull();
-  }
-}
index 2f54bfea404ec64aa6e4c14705637446f694bb41..2c2b51fd0ca08121d3e1b6d78afec190585be5fa 100644 (file)
@@ -33,15 +33,13 @@ import static org.mockito.Mockito.when;
 
 public class ModuleIndexerTest {
   private ModuleIndexer indexer;
-  private DefaultComponentTree tree;
   private DefaultInputModuleHierarchy moduleHierarchy;
   private InputComponentStore componentStore;
 
   public void createIndexer(DefaultInputProject rootProject) {
     componentStore = new InputComponentStore(rootProject, mock(BranchConfiguration.class));
-    tree = new DefaultComponentTree();
     moduleHierarchy = mock(DefaultInputModuleHierarchy.class);
-    indexer = new ModuleIndexer(tree, componentStore, moduleHierarchy);
+    indexer = new ModuleIndexer(componentStore, moduleHierarchy);
   }
 
   @Test
@@ -80,6 +78,5 @@ public class ModuleIndexerTest {
     DefaultInputModule rootModule = moduleHierarchy.root();
     assertThat(rootModule).isNotNull();
     assertThat(moduleHierarchy.children(rootModule)).hasSize(3);
-    assertThat(tree.getChildren(rootModule)).hasSize(3);
   }
 }
index 5170bf0745ebfe6c7e72d63be386c649de41de4b..a9d30ff3bedad13f011e70b1156493d45b3beea8 100644 (file)
@@ -60,15 +60,15 @@ public class InputComponentStoreTest {
     DefaultInputProject rootProject = TestInputFileBuilder.newDefaultInputProject(rootDef);
     DefaultInputModule subModule = TestInputFileBuilder.newDefaultInputModule(moduleDef);
 
-    InputComponentStore cache = new InputComponentStore(rootProject, mock(BranchConfiguration.class));
-    cache.put(subModule);
+    InputComponentStore store = new InputComponentStore(rootProject, mock(BranchConfiguration.class));
+    store.put(subModule);
 
     DefaultInputFile fooFile = new TestInputFileBuilder(rootModuleKey, "src/main/java/Foo.java")
       .setModuleBaseDir(rootBaseDir.toPath())
       .setPublish(true)
       .build();
-    cache.put(fooFile);
-    cache.put(new TestInputFileBuilder(subModuleKey, "src/main/java/Bar.java")
+    store.put(rootProject.key(), fooFile);
+    store.put(subModuleKey, new TestInputFileBuilder(rootModuleKey, "src/main/java/Bar.java")
       .setLanguage("bla")
       .setPublish(false)
       .setType(Type.MAIN)
@@ -78,28 +78,20 @@ public class InputComponentStoreTest {
       .setModuleBaseDir(temp.newFolder().toPath())
       .build());
 
-    DefaultInputFile loadedFile = (DefaultInputFile) cache.getFile(subModuleKey, "src/main/java/Bar.java");
+    DefaultInputFile loadedFile = (DefaultInputFile) store.getFile(subModuleKey, "src/main/java/Bar.java");
     assertThat(loadedFile.relativePath()).isEqualTo("src/main/java/Bar.java");
     assertThat(loadedFile.charset()).isEqualTo(StandardCharsets.UTF_8);
 
-    assertThat(cache.filesByModule(rootModuleKey)).hasSize(1);
-    assertThat(cache.filesByModule(subModuleKey)).hasSize(1);
-    assertThat(cache.allFiles()).hasSize(2);
-    for (InputPath inputPath : cache.allFiles()) {
+    assertThat(store.filesByModule(rootModuleKey)).hasSize(1);
+    assertThat(store.filesByModule(subModuleKey)).hasSize(1);
+    assertThat(store.allFiles()).hasSize(2);
+    for (InputPath inputPath : store.allFiles()) {
       assertThat(inputPath.relativePath()).startsWith("src/main/java/");
     }
 
     List<InputFile> toPublish = new LinkedList<>();
-    cache.allFilesToPublish().forEach(toPublish::add);
+    store.allFilesToPublish().forEach(toPublish::add);
     assertThat(toPublish).containsExactly(fooFile);
-
-    cache.remove(fooFile);
-    assertThat(cache.allFiles()).hasSize(1);
-
-    cache.removeModule(rootModuleKey);
-    assertThat(cache.filesByModule(rootModuleKey)).hasSize(0);
-    assertThat(cache.filesByModule(subModuleKey)).hasSize(1);
-    assertThat(cache.allFiles()).hasSize(1);
   }
 
   static class InputComponentStoreTester extends InputComponentStore {
@@ -111,7 +103,7 @@ public class InputComponentStoreTest {
       DefaultInputFile file = new TestInputFileBuilder(moduleKey, relpath)
         .setLanguage(language)
         .build();
-      put(file);
+      put(moduleKey, file);
       return file;
     }
   }
index 32ba8fbc390c34951c9d0057a5013aefd43192d8..840cd7d92572a6192d0027c7fcf7c59ed39c6975 100644 (file)
@@ -53,21 +53,17 @@ public class InputFileBuilderTest {
   public void setUp() throws IOException {
     baseDir = temp.newFolder().toPath();
     workDir = temp.newFolder().toPath();
-    DefaultInputModule root = new DefaultInputModule(ProjectDefinition.create()
+    DefaultInputProject project = new DefaultInputProject(ProjectDefinition.create()
       .setBaseDir(baseDir.toFile())
       .setWorkDir(workDir.toFile())
+      .setProperty(CoreProperties.ENCODING_PROPERTY, StandardCharsets.UTF_8.name())
       .setKey("root"), 0);
     Path moduleBaseDir = baseDir.resolve("module1");
     Files.createDirectories(moduleBaseDir);
-    DefaultInputProject project = new DefaultInputProject(ProjectDefinition.create()
-      .setBaseDir(baseDir.toFile())
-      .setWorkDir(workDir.toFile())
-      .setProperty(CoreProperties.ENCODING_PROPERTY, StandardCharsets.UTF_8.name())
-      .setKey("module1"), 0);
     DefaultInputModule module = new DefaultInputModule(ProjectDefinition.create()
       .setBaseDir(moduleBaseDir.toFile())
       .setWorkDir(workDir.toFile())
-      .setKey("module1"), 0);
+      .setKey("module1"), 1);
 
     MetadataGenerator metadataGenerator = mock(MetadataGenerator.class);
     ScannerComponentIdGenerator idGenerator = new ScannerComponentIdGenerator();
@@ -82,11 +78,10 @@ public class InputFileBuilderTest {
     Path filePath = baseDir.resolve("module1/src/File1.xoo");
     DefaultInputFile inputFile = builder.create(Type.MAIN, filePath, null);
 
-    assertThat(inputFile.moduleKey()).isEqualTo("module1");
     assertThat(inputFile.absolutePath()).isEqualTo(filePath.toString().replaceAll("\\\\", "/"));
     assertThat(inputFile.relativePath()).isEqualTo("src/File1.xoo");
     assertThat(inputFile.path()).isEqualTo(filePath);
-    assertThat(inputFile.key()).isEqualTo("module1:src/File1.xoo");
+    assertThat(inputFile.key()).isEqualTo("root:module1/src/File1.xoo");
     assertThat(inputFile.isPublished()).isFalse();
 
     sensorStrategy.setGlobal(true);
index dcd265010d154717b3408ffddcf6ea3416f022d4..523d875470d1f7571ac7a6c8cfcedf1f7699f583 100644 (file)
@@ -114,7 +114,9 @@ public class ModuleInputComponentStoreTest {
   }
 
   private ModuleInputComponentStore newModuleInputComponentStore() {
-    return new ModuleInputComponentStore(mock(InputModule.class), componentStore, mock(SensorStrategy.class));
+    InputModule module = mock(InputModule.class);
+    when(module.key()).thenReturn("moduleKey");
+    return new ModuleInputComponentStore(module, componentStore, mock(SensorStrategy.class));
   }
 
   @Test
@@ -132,9 +134,6 @@ public class ModuleInputComponentStoreTest {
     store.inputFile(relativePath);
     verify(inputComponentStore).getFile(any(String.class), eq(relativePath));
 
-    store.inputDir(relativePath);
-    verify(inputComponentStore).getDir(any(String.class), eq(relativePath));
-
     store.languages();
     verify(inputComponentStore).getLanguages(any(String.class));
   }
@@ -154,9 +153,6 @@ public class ModuleInputComponentStoreTest {
     store.inputFile(relativePath);
     verify(inputComponentStore).getFile(relativePath);
 
-    store.inputDir(relativePath);
-    verify(inputComponentStore).getDir(relativePath);
-
     store.languages();
     verify(inputComponentStore).getLanguages();
   }
index d813051b3391af50a7163732ae4aca2cb98dbf9b..36f422d95bf730a1344a85db2de891d0d4c9fad7 100644 (file)
@@ -23,7 +23,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.text.SimpleDateFormat;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.TimeZone;
 import org.apache.commons.io.IOUtils;
@@ -34,9 +33,7 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.fs.internal.DefaultInputProject;
 import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
 import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
@@ -48,7 +45,6 @@ import org.sonar.api.platform.Server;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.scanner.issue.IssueCache;
 import org.sonar.scanner.issue.tracking.TrackedIssue;
-import org.sonar.scanner.scan.DefaultComponentTree;
 import org.sonar.scanner.scan.branch.BranchConfiguration;
 import org.sonar.scanner.scan.filesystem.InputComponentStore;
 
@@ -81,39 +77,20 @@ public class JSONReportTest {
     SIMPLE_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
     when(server.getVersion()).thenReturn("3.6");
 
-    DefaultComponentTree inputComponentTree = new DefaultComponentTree();
     ProjectDefinition def = ProjectDefinition.create().setBaseDir(projectBaseDir).setWorkDir(temp.newFolder()).setKey("struts");
     DefaultInputProject project = new DefaultInputProject(def, 1);
-    DefaultInputModule rootModule = new DefaultInputModule(def, 1);
     InputComponentStore inputComponentStore = new InputComponentStore(project, mock(BranchConfiguration.class));
 
-    DefaultInputModule moduleA = new DefaultInputModule(ProjectDefinition.create().setKey("struts-core").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-    inputComponentTree.index(moduleA, rootModule);
-    DefaultInputModule moduleB = new DefaultInputModule(ProjectDefinition.create().setKey("struts-ui").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()));
-    inputComponentTree.index(moduleB, rootModule);
-
-    DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts", TestInputFileBuilder.nextBatchId())
-      .setModuleBaseDir(projectBaseDir.toPath());
     DefaultInputFile inputFile = new TestInputFileBuilder("struts", "src/main/java/org/apache/struts/Action.java")
       .setModuleBaseDir(projectBaseDir.toPath()).build();
     inputFile.setStatus(InputFile.Status.CHANGED);
     inputFile.setPublished(true);
-    inputComponentStore.put(inputFile);
-    inputComponentStore.put(inputDir);
-
-    inputComponentTree.index(inputDir, rootModule);
-    inputComponentTree.index(inputFile, inputDir);
-
-    when(moduleHierarchy.children(rootModule)).thenReturn(Arrays.asList(moduleA, moduleB));
-    when(moduleHierarchy.parent(moduleA)).thenReturn(rootModule);
-    when(moduleHierarchy.parent(moduleB)).thenReturn(rootModule);
-    when(moduleHierarchy.relativePath(moduleA)).thenReturn("core");
-    when(moduleHierarchy.relativePath(moduleB)).thenReturn("ui");
+    inputComponentStore.put("struts", inputFile);
 
     RulesBuilder builder = new RulesBuilder();
     builder.add(RuleKey.of("squid", "AvoidCycles")).setName("Avoid Cycles");
     rules = builder.build();
-    jsonReport = new JSONReport(moduleHierarchy, settings.asConfig(), fs, server, rules, issueCache, rootModule, inputComponentStore, inputComponentTree);
+    jsonReport = new JSONReport(settings.asConfig(), fs, server, rules, issueCache, project, inputComponentStore);
   }
 
   @Test
index b5af45efe6c0be9bf12d78183681ea27d2811ca3..8238d2eae85fd475bfbbc6faddee77de8bedee6f 100644 (file)
@@ -3,24 +3,10 @@
   "issues": [],
   "components": [
     {"key": "struts"},
-    {
-      "key": "struts-core",
-      "path": "core"
-    },
-    {
-      "key": "struts-ui",
-      "path": "ui"
-    },
     {
       "key": "struts:src/main/java/org/apache/struts/Action.java",
       "path": "src/main/java/org/apache/struts/Action.java",
-      "moduleKey": "struts",
       "status": "CHANGED"
-    },
-    {
-      "key": "struts:src/main/java/org/apache/struts",
-      "path": "src/main/java/org/apache/struts",
-      "moduleKey": "struts"
     }
   ],
   "rules": [],
index a78fbca71e580f5c6daefdce069479a6341ad63a..f80eadc890cb8e955f59d683ede68047c8796a22 100644 (file)
     {
       "key": "struts"
     },
-    {
-      "key": "struts-core",
-      "path": "core"
-    },
-    {
-      "key": "struts-ui",
-      "path": "ui"
-    },
     {
       "key": "struts:src/main/java/org/apache/struts/Action.java",
       "path": "src/main/java/org/apache/struts/Action.java",
-      "moduleKey": "struts",
       "status": "CHANGED"
-    },
-    {
-      "key": "struts:src/main/java/org/apache/struts",
-      "path": "src/main/java/org/apache/struts",
-      "moduleKey": "struts"
     }
   ],
   "rules": [
index 7642e1dce0bb68c25bb43472c61e7e07b1387baf..f81097b5a92dc356355623cf5eb3b9e78d9ea9de 100644 (file)
@@ -102,7 +102,7 @@ message Component {
   int32 ref = 1;
 
   // Path relative to module base directory
-  string path = 2;
+  string path = 2 [deprecated=true];
   string name = 3;
   ComponentType type = 4;
   bool is_test = 5;
@@ -126,8 +126,8 @@ message Component {
   enum ComponentType {
     UNSET = 0;
     PROJECT = 1;
-    MODULE = 2;
-    DIRECTORY = 3;
+    MODULE = 2 [deprecated=true];
+    DIRECTORY = 3 [deprecated=true];
     FILE = 4;
   }