From b6f878d8d48c55c03bcbf2ba8010526f1fa12f49 Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Fri, 16 Nov 2018 15:19:14 +0100 Subject: [PATCH] SONAR-11459 Stop publishing modules and folders in the scanner report --- .../server/config/ConfigurationProvider.java | 2 +- .../sonar/core/component/ComponentKeys.java | 6 +- .../core/component/ComponentKeysTest.java | 14 +- .../org/sonar/api/batch/fs/FileSystem.java | 3 - .../batch/fs/internal/DefaultFileSystem.java | 25 +- .../batch/fs/internal/DefaultIndexedFile.java | 16 +- .../fs/internal/DefaultInputComponent.java | 4 +- .../batch/fs/internal/DefaultInputDir.java | 6 +- .../batch/fs/internal/DefaultInputFile.java | 4 - .../batch/fs/internal/InputComponentTree.java | 30 - .../fs/internal/TestInputFileBuilder.java | 33 +- .../batch/fs/internal/PathPatternTest.java | 24 +- .../issue/tracking/LocalIssueTracking.java | 18 +- .../issue/tracking/SourceHashHolder.java | 21 +- .../scanner/mediumtest/AnalysisResult.java | 95 ++- .../scanner/report/ComponentsPublisher.java | 241 ++------ .../scanner/scan/DefaultComponentTree.java | 54 -- .../org/sonar/scanner/scan/ModuleIndexer.java | 5 +- .../scanner/scan/ProjectScanContainer.java | 1 - .../scanner/scan/filesystem/FileIndexer.java | 32 +- .../scan/filesystem/InputComponentStore.java | 79 +-- .../scan/filesystem/InputFileBuilder.java | 4 +- .../filesystem/ModuleInputComponentStore.java | 17 +- .../sonar/scanner/scan/report/JSONReport.java | 63 +- .../sonar/scanner/cpd/CpdExecutorTest.java | 2 +- .../issue/tracking/SourceHashHolderTest.java | 19 +- .../mediumtest/branch/BranchMediumTest.java | 4 +- .../branch/DeprecatedBranchMediumTest.java | 11 +- .../coverage/CoverageMediumTest.java | 6 +- .../scanner/mediumtest/cpd/CpdMediumTest.java | 8 +- .../mediumtest/fs/FileSystemMediumTest.java | 72 +-- .../issues/IssuesOnDirMediumTest.java | 2 - .../issues/IssuesOnModuleMediumTest.java | 2 +- .../IssueModeAndReportsMediumTest.java | 2 +- .../scanner/mediumtest/scm/ScmMediumTest.java | 5 +- .../postjob/DefaultPostJobContextTest.java | 2 +- .../report/ComponentsPublisherTest.java | 554 ++---------------- .../scanner/report/CoveragePublisherTest.java | 2 +- .../scanner/report/MeasuresPublisherTest.java | 2 +- .../scanner/report/SourcePublisherTest.java | 2 +- .../scan/DefaultComponentTreeTest.java | 67 --- .../sonar/scanner/scan/ModuleIndexerTest.java | 5 +- .../filesystem/InputComponentStoreTest.java | 30 +- .../scan/filesystem/InputFileBuilderTest.java | 13 +- .../ModuleInputComponentStoreTest.java | 10 +- .../scanner/scan/report/JSONReportTest.java | 27 +- .../report-without-resolved-issues.json | 14 - .../scan/report/JSONReportTest/report.json | 14 - .../src/main/protobuf/scanner_report.proto | 6 +- 49 files changed, 289 insertions(+), 1389 deletions(-) delete mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputComponentTree.java delete mode 100644 sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java delete mode 100644 sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultComponentTreeTest.java diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/config/ConfigurationProvider.java b/server/sonar-server-common/src/main/java/org/sonar/server/config/ConfigurationProvider.java index 237b4443460..bd3ff03f8f8 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/config/ConfigurationProvider.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/config/ConfigurationProvider.java @@ -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 { diff --git a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java index 0b2285aaaae..440f7339f1f 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java +++ b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java @@ -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) { diff --git a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java index 954c016b010..f2104fbcab4 100644 --- a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java +++ b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java @@ -19,14 +19,14 @@ */ 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"); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java index 705934458b4..433c87c57bb 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java @@ -165,9 +165,6 @@ public interface FileSystem { @CheckForNull InputFile inputFile(String relativePath); - @CheckForNull - InputDir inputDir(String relativePath); - /** * @since 6.3 */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java index 096d0eb5d03..ee90497714d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java @@ -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 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 languages(); } @@ -217,7 +207,6 @@ public class DefaultFileSystem implements FileSystem { */ private static class MapCache extends Cache { private final Map fileMap = new HashMap<>(); - private final Map dirMap = new HashMap<>(); private final SetMultimap filesByNameCache = LinkedHashMultimap.create(); private final SetMultimap filesByExtensionCache = LinkedHashMultimap.create(); private SortedSet 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 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 languages() { return languages; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java index 5b3bdf7a671..1488121129c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java @@ -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 diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java index 7138f95adcc..9908523fc9a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java @@ -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 diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java index 32b8ad6cb23..14a39ee1b32 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java @@ -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); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java index efa7804d512..01316b2ad30 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java @@ -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 index ddb76b83624..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/InputComponentTree.java +++ /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 getChildren(InputComponent module); - - InputComponent getParent(InputComponent module); -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java index d84961b76c5..00f9319c2d4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java @@ -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 module key and a relative path, so these parameters are mandatory. - * + *

* A module base directory is only needed to construct absolute paths. - * + *

* Examples of usage of the constructors: - * + * *

  * InputFile file1 = TestInputFileBuilder.create("module1", "myfile.java").build();
  * InputFile file2 = TestInputFileBuilder.create("", fs.baseDir(), myfile).build();
  * 
- * + *

* 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); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java index aa6ed4c7d97..cc2d186da44 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java @@ -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(); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java index bf026425205..7e496fd478b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java @@ -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 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 tracker, ServerLineHashesLoader lastLineHashes, InputComponentTree componentTree, - ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) { + public LocalIssueTracking(DefaultInputProject project, Tracker 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; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java index b1b56be89a8..48721f3cbdd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java @@ -19,25 +19,23 @@ */ 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 getNewLinesMatching(Integer originLine) { - FileHashes reference = getHashedReference(); - if (reference == null) { - return Collections.emptySet(); - } else { - return getHashedSource().getLinesForHash(reference.getHash(originLine)); - } - } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java index 4c2cff60a32..db4f0787172 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java @@ -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 issues = new ArrayList<>(); - private Map inputFiles = new HashMap<>(); - private Map reportComponents = new HashMap<>(); - private Map inputDirs = new HashMap<>(); + private Map 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 issuesFor(InputComponent inputComponent) { - int ref = reportComponents.get(inputComponent.key()).getRef(); - return issuesFor(ref); + return issuesFor(((DefaultInputComponent) inputComponent).scannerId()); } - + public List externalIssuesFor(InputComponent inputComponent) { - int ref = reportComponents.get(inputComponent.key()).getRef(); - return externalIssuesFor(ref); + return externalIssuesFor(((DefaultInputComponent) inputComponent).scannerId()); } public List issuesFor(Component reportComponent) { @@ -146,7 +121,7 @@ public class AnalysisResult implements AnalysisObserver { } return result; } - + private List externalIssuesFor(int ref) { List result = Lists.newArrayList(); try (CloseableIterator it = reader.readComponentExternalIssues(ref)) { @@ -162,41 +137,38 @@ public class AnalysisResult implements AnalysisObserver { } public Collection inputFiles() { - return inputFiles.values(); + return inputFilesByKeys.values(); } @CheckForNull public InputFile inputFile(String relativePath) { - return inputFiles.get(relativePath); - } - - public Collection inputDirs() { - return inputDirs.values(); - } - - @CheckForNull - public InputDir inputDir(String relativePath) { - return inputDirs.get(relativePath); + return inputFilesByKeys.get(relativePath); } public Map> allMeasures() { Map> result = new HashMap<>(); - for (Map.Entry component : reportComponents.entrySet()) { + List projectMeasures = new ArrayList<>(); + try (CloseableIterator it = reader.readComponentMeasures(((DefaultInputComponent) project).scannerId())) { + Iterators.addAll(projectMeasures, it); + } + result.put(project.key(), projectMeasures); + for (InputFile inputFile : inputFilesByKeys.values()) { List measures = new ArrayList<>(); - try (CloseableIterator it = reader.readComponentMeasures(component.getValue().getRef())) { + try (CloseableIterator 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 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 symbolReferencesFor(InputFile file, int symbolStartLine, int symbolStartLineOffset) { - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); try (CloseableIterator symbols = getReportReader().readComponentSymbols(ref)) { while (symbols.hasNext()) { Symbol symbol = symbols.next(); @@ -241,7 +214,7 @@ public class AnalysisResult implements AnalysisObserver { public List duplicationsFor(InputFile file) { List result = new ArrayList<>(); - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); try (CloseableIterator it = getReportReader().readComponentDuplications(ref)) { while (it.hasNext()) { result.add(it.next()); @@ -254,7 +227,7 @@ public class AnalysisResult implements AnalysisObserver { public List duplicationBlocksFor(InputFile file) { List result = new ArrayList<>(); - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); try (CloseableIterator 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 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) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java index 7902bcde706..a9d042489b9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java @@ -19,129 +19,93 @@ */ 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 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 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 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 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 index 7da8990ded6..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java +++ /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 parents = new HashMap<>(); - private Map> 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 getChildren(InputComponent component) { - return children.getOrDefault(component, Collections.emptySet()); - } - - @CheckForNull - @Override - public InputComponent getParent(InputComponent component) { - return parents.get(component); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java index 60baccdfa5a..4b85e732f66 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java @@ -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); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java index eb33fe12f42..7e595179de1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java @@ -160,7 +160,6 @@ public class ProjectScanContainer extends ComponentContainer { PathResolver.class, new InputProjectProvider(), new InputModuleHierarchyProvider(), - DefaultComponentTree.class, ScannerComponentIdGenerator.class, new ScmChangedFilesProvider(), StatusDetection.class, diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java index 5294797c67c..20a1d803688 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java @@ -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) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java index 15eb4f6b0a0..8d1071b172c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java @@ -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 globalLanguagesCache = new TreeSet<>(); private final Map> languagesCache = new HashMap<>(); private final Map globalInputFileCache = new HashMap<>(); - private final Table inputFileCache = TreeBasedTable.create(); - private final Map globalInputDirCache = new HashMap<>(); - private final Table inputDirCache = TreeBasedTable.create(); + private final Table inputFileByModuleCache = TreeBasedTable.create(); // indexed by key with branch private final Map inputModuleCache = new HashMap<>(); private final Map inputComponents = new HashMap<>(); @@ -74,7 +68,7 @@ public class InputComponentStore { } private Stream 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 allFiles() { - return inputFileCache.values(); - } - - public Iterable allDirs() { - return inputDirCache.values(); + return globalInputFileCache.values(); } public InputComponent getByKey(String key) { @@ -102,35 +92,13 @@ public class InputComponentStore { } public Iterable filesByModule(String moduleKey) { - return inputFileCache.row(moduleKey).values(); - } - - public Iterable 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); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java index 4de7d1bf07e..438a0edd44b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java @@ -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); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java index 8d694756fb9..6bb17759043 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java @@ -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 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 diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java index b302742bf7b..d965bb3e908 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java @@ -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 ruleKeys) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java index 611e42c7793..6588f2e3c0a 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java @@ -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; } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java index 6aa8686690f..590d4119282 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/tracking/SourceHashHolderTest.java @@ -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)}); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java index 21d88ed6f5d..62899cf17f1 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java @@ -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(); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java index bcc46d488d4..41ea161bc72 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java @@ -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"); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java index f230f2b8bf8..1417262c3f9 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java @@ -330,14 +330,14 @@ public class CoverageMediumTest { Map> 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); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/cpd/CpdMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/cpd/CpdMediumTest.java index 6ce98f526ac..e31dfbb1b4e 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/cpd/CpdMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/cpd/CpdMediumTest.java @@ -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 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 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(); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java index a8e84a6faf2..705692a6777 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java @@ -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.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 diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumTest.java index ed76bba6c25..e09f0b42967 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnDirMediumTest.java @@ -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); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumTest.java index 48561c72e0a..5c8fa0d92e1 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issues/IssuesOnModuleMediumTest.java @@ -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); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java index cb29125779c..2e58d577288 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java @@ -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() { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java index 5b42f3e016c..94f6030b3e6 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java @@ -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()); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java index 245fe2cefc1..3d45aa214d8 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java @@ -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(); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java index 4b27f676ae9..e13bc24a9d0 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java @@ -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 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 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"); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java index d2cc7ac178d..93663f7f57b 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java @@ -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); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java index 08cb3b61e3c..7583eac0971 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java @@ -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.>emptyList()); publisher = new MeasuresPublisher(componentCache, measureCache, mock(TestPlanBuilder.class)); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java index f6840f3b175..da37398e387 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java @@ -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 index 930f5ee8086..00000000000 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/DefaultComponentTreeTest.java +++ /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(); - } -} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java index 2f54bfea404..2c2b51fd0ca 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java @@ -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); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java index 5170bf0745e..a9d30ff3bed 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java @@ -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 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; } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java index 32ba8fbc390..840cd7d9257 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java @@ -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); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java index dcd265010d1..523d875470d 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java @@ -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(); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java index d813051b339..36f422d95bf 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java @@ -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 diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report-without-resolved-issues.json b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report-without-resolved-issues.json index b5af45efe6c..8238d2eae85 100644 --- a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report-without-resolved-issues.json +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report-without-resolved-issues.json @@ -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": [], diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report.json b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report.json index a78fbca71e5..f80eadc890c 100644 --- a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report.json +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/scan/report/JSONReportTest/report.json @@ -23,24 +23,10 @@ { "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": [ diff --git a/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto b/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto index 7642e1dce0b..f81097b5a92 100644 --- a/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto +++ b/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto @@ -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; } -- 2.39.5