diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2017-07-21 17:51:29 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2017-08-07 11:44:06 +0200 |
commit | 460f96aa6333c848b3b733d538b27459fee3999a (patch) | |
tree | a9eed04e9681e57e6b00575db3b1e8b54b2b65ae /sonar-scanner-engine | |
parent | c69324daaf2b08efa2fdc68d01c2fff105b34cdf (diff) | |
download | sonarqube-460f96aa6333c848b3b733d538b27459fee3999a.tar.gz sonarqube-460f96aa6333c848b3b733d538b27459fee3999a.zip |
SONAR-9576 Add component status in the scanner report
Diffstat (limited to 'sonar-scanner-engine')
6 files changed, 106 insertions, 25 deletions
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 be8847063f3..f28f73c7a43 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 @@ -28,6 +28,7 @@ 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; @@ -37,6 +38,7 @@ import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.core.util.CloseableIterator; 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; @@ -107,6 +109,7 @@ public class ComponentsPublisher implements ReportPublisherStep { DefaultInputFile file = (DefaultInputFile) component; builder.setIsTest(file.type() == InputFile.Type.TEST); builder.setLines(file.lines()); + builder.setStatus(convert(file.status())); String lang = getLanguageKey(file); if (lang != null) { @@ -127,6 +130,19 @@ public class ComponentsPublisher implements ReportPublisherStep { return true; } + private FileStatus convert(Status status) { + switch (status) { + case ADDED: + return FileStatus.ADDED; + case CHANGED: + return FileStatus.CHANGED; + case SAME: + return FileStatus.SAME; + default: + throw new IllegalArgumentException("Unexpected status: " + status); + } + } + private boolean shouldSkipComponent(DefaultInputComponent component, Collection<InputComponent> children) { if (component instanceof InputDir && children.isEmpty()) { try (CloseableIterator<Issue> componentIssuesIt = reader.readComponentIssues(component.batchId())) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java index c2eed43a108..46c019850a5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java @@ -45,7 +45,7 @@ public class DefaultModuleFileSystem extends DefaultFileSystem { // filter the files sensors have access to if (!mode.scanAllFiles()) { - setDefaultPredicate(new SameInputFilePredicate(projectRepositories, module.definition().getKeyWithBranch())); + setDefaultPredicate(p -> new SameInputFilePredicate(p, projectRepositories, module.definition().getKeyWithBranch())); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java index 629a25161aa..5e75d5213e0 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java @@ -21,25 +21,31 @@ package org.sonar.scanner.scan.filesystem; import java.util.function.Predicate; import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.OperatorPredicate; +import org.sonar.api.batch.fs.internal.StatusPredicate; import org.sonar.scanner.repository.FileData; import org.sonar.scanner.repository.ProjectRepositories; public class SameInputFilePredicate implements Predicate<InputFile> { - private static final Logger LOG = LoggerFactory.getLogger(SameInputFilePredicate.class); private final ProjectRepositories projectRepositories; private final String moduleKeyWithBranch; + private final FilePredicate currentPredicate; - public SameInputFilePredicate(ProjectRepositories projectRepositories, String moduleKeyWithBranch) { + public SameInputFilePredicate(FilePredicate currentPredicate, ProjectRepositories projectRepositories, String moduleKeyWithBranch) { + this.currentPredicate = currentPredicate; this.projectRepositories = projectRepositories; this.moduleKeyWithBranch = moduleKeyWithBranch; } @Override public boolean test(InputFile inputFile) { + if (hasExplicitFilterOnStatus(currentPredicate)) { + // If user explicitely requested a given status, don't change the result + return true; + } + // Try to avoid initializing metadata FileData fileDataPerPath = projectRepositories.fileData(moduleKeyWithBranch, inputFile.relativePath()); if (fileDataPerPath == null) { // ADDED @@ -52,15 +58,17 @@ public class SameInputFilePredicate implements Predicate<InputFile> { } // this will trigger computation of metadata - String hash = ((DefaultInputFile) inputFile).hash(); - if (StringUtils.equals(hash, previousHash)) { - // SAME - LOG.debug("'{}' filtering unmodified file", inputFile.relativePath()); - return false; - } + return inputFile.status() != InputFile.Status.SAME; + } - // CHANGED - return true; + static boolean hasExplicitFilterOnStatus(FilePredicate predicate) { + if (predicate instanceof StatusPredicate) { + return true; + } + if (predicate instanceof OperatorPredicate) { + return ((OperatorPredicate) predicate).operands().stream().anyMatch(SameInputFilePredicate::hasExplicitFilterOnStatus); + } + return false; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java index ac11c11d3b8..79f3576e67b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java @@ -29,14 +29,14 @@ import org.sonar.scanner.repository.ProjectRepositories; @Immutable class StatusDetection { - private final ProjectRepositories projectSettings; + private final ProjectRepositories projectRepositories; StatusDetection(ProjectRepositories projectSettings) { - this.projectSettings = projectSettings; + this.projectRepositories = projectSettings; } InputFile.Status status(String projectKeyWithBranch, String relativePath, String hash) { - FileData fileDataPerPath = projectSettings.fileData(projectKeyWithBranch, relativePath); + FileData fileDataPerPath = projectRepositories.fileData(projectKeyWithBranch, relativePath); if (fileDataPerPath == null) { return InputFile.Status.ADDED; } 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 9170a07fbac..20966ceef77 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 @@ -28,6 +28,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; 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; @@ -39,6 +40,7 @@ import org.sonar.scanner.ProjectAnalysisInfo; import org.sonar.scanner.protocol.output.FileStructure; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Component; +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; @@ -100,16 +102,16 @@ public class ComponentsPublisherTest { DefaultInputDir dir = new DefaultInputDir("module1", "src", 3); tree.index(dir, module1); - DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).build(); + DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).setStatus(InputFile.Status.SAME).build(); tree.index(file, dir); DefaultInputFile file2 = new TestInputFileBuilder("module1", "src/Foo2.java", 5).setPublish(false).setLines(2).build(); tree.index(file2, dir); - DefaultInputFile fileWithoutLang = new TestInputFileBuilder("module1", "src/make", 6).setLines(10).build(); + DefaultInputFile fileWithoutLang = new TestInputFileBuilder("module1", "src/make", 6).setLines(10).setStatus(InputFile.Status.CHANGED).build(); tree.index(fileWithoutLang, dir); - DefaultInputFile testFile = new TestInputFileBuilder("module1", "test/FooTest.java", 7).setType(Type.TEST).setLines(4).build(); + 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); @@ -138,6 +140,10 @@ public class ComponentsPublisherTest { 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); } @Test @@ -171,7 +177,7 @@ public class ComponentsPublisherTest { tree.index(dir3, root); writeIssue(4); - DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 5).setLines(2).build(); + 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(); @@ -223,13 +229,13 @@ public class ComponentsPublisherTest { DefaultInputDir dir = new DefaultInputDir("module1", "src", 3); tree.index(dir, module1); - DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).build(); + 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).build(); + DefaultInputFile fileWithoutLang = new TestInputFileBuilder("module1", "src/make", 5).setLines(10).setStatus(InputFile.Status.SAME).build(); tree.index(fileWithoutLang, dir); - DefaultInputFile testFile = new TestInputFileBuilder("module1", "test/FooTest.java", 6).setType(Type.TEST).setLines(4).build(); + 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); @@ -294,7 +300,7 @@ public class ComponentsPublisherTest { DefaultInputDir dir = new DefaultInputDir("module1", "src", 3); tree.index(dir, module1); - DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).build(); + 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); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicateTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicateTest.java new file mode 100644 index 00000000000..049f576d84d --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicateTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.filesystem; + +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.fs.FilePredicates; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultFilePredicates; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SameInputFilePredicateTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + FilePredicates predicates; + + @Before + public void before() throws IOException { + predicates = new DefaultFilePredicates(temp.newFolder().toPath()); + } + + @Test + public void testHasExplicitFilterOnStatus() { + assertThat(SameInputFilePredicate.hasExplicitFilterOnStatus(predicates.all())).isFalse(); + assertThat(SameInputFilePredicate.hasExplicitFilterOnStatus(predicates.hasStatus(InputFile.Status.ADDED))).isTrue(); + assertThat(SameInputFilePredicate.hasExplicitFilterOnStatus(predicates.and(predicates.all(), predicates.hasStatus(InputFile.Status.ADDED)))).isTrue(); + } +} |