aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2019-01-03 17:36:03 +0100
committersonartech <sonartech@sonarsource.com>2019-01-16 09:43:11 +0100
commit2e7846d8c26cc62798f03f72cd6becaf0ec5217e (patch)
treee00b1d0fe298dfc24febfc4c020a85d9e22eee75 /sonar-scanner-engine
parentbd541850bcf71d2e323b74d36fb84727984ae41d (diff)
downloadsonarqube-2e7846d8c26cc62798f03f72cd6becaf0ec5217e.tar.gz
sonarqube-2e7846d8c26cc62798f03f72cd6becaf0ec5217e.zip
SONAR-11508 Rework inclusion/exclusion to restore support of module overrides
Diffstat (limited to 'sonar-scanner-engine')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java82
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java143
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java17
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/coverage/CoverageMediumTest.java39
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/cpd/CpdMediumTest.java46
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java103
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java24
7 files changed, 328 insertions, 126 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java
index 89809081735..0a74fad2261 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java
@@ -91,38 +91,6 @@ public abstract class AbstractExclusionFilters {
}
}
- public boolean accept(Path absolutePath, Path relativePath, InputFile.Type type) {
- PathPattern[] inclusionPatterns;
- PathPattern[] exclusionPatterns;
- if (InputFile.Type.MAIN == type) {
- inclusionPatterns = mainInclusionsPattern;
- exclusionPatterns = mainExclusionsPattern;
- } else if (InputFile.Type.TEST == type) {
- inclusionPatterns = testInclusionsPattern;
- exclusionPatterns = testExclusionsPattern;
- } else {
- throw new IllegalArgumentException("Unknown file type: " + type);
- }
-
- if (inclusionPatterns.length > 0) {
- boolean matchInclusion = false;
- for (PathPattern pattern : inclusionPatterns) {
- matchInclusion |= pattern.match(absolutePath, relativePath);
- }
- if (!matchInclusion) {
- return false;
- }
- }
- if (exclusionPatterns.length > 0) {
- for (PathPattern pattern : exclusionPatterns) {
- if (pattern.match(absolutePath, relativePath)) {
- return false;
- }
- }
- }
- return true;
- }
-
private static PathPattern[] prepareMainInclusions(String[] sourceInclusions) {
if (sourceInclusions.length > 0) {
// User defined params
@@ -145,27 +113,43 @@ public abstract class AbstractExclusionFilters {
return PathPattern.create(testExclusions);
}
- @Override
- public boolean equals(Object o) {
- if (this == o) {
+ public String[] getInclusionsConfig(InputFile.Type type) {
+ return type == InputFile.Type.MAIN ? sourceInclusions : testInclusions;
+ }
+
+ public String[] getExclusionsConfig(InputFile.Type type) {
+ return type == InputFile.Type.MAIN ? sourceExclusions : testExclusions;
+ }
+
+ public boolean isIncluded(Path absolutePath, Path relativePath, InputFile.Type type) {
+ PathPattern[] inclusionPatterns = InputFile.Type.MAIN == type ? mainInclusionsPattern : testInclusionsPattern;
+
+ if (inclusionPatterns.length == 0) {
return true;
}
- if (!(o instanceof AbstractExclusionFilters)) {
- return false;
+
+ for (PathPattern pattern : inclusionPatterns) {
+ if (pattern.match(absolutePath, relativePath)) {
+ return true;
+ }
}
- AbstractExclusionFilters that = (AbstractExclusionFilters) o;
- return Arrays.equals(sourceInclusions, that.sourceInclusions) &&
- Arrays.equals(testInclusions, that.testInclusions) &&
- Arrays.equals(sourceExclusions, that.sourceExclusions) &&
- Arrays.equals(testExclusions, that.testExclusions);
+
+ return false;
}
- @Override
- public int hashCode() {
- int result = Arrays.hashCode(sourceInclusions);
- result = 31 * result + Arrays.hashCode(testInclusions);
- result = 31 * result + Arrays.hashCode(sourceExclusions);
- result = 31 * result + Arrays.hashCode(testExclusions);
- return result;
+ public boolean isExcluded(Path absolutePath, Path relativePath, InputFile.Type type) {
+ PathPattern[] exclusionPatterns = InputFile.Type.MAIN == type ? mainExclusionsPattern : testExclusionsPattern;
+
+ if (exclusionPatterns.length == 0) {
+ return false;
+ }
+
+ for (PathPattern pattern : exclusionPatterns) {
+ if (pattern.match(absolutePath, relativePath)) {
+ return true;
+ }
+ }
+
+ return false;
}
}
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 60798fe990b..2464a6350c7 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
@@ -24,6 +24,8 @@ import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BooleanSupplier;
+import org.apache.commons.io.FilenameUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
@@ -60,14 +62,15 @@ public class FileIndexer {
private final SensorStrategy sensorStrategy;
private final LanguageDetection langDetection;
+ private boolean warnInclusionsAlreadyLogged;
private boolean warnExclusionsAlreadyLogged;
private boolean warnCoverageExclusionsAlreadyLogged;
private boolean warnDuplicationExclusionsAlreadyLogged;
public FileIndexer(DefaultInputProject project, ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore,
- ProjectExclusionFilters projectExclusionFilters, ProjectCoverageAndDuplicationExclusions projectCoverageAndDuplicationExclusions, IssueExclusionsLoader issueExclusionsLoader,
- MetadataGenerator metadataGenerator, SensorStrategy sensorStrategy, LanguageDetection languageDetection, AnalysisWarnings analysisWarnings, ScanProperties properties,
- InputFileFilter[] filters) {
+ ProjectExclusionFilters projectExclusionFilters, ProjectCoverageAndDuplicationExclusions projectCoverageAndDuplicationExclusions, IssueExclusionsLoader issueExclusionsLoader,
+ MetadataGenerator metadataGenerator, SensorStrategy sensorStrategy, LanguageDetection languageDetection, AnalysisWarnings analysisWarnings, ScanProperties properties,
+ InputFileFilter[] filters) {
this.project = project;
this.scannerComponentIdGenerator = scannerComponentIdGenerator;
this.componentStore = componentStore;
@@ -83,17 +86,19 @@ public class FileIndexer {
}
public FileIndexer(DefaultInputProject project, ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore,
- ProjectExclusionFilters projectExclusionFilters, ProjectCoverageAndDuplicationExclusions projectCoverageAndDuplicationExclusions, IssueExclusionsLoader issueExclusionsLoader,
- MetadataGenerator metadataGenerator, SensorStrategy sensorStrategy, LanguageDetection languageDetection, AnalysisWarnings analysisWarnings, ScanProperties properties) {
- this(project, scannerComponentIdGenerator, componentStore, projectExclusionFilters, projectCoverageAndDuplicationExclusions, issueExclusionsLoader, metadataGenerator, sensorStrategy,
+ ProjectExclusionFilters projectExclusionFilters, ProjectCoverageAndDuplicationExclusions projectCoverageAndDuplicationExclusions, IssueExclusionsLoader issueExclusionsLoader,
+ MetadataGenerator metadataGenerator, SensorStrategy sensorStrategy, LanguageDetection languageDetection, AnalysisWarnings analysisWarnings, ScanProperties properties) {
+ this(project, scannerComponentIdGenerator, componentStore, projectExclusionFilters, projectCoverageAndDuplicationExclusions, issueExclusionsLoader, metadataGenerator,
+ sensorStrategy,
languageDetection,
analysisWarnings,
properties, new InputFileFilter[0]);
}
- public void indexFile(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, Path sourceFile,
- InputFile.Type type, ProgressReport progressReport,
- AtomicInteger excludedByPatternsCount)
+ void indexFile(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions,
+ Path sourceFile,
+ InputFile.Type type, ProgressReport progressReport,
+ AtomicInteger excludedByPatternsCount)
throws IOException {
// get case of real file without resolving link
Path realAbsoluteFile = sourceFile.toRealPath(LinkOption.NOFOLLOW_LINKS).toAbsolutePath().normalize();
@@ -103,17 +108,13 @@ public class FileIndexer {
}
Path projectRelativePath = project.getBaseDir().relativize(realAbsoluteFile);
Path moduleRelativePath = module.getBaseDir().relativize(realAbsoluteFile);
- if (!projectExclusionFilters.accept(realAbsoluteFile, projectRelativePath, type)) {
+ boolean included = evaluateInclusionsFilters(moduleExclusionFilters, realAbsoluteFile, projectRelativePath, moduleRelativePath, type);
+ if (!included) {
excludedByPatternsCount.incrementAndGet();
return;
}
- if (!moduleExclusionFilters.accept(realAbsoluteFile, moduleRelativePath, type)) {
- if (projectExclusionFilters.equals(moduleExclusionFilters)) {
- warnOnceDeprecatedExclusion(
- "Specifying module-relative paths at project level in the files exclusions/inclusions properties is deprecated. " +
- "To continue matching files like '" + projectRelativePath + "', " +
- "update these properties so that patterns refer to project-relative paths.");
- }
+ boolean excluded = evaluateExclusionsFilters(moduleExclusionFilters, realAbsoluteFile, projectRelativePath, moduleRelativePath, type);
+ if (excluded) {
excludedByPatternsCount.incrementAndGet();
return;
}
@@ -146,6 +147,42 @@ public class FileIndexer {
progressReport.message(count + " " + pluralizeFiles(count) + " indexed... (last one was " + inputFile.getProjectRelativePath() + ")");
}
+ private boolean evaluateInclusionsFilters(ModuleExclusionFilters moduleExclusionFilters, Path realAbsoluteFile, Path projectRelativePath, Path moduleRelativePath,
+ InputFile.Type type) {
+ if (!Arrays.equals(moduleExclusionFilters.getInclusionsConfig(type), projectExclusionFilters.getInclusionsConfig(type))) {
+ // Module specific configuration
+ return moduleExclusionFilters.isIncluded(realAbsoluteFile, moduleRelativePath, type);
+ }
+ boolean includedByProjectConfiguration = projectExclusionFilters.isIncluded(realAbsoluteFile, projectRelativePath, type);
+ if (includedByProjectConfiguration) {
+ return true;
+ } else if (moduleExclusionFilters.isIncluded(realAbsoluteFile, moduleRelativePath, type)) {
+ warnOnce(
+ type == Type.MAIN ? CoreProperties.PROJECT_INCLUSIONS_PROPERTY : CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY,
+ FilenameUtils.normalize(projectRelativePath.toString(), true), () -> warnInclusionsAlreadyLogged, () -> warnInclusionsAlreadyLogged = true);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean evaluateExclusionsFilters(ModuleExclusionFilters moduleExclusionFilters, Path realAbsoluteFile, Path projectRelativePath, Path moduleRelativePath,
+ InputFile.Type type) {
+ if (!Arrays.equals(moduleExclusionFilters.getExclusionsConfig(type), projectExclusionFilters.getExclusionsConfig(type))) {
+ // Module specific configuration
+ return moduleExclusionFilters.isExcluded(realAbsoluteFile, moduleRelativePath, type);
+ }
+ boolean includedByProjectConfiguration = projectExclusionFilters.isExcluded(realAbsoluteFile, projectRelativePath, type);
+ if (includedByProjectConfiguration) {
+ return true;
+ } else if (moduleExclusionFilters.isExcluded(realAbsoluteFile, moduleRelativePath, type)) {
+ warnOnce(
+ type == Type.MAIN ? CoreProperties.PROJECT_EXCLUSIONS_PROPERTY : CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY,
+ FilenameUtils.normalize(projectRelativePath.toString(), true), () -> warnExclusionsAlreadyLogged, () -> warnExclusionsAlreadyLogged = true);
+ return true;
+ }
+ return false;
+ }
+
private void checkIfAlreadyIndexed(DefaultInputFile inputFile) {
if (componentStore.inputFile(inputFile.getProjectRelativePath()) != null) {
throw MessageException.of("File " + inputFile + " can't be indexed twice. Please check that inclusion/exclusion patterns produce "
@@ -154,58 +191,60 @@ public class FileIndexer {
}
private void evaluateCoverageExclusions(ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, DefaultInputFile inputFile) {
+ boolean excludedForCoverage = isExcludedForCoverage(moduleCoverageAndDuplicationExclusions, inputFile);
+ inputFile.setExcludedForCoverage(excludedForCoverage);
+ if (excludedForCoverage) {
+ LOG.debug("File {} excluded for coverage", inputFile);
+ }
+ }
+
+ private boolean isExcludedForCoverage(ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, DefaultInputFile inputFile) {
+ if (!Arrays.equals(moduleCoverageAndDuplicationExclusions.getCoverageExclusionConfig(), projectCoverageAndDuplicationExclusions.getCoverageExclusionConfig())) {
+ // Module specific configuration
+ return moduleCoverageAndDuplicationExclusions.isExcludedForCoverage(inputFile);
+ }
boolean excludedByProjectConfiguration = projectCoverageAndDuplicationExclusions.isExcludedForCoverage(inputFile);
if (excludedByProjectConfiguration) {
- inputFile.setExcludedForCoverage(true);
- LOG.debug("File {} excluded for coverage", inputFile);
+ return true;
} else if (moduleCoverageAndDuplicationExclusions.isExcludedForCoverage(inputFile)) {
- inputFile.setExcludedForCoverage(true);
- if (Arrays.equals(moduleCoverageAndDuplicationExclusions.getCoverageExclusionConfig(), projectCoverageAndDuplicationExclusions.getCoverageExclusionConfig())) {
- warnOnceDeprecatedCoverageExclusion(
- "Specifying module-relative paths at project level in the property '" + CoreProperties.PROJECT_COVERAGE_EXCLUSIONS_PROPERTY + "' is deprecated. " +
- "To continue matching files like '" + inputFile + "', update this property so that patterns refer to project-relative paths.");
- }
- LOG.debug("File {} excluded for coverage", inputFile);
+ warnOnce(CoreProperties.PROJECT_COVERAGE_EXCLUSIONS_PROPERTY, inputFile.getProjectRelativePath(), () -> warnCoverageExclusionsAlreadyLogged,
+ () -> warnCoverageExclusionsAlreadyLogged = true);
+ return true;
}
+ return false;
}
private void evaluateDuplicationExclusions(ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, DefaultInputFile inputFile) {
- boolean excludedByProjectConfiguration = projectCoverageAndDuplicationExclusions.isExcludedForDuplication(inputFile);
- if (excludedByProjectConfiguration) {
- inputFile.setExcludedForDuplication(true);
- LOG.debug("File {} excluded for duplication", inputFile);
- } else if (moduleCoverageAndDuplicationExclusions.isExcludedForDuplication(inputFile)) {
- inputFile.setExcludedForDuplication(true);
- if (Arrays.equals(moduleCoverageAndDuplicationExclusions.getDuplicationExclusionConfig(), projectCoverageAndDuplicationExclusions.getDuplicationExclusionConfig())) {
- warnOnceDeprecatedDuplicationExclusion(
- "Specifying module-relative paths at project level in the property '" + CoreProperties.CPD_EXCLUSIONS + "' is deprecated. " +
- "To continue matching files like '" + inputFile + "', update this property so that patterns refer to project-relative paths.");
- }
+ boolean excludedForDuplications = isExcludedForDuplications(moduleCoverageAndDuplicationExclusions, inputFile);
+ inputFile.setExcludedForDuplication(excludedForDuplications);
+ if (excludedForDuplications) {
LOG.debug("File {} excluded for duplication", inputFile);
}
}
- private void warnOnceDeprecatedExclusion(String msg) {
- if (!warnExclusionsAlreadyLogged) {
- LOG.warn(msg);
- analysisWarnings.addUnique(msg);
- warnExclusionsAlreadyLogged = true;
+ private boolean isExcludedForDuplications(ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, DefaultInputFile inputFile) {
+ if (!Arrays.equals(moduleCoverageAndDuplicationExclusions.getDuplicationExclusionConfig(), projectCoverageAndDuplicationExclusions.getDuplicationExclusionConfig())) {
+ // Module specific configuration
+ return moduleCoverageAndDuplicationExclusions.isExcludedForDuplication(inputFile);
}
- }
-
- private void warnOnceDeprecatedCoverageExclusion(String msg) {
- if (!warnCoverageExclusionsAlreadyLogged) {
- LOG.warn(msg);
- analysisWarnings.addUnique(msg);
- warnCoverageExclusionsAlreadyLogged = true;
+ boolean excludedByProjectConfiguration = projectCoverageAndDuplicationExclusions.isExcludedForDuplication(inputFile);
+ if (excludedByProjectConfiguration) {
+ return true;
+ } else if (moduleCoverageAndDuplicationExclusions.isExcludedForDuplication(inputFile)) {
+ warnOnce(CoreProperties.CPD_EXCLUSIONS, inputFile.getProjectRelativePath(), () -> warnDuplicationExclusionsAlreadyLogged,
+ () -> warnDuplicationExclusionsAlreadyLogged = true);
+ return true;
}
+ return false;
}
- private void warnOnceDeprecatedDuplicationExclusion(String msg) {
- if (!warnDuplicationExclusionsAlreadyLogged) {
+ private void warnOnce(String propKey, String filePath, BooleanSupplier alreadyLoggedGetter, Runnable markAsLogged) {
+ if (!alreadyLoggedGetter.getAsBoolean()) {
+ String msg = "Specifying module-relative paths at project level in the property '" + propKey + "' is deprecated. " +
+ "To continue matching files like '" + filePath + "', update this property so that patterns refer to project-relative paths.";
LOG.warn(msg);
analysisWarnings.addUnique(msg);
- warnDuplicationExclusionsAlreadyLogged = true;
+ markAsLogged.run();
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java
index a0372a6d633..83d1382ec3e 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFileIndexer.java
@@ -84,8 +84,8 @@ public class ProjectFileIndexer {
int totalIndexed = componentStore.inputFiles().size();
progressReport.stop(totalIndexed + " " + pluralizeFiles(totalIndexed) + " indexed");
- if (projectExclusionFilters.hasPattern()) {
- int excludedFileCount = excludedByPatternsCount.get();
+ int excludedFileCount = excludedByPatternsCount.get();
+ if (projectExclusionFilters.hasPattern() || excludedFileCount > 0) {
LOG.info("{} {} ignored because of inclusion/exclusion patterns", excludedFileCount, pluralizeFiles(excludedFileCount));
}
}
@@ -139,8 +139,8 @@ public class ProjectFileIndexer {
return count == 1 ? "file" : "files";
}
- private void indexFiles(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, List<Path> sources,
- Type type, AtomicInteger excludedByPatternsCount) {
+ private void indexFiles(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions,
+ List<Path> sources, Type type, AtomicInteger excludedByPatternsCount) {
try {
for (Path dirOrFile : sources) {
if (dirOrFile.toFile().isDirectory()) {
@@ -154,8 +154,8 @@ public class ProjectFileIndexer {
}
}
- private void indexDirectory(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, Path dirToIndex,
- Type type, AtomicInteger excludedByPatternsCount)
+ private void indexDirectory(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters,
+ ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, Path dirToIndex, Type type, AtomicInteger excludedByPatternsCount)
throws IOException {
Files.walkFileTree(dirToIndex.normalize(), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
new IndexFileVisitor(module, moduleExclusionFilters, moduleCoverageAndDuplicationExclusions, type, excludedByPatternsCount));
@@ -168,8 +168,9 @@ public class ProjectFileIndexer {
private final Type type;
private final AtomicInteger excludedByPatternsCount;
- IndexFileVisitor(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions, Type type,
- AtomicInteger excludedByPatternsCount) {
+ IndexFileVisitor(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions,
+ Type type,
+ AtomicInteger excludedByPatternsCount) {
this.module = module;
this.moduleExclusionFilters = moduleExclusionFilters;
this.moduleCoverageAndDuplicationExclusions = moduleCoverageAndDuplicationExclusions;
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 6b622327bcc..0b6744565de 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
@@ -197,6 +197,45 @@ public class CoverageMediumTest {
}
@Test
+ public void module_level_exclusions_override_parent_for_multi_module_project() throws IOException {
+
+ File baseDir = temp.getRoot();
+ File baseDirModuleA = new File(baseDir, "moduleA");
+ File baseDirModuleB = new File(baseDir, "moduleB");
+ File srcDirA = new File(baseDirModuleA, "src");
+ srcDirA.mkdirs();
+ File srcDirB = new File(baseDirModuleB, "src");
+ srcDirB.mkdirs();
+
+ File xooFileA = new File(srcDirA, "sampleA.xoo");
+ File xooUtCoverageFileA = new File(srcDirA, "sampleA.xoo.coverage");
+ FileUtils.write(xooFileA, "function foo() {\n if (a && b) {\nalert('hello');\n}\n}", StandardCharsets.UTF_8);
+ FileUtils.write(xooUtCoverageFileA, "2:2:2:1\n3:1", StandardCharsets.UTF_8);
+
+ File xooFileB = new File(srcDirB, "sampleB.xoo");
+ File xooUtCoverageFileB = new File(srcDirB, "sampleB.xoo.coverage");
+ FileUtils.write(xooFileB, "function foo() {\n if (a && b) {\nalert('hello');\n}\n}", StandardCharsets.UTF_8);
+ FileUtils.write(xooUtCoverageFileB, "2:2:2:1\n3:1", StandardCharsets.UTF_8);
+
+ AnalysisResult result = tester.newAnalysis()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.sources", "src")
+ .put("sonar.modules", "moduleA,moduleB")
+ .put("sonar.coverage.exclusions", "**/*.xoo")
+ .put("moduleA.sonar.coverage.exclusions", "**/*.nothing")
+ .build())
+ .execute();
+
+ InputFile fileA = result.inputFile("moduleA/src/sampleA.xoo");
+ assertThat(result.coverageFor(fileA, 2)).isNotNull();
+
+ InputFile fileB = result.inputFile("moduleB/src/sampleB.xoo");
+ assertThat(result.coverageFor(fileB, 2)).isNull();
+ }
+
+ @Test
public void warn_user_for_outdated_server_side_exclusions_for_multi_module_project() throws IOException {
File baseDir = temp.getRoot();
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 d8900cfa569..eaea6f109ea 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
@@ -354,6 +354,52 @@ public class CpdMediumTest {
}
@Test
+ public void module_level_exclusions_override_parent_for_multi_module_project() throws IOException {
+
+ String duplicatedStuff = "Sample xoo\ncontent\n"
+ + "foo\nbar\ntoto\ntiti\n"
+ + "foo\nbar\ntoto\ntiti\n"
+ + "bar\ntoto\ntiti\n"
+ + "foo\nbar\ntoto\ntiti";
+
+ File baseDir = temp.getRoot();
+ File baseDirModuleA = new File(baseDir, "moduleA");
+ File baseDirModuleB = new File(baseDir, "moduleB");
+ File srcDirA = new File(baseDirModuleA, "src");
+ srcDirA.mkdirs();
+ File srcDirB = new File(baseDirModuleB, "src");
+ srcDirB.mkdirs();
+
+ File xooFileA = new File(srcDirA, "sampleA.xoo");
+ FileUtils.write(xooFileA, duplicatedStuff, StandardCharsets.UTF_8);
+
+ File xooFileB = new File(srcDirB, "sampleB.xoo");
+ FileUtils.write(xooFileB, duplicatedStuff, StandardCharsets.UTF_8);
+
+ AnalysisResult result = tester.newAnalysis()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.sources", "src")
+ .put("sonar.modules", "moduleA,moduleB")
+ .put("sonar.cpd.xoo.minimumTokens", "10")
+ .put("sonar.cpd.exclusions", "**/*")
+ .put("moduleA.sonar.cpd.exclusions", "**/*.nothing")
+ .put("moduleB.sonar.cpd.exclusions", "**/*.nothing")
+ .build())
+ .execute();
+
+ InputFile inputFile1 = result.inputFile("moduleA/src/sampleA.xoo");
+ InputFile inputFile2 = result.inputFile("moduleB/src/sampleB.xoo");
+
+ List<ScannerReport.Duplication> duplicationGroupsFile1 = result.duplicationsFor(inputFile1);
+ assertThat(duplicationGroupsFile1).isNotEmpty();
+
+ List<ScannerReport.Duplication> duplicationGroupsFile2 = result.duplicationsFor(inputFile2);
+ assertThat(duplicationGroupsFile2).isNotEmpty();
+ }
+
+ @Test
public void enableCrossProjectDuplication() throws IOException {
File srcDir = new File(baseDir, "src");
srcDir.mkdir();
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 293ef226b5f..1eaec75bde6 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
@@ -509,6 +509,99 @@ public class FileSystemMediumTest {
}
@Test
+ public void test_inclusions_on_multi_modules() throws IOException {
+ File baseDir = temp.getRoot();
+ File baseDirModuleA = new File(baseDir, "moduleA");
+ File baseDirModuleB = new File(baseDir, "moduleB");
+ File srcDirA = new File(baseDirModuleA, "tests");
+ srcDirA.mkdirs();
+ File srcDirB = new File(baseDirModuleB, "tests");
+ srcDirB.mkdirs();
+
+ File xooFileA = new File(srcDirA, "sampleTestA.xoo");
+ FileUtils.write(xooFileA, "Sample xoo\ncontent", StandardCharsets.UTF_8);
+
+ File xooFileB = new File(srcDirB, "sampleTestB.xoo");
+ FileUtils.write(xooFileB, "Sample xoo\ncontent", StandardCharsets.UTF_8);
+
+ final ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder()
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.sources", "")
+ .put("sonar.tests", "tests")
+ .put("sonar.modules", "moduleA,moduleB");
+
+
+ AnalysisResult result = tester.newAnalysis()
+ .properties(builder.build())
+ .execute();
+
+ assertThat(result.inputFiles()).hasSize(2);
+
+ InputFile fileA = result.inputFile("moduleA/tests/sampleTestA.xoo");
+ assertThat(fileA).isNotNull();
+
+ InputFile fileB = result.inputFile("moduleB/tests/sampleTestB.xoo");
+ assertThat(fileB).isNotNull();
+
+ result = tester.newAnalysis()
+ .properties(builder
+ .put("sonar.test.inclusions", "moduleA/tests/**")
+ .build())
+ .execute();
+
+ assertThat(result.inputFiles()).hasSize(1);
+
+ fileA = result.inputFile("moduleA/tests/sampleTestA.xoo");
+ assertThat(fileA).isNotNull();
+
+ fileB = result.inputFile("moduleB/tests/sampleTestB.xoo");
+ assertThat(fileB).isNull();
+ }
+
+ @Test
+ public void test_module_level_inclusions_override_parent_on_multi_modules() throws IOException {
+ File baseDir = temp.getRoot();
+ File baseDirModuleA = new File(baseDir, "moduleA");
+ File baseDirModuleB = new File(baseDir, "moduleB");
+ File srcDirA = new File(baseDirModuleA, "src");
+ srcDirA.mkdirs();
+ File srcDirB = new File(baseDirModuleB, "src");
+ srcDirB.mkdirs();
+
+ File xooFileA = new File(srcDirA, "sampleA.xoo");
+ FileUtils.write(xooFileA, "Sample xoo\ncontent", StandardCharsets.UTF_8);
+
+ File xooFileB = new File(srcDirB, "sampleB.xoo");
+ FileUtils.write(xooFileB, "Sample xoo\ncontent", StandardCharsets.UTF_8);
+
+ final ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder()
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.sources", "src")
+ .put("sonar.modules", "moduleA,moduleB")
+ .put("sonar.inclusions", "**/*.php");
+
+
+ AnalysisResult result = tester.newAnalysis()
+ .properties(builder.build())
+ .execute();
+
+ assertThat(result.inputFiles()).isEmpty();
+
+ result = tester.newAnalysis()
+ .properties(builder
+ .put("moduleA.sonar.inclusions", "**/*.xoo")
+ .build())
+ .execute();
+
+ assertThat(result.inputFiles()).hasSize(1);
+
+ InputFile fileA = result.inputFile("moduleA/src/sampleA.xoo");
+ assertThat(fileA).isNotNull();
+ }
+
+ @Test
public void warn_user_for_outdated_scanner_side_inherited_exclusions_for_multi_module_project() throws IOException {
File baseDir = temp.getRoot();
File baseDirModuleA = new File(baseDir, "moduleA");
@@ -526,7 +619,6 @@ public class FileSystemMediumTest {
AnalysisResult result = tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", "com.foo.project")
.put("sonar.sources", "src")
@@ -542,8 +634,8 @@ public class FileSystemMediumTest {
assertThat(fileB).isNull();
assertThat(logTester.logs(LoggerLevel.WARN))
- .contains("Specifying module-relative paths at project level in the files exclusions/inclusions properties is deprecated. " +
- "To continue matching files like 'moduleA/src/sample.xoo', update these properties so that patterns refer to project-relative paths.");
+ .contains("Specifying module-relative paths at project level in the property 'sonar.exclusions' is deprecated. " +
+ "To continue matching files like 'moduleA/src/sample.xoo', update this property so that patterns refer to project-relative paths.");
}
@Test
@@ -566,7 +658,6 @@ public class FileSystemMediumTest {
AnalysisResult result = tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", "com.foo.project")
.put("sonar.sources", "src")
@@ -581,8 +672,8 @@ public class FileSystemMediumTest {
assertThat(fileB).isNull();
assertThat(logTester.logs(LoggerLevel.WARN))
- .contains("Specifying module-relative paths at project level in the files exclusions/inclusions properties is deprecated. " +
- "To continue matching files like 'moduleA/src/sample.xoo', update these properties so that patterns refer to project-relative paths.");
+ .contains("Specifying module-relative paths at project level in the property 'sonar.exclusions' is deprecated. " +
+ "To continue matching files like 'moduleA/src/sample.xoo', update this property so that patterns refer to project-relative paths.");
}
@Test
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java
index a4f0a30761d..7e6540f69f1 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ProjectExclusionFiltersTest.java
@@ -53,8 +53,10 @@ public class ProjectExclusionFiltersTest {
ProjectExclusionFilters filter = new ProjectExclusionFilters(settings.asConfig());
IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.TEST)).isTrue();
+ assertThat(filter.isExcluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
+ assertThat(filter.isExcluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.TEST)).isFalse();
+ assertThat(filter.isIncluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
+ assertThat(filter.isIncluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.TEST)).isTrue();
}
@Test
@@ -63,10 +65,10 @@ public class ProjectExclusionFiltersTest {
ProjectExclusionFilters filter = new ProjectExclusionFilters(settings.asConfig());
IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
+ assertThat(filter.isIncluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
+ assertThat(filter.isIncluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
}
@Test
@@ -75,10 +77,10 @@ public class ProjectExclusionFiltersTest {
ProjectExclusionFilters filter = new ProjectExclusionFilters(settings.asConfig());
IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
+ assertThat(filter.isIncluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDto.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
+ assertThat(filter.isIncluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
}
@Test
@@ -89,14 +91,14 @@ public class ProjectExclusionFiltersTest {
ProjectExclusionFilters filter = new ProjectExclusionFilters(settings.asConfig());
IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
+ assertThat(filter.isExcluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
+ assertThat(filter.isExcluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
// source exclusions do not apply to tests
indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/test/java/com/mycompany/FooDao.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.TEST)).isTrue();
+ assertThat(filter.isExcluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.TEST)).isFalse();
}
@Test
@@ -108,10 +110,10 @@ public class ProjectExclusionFiltersTest {
ProjectExclusionFilters filter = new ProjectExclusionFilters(settings.asConfig());
IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/org/bar/Foo.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
+ assertThat(filter.isExcluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/org/bar/Bar.java", null);
- assertThat(filter.accept(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isFalse();
+ assertThat(filter.isExcluded(indexedFile.path(), Paths.get(indexedFile.relativePath()), InputFile.Type.MAIN)).isTrue();
}
@Test