From 460f96aa6333c848b3b733d538b27459fee3999a Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Fri, 21 Jul 2017 17:51:29 +0200 Subject: [PATCH] SONAR-9576 Add component status in the scanner report --- .../org/sonar/api/batch/fs/FilePredicate.java | 1 - .../sonar/api/batch/fs/FilePredicates.java | 2 + .../api/batch/fs/internal/AndPredicate.java | 16 ++++-- .../fs/internal/DefaultFilePredicates.java | 8 ++- .../batch/fs/internal/DefaultFileSystem.java | 11 ++-- .../api/batch/fs/internal/NotPredicate.java | 9 +++- .../batch/fs/internal/OperatorPredicate.java | 32 ++++++++++++ .../api/batch/fs/internal/OrPredicate.java | 15 ++++-- .../batch/fs/internal/StatusPredicate.java | 37 ++++++++++++++ .../internal/DefaultFilePredicatesTest.java | 8 +++ .../fs/internal/DefaultFileSystemTest.java | 2 +- .../scanner/report/ComponentsPublisher.java | 16 ++++++ .../filesystem/DefaultModuleFileSystem.java | 2 +- .../filesystem/SameInputFilePredicate.java | 34 ++++++++----- .../scan/filesystem/StatusDetection.java | 6 +-- .../report/ComponentsPublisherTest.java | 22 +++++--- .../SameInputFilePredicateTest.java | 51 +++++++++++++++++++ 17 files changed, 228 insertions(+), 44 deletions(-) create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OperatorPredicate.java create mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java create mode 100644 sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicateTest.java diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java index dac1bedf984..c841431b43f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicate.java @@ -19,7 +19,6 @@ */ package org.sonar.api.batch.fs; - /** * Determines if a file must be kept in search results. See {@link org.sonar.api.batch.fs.FileSystem} * and {@link org.sonar.api.batch.fs.FilePredicates}. diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java index 255d6e2a8c8..0c8b576bc0c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FilePredicates.java @@ -154,4 +154,6 @@ public interface FilePredicates { FilePredicate and(FilePredicate first, FilePredicate second); + FilePredicate hasStatus(InputFile.Status status); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java index 863864c185c..48cb675c8b9 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AndPredicate.java @@ -19,19 +19,20 @@ */ package org.sonar.api.batch.fs.internal; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.FileSystem.Index; -import org.sonar.api.batch.fs.InputFile; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import org.sonar.api.batch.fs.FilePredicate; +import org.sonar.api.batch.fs.FileSystem.Index; +import org.sonar.api.batch.fs.InputFile; + +import static java.util.stream.Collectors.toList; /** * @since 4.2 */ -class AndPredicate extends AbstractFilePredicate { +class AndPredicate extends AbstractFilePredicate implements OperatorPredicate { private final List predicates = new ArrayList<>(); @@ -94,4 +95,9 @@ class AndPredicate extends AbstractFilePredicate { return predicates; } + @Override + public List operands() { + return predicates.stream().map(p -> (FilePredicate) p).collect(toList()); + } + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java index 3e06099e4e4..83c4dd41aab 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFilePredicates.java @@ -29,6 +29,7 @@ import java.util.List; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputFile.Status; /** * Factory of {@link org.sonar.api.batch.fs.FilePredicate} @@ -42,7 +43,7 @@ public class DefaultFilePredicates implements FilePredicates { /** * Client code should use {@link org.sonar.api.batch.fs.FileSystem#predicates()} to get an instance */ - DefaultFilePredicates(Path baseDir) { + public DefaultFilePredicates(Path baseDir) { this.baseDir = baseDir; } @@ -199,4 +200,9 @@ public class DefaultFilePredicates implements FilePredicates { public FilePredicate and(FilePredicate first, FilePredicate second) { return AndPredicate.create(Arrays.asList(first, second)); } + + @Override + public FilePredicate hasStatus(Status status) { + return new StatusPredicate(status); + } } 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 e5246813378..0794bd9bddb 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 @@ -31,6 +31,7 @@ import java.util.Iterator; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -53,7 +54,7 @@ public class DefaultFileSystem implements FileSystem { private Path workDir; private Charset encoding; protected final FilePredicates predicates; - private Predicate defaultPredicate; + private Function> defaultPredicateFactory; /** * Only for testing @@ -99,8 +100,8 @@ public class DefaultFileSystem implements FileSystem { return this; } - public DefaultFileSystem setDefaultPredicate(@Nullable Predicate predicate) { - this.defaultPredicate = predicate; + public DefaultFileSystem setDefaultPredicate(@Nullable Function> defaultPredicateFactory) { + this.defaultPredicateFactory = defaultPredicateFactory; return this; } @@ -146,9 +147,9 @@ public class DefaultFileSystem implements FileSystem { @Override public Iterable inputFiles(FilePredicate predicate) { Iterable iterable = OptimizedFilePredicateAdapter.create(predicate).get(cache); - if (defaultPredicate != null) { + if (defaultPredicateFactory != null) { return StreamSupport.stream(iterable.spliterator(), false) - .filter(defaultPredicate::test).collect(Collectors.toList()); + .filter(defaultPredicateFactory.apply(predicate)).collect(Collectors.toList()); } return iterable; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java index 9fda653d7ac..fb90e16c580 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/NotPredicate.java @@ -19,13 +19,15 @@ */ package org.sonar.api.batch.fs.internal; +import java.util.Arrays; +import java.util.List; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.InputFile; /** * @since 4.2 */ -class NotPredicate extends AbstractFilePredicate { +class NotPredicate extends AbstractFilePredicate implements OperatorPredicate { private final FilePredicate predicate; @@ -38,4 +40,9 @@ class NotPredicate extends AbstractFilePredicate { return !predicate.apply(f); } + @Override + public List operands() { + return Arrays.asList(predicate); + } + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OperatorPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OperatorPredicate.java new file mode 100644 index 00000000000..e42e296b675 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OperatorPredicate.java @@ -0,0 +1,32 @@ +/* + * 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.api.batch.fs.internal; + +import java.util.List; +import org.sonar.api.batch.fs.FilePredicate; + +/** + * A predicate that associate other predicates + */ +public interface OperatorPredicate extends FilePredicate { + + List operands(); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java index b711b7c87ef..0f70fb7545a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/OrPredicate.java @@ -19,18 +19,18 @@ */ package org.sonar.api.batch.fs.internal; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.InputFile; - import java.util.ArrayList; import java.util.Collection; +import java.util.List; +import org.sonar.api.batch.fs.FilePredicate; +import org.sonar.api.batch.fs.InputFile; /** * @since 4.2 */ -class OrPredicate extends AbstractFilePredicate { +class OrPredicate extends AbstractFilePredicate implements OperatorPredicate { - private final Collection predicates = new ArrayList<>(); + private final List predicates = new ArrayList<>(); private OrPredicate() { } @@ -68,4 +68,9 @@ class OrPredicate extends AbstractFilePredicate { return predicates; } + @Override + public List operands() { + return predicates; + } + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java new file mode 100644 index 00000000000..342748d2a4f --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/StatusPredicate.java @@ -0,0 +1,37 @@ +/* + * 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.api.batch.fs.internal; + +import org.sonar.api.batch.fs.InputFile; + +public class StatusPredicate extends AbstractFilePredicate { + + private final InputFile.Status status; + + StatusPredicate(InputFile.Status status) { + this.status = status; + } + + @Override + public boolean apply(InputFile f) { + return status == f.status(); + } + +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java index 8efcbe6d3cd..fb543499dd7 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java @@ -32,6 +32,7 @@ import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputFile.Status; import static org.assertj.core.api.Assertions.assertThat; @@ -56,6 +57,7 @@ public class DefaultFilePredicatesTest { javaFile = new TestInputFileBuilder("foo", "src/main/java/struts/Action.java") .setModuleBaseDir(moduleBasePath) .setLanguage("java") + .setStatus(Status.SAME) .build(); } @@ -172,6 +174,12 @@ public class DefaultFilePredicatesTest { assertThat(predicates.hasType(InputFile.Type.TEST).apply(javaFile)).isFalse(); } + @Test + public void has_status() { + assertThat(predicates.hasStatus(InputFile.Status.SAME).apply(javaFile)).isTrue(); + assertThat(predicates.hasStatus(InputFile.Status.ADDED).apply(javaFile)).isFalse(); + } + @Test public void not() { assertThat(predicates.not(predicates.hasType(InputFile.Type.MAIN)).apply(javaFile)).isFalse(); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java index 60908c48166..55d2d4b53de 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java @@ -120,7 +120,7 @@ public class DefaultFileSystemTest { fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); - fs.setDefaultPredicate(f -> f.relativePath().endsWith("Foo.php")); + fs.setDefaultPredicate(p -> f -> f.relativePath().endsWith("Foo.php")); Iterator iterator = fs.files(fs.predicates().all()).iterator(); assertThat(iterator.hasNext()).isTrue(); assertThat(iterator.next()).isEqualTo(file1.file()); 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 children) { if (component instanceof InputDir && children.isEmpty()) { try (CloseableIterator 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 { - 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 { } // 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(); + } +} -- 2.39.5