aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine/src
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2017-04-05 14:21:53 +0200
committerdbmeneses <duarte.meneses@sonarsource.com>2017-04-11 13:39:57 +0200
commit964fff7ca9f072e6e084c0fac605980f19bc0278 (patch)
tree0176917753cd10f0c776492bc33c1cf05ea77613 /sonar-scanner-engine/src
parent2489c157e7a4e563c7279b57f12c197aa53d28b5 (diff)
downloadsonarqube-964fff7ca9f072e6e084c0fac605980f19bc0278.tar.gz
sonarqube-964fff7ca9f072e6e084c0fac605980f19bc0278.zip
SONAR-9025 Optimize computation issue exclusions
Diffstat (limited to 'sonar-scanner-engine/src')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java13
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java27
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java7
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java10
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/BlockIssuePattern.java38
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializer.java37
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializer.java15
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssuePattern.java92
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/LineRange.java24
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoder.java81
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcher.java38
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java98
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java168
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java15
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java10
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java6
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java9
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java17
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java13
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java53
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java9
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java39
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoderTest.java131
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcherTest.java44
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java162
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java118
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java11
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java6
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java7
-rw-r--r--sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt33
-rw-r--r--sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt6
34 files changed, 527 insertions, 824 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java
index 5e34e44d6be..958b1e63843 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ModuleIssues.java
@@ -21,7 +21,6 @@ package org.sonar.scanner.issue;
import com.google.common.base.Strings;
-import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.fs.internal.DefaultInputComponent;
import org.sonar.api.batch.rule.ActiveRule;
@@ -32,7 +31,6 @@ import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.issue.Issue.Flow;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
import org.sonar.scanner.protocol.Constants.Severity;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.IssueLocation;
@@ -47,14 +45,12 @@ public class ModuleIssues {
private final Rules rules;
private final IssueFilters filters;
private final ReportPublisher reportPublisher;
- private final IssueExclusionsLoader issueExclusionsLoader;
- public ModuleIssues(ActiveRules activeRules, Rules rules, IssueFilters filters, ReportPublisher reportPublisher, IssueExclusionsLoader issueExclusionsLoader) {
+ public ModuleIssues(ActiveRules activeRules, Rules rules, IssueFilters filters, ReportPublisher reportPublisher) {
this.activeRules = activeRules;
this.rules = rules;
this.filters = filters;
this.reportPublisher = reportPublisher;
- this.issueExclusionsLoader = issueExclusionsLoader;
}
public boolean initAndAddIssue(Issue issue) {
@@ -93,13 +89,6 @@ public class ModuleIssues {
applyFlows(builder, locationBuilder, textRangeBuilder, issue);
ScannerReport.Issue rawIssue = builder.build();
- if (issueExclusionsLoader.shouldExecute() && inputComponent.isFile()) {
- InputFile inputFile = (InputFile) inputComponent;
- if (!issueExclusionsLoader.isLoaded(inputFile)) {
- issueExclusionsLoader.loadFile(inputFile);
- }
- }
-
if (filters.accept(inputComponent.key(), rawIssue)) {
write(inputComponent.batchId(), rawIssue);
return true;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java
index b22aa81a516..5c6e4caf409 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilter.java
@@ -19,22 +19,29 @@
*/
package org.sonar.scanner.issue.ignore;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.scan.issue.filter.FilterableIssue;
+
+import javax.annotation.CheckForNull;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.scan.issue.filter.IssueFilter;
import org.sonar.api.scan.issue.filter.IssueFilterChain;
import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
public class EnforceIssuesFilter implements IssueFilter {
+ private static final Logger LOG = LoggerFactory.getLogger(EnforceIssuesFilter.class);
private IssueInclusionPatternInitializer patternInitializer;
+ private InputComponentStore componentStore;
- private static final Logger LOG = LoggerFactory.getLogger(EnforceIssuesFilter.class);
-
- public EnforceIssuesFilter(IssueInclusionPatternInitializer patternInitializer) {
+ public EnforceIssuesFilter(IssueInclusionPatternInitializer patternInitializer, InputComponentStore componentStore) {
this.patternInitializer = patternInitializer;
+ this.componentStore = componentStore;
}
@Override
@@ -46,8 +53,8 @@ public class EnforceIssuesFilter implements IssueFilter {
for (IssuePattern pattern : patternInitializer.getMulticriteriaPatterns()) {
if (pattern.getRulePattern().match(issue.ruleKey().toString())) {
atLeastOneRuleMatched = true;
- String pathForComponent = patternInitializer.getPathForComponent(issue.componentKey());
- if (pathForComponent != null && pattern.getResourcePattern().match(pathForComponent)) {
+ String relativePath = getRelativePath(issue.componentKey());
+ if (relativePath != null && pattern.getResourcePattern().match(relativePath)) {
atLeastOnePatternFullyMatched = true;
matchingPattern = pattern;
}
@@ -63,4 +70,14 @@ public class EnforceIssuesFilter implements IssueFilter {
return chain.accept(issue);
}
}
+
+ @CheckForNull
+ private String getRelativePath(String componentKey) {
+ InputComponent component = componentStore.getByKey(componentKey);
+ if (component == null || !component.isFile()) {
+ return null;
+ }
+ InputFile inputPath = (InputFile) component;
+ return inputPath.relativePath();
+ }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java
index 0eaf1193cb6..0c543eab505 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java
@@ -24,7 +24,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.scan.issue.filter.IssueFilter;
import org.sonar.api.scan.issue.filter.IssueFilterChain;
-import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
@@ -34,8 +33,8 @@ public class IgnoreIssuesFilter implements IssueFilter {
private static final Logger LOG = LoggerFactory.getLogger(IgnoreIssuesFilter.class);
- public IgnoreIssuesFilter(IssueExclusionPatternInitializer patternInitializer) {
- this.patternMatcher = patternInitializer.getPatternMatcher();
+ public IgnoreIssuesFilter(PatternMatcher patternMatcher) {
+ this.patternMatcher = patternMatcher;
}
@Override
@@ -48,7 +47,7 @@ public class IgnoreIssuesFilter implements IssueFilter {
}
private boolean hasMatchFor(FilterableIssue issue) {
- IssuePattern pattern = patternMatcher.getMatchingPattern(issue);
+ IssuePattern pattern = patternMatcher.getMatchingPattern(issue.componentKey(), issue.ruleKey(), issue.line());
if (pattern != null) {
logExclusion(issue, pattern);
return true;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java
index 765085967d6..b77a921e27f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java
@@ -26,14 +26,13 @@ import org.sonar.api.config.Settings;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import static com.google.common.base.MoreObjects.firstNonNull;
@ScannerSide
public abstract class AbstractPatternInitializer {
-
private Settings settings;
-
private List<IssuePattern> multicriteriaPatterns;
protected AbstractPatternInitializer(Settings settings) {
@@ -57,8 +56,6 @@ public abstract class AbstractPatternInitializer {
return !multicriteriaPatterns.isEmpty();
}
- public abstract void initializePatternsForPath(String relativePath, String componentKey);
-
@VisibleForTesting
protected final void initPatterns() {
// Patterns Multicriteria
@@ -71,8 +68,9 @@ public abstract class AbstractPatternInitializer {
String lineRange = "*";
String[] fields = new String[] {resourceKeyPattern, ruleKeyPattern, lineRange};
PatternDecoder.checkRegularLineConstraints(StringUtils.join(fields, ","), fields);
- IssuePattern pattern = new IssuePattern(firstNonNull(resourceKeyPattern, "*"), firstNonNull(ruleKeyPattern, "*"));
- PatternDecoder.decodeRangeOfLines(pattern, firstNonNull(lineRange, "*"));
+ Set<LineRange> rangeOfLines = PatternDecoder.decodeRangeOfLines(firstNonNull(lineRange, "*"));
+ IssuePattern pattern = new IssuePattern(firstNonNull(resourceKeyPattern, "*"), firstNonNull(ruleKeyPattern, "*"), rangeOfLines);
+
multicriteriaPatterns.add(pattern);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/BlockIssuePattern.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/BlockIssuePattern.java
new file mode 100644
index 00000000000..e221a70ef91
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/BlockIssuePattern.java
@@ -0,0 +1,38 @@
+/*
+ * 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.issue.ignore.pattern;
+
+public class BlockIssuePattern {
+ private String beginBlockRegexp;
+ private String endBlockRegexp;
+
+ public BlockIssuePattern(String beginBlockRegexp, String endBlockRegexp) {
+ this.beginBlockRegexp = beginBlockRegexp;
+ this.endBlockRegexp = endBlockRegexp;
+ }
+
+ public String getBeginBlockRegexp() {
+ return beginBlockRegexp;
+ }
+
+ public String getEndBlockRegexp() {
+ return endBlockRegexp;
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializer.java
index 55aac19be3f..37d16ef51c5 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializer.java
@@ -19,25 +19,23 @@
*/
package org.sonar.scanner.issue.ignore.pattern;
-import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.config.Settings;
import org.sonar.core.config.IssueExclusionProperties;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import static com.google.common.base.Strings.nullToEmpty;
public class IssueExclusionPatternInitializer extends AbstractPatternInitializer {
- private List<IssuePattern> blockPatterns;
- private List<IssuePattern> allFilePatterns;
- private PatternMatcher patternMatcher;
+ private List<BlockIssuePattern> blockPatterns;
+ private List<String> allFilePatterns;
public IssueExclusionPatternInitializer(Settings settings) {
super(settings);
- patternMatcher = new PatternMatcher();
loadFileContentPatterns();
}
@@ -46,26 +44,12 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer
return "sonar.issue.ignore" + ".multicriteria";
}
- public PatternMatcher getPatternMatcher() {
- return patternMatcher;
- }
-
- @Override
- public void initializePatternsForPath(String relativePath, String componentKey) {
- for (IssuePattern pattern : getMulticriteriaPatterns()) {
- if (pattern.matchResource(relativePath)) {
- getPatternMatcher().addPatternForComponent(componentKey, pattern);
- }
- }
- }
-
@Override
public boolean hasConfiguredPatterns() {
return hasFileContentPattern() || hasMulticriteriaPatterns();
}
- @VisibleForTesting
- protected final void loadFileContentPatterns() {
+ private final void loadFileContentPatterns() {
// Patterns Block
blockPatterns = new ArrayList<>();
String patternConf = StringUtils.defaultIfBlank(getSettings().getString(IssueExclusionProperties.PATTERNS_BLOCK_KEY), "");
@@ -73,11 +57,12 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer
String propPrefix = IssueExclusionProperties.PATTERNS_BLOCK_KEY + "." + id + ".";
String beginBlockRegexp = getSettings().getString(propPrefix + IssueExclusionProperties.BEGIN_BLOCK_REGEXP);
String endBlockRegexp = getSettings().getString(propPrefix + IssueExclusionProperties.END_BLOCK_REGEXP);
- String[] fields = new String[]{beginBlockRegexp, endBlockRegexp};
+ String[] fields = new String[] {beginBlockRegexp, endBlockRegexp};
PatternDecoder.checkDoubleRegexpLineConstraints(StringUtils.join(fields, ","), fields);
- IssuePattern pattern = new IssuePattern().setBeginBlockRegexp(nullToEmpty(beginBlockRegexp)).setEndBlockRegexp(nullToEmpty(endBlockRegexp));
+ BlockIssuePattern pattern = new BlockIssuePattern(nullToEmpty(beginBlockRegexp), nullToEmpty(endBlockRegexp));
blockPatterns.add(pattern);
}
+ blockPatterns = Collections.unmodifiableList(blockPatterns);
// Patterns All File
allFilePatterns = new ArrayList<>();
@@ -86,16 +71,16 @@ public class IssueExclusionPatternInitializer extends AbstractPatternInitializer
String propPrefix = IssueExclusionProperties.PATTERNS_ALLFILE_KEY + "." + id + ".";
String allFileRegexp = getSettings().getString(propPrefix + IssueExclusionProperties.FILE_REGEXP);
PatternDecoder.checkWholeFileRegexp(allFileRegexp);
- IssuePattern pattern = new IssuePattern().setAllFileRegexp(nullToEmpty(allFileRegexp));
- allFilePatterns.add(pattern);
+ allFilePatterns.add(nullToEmpty(allFileRegexp));
}
+ allFilePatterns = Collections.unmodifiableList(allFilePatterns);
}
- public List<IssuePattern> getBlockPatterns() {
+ public List<BlockIssuePattern> getBlockPatterns() {
return blockPatterns;
}
- public List<IssuePattern> getAllFilePatterns() {
+ public List<String> getAllFilePatterns() {
return allFilePatterns;
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializer.java
index c674c45aaff..7e3992e493c 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializer.java
@@ -19,31 +19,16 @@
*/
package org.sonar.scanner.issue.ignore.pattern;
-import com.google.common.collect.Maps;
import org.sonar.api.config.Settings;
-import java.util.Map;
-
public class IssueInclusionPatternInitializer extends AbstractPatternInitializer {
- private Map<String, String> pathForComponent;
-
public IssueInclusionPatternInitializer(Settings settings) {
super(settings);
- pathForComponent = Maps.newHashMap();
}
@Override
protected String getMulticriteriaConfigurationKey() {
return "sonar.issue.enforce" + ".multicriteria";
}
-
- @Override
- public void initializePatternsForPath(String relativePath, String componentKey) {
- pathForComponent.put(componentKey, relativePath);
- }
-
- public String getPathForComponent(String componentKey) {
- return pathForComponent.get(componentKey);
- }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssuePattern.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssuePattern.java
index 14867725dcd..9ef0d64c9d4 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssuePattern.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/IssuePattern.java
@@ -20,36 +20,39 @@
package org.sonar.scanner.issue.ignore.pattern;
import com.google.common.collect.Sets;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.Set;
import javax.annotation.Nullable;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.scan.issue.filter.FilterableIssue;
import org.sonar.api.utils.WildcardPattern;
public class IssuePattern {
- private WildcardPattern resourcePattern;
- private WildcardPattern rulePattern;
- private Set<Integer> lines = Sets.newLinkedHashSet();
- private Set<LineRange> lineRanges = Sets.newLinkedHashSet();
- private String beginBlockRegexp;
- private String endBlockRegexp;
- private String allFileRegexp;
- private boolean checkLines = true;
-
- public IssuePattern() {
- }
+ private final WildcardPattern resourcePattern;
+ private final WildcardPattern rulePattern;
+ private final Set<Integer> lines = new LinkedHashSet<>();
+ private final Set<LineRange> lineRanges = new LinkedHashSet<>();
+ private final boolean checkLines;
public IssuePattern(String resourcePattern, String rulePattern) {
- this.resourcePattern = WildcardPattern.create(resourcePattern);
- this.rulePattern = WildcardPattern.create(rulePattern);
+ this(resourcePattern, rulePattern, Collections.emptySet());
}
public IssuePattern(String resourcePattern, String rulePattern, Set<LineRange> lineRanges) {
- this(resourcePattern, rulePattern);
- this.lineRanges = lineRanges;
+ this.resourcePattern = WildcardPattern.create(resourcePattern);
+ this.rulePattern = WildcardPattern.create(rulePattern);
+ this.checkLines = !lineRanges.isEmpty();
+ for (LineRange range : lineRanges) {
+ if (range.from() == range.to()) {
+ this.lines.add(range.from());
+ } else {
+ this.lineRanges.add(range);
+ }
+ }
}
public WildcardPattern getResourcePattern() {
@@ -60,52 +63,10 @@ public class IssuePattern {
return rulePattern;
}
- public String getBeginBlockRegexp() {
- return beginBlockRegexp;
- }
-
- public String getEndBlockRegexp() {
- return endBlockRegexp;
- }
-
- public String getAllFileRegexp() {
- return allFileRegexp;
- }
-
- IssuePattern addLineRange(int fromLineId, int toLineId) {
- lineRanges.add(new LineRange(fromLineId, toLineId));
- return this;
- }
-
- IssuePattern addLine(int lineId) {
- lines.add(lineId);
- return this;
- }
-
boolean isCheckLines() {
return checkLines;
}
- IssuePattern setCheckLines(boolean b) {
- this.checkLines = b;
- return this;
- }
-
- IssuePattern setBeginBlockRegexp(String beginBlockRegexp) {
- this.beginBlockRegexp = beginBlockRegexp;
- return this;
- }
-
- IssuePattern setEndBlockRegexp(String endBlockRegexp) {
- this.endBlockRegexp = endBlockRegexp;
- return this;
- }
-
- IssuePattern setAllFileRegexp(String allFileRegexp) {
- this.allFileRegexp = allFileRegexp;
- return this;
- }
-
Set<Integer> getAllLines() {
Set<Integer> allLines = Sets.newLinkedHashSet(lines);
for (LineRange lineRange : lineRanges) {
@@ -114,18 +75,15 @@ public class IssuePattern {
return allLines;
}
- public boolean match(FilterableIssue issue) {
- boolean match = matchResource(issue.componentKey())
- && matchRule(issue.ruleKey());
+ public boolean match(@Nullable String componentKey, RuleKey ruleKey, @Nullable Integer line) {
if (checkLines) {
- Integer line = issue.line();
if (line == null) {
- match = false;
+ return false;
} else {
- match = match && matchLine(line);
+ return matchResource(componentKey) && matchRule(ruleKey) && matchLine(line);
}
}
- return match;
+ return matchResource(componentKey) && matchRule(ruleKey);
}
boolean matchLine(int lineId) {
@@ -147,12 +105,12 @@ public class IssuePattern {
return rulePattern.match(key);
}
- boolean matchResource(@Nullable String resource) {
+ public boolean matchResource(@Nullable String resource) {
return resource != null && resourcePattern.match(resource);
}
public IssuePattern forResource(String resource) {
- return new IssuePattern(resource, rulePattern.toString(), lineRanges).setCheckLines(isCheckLines());
+ return new IssuePattern(resource, rulePattern.toString(), lineRanges);
}
@Override
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/LineRange.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/LineRange.java
index 0c76bd5cf2a..b252484fb7a 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/LineRange.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/LineRange.java
@@ -28,8 +28,12 @@ public class LineRange {
private int from;
private int to;
+ public LineRange(int line) {
+ this(line, line);
+ }
+
public LineRange(int from, int to) {
- Preconditions.checkArgument(from <= to, "Line range is not valid: %s must be greater than %s", from, to);
+ Preconditions.checkArgument(from <= to, "Line range is not valid: %s must be greater or equal than %s", to, from);
this.from = from;
this.to = to;
@@ -40,13 +44,21 @@ public class LineRange {
}
public Set<Integer> toLines() {
- Set<Integer> lines = new LinkedHashSet<>(to-from+1);
+ Set<Integer> lines = new LinkedHashSet<>(to - from + 1);
for (int index = from; index <= to; index++) {
lines.add(index);
}
return lines;
}
+ public int from() {
+ return from;
+ }
+
+ public int to() {
+ return to;
+ }
+
@Override
public String toString() {
return "[" + from + "-" + to + "]";
@@ -79,12 +91,6 @@ public class LineRange {
}
private boolean fieldsDiffer(LineRange other) {
- if (from != other.from) {
- return true;
- }
- if (to != other.to) {
- return true;
- }
- return false;
+ return from != other.from || to != other.to;
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoder.java
index 32fde5bdd0a..f0ce08b2a19 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoder.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoder.java
@@ -19,100 +19,64 @@
*/
package org.sonar.scanner.issue.ignore.pattern;
-import com.google.common.annotations.VisibleForTesting;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.utils.SonarException;
-import java.util.LinkedList;
-import java.util.List;
+import com.google.common.annotations.VisibleForTesting;
public class PatternDecoder {
-
- private static final int THREE_FIELDS_PER_LINE = 3;
private static final String LINE_RANGE_REGEXP = "\\[((\\d+|\\d+-\\d+),?)*\\]";
private static final String CONFIG_FORMAT_ERROR_PREFIX = "Exclusions > Issues : Invalid format. ";
- public List<IssuePattern> decode(String patternsList) {
- List<IssuePattern> patterns = new LinkedList<>();
- String[] patternsLines = StringUtils.split(patternsList, "\n");
- for (String patternLine : patternsLines) {
- IssuePattern pattern = decodeLine(patternLine.trim());
- if (pattern != null) {
- patterns.add(pattern);
- }
- }
- return patterns;
+ private PatternDecoder() {
+ // static only
}
-
- /**
- * Main method that decodes a line which defines a pattern
- */
- public IssuePattern decodeLine(String line) {
- if (isBlankOrComment(line)) {
- return null;
- }
-
- String[] fields = StringUtils.splitPreserveAllTokens(line, ';');
- if (fields.length > THREE_FIELDS_PER_LINE) {
- throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The following line has more than 3 fields separated by comma: " + line);
- }
-
- IssuePattern pattern;
- if (fields.length == THREE_FIELDS_PER_LINE) {
- checkRegularLineConstraints(line, fields);
- pattern = new IssuePattern(StringUtils.trim(fields[0]), StringUtils.trim(fields[1]));
- decodeRangeOfLines(pattern, fields[2]);
- } else if (fields.length == 2) {
- checkDoubleRegexpLineConstraints(line, fields);
- pattern = new IssuePattern().setBeginBlockRegexp(fields[0]).setEndBlockRegexp(fields[1]);
- } else {
- checkWholeFileRegexp(fields[0]);
- pattern = new IssuePattern().setAllFileRegexp(fields[0]);
- }
-
- return pattern;
- }
-
+
static void checkRegularLineConstraints(String line, String[] fields) {
if (!isResource(fields[0])) {
- throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a resource pattern: " + line);
+ throw new IllegalStateException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a resource pattern: " + line);
}
if (!isRule(fields[1])) {
- throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The second field does not define a rule pattern: " + line);
+ throw new IllegalStateException(CONFIG_FORMAT_ERROR_PREFIX + "The second field does not define a rule pattern: " + line);
}
if (!isLinesRange(fields[2])) {
- throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The third field does not define a range of lines: " + line);
+ throw new IllegalStateException(CONFIG_FORMAT_ERROR_PREFIX + "The third field does not define a range of lines: " + line);
}
}
static void checkDoubleRegexpLineConstraints(String line, String[] fields) {
if (!isRegexp(fields[0])) {
- throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a regular expression: " + line);
+ throw new IllegalStateException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a regular expression: " + line);
}
// As per configuration help, missing second field means: from start regexp to EOF
}
static void checkWholeFileRegexp(String regexp) {
if (!isRegexp(regexp)) {
- throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The field does not define a regular expression: " + regexp);
+ throw new IllegalStateException(CONFIG_FORMAT_ERROR_PREFIX + "The field does not define a regular expression: " + regexp);
}
}
- public static void decodeRangeOfLines(IssuePattern pattern, String field) {
+ public static Set<LineRange> decodeRangeOfLines(String field) {
if (StringUtils.equals(field, "*")) {
- pattern.setCheckLines(false);
+ return Collections.emptySet();
} else {
- pattern.setCheckLines(true);
+ Set<LineRange> lineRanges = new HashSet<>();
+
String s = StringUtils.substringBetween(StringUtils.trim(field), "[", "]");
String[] parts = StringUtils.split(s, ',');
for (String part : parts) {
if (StringUtils.contains(part, '-')) {
String[] range = StringUtils.split(part, '-');
- pattern.addLineRange(Integer.valueOf(range[0]), Integer.valueOf(range[1]));
+ lineRanges.add(new LineRange(Integer.valueOf(range[0]), Integer.valueOf(range[1])));
} else {
- pattern.addLine(Integer.valueOf(part));
+ lineRanges.add(new LineRange(Integer.valueOf(part), Integer.valueOf(part)));
}
}
+ return lineRanges;
}
}
@@ -122,11 +86,6 @@ public class PatternDecoder {
}
@VisibleForTesting
- static boolean isBlankOrComment(String line) {
- return StringUtils.isBlank(line) ^ StringUtils.startsWith(line, "#");
- }
-
- @VisibleForTesting
static boolean isResource(String field) {
return StringUtils.isNotBlank(field);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcher.java
index 02149148258..2d008410cbe 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcher.java
@@ -19,45 +19,47 @@
*/
package org.sonar.scanner.issue.ignore.pattern;
-import org.sonar.api.scan.issue.filter.FilterableIssue;
+import org.sonar.api.rule.RuleKey;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
-import java.util.Iterator;
import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
public class PatternMatcher {
- private Multimap<String, IssuePattern> patternByComponent = LinkedHashMultimap.create();
+ private Multimap<String, IssuePattern> excludePatternByComponent = LinkedHashMultimap.create();
- public IssuePattern getMatchingPattern(FilterableIssue issue) {
- IssuePattern matchingPattern = null;
- Iterator<IssuePattern> patternIterator = getPatternsForComponent(issue.componentKey()).iterator();
- while(matchingPattern == null && patternIterator.hasNext()) {
- IssuePattern nextPattern = patternIterator.next();
- if (nextPattern.match(issue)) {
- matchingPattern = nextPattern;
+ @CheckForNull
+ public IssuePattern getMatchingPattern(String componentKey, RuleKey ruleKey, @Nullable Integer line) {
+ for (IssuePattern pattern : getPatternsForComponent(componentKey)) {
+ if (pattern.match(componentKey, ruleKey, line)) {
+ return pattern;
}
}
- return matchingPattern;
+ return null;
}
+ @VisibleForTesting
public Collection<IssuePattern> getPatternsForComponent(String componentKey) {
- return patternByComponent.get(componentKey);
+ return excludePatternByComponent.get(componentKey);
}
- public void addPatternForComponent(String component, IssuePattern pattern) {
- patternByComponent.put(component, pattern.forResource(component));
+ public void addPatternForComponent(String componentKey, IssuePattern pattern) {
+ excludePatternByComponent.put(componentKey, pattern.forResource(componentKey));
}
- public void addPatternToExcludeResource(String resource) {
- addPatternForComponent(resource, new IssuePattern(resource, "*").setCheckLines(false));
+ public void addPatternToExcludeResource(String componentKey) {
+ addPatternForComponent(componentKey, new IssuePattern(componentKey, "*"));
}
- public void addPatternToExcludeLines(String resource, Set<LineRange> lineRanges) {
- addPatternForComponent(resource, new IssuePattern(resource, "*", lineRanges).setCheckLines(true));
+ public void addPatternToExcludeLines(String componentKey, Set<LineRange> lineRanges) {
+ addPatternForComponent(componentKey, new IssuePattern(componentKey, "*", lineRanges));
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java
index 433e8c5ccbf..30cdeb0c582 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoader.java
@@ -19,55 +19,82 @@
*/
package org.sonar.scanner.issue.ignore.scanner;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.CheckForNull;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.internal.FileMetadata.CharHandler;
+import org.sonar.scanner.issue.ignore.pattern.BlockIssuePattern;
import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
-import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
+import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
public final class IssueExclusionsLoader {
+ private final List<java.util.regex.Pattern> allFilePatterns;
+ private final List<DoubleRegexpMatcher> blockMatchers;
+ private final PatternMatcher patternMatcher;
+ private final IssueExclusionPatternInitializer patternsInitializer;
+ private final boolean enableCharHandler;
+
+ public IssueExclusionsLoader(IssueExclusionPatternInitializer patternsInitializer, PatternMatcher patternMatcher) {
+ this.patternsInitializer = patternsInitializer;
+ this.patternMatcher = patternMatcher;
+ this.allFilePatterns = new ArrayList<>();
+ this.blockMatchers = new ArrayList<>();
- private final IssueExclusionsRegexpScanner regexpScanner;
- private final IssueExclusionPatternInitializer exclusionPatternInitializer;
- private final IssueInclusionPatternInitializer inclusionPatternInitializer;
- private final FileSystem fileSystem;
-
- public IssueExclusionsLoader(IssueExclusionsRegexpScanner regexpScanner, IssueExclusionPatternInitializer exclusionPatternInitializer,
- IssueInclusionPatternInitializer inclusionPatternInitializer, FileSystem fileSystem) {
- this.regexpScanner = regexpScanner;
- this.exclusionPatternInitializer = exclusionPatternInitializer;
- this.inclusionPatternInitializer = inclusionPatternInitializer;
- this.fileSystem = fileSystem;
+ for (String pattern : patternsInitializer.getAllFilePatterns()) {
+ allFilePatterns.add(java.util.regex.Pattern.compile(pattern));
+ }
+ for (BlockIssuePattern pattern : patternsInitializer.getBlockPatterns()) {
+ blockMatchers.add(new DoubleRegexpMatcher(
+ java.util.regex.Pattern.compile(pattern.getBeginBlockRegexp()),
+ java.util.regex.Pattern.compile(pattern.getEndBlockRegexp())));
+ }
+ enableCharHandler = !allFilePatterns.isEmpty() || !blockMatchers.isEmpty();
}
public boolean shouldExecute() {
- return inclusionPatternInitializer.hasConfiguredPatterns()
- || exclusionPatternInitializer.hasConfiguredPatterns();
+ return patternsInitializer.hasMulticriteriaPatterns();
}
- public void preLoadAllFiles() {
- for (InputFile inputFile : fileSystem.inputFiles(fileSystem.predicates().all())) {
- loadFile(inputFile);
+ public void addMulticriteriaPatterns(String relativePath, String componentKey) {
+ for (IssuePattern pattern : patternsInitializer.getMulticriteriaPatterns()) {
+ if (pattern.matchResource(relativePath)) {
+ patternMatcher.addPatternForComponent(componentKey, pattern);
+ }
}
}
- public boolean isLoaded(InputFile inputFile) {
- String componentEffectiveKey = ((DefaultInputFile) inputFile).key();
- return inclusionPatternInitializer.getPathForComponent(componentEffectiveKey) != null;
+ @CheckForNull
+ public CharHandler createCharHandlerFor(String componentKey) {
+ if (enableCharHandler) {
+ return new IssueExclusionsRegexpScanner(componentKey, allFilePatterns, blockMatchers, patternMatcher);
+ }
+ return null;
}
- public void loadFile(InputFile inputFile) {
- try {
- String componentEffectiveKey = ((DefaultInputFile) inputFile).key();
- String path = inputFile.relativePath();
- inclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
- exclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
- if (exclusionPatternInitializer.hasFileContentPattern()) {
- regexpScanner.scan(componentEffectiveKey, inputFile.path(), inputFile.charset());
- }
- } catch (Exception e) {
- throw new IllegalStateException("Unable to read the source file : '" + inputFile.absolutePath() + "' with the charset : '"
- + inputFile.charset().name() + "'.", e);
+ public static class DoubleRegexpMatcher {
+
+ private java.util.regex.Pattern firstPattern;
+ private java.util.regex.Pattern secondPattern;
+
+ DoubleRegexpMatcher(java.util.regex.Pattern firstPattern, java.util.regex.Pattern secondPattern) {
+ this.firstPattern = firstPattern;
+ this.secondPattern = secondPattern;
+ }
+
+ boolean matchesFirstPattern(String line) {
+ return firstPattern.matcher(line).find();
+ }
+
+ boolean matchesSecondPattern(String line) {
+ return hasSecondPattern() && secondPattern.matcher(line).find();
+ }
+
+ boolean hasSecondPattern() {
+ return StringUtils.isNotEmpty(secondPattern.toString());
}
}
@@ -75,5 +102,4 @@ public final class IssueExclusionsLoader {
public String toString() {
return "Issues Exclusions - Source Scanner";
}
-
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java
index 0c4794cb2b9..0ad4373665a 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java
@@ -19,92 +19,59 @@
*/
package org.sonar.scanner.issue.ignore.scanner;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.ScannerSide;
-import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
-import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
-import org.sonar.scanner.issue.ignore.pattern.LineRange;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.regex.Pattern;
-@ScannerSide
-public class IssueExclusionsRegexpScanner {
-
- private static final Logger LOG = LoggerFactory.getLogger(IssueExclusionsRegexpScanner.class);
-
- private IssueExclusionPatternInitializer exclusionPatternInitializer;
- private List<java.util.regex.Pattern> allFilePatterns;
- private List<DoubleRegexpMatcher> blockMatchers;
-
- // fields to be reset at every new scan
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.fs.internal.FileMetadata.CharHandler;
+import org.sonar.scanner.issue.ignore.pattern.LineRange;
+import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
+import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader.DoubleRegexpMatcher;
+
+public class IssueExclusionsRegexpScanner extends CharHandler {
+ private static final Logger LOG = LoggerFactory.getLogger(IssueExclusionsLoader.class);
+
+ private final StringBuilder sb = new StringBuilder();
+ private final List<Pattern> allFilePatterns;
+ private final List<DoubleRegexpMatcher> blockMatchers;
+ private final String componentKey;
+ private final PatternMatcher patternMatcher;
+
+ private int lineIndex = 1;
+ private List<LineExclusion> lineExclusions = new ArrayList<>();
+ private LineExclusion currentLineExclusion = null;
+ private int fileLength = 0;
private DoubleRegexpMatcher currentMatcher;
- private int fileLength;
- private List<LineExclusion> lineExclusions;
- private LineExclusion currentLineExclusion;
- public IssueExclusionsRegexpScanner(IssueExclusionPatternInitializer patternsInitializer) {
- this.exclusionPatternInitializer = patternsInitializer;
-
- lineExclusions = new ArrayList<>();
- allFilePatterns = new ArrayList<>();
- blockMatchers = new ArrayList<>();
-
- for (IssuePattern pattern : patternsInitializer.getAllFilePatterns()) {
- allFilePatterns.add(java.util.regex.Pattern.compile(pattern.getAllFileRegexp()));
- }
- for (IssuePattern pattern : patternsInitializer.getBlockPatterns()) {
- blockMatchers.add(new DoubleRegexpMatcher(
- java.util.regex.Pattern.compile(pattern.getBeginBlockRegexp()),
- java.util.regex.Pattern.compile(pattern.getEndBlockRegexp())));
- }
-
- init();
+ IssueExclusionsRegexpScanner(String componentKey, List<Pattern> allFilePatterns, List<DoubleRegexpMatcher> blockMatchers, PatternMatcher patternMatcher) {
+ this.allFilePatterns = allFilePatterns;
+ this.blockMatchers = blockMatchers;
+ this.patternMatcher = patternMatcher;
+ this.componentKey = componentKey;
+ String relativePath = StringUtils.substringAfterLast(componentKey, ":");
+ LOG.info("'{}' generating issue exclusions", relativePath);
}
- private void init() {
- currentMatcher = null;
- fileLength = 0;
- lineExclusions.clear();
- currentLineExclusion = null;
+ @Override
+ protected void handleIgnoreEoL(char c) {
+ sb.append(c);
}
- public void scan(String resource, Path filePath, Charset encoding) throws IOException {
- LOG.debug("Scanning {}", resource);
- init();
-
- int lineIndex = 0;
- try (BufferedReader br = Files.newBufferedReader(filePath, encoding)) {
- String line;
- while ((line = br.readLine()) != null) {
- lineIndex++;
- if (line.trim().length() == 0) {
- continue;
- }
+ @Override
+ protected void newLine() {
+ processLine(sb.toString());
+ sb.setLength(0);
+ lineIndex++;
+ }
- // first check the single regexp patterns that can be used to totally exclude a file
- for (java.util.regex.Pattern pattern : allFilePatterns) {
- if (pattern.matcher(line).find()) {
- exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeResource(resource);
- // nothing more to do on this file
- LOG.debug("- Exclusion pattern '{}': every issue in this file will be ignored.", pattern);
- return;
- }
- }
-
- // then check the double regexps if we're still here
- checkDoubleRegexps(line, lineIndex);
- }
- }
+ @Override
+ protected void eof() {
+ processLine(sb.toString());
if (currentMatcher != null && !currentMatcher.hasSecondPattern()) {
// this will happen when there is a start block regexp but no end block regexp
@@ -116,14 +83,33 @@ public class IssueExclusionsRegexpScanner {
if (!lineExclusions.isEmpty()) {
Set<LineRange> lineRanges = convertLineExclusionsToLineRanges();
LOG.debug("- Line exclusions found: {}", lineRanges);
- exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeLines(resource, lineRanges);
+ patternMatcher.addPatternToExcludeLines(componentKey, lineRanges);
}
}
+ private void processLine(String line) {
+ if (line.trim().length() == 0) {
+ return;
+ }
+
+ // first check the single regexp patterns that can be used to totally exclude a file
+ for (Pattern pattern : allFilePatterns) {
+ if (pattern.matcher(line).find()) {
+ patternMatcher.addPatternToExcludeResource(componentKey);
+ // nothing more to do on this file
+ LOG.debug("- Exclusion pattern '{}': every issue in this file will be ignored.", pattern);
+ return;
+ }
+ }
+
+ // then check the double regexps if we're still here
+ checkDoubleRegexps(line, lineIndex);
+ }
+
private Set<LineRange> convertLineExclusionsToLineRanges() {
Set<LineRange> lineRanges = new HashSet<>(lineExclusions.size());
for (LineExclusion lineExclusion : lineExclusions) {
- lineRanges.add(lineExclusion.toLineRange());
+ lineRanges.add(lineExclusion.toLineRange(fileLength));
}
return lineRanges;
}
@@ -155,8 +141,7 @@ public class IssueExclusionsRegexpScanner {
currentLineExclusion = null;
}
- private class LineExclusion {
-
+ private static class LineExclusion {
private int start;
private int end;
@@ -169,33 +154,8 @@ public class IssueExclusionsRegexpScanner {
this.end = end;
}
- public LineRange toLineRange() {
+ public LineRange toLineRange(int fileLength) {
return new LineRange(start, end == -1 ? fileLength : end);
}
-
- }
-
- private static class DoubleRegexpMatcher {
-
- private java.util.regex.Pattern firstPattern;
- private java.util.regex.Pattern secondPattern;
-
- DoubleRegexpMatcher(java.util.regex.Pattern firstPattern, java.util.regex.Pattern secondPattern) {
- this.firstPattern = firstPattern;
- this.secondPattern = secondPattern;
- }
-
- boolean matchesFirstPattern(String line) {
- return firstPattern.matcher(line).find();
- }
-
- boolean matchesSecondPattern(String line) {
- return hasSecondPattern() && secondPattern.matcher(line).find();
- }
-
- boolean hasSecondPattern() {
- return StringUtils.isNotEmpty(secondPattern.toString());
- }
}
-
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java
index e48247aee05..46acfff0279 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/AbstractPhaseExecutor.java
@@ -20,15 +20,14 @@
package org.sonar.scanner.phases;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.config.Settings;
import org.sonar.scanner.events.BatchStepEvent;
import org.sonar.scanner.events.EventBus;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
import org.sonar.scanner.rule.QProfileVerifier;
import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.scanner.scan.filesystem.FileSystemLogger;
-import org.sonar.scanner.scan.filesystem.InputFileBuilder;
public abstract class AbstractPhaseExecutor {
@@ -41,11 +40,10 @@ public abstract class AbstractPhaseExecutor {
private final DefaultModuleFileSystem fs;
private final QProfileVerifier profileVerifier;
private final IssueExclusionsLoader issueExclusionsLoader;
- private final boolean preloadIssueExclusions;
public AbstractPhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
SensorContext sensorContext, EventBus eventBus, FileSystemLogger fsLogger, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
- IssueExclusionsLoader issueExclusionsLoader, Settings settings) {
+ IssueExclusionsLoader issueExclusionsLoader) {
this.postJobsExecutor = postJobsExecutor;
this.initializersExecutor = initializersExecutor;
this.sensorsExecutor = sensorsExecutor;
@@ -55,7 +53,6 @@ public abstract class AbstractPhaseExecutor {
this.fs = fs;
this.profileVerifier = profileVerifier;
this.issueExclusionsLoader = issueExclusionsLoader;
- this.preloadIssueExclusions = settings.getBoolean(InputFileBuilder.PRELOAD_FILE_METADATA_KEY);
}
/**
@@ -92,10 +89,14 @@ public abstract class AbstractPhaseExecutor {
protected abstract void executeOnRoot();
private void initIssueExclusions() {
- if (preloadIssueExclusions && issueExclusionsLoader.shouldExecute()) {
+ if (issueExclusionsLoader.shouldExecute()) {
String stepName = "Init issue exclusions";
eventBus.fireEvent(new BatchStepEvent(stepName, true));
- issueExclusionsLoader.preLoadAllFiles();
+
+ for (InputFile inputFile : fs.inputFiles(fs.predicates().all())) {
+ issueExclusionsLoader.addMulticriteriaPatterns(inputFile.relativePath(), inputFile.key());
+ }
+
eventBus.fireEvent(new BatchStepEvent(stepName, false));
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java
index b650656b592..7893e6a0024 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/IssuesPhaseExecutor.java
@@ -22,7 +22,6 @@ package org.sonar.scanner.phases;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.SensorContext;
-import org.sonar.api.config.Settings;
import org.sonar.scanner.events.BatchStepEvent;
import org.sonar.scanner.events.EventBus;
import org.sonar.scanner.issue.IssueCallback;
@@ -44,8 +43,8 @@ public final class IssuesPhaseExecutor extends AbstractPhaseExecutor {
public IssuesPhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext,
EventBus eventBus, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
- IssueExclusionsLoader issueExclusionsLoader, IssueTransition localIssueTracking, IssueCallback issueCallback, Settings settings) {
- super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader, settings);
+ IssueExclusionsLoader issueExclusionsLoader, IssueTransition localIssueTracking, IssueCallback issueCallback) {
+ super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader);
this.eventBus = eventBus;
this.issuesReport = jsonReport;
this.localIssueTracking = localIssueTracking;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java
index e8bf655674d..434c88a96dd 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PublishPhaseExecutor.java
@@ -20,7 +20,6 @@
package org.sonar.scanner.phases;
import org.sonar.api.batch.SensorContext;
-import org.sonar.api.config.Settings;
import org.sonar.scanner.cpd.CpdExecutor;
import org.sonar.scanner.events.BatchStepEvent;
import org.sonar.scanner.events.EventBus;
@@ -39,9 +38,9 @@ public final class PublishPhaseExecutor extends AbstractPhaseExecutor {
private final ScmPublisher scm;
public PublishPhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext,
- EventBus eventBus, ReportPublisher reportPublisher, FileSystemLogger fsLogger, DefaultModuleFileSystem fs, Settings settings,
+ EventBus eventBus, ReportPublisher reportPublisher, FileSystemLogger fsLogger, DefaultModuleFileSystem fs,
QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader, CpdExecutor cpdExecutor, ScmPublisher scm) {
- super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader, settings);
+ super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader);
this.eventBus = eventBus;
this.reportPublisher = reportPublisher;
this.cpdExecutor = cpdExecutor;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
index 9053ad07f89..b7ba4b5cf0b 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
@@ -44,8 +44,8 @@ import org.sonar.scanner.issue.ignore.EnforceIssuesFilter;
import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter;
import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
-import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsRegexpScanner;
import org.sonar.scanner.phases.AbstractPhaseExecutor;
import org.sonar.scanner.phases.InitializersExecutor;
import org.sonar.scanner.phases.IssuesPhaseExecutor;
@@ -152,7 +152,7 @@ public class ModuleScanContainer extends ComponentContainer {
// issue exclusions
IssueInclusionPatternInitializer.class,
IssueExclusionPatternInitializer.class,
- IssueExclusionsRegexpScanner.class,
+ PatternMatcher.class,
IssueExclusionsLoader.class,
EnforceIssuesFilter.class,
IgnoreIssuesFilter.class,
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
index 5e814625b52..c04483cc784 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
@@ -35,6 +35,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.fs.internal.Metadata;
+import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
class MetadataGenerator {
private static final Logger LOG = LoggerFactory.getLogger(MetadataGenerator.class);
@@ -47,11 +48,13 @@ class MetadataGenerator {
private final StatusDetection statusDetection;
private final FileMetadata fileMetadata;
private final DefaultInputModule inputModule;
+ private final IssueExclusionsLoader exclusionsScanner;
- MetadataGenerator(DefaultInputModule inputModule, StatusDetection statusDetection, FileMetadata fileMetadata) {
+ MetadataGenerator(DefaultInputModule inputModule, StatusDetection statusDetection, FileMetadata fileMetadata, IssueExclusionsLoader exclusionsScanner) {
this.inputModule = inputModule;
this.statusDetection = statusDetection;
this.fileMetadata = fileMetadata;
+ this.exclusionsScanner = exclusionsScanner;
}
/**
@@ -62,11 +65,10 @@ class MetadataGenerator {
try {
Charset charset = detectCharset(inputFile.path(), defaultEncoding);
inputFile.setCharset(charset);
- Metadata metadata = fileMetadata.readMetadata(inputFile.file(), charset);
+ Metadata metadata = fileMetadata.readMetadata(inputFile.file(), charset, exclusionsScanner.createCharHandlerFor(inputFile.key()));
inputFile.setMetadata(metadata);
inputFile.setStatus(statusDetection.status(inputModule.definition().getKeyWithBranch(), inputFile.relativePath(), metadata.hash()));
- LOG.debug("'{}' generated metadata {} with charset '{}'",
- inputFile.relativePath(), inputFile.type() == Type.TEST ? "as test " : "", charset);
+ LOG.debug("'{}' generated metadata {} with charset '{}'", inputFile.relativePath(), inputFile.type() == Type.TEST ? "as test " : "", charset);
} catch (Exception e) {
throw new IllegalStateException(e);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java
index 59d89e38539..4e935f1905e 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java
@@ -23,10 +23,12 @@ import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
@ScannerSide
public class MetadataGeneratorProvider extends ProviderAdapter {
- public MetadataGenerator provide(DefaultInputModule inputModule, StatusDetectionFactory statusDetectionFactory, FileMetadata fileMetadata) {
- return new MetadataGenerator(inputModule, statusDetectionFactory.create(), fileMetadata);
+ public MetadataGenerator provide(DefaultInputModule inputModule, StatusDetectionFactory statusDetectionFactory, FileMetadata fileMetadata,
+ IssueExclusionsLoader exclusionsScanner) {
+ return new MetadataGenerator(inputModule, statusDetectionFactory.create(), fileMetadata, exclusionsScanner);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java
index af240c47660..c180e8e1da6 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java
@@ -24,7 +24,6 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
@@ -36,10 +35,6 @@ import org.sonar.api.rule.Severity;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.issue.IssueFilters;
import org.sonar.scanner.issue.ModuleIssues;
-import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
-import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
-import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
-import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsRegexpScanner;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.report.ReportPublisher;
@@ -211,9 +206,7 @@ public class ModuleIssuesTest {
* Every rules and active rules has to be added in builders before creating ModuleIssues
*/
private void initModuleIssues() {
- IssueExclusionsLoader issueExclusionsLoader = new IssueExclusionsLoader(mock(IssueExclusionsRegexpScanner.class), mock(IssueExclusionPatternInitializer.class),
- mock(IssueInclusionPatternInitializer.class), mock(FileSystem.class));
- moduleIssues = new ModuleIssues(activeRulesBuilder.build(), ruleBuilder.build(), filters, reportPublisher, issueExclusionsLoader);
+ moduleIssues = new ModuleIssues(activeRulesBuilder.build(), ruleBuilder.build(), filters, reportPublisher);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java
index dab1de1df03..d3089b298fa 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java
@@ -25,11 +25,14 @@ import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.scan.issue.filter.IssueFilterChain;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.WildcardPattern;
import org.sonar.scanner.issue.ignore.EnforceIssuesFilter;
import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -40,18 +43,20 @@ import static org.mockito.Mockito.when;
public class EnforceIssuesFilterTest {
private IssueInclusionPatternInitializer exclusionPatternInitializer;
+ private InputComponentStore inputComponentStore;
private EnforceIssuesFilter ignoreFilter;
private FilterableIssue issue;
private IssueFilterChain chain;
@Before
public void init() {
+ inputComponentStore = mock(InputComponentStore.class);
exclusionPatternInitializer = mock(IssueInclusionPatternInitializer.class);
issue = mock(FilterableIssue.class);
chain = mock(IssueFilterChain.class);
when(chain.accept(issue)).thenReturn(true);
- ignoreFilter = new EnforceIssuesFilter(exclusionPatternInitializer);
+ ignoreFilter = new EnforceIssuesFilter(exclusionPatternInitializer, inputComponentStore);
}
@Test
@@ -95,12 +100,16 @@ public class EnforceIssuesFilterTest {
when(matching.getResourcePattern()).thenReturn(pathPattern);
when(pathPattern.match(path)).thenReturn(true);
when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
- when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path);
+ when(inputComponentStore.getByKey(componentKey)).thenReturn(createComponentWithPath(path));
assertThat(ignoreFilter.accept(issue, chain)).isTrue();
verifyZeroInteractions(chain);
}
+ private InputComponent createComponentWithPath(String path) {
+ return new TestInputFileBuilder("", path).build();
+ }
+
@Test
public void shouldRefuseIssueIfRuleMatchesButNotPath() {
String rule = "rule";
@@ -119,7 +128,7 @@ public class EnforceIssuesFilterTest {
when(matching.getResourcePattern()).thenReturn(pathPattern);
when(pathPattern.match(path)).thenReturn(false);
when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
- when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path);
+ when(inputComponentStore.getByKey(componentKey)).thenReturn(createComponentWithPath(path));
assertThat(ignoreFilter.accept(issue, chain)).isFalse();
verifyZeroInteractions(chain);
@@ -143,7 +152,7 @@ public class EnforceIssuesFilterTest {
when(matching.getResourcePattern()).thenReturn(pathPattern);
when(pathPattern.match(path)).thenReturn(false);
when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
- when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(null);
+ when(inputComponentStore.getByKey(componentKey)).thenReturn(null);
assertThat(ignoreFilter.accept(issue, chain)).isFalse();
verifyZeroInteractions(chain);
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java
index b1a88ce858c..ccf1ed016c6 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilterTest.java
@@ -19,23 +19,24 @@
*/
package org.sonar.scanner.issue.ignore;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.scan.issue.filter.FilterableIssue;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.scan.issue.filter.IssueFilterChain;
import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter;
-import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
public class IgnoreIssuesFilterTest {
- private IssueExclusionPatternInitializer exclusionPatternInitializer;
private PatternMatcher exclusionPatternMatcher;
private IgnoreIssuesFilter ignoreFilter;
private FilterableIssue issue;
@@ -44,25 +45,23 @@ public class IgnoreIssuesFilterTest {
@Before
public void init() {
exclusionPatternMatcher = mock(PatternMatcher.class);
- exclusionPatternInitializer = mock(IssueExclusionPatternInitializer.class);
- when(exclusionPatternInitializer.getPatternMatcher()).thenReturn(exclusionPatternMatcher);
issue = mock(FilterableIssue.class);
chain = mock(IssueFilterChain.class);
when(chain.accept(issue)).thenReturn(true);
- ignoreFilter = new IgnoreIssuesFilter(exclusionPatternInitializer);
+ ignoreFilter = new IgnoreIssuesFilter(exclusionPatternMatcher);
}
@Test
public void shouldPassToChainIfMatcherHasNoPatternForIssue() {
- when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(null);
+ when(exclusionPatternMatcher.getMatchingPattern(anyString(), any(RuleKey.class), any(Integer.class))).thenReturn(null);
assertThat(ignoreFilter.accept(issue, chain)).isTrue();
}
@Test
public void shouldAcceptOrRefuseIfMatcherHasPatternForIssue() {
- when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(mock(IssuePattern.class));
+ when(exclusionPatternMatcher.getMatchingPattern(anyString(), any(RuleKey.class), any(Integer.class))).thenReturn(mock(IssuePattern.class));
assertThat(ignoreFilter.accept(issue, chain)).isFalse();
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java
index a298c822a2e..7fadd593235 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java
@@ -19,76 +19,45 @@
*/
package org.sonar.scanner.issue.ignore.pattern;
-
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.Settings;
import org.sonar.api.config.MapSettings;
-import org.sonar.api.utils.SonarException;
import org.sonar.core.config.IssueExclusionProperties;
import static org.assertj.core.api.Assertions.assertThat;
public class IssueExclusionPatternInitializerTest {
-
private IssueExclusionPatternInitializer patternsInitializer;
-
private Settings settings;
@Before
public void init() {
settings = new MapSettings(new PropertyDefinitions(IssueExclusionProperties.all()));
- patternsInitializer = new IssueExclusionPatternInitializer(settings);
}
@Test
public void testNoConfiguration() {
- patternsInitializer.initPatterns();
+ patternsInitializer = new IssueExclusionPatternInitializer(settings);
assertThat(patternsInitializer.hasConfiguredPatterns()).isFalse();
assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0);
}
- @Test
- public void shouldHavePatternsBasedOnMulticriteriaPattern() {
- settings.setProperty("sonar.issue.ignore" + ".multicriteria", "1,2");
- settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "resourceKey", "org/foo/Bar.java");
- settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "ruleKey", "*");
- settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".2." + "resourceKey", "org/foo/Hello.java");
- settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".2." + "ruleKey", "checkstyle:MagicNumber");
- patternsInitializer.initPatterns();
-
- assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
- assertThat(patternsInitializer.hasFileContentPattern()).isFalse();
- assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue();
- assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2);
- assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(0);
- assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0);
-
- patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar");
- patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz");
- patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello");
-
- assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Bar")).hasSize(1);
- assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Baz")).hasSize(0);
- assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Hello")).hasSize(1);
-
- }
-
- @Test(expected = SonarException.class)
+ @Test(expected = IllegalStateException.class)
public void shouldLogInvalidResourceKey() {
settings.setProperty("sonar.issue.ignore" + ".multicriteria", "1");
settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "resourceKey", "");
settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "ruleKey", "*");
- patternsInitializer.initPatterns();
+ patternsInitializer = new IssueExclusionPatternInitializer(settings);
}
- @Test(expected = SonarException.class)
+ @Test(expected = IllegalStateException.class)
public void shouldLogInvalidRuleKey() {
settings.setProperty("sonar.issue.ignore" + ".multicriteria", "1");
settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "resourceKey", "*");
settings.setProperty("sonar.issue.ignore" + ".multicriteria" + ".1." + "ruleKey", "");
- patternsInitializer.initPatterns();
+ patternsInitializer = new IssueExclusionPatternInitializer(settings);
}
@Test
@@ -100,7 +69,7 @@ public class IssueExclusionPatternInitializerTest {
settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionProperties.END_BLOCK_REGEXP, "// FOO-ON");
settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionProperties.BEGIN_BLOCK_REGEXP, "// IGNORE-TO-EOF");
settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionProperties.END_BLOCK_REGEXP, "");
- patternsInitializer.loadFileContentPatterns();
+ patternsInitializer = new IssueExclusionPatternInitializer(settings);
assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
assertThat(patternsInitializer.hasFileContentPattern()).isTrue();
@@ -110,12 +79,12 @@ public class IssueExclusionPatternInitializerTest {
assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0);
}
- @Test(expected = SonarException.class)
+ @Test(expected = IllegalStateException.class)
public void shouldLogInvalidStartBlockPattern() {
settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY, "1");
settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionProperties.BEGIN_BLOCK_REGEXP, "");
settings.setProperty(IssueExclusionProperties.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionProperties.END_BLOCK_REGEXP, "// SONAR-ON");
- patternsInitializer.loadFileContentPatterns();
+ patternsInitializer = new IssueExclusionPatternInitializer(settings);
}
@Test
@@ -123,7 +92,7 @@ public class IssueExclusionPatternInitializerTest {
settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY, "1,2");
settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionProperties.FILE_REGEXP, "@SONAR-IGNORE-ALL");
settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY + ".2." + IssueExclusionProperties.FILE_REGEXP, "//FOO-IGNORE-ALL");
- patternsInitializer.loadFileContentPatterns();
+ patternsInitializer = new IssueExclusionPatternInitializer(settings);
assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
assertThat(patternsInitializer.hasFileContentPattern()).isTrue();
@@ -133,10 +102,10 @@ public class IssueExclusionPatternInitializerTest {
assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(2);
}
- @Test(expected = SonarException.class)
+ @Test(expected = IllegalStateException.class)
public void shouldLogInvalidAllFilePattern() {
settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY, "1");
settings.setProperty(IssueExclusionProperties.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionProperties.FILE_REGEXP, "");
- patternsInitializer.loadFileContentPatterns();
+ patternsInitializer = new IssueExclusionPatternInitializer(settings);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java
index de3982e504e..6feecb28637 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java
@@ -31,7 +31,6 @@ import static org.assertj.core.api.Assertions.assertThat;
public class IssueInclusionPatternInitializerTest {
private IssueInclusionPatternInitializer patternsInitializer;
-
private Settings settings;
@Before
@@ -58,14 +57,6 @@ public class IssueInclusionPatternInitializerTest {
assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue();
assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2);
-
- patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar");
- patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz");
- patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello");
-
- assertThat(patternsInitializer.getPathForComponent("org.foo.Bar")).isEqualTo("org/foo/Bar.java");
- assertThat(patternsInitializer.getPathForComponent("org.foo.Baz")).isEqualTo("org/foo/Baz.java");
- assertThat(patternsInitializer.getPathForComponent("org.foo.Hello")).isEqualTo("org/foo/Hello.java");
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java
index b14cc76e4a3..d6c6f778b53 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssuePatternTest.java
@@ -22,18 +22,23 @@ package org.sonar.scanner.issue.ignore.pattern;
import org.junit.Test;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
-import org.sonar.api.scan.issue.filter.FilterableIssue;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
public class IssuePatternTest {
@Test
public void shouldMatchLines() {
- IssuePattern pattern = new IssuePattern("*", "*");
- pattern.addLine(12).addLine(15).addLineRange(20, 25);
+ Set<LineRange> lineRanges = new HashSet<>();
+ lineRanges.add(new LineRange(12));
+ lineRanges.add(new LineRange(15));
+ lineRanges.add(new LineRange(20, 25));
+
+ IssuePattern pattern = new IssuePattern("*", "*", lineRanges);
assertThat(pattern.matchLine(3)).isFalse();
assertThat(pattern.matchLine(12)).isTrue();
@@ -77,31 +82,17 @@ public class IssuePatternTest {
Rule rule = Rule.create("checkstyle", "IllegalRegexp", "");
String javaFile = "org.foo.Bar";
- IssuePattern pattern = new IssuePattern("*", "*");
- pattern.addLine(12);
-
- assertThat(pattern.match(create(rule, javaFile, null))).isFalse();
- assertThat(pattern.match(create(rule, javaFile, 12))).isTrue();
- assertThat(pattern.match(create(rule, null, null))).isFalse();
- }
+ IssuePattern pattern = new IssuePattern("*", "*", Collections.singleton(new LineRange(12)));
- private FilterableIssue create(Rule rule, String component, Integer line) {
- FilterableIssue mockIssue = mock(FilterableIssue.class);
- RuleKey ruleKey = null;
- if (rule != null) {
- ruleKey = rule.ruleKey();
- }
- when(mockIssue.ruleKey()).thenReturn(ruleKey);
- when(mockIssue.componentKey()).thenReturn(component);
- when(mockIssue.line()).thenReturn(line);
- return mockIssue;
+ assertThat(pattern.match(javaFile, rule.ruleKey(), null)).isFalse();
+ assertThat(pattern.match(javaFile, rule.ruleKey(), 12)).isTrue();
+ assertThat(pattern.match(null, rule.ruleKey(), null)).isFalse();
}
@Test
public void shouldPrintPatternToString() {
IssuePattern pattern = new IssuePattern("*", "checkstyle:*");
- assertThat(pattern.toString()).isEqualTo(
- "IssuePattern[resourcePattern=*,rulePattern=checkstyle:*,lines=[],lineRanges=[],beginBlockRegexp=<null>,endBlockRegexp=<null>,allFileRegexp=<null>,checkLines=true]");
+ assertThat(pattern.toString()).isEqualTo("IssuePattern[resourcePattern=*,rulePattern=checkstyle:*,lines=[],lineRanges=[],checkLines=false]");
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoderTest.java
index 056451fb3e2..f4ca8b9c745 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternDecoderTest.java
@@ -19,41 +19,12 @@
*/
package org.sonar.scanner.issue.ignore.pattern;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.SonarException;
-import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
import org.sonar.scanner.issue.ignore.pattern.PatternDecoder;
-import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class PatternDecoderTest {
-
- private PatternDecoder decoder = new PatternDecoder();
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Test
- public void shouldReadString() {
- String patternsList = "# a comment followed by a blank line\n\n" +
- "# suppress all violations\n" +
- "*;*;*\n\n" +
- "# exclude a Java file\n" +
- "com.foo.Bar;*;*\n\n" +
- "# exclude a Java package\n" +
- "com.foo.*;*;*\n\n" +
- "# exclude a specific rule\n" +
- "*;checkstyle:IllegalRegexp;*\n\n" +
- "# exclude a specific rule on a specific file\n" +
- "com.foo.Bar;checkstyle:IllegalRegexp;*\n";
- List<IssuePattern> patterns = decoder.decode(patternsList);
-
- assertThat(patterns).hasSize(5);
- }
-
@Test
public void shouldCheckFormatOfResource() {
assertThat(PatternDecoder.isResource("")).isFalse();
@@ -83,106 +54,4 @@ public class PatternDecoderTest {
assertThat(PatternDecoder.isLinesRange("[24-65]")).isTrue();
assertThat(PatternDecoder.isLinesRange("[13,24-65,84-89,122]")).isTrue();
}
-
- @Test
- public void shouldReadStarPatterns() {
- IssuePattern pattern = decoder.decodeLine("*;*;*");
-
- assertThat(pattern.getResourcePattern().toString()).isEqualTo("*");
- assertThat(pattern.getRulePattern().toString()).isEqualTo("*");
- assertThat(pattern.isCheckLines()).isFalse();
- }
-
- @Test
- public void shouldReadLineIds() {
- IssuePattern pattern = decoder.decodeLine("*;*;[10,25,98]");
-
- assertThat(pattern.isCheckLines()).isTrue();
- assertThat(pattern.getAllLines()).containsOnly(10, 25, 98);
- }
-
- @Test
- public void shouldReadRangeOfLineIds() {
- IssuePattern pattern = decoder.decodeLine("*;*;[10-12,25,97-100]");
-
- assertThat(pattern.isCheckLines()).isTrue();
- assertThat(pattern.getAllLines()).containsOnly(10, 11, 12, 25, 97, 98, 99, 100);
- }
-
- @Test
- public void shouldNotExcludeLines() {
- // [] is different than *
- // - all violations are excluded on *
- // * no violations are excluded on []
- IssuePattern pattern = decoder.decodeLine("*;*;[]");
-
- assertThat(pattern.isCheckLines()).isTrue();
- assertThat(pattern.getAllLines()).isEmpty();
- }
-
- @Test
- public void shouldReadBlockPattern() {
- IssuePattern pattern = decoder.decodeLine("SONAR-OFF;SONAR-ON");
-
- assertThat(pattern.getResourcePattern()).isNull();
- assertThat(pattern.getBeginBlockRegexp()).isEqualTo("SONAR-OFF");
- assertThat(pattern.getEndBlockRegexp()).isEqualTo("SONAR-ON");
- }
-
- @Test
- public void shouldReadAllFilePattern() {
- IssuePattern pattern = decoder.decodeLine("SONAR-ALL-OFF");
-
- assertThat(pattern.getResourcePattern()).isNull();
- assertThat(pattern.getAllFileRegexp()).isEqualTo("SONAR-ALL-OFF");
- }
-
- @Test
- public void shouldFailToReadUncorrectLine1() {
- thrown.expect(SonarException.class);
- thrown.expectMessage("Exclusions > Issues : Invalid format. The following line has more than 3 fields separated by comma");
-
- decoder.decode(";;;;");
- }
-
- @Test
- public void shouldFailToReadUncorrectLine3() {
- thrown.expect(SonarException.class);
- thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a resource pattern");
-
- decoder.decode(";*;*");
- }
-
- @Test
- public void shouldFailToReadUncorrectLine4() {
- thrown.expect(SonarException.class);
- thrown.expectMessage("Exclusions > Issues : Invalid format. The second field does not define a rule pattern");
-
- decoder.decode("*;;*");
- }
-
- @Test
- public void shouldFailToReadUncorrectLine5() {
- thrown.expect(SonarException.class);
- thrown.expectMessage("Exclusions > Issues : Invalid format. The third field does not define a range of lines");
-
- decoder.decode("*;*;blabla");
- }
-
- @Test
- public void shouldFailToReadUncorrectLine6() {
- thrown.expect(SonarException.class);
- thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a regular expression");
-
- decoder.decode(";ON");
- }
-
- @Test
- public void shouldAcceptEmptyEndBlockRegexp() {
- IssuePattern pattern = decoder.decodeLine("OFF;");
-
- assertThat(pattern.getResourcePattern()).isNull();
- assertThat(pattern.getBeginBlockRegexp()).isEqualTo("OFF");
- assertThat(pattern.getEndBlockRegexp()).isEmpty();
- }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcherTest.java
index 2025d0d1fd8..ea9cdb5606c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcherTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/PatternMatcherTest.java
@@ -19,22 +19,20 @@
*/
package org.sonar.scanner.issue.ignore.pattern;
-import org.sonar.api.scan.issue.filter.FilterableIssue;
import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
import org.sonar.scanner.issue.ignore.pattern.LineRange;
-import org.sonar.scanner.issue.ignore.pattern.PatternDecoder;
import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
+import java.util.Collections;
import java.util.Set;
+import javax.annotation.Nullable;
+
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class PatternMatcherTest {
@@ -72,51 +70,47 @@ public class PatternMatcherTest {
@Test
public void shouldHaveNoMatcherIfNoneDefined() {
- assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, null))).isNull();
+ assertThat(patternMatcher.getMatchingPattern(JAVA_FILE, CHECKSTYLE_RULE.ruleKey(), null)).isNull();
}
@Test
public void shouldMatchWithStandardPatterns() {
- patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello", "checkstyle:MagicNumber", createRanges(15, 200)));
- assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
+ assertThat(patternMatcher.getMatchingPattern(JAVA_FILE, CHECKSTYLE_RULE.ruleKey(), 150)).isNotNull();
}
@Test
public void shouldNotMatchWithStandardPatterns() {
- patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello", "checkstyle:MagicNumber", createRanges(15, 200)));
- assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
+ assertThat(patternMatcher.getMatchingPattern(JAVA_FILE, CHECKSTYLE_RULE.ruleKey(), 5)).isNull();
}
@Test
public void shouldMatchWithExtraPattern() {
- patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello", "*", createRanges(15, 200)));
- assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
+ assertThat(patternMatcher.getMatchingPattern(JAVA_FILE, CHECKSTYLE_RULE.ruleKey(), 150)).isNotNull();
}
@Test
public void shouldNotMatchWithExtraPattern() {
- patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello", "*", createRanges(15, 200)));
- assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
+ assertThat(patternMatcher.getMatchingPattern(JAVA_FILE, CHECKSTYLE_RULE.ruleKey(), 5)).isNull();
}
- private FilterableIssue create(Rule rule, String component, Integer line) {
- FilterableIssue mockIssue = mock(FilterableIssue.class);
- RuleKey ruleKey = null;
- if (rule != null) {
- ruleKey = rule.ruleKey();
+ private IssuePattern createPattern(String resourcePattern, String rulePattern, @Nullable Set<LineRange> lineRanges) {
+ if (lineRanges != null) {
+ return new IssuePattern(resourcePattern, rulePattern, lineRanges);
+ } else {
+ return new IssuePattern(resourcePattern, rulePattern);
}
- when(mockIssue.ruleKey()).thenReturn(ruleKey);
- when(mockIssue.componentKey()).thenReturn(component);
- when(mockIssue.line()).thenReturn(line);
- return mockIssue;
}
- private IssuePattern createPattern(String line) {
- return new PatternDecoder().decode(line).get(0);
+ private Set<LineRange> createRanges(int from, int to) {
+ return Collections.singleton(new LineRange(from, to));
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java
index 1c2922c2141..638e504b6ce 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java
@@ -20,31 +20,23 @@
package org.sonar.scanner.issue.ignore.scanner;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
-import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
-import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
public class IssueExclusionsLoaderTest {
@@ -52,31 +44,18 @@ public class IssueExclusionsLoaderTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Mock
- private IssueExclusionsRegexpScanner regexpScanner;
-
- @Mock
- private IssueInclusionPatternInitializer inclusionPatternInitializer;
-
@Mock
private IssueExclusionPatternInitializer exclusionPatternInitializer;
- @Mock
private PatternMatcher patternMatcher;
- private DefaultFileSystem fs;
private IssueExclusionsLoader scanner;
- private Path baseDir;
@Before
public void before() throws Exception {
- baseDir = temp.newFolder().toPath();
- fs = new DefaultFileSystem(baseDir).setEncoding(UTF_8);
+ patternMatcher = new PatternMatcher();
MockitoAnnotations.initMocks(this);
- scanner = new IssueExclusionsLoader(regexpScanner, exclusionPatternInitializer, inclusionPatternInitializer, fs);
+ scanner = new IssueExclusionsLoader(exclusionPatternInitializer, patternMatcher);
}
@Test
@@ -85,108 +64,55 @@ public class IssueExclusionsLoaderTest {
}
@Test
- public void shouldExecute() {
- when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
- when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
- assertThat(scanner.shouldExecute()).isTrue();
+ public void createComputer() {
+ assertThat(scanner.createCharHandlerFor("src/main/java/Foo.java")).isNull();
- when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
- when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
- assertThat(scanner.shouldExecute()).isTrue();
+ when(exclusionPatternInitializer.getAllFilePatterns()).thenReturn(Collections.singletonList("pattern"));
+ scanner = new IssueExclusionsLoader(exclusionPatternInitializer, patternMatcher);
+ assertThat(scanner.createCharHandlerFor("src/main/java/Foo.java")).isNotNull();
- when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
- when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
- assertThat(scanner.shouldExecute()).isTrue();
- when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
- when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
- assertThat(scanner.shouldExecute()).isFalse();
}
@Test
- public void shouldAnalyzeProject() throws IOException {
- Path javaFile1 = baseDir.resolve("src/main/java/Foo.java");
- fs.add(new TestInputFileBuilder("polop", "src/main/java/Foo.java")
- .setModuleBaseDir(baseDir)
- .setCharset(StandardCharsets.UTF_8)
- .setType(InputFile.Type.MAIN)
- .build());
- Path javaTestFile1 = baseDir.resolve("src/test/java/FooTest.java");
- fs.add(new TestInputFileBuilder("polop", "src/test/java/FooTest.java")
- .setModuleBaseDir(baseDir)
- .setCharset(StandardCharsets.UTF_8)
- .setType(InputFile.Type.TEST)
- .build());
-
- when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
-
- scanner.preLoadAllFiles();
-
- verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
- verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
- verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
- verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
- verify(regexpScanner).scan("polop:src/main/java/Foo.java", javaFile1, UTF_8);
- verify(regexpScanner).scan("polop:src/test/java/FooTest.java", javaTestFile1, UTF_8);
- }
-
- @Test
- public void isLoaded() {
- DefaultInputFile inputFile1 = new TestInputFileBuilder("polop", "src/test/java/FooTest1.java")
- .setModuleBaseDir(baseDir)
- .setCharset(StandardCharsets.UTF_8)
- .setType(InputFile.Type.TEST)
- .build();
- DefaultInputFile inputFile2 = new TestInputFileBuilder("polop", "src/test/java/FooTest2.java")
- .setModuleBaseDir(baseDir)
- .setCharset(StandardCharsets.UTF_8)
- .setType(InputFile.Type.TEST)
- .build();
-
- when(inclusionPatternInitializer.getPathForComponent(inputFile1.key())).thenReturn(null);
- when(inclusionPatternInitializer.getPathForComponent(inputFile2.key())).thenReturn("path1");
-
- assertFalse(scanner.isLoaded(inputFile1));
- assertTrue(scanner.isLoaded(inputFile2));
-
+ public void shouldHavePatternsBasedOnMulticriteriaPattern() {
+ IssuePattern pattern1 = new IssuePattern("org/foo/Bar.java", "*");
+ IssuePattern pattern2 = new IssuePattern("org/foo/Hello.java", "checkstyle:MagicNumber");
+ when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(Arrays.asList(new IssuePattern[] {pattern1, pattern2}));
+
+ IssueExclusionsLoader loader = new IssueExclusionsLoader(exclusionPatternInitializer, patternMatcher);
+ loader.addMulticriteriaPatterns("org/foo/Bar.java", "org.foo.Bar");
+ loader.addMulticriteriaPatterns("org/foo/Baz.java", "org.foo.Baz");
+ loader.addMulticriteriaPatterns("org/foo/Hello.java", "org.foo.Hello");
+
+ assertThat(patternMatcher.getPatternsForComponent("org.foo.Bar")).hasSize(1);
+ assertThat(patternMatcher.getPatternsForComponent("org.foo.Baz")).hasSize(0);
+ assertThat(patternMatcher.getPatternsForComponent("org.foo.Hello")).hasSize(1);
}
@Test
- public void shouldAnalyseFilesOnlyWhenRegexConfigured() {
- fs.add(new TestInputFileBuilder("polop", "src/main/java/Foo.java")
- .setType(InputFile.Type.MAIN)
- .setCharset(StandardCharsets.UTF_8)
- .build());
- fs.add(new TestInputFileBuilder("polop", "src/test/java/FooTest.java")
- .setType(InputFile.Type.TEST)
- .setCharset(StandardCharsets.UTF_8)
- .build());
- when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false);
-
- scanner.preLoadAllFiles();
-
- verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
- verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
- verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
- verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
- verifyZeroInteractions(regexpScanner);
+ public void shouldAnalyzeProject() throws IOException {
+ IssuePattern pattern = new IssuePattern("**", "*");
+ when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(Collections.singletonList(pattern));
+ when(exclusionPatternInitializer.hasMulticriteriaPatterns()).thenReturn(true);
+
+ PatternMatcher patternMatcher = mock(PatternMatcher.class);
+ IssueExclusionsLoader loader = new IssueExclusionsLoader(exclusionPatternInitializer, patternMatcher);
+ assertThat(loader.shouldExecute()).isTrue();
+ loader.addMulticriteriaPatterns("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
+ loader.addMulticriteriaPatterns("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
+
+ verify(patternMatcher).addPatternForComponent("polop:src/main/java/Foo.java", pattern);
+ verify(patternMatcher).addPatternForComponent("polop:src/test/java/FooTest.java", pattern);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
- public void shouldReportFailure() throws IOException {
- Path phpFile1 = baseDir.resolve("src/Foo.php");
- fs.add(new TestInputFileBuilder("polop", "src/Foo.php")
- .setModuleBaseDir(baseDir)
- .setType(InputFile.Type.MAIN)
- .setCharset(StandardCharsets.UTF_8)
- .build());
-
- when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
- doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8);
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Unable to read the source file");
+ public void shouldExecute() {
+ when(exclusionPatternInitializer.hasMulticriteriaPatterns()).thenReturn(true);
+ assertThat(scanner.shouldExecute()).isTrue();
- scanner.preLoadAllFiles();
+ when(exclusionPatternInitializer.hasMulticriteriaPatterns()).thenReturn(false);
+ assertThat(scanner.shouldExecute()).isFalse();
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
index 55581e74adc..37c2b957b65 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
@@ -19,150 +19,146 @@
*/
package org.sonar.scanner.issue.ignore.scanner;
-import com.google.common.collect.Sets;
import com.google.common.io.Resources;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
-import org.sonar.scanner.issue.ignore.pattern.IssuePattern;
import org.sonar.scanner.issue.ignore.pattern.LineRange;
import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsRegexpScanner;
+import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader.DoubleRegexpMatcher;
+
+import java.net.URISyntaxException;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import java.util.regex.Pattern;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
public class IssueExclusionsRegexpScannerTest {
-
- private IssueExclusionsRegexpScanner regexpScanner;
-
private String javaFile;
+
@Mock
private IssueExclusionPatternInitializer patternsInitializer;
@Mock
private PatternMatcher patternMatcher;
- @Mock
- private IssuePattern allFilePattern;
- @Mock
- private IssuePattern blockPattern1;
- @Mock
- private IssuePattern blockPattern2;
+
+ private List<Pattern> allFilePatterns;
+ private List<DoubleRegexpMatcher> blockPatterns;
+ private IssueExclusionsRegexpScanner regexpScanner;
+ private FileMetadata fileMetadata = new FileMetadata();
@Before
public void init() {
MockitoAnnotations.initMocks(this);
- when(allFilePattern.getAllFileRegexp()).thenReturn("@SONAR-IGNORE-ALL");
- when(blockPattern1.getBeginBlockRegexp()).thenReturn("// SONAR-OFF");
- when(blockPattern1.getEndBlockRegexp()).thenReturn("// SONAR-ON");
- when(blockPattern2.getBeginBlockRegexp()).thenReturn("// FOO-OFF");
- when(blockPattern2.getEndBlockRegexp()).thenReturn("// FOO-ON");
- when(patternsInitializer.getAllFilePatterns()).thenReturn(Arrays.asList(allFilePattern));
- when(patternsInitializer.getBlockPatterns()).thenReturn(Arrays.asList(blockPattern1, blockPattern2));
- when(patternsInitializer.getPatternMatcher()).thenReturn(patternMatcher);
-
- regexpScanner = new IssueExclusionsRegexpScanner(patternsInitializer);
- verify(patternsInitializer, times(1)).getAllFilePatterns();
- verify(patternsInitializer, times(1)).getBlockPatterns();
+ blockPatterns = Arrays.asList(new DoubleRegexpMatcher[] {
+ new DoubleRegexpMatcher(Pattern.compile("// SONAR-OFF"), Pattern.compile("// SONAR-ON")),
+ new DoubleRegexpMatcher(Pattern.compile("// FOO-OFF"), Pattern.compile("// FOO-ON"))
+ });
+ allFilePatterns = Collections.singletonList(Pattern.compile("@SONAR-IGNORE-ALL"));
javaFile = "org.sonar.test.MyFile";
+ regexpScanner = new IssueExclusionsRegexpScanner(javaFile, allFilePatterns, blockPatterns, patternMatcher);
+ }
+
+ @Test
+ public void shouldDetectPatternLastLine() throws URISyntaxException {
+ fileMetadata.readMetadata(getResource("file-with-single-regexp-last-line.txt").toFile(), UTF_8, regexpScanner);
+
+ verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldDoNothing() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-no-regexp.txt").toURI()), UTF_8);
-
- verifyNoMoreInteractions(patternsInitializer);
+ fileMetadata.readMetadata(getResource("file-with-no-regexp.txt").toFile(), UTF_8, regexpScanner);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeFile() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt").toURI()), UTF_8);
+ fileMetadata.readMetadata(getResource("file-with-single-regexp.txt").toFile(), UTF_8, regexpScanner);
- verify(patternsInitializer).getPatternMatcher();
verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
- verifyNoMoreInteractions(patternsInitializer);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeFileEvenIfAlsoDoubleRegexps() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-and-double-regexp.txt").toURI()), UTF_8);
+ fileMetadata.readMetadata(getResource("file-with-single-regexp-and-double-regexp.txt").toFile(), UTF_8, regexpScanner);
- verify(patternsInitializer).getPatternMatcher();
+ Set<LineRange> lineRanges = new HashSet<>();
+ lineRanges.add(new LineRange(5, 26));
verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
- verifyNoMoreInteractions(patternsInitializer);
+ verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeLines() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp.txt").toURI()), UTF_8);
+ fileMetadata.readMetadata(getResource("file-with-double-regexp.txt").toFile(), UTF_8, regexpScanner);
- Set<LineRange> lineRanges = Sets.newHashSet();
+ Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 25));
- verify(patternsInitializer).getPatternMatcher();
verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
- verifyNoMoreInteractions(patternsInitializer);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeLinesTillTheEnd() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-unfinished.txt").toURI()), UTF_8);
+ fileMetadata.readMetadata(getResource("file-with-double-regexp-unfinished.txt").toFile(), UTF_8, regexpScanner);
- Set<LineRange> lineRanges = Sets.newHashSet();
+ Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 34));
- verify(patternsInitializer).getPatternMatcher();
verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
- verifyNoMoreInteractions(patternsInitializer);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeSeveralLineRanges() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-twice.txt").toURI()), UTF_8);
+ fileMetadata.readMetadata(getResource("file-with-double-regexp-twice.txt").toFile(), UTF_8, regexpScanner);
- Set<LineRange> lineRanges = Sets.newHashSet();
+ Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 25));
lineRanges.add(new LineRange(29, 33));
- verify(patternsInitializer).getPatternMatcher();
verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
- verifyNoMoreInteractions(patternsInitializer);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeLinesWithWrongOrder() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-wrong-order.txt").toURI()), UTF_8);
+ fileMetadata.readMetadata(getResource("file-with-double-regexp-wrong-order.txt").toFile(), UTF_8, regexpScanner);
- Set<LineRange> lineRanges = Sets.newHashSet();
+ Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(25, 35));
- verify(patternsInitializer).getPatternMatcher();
verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
- verifyNoMoreInteractions(patternsInitializer);
+ verifyNoMoreInteractions(patternMatcher);
}
@Test
public void shouldAddPatternToExcludeLinesWithMess() throws Exception {
- regexpScanner.scan(javaFile, Paths.get(Resources.getResource(
- "org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-mess.txt").toURI()), UTF_8);
+ fileMetadata.readMetadata(getResource("file-with-double-regexp-mess.txt").toFile(), UTF_8, regexpScanner);
- Set<LineRange> lineRanges = Sets.newHashSet();
+ Set<LineRange> lineRanges = new HashSet<>();
lineRanges.add(new LineRange(21, 29));
- verify(patternsInitializer).getPatternMatcher();
verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
- verifyNoMoreInteractions(patternsInitializer);
+ verifyNoMoreInteractions(patternMatcher);
+ }
+
+ private Path getResource(String fileName) throws URISyntaxException {
+ return Paths.get(Resources.getResource("org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/" + fileName).toURI());
}
}
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 6f569def502..d14f205ed8a 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
@@ -349,8 +349,8 @@ public class FileSystemMediumTest {
.start();
assertThat(logs.getAllAsString()).containsOnlyOnce("'src/myfile.binary' indexed with language 'null'");
- assertThat(logs.getAllAsString()).doesNotContain("Scanning com.foo.project:src/myfile.binary");
- assertThat(logs.getAllAsString()).containsOnlyOnce("Scanning com.foo.project:src/sample.xoo");
+ assertThat(logs.getAllAsString()).doesNotContain("'src/myfile.binary' generating issue exclusions");
+ assertThat(logs.getAllAsString()).containsOnlyOnce("'src/sample.xoo' generating issue exclusions");
tester2.stop();
@@ -366,7 +366,7 @@ public class FileSystemMediumTest {
srcDir.mkdir();
File xooFile = new File(srcDir, "sample.xoo");
- FileUtils.write(xooFile, "Sample xoo\ncontent");
+ FileUtils.write(xooFile, "Sample xoo\npattern");
File unknownFile = new File(srcDir, "myfile.binary");
FileUtils.write(unknownFile, "some text");
@@ -376,8 +376,9 @@ public class FileSystemMediumTest {
.put("sonar.sources", "src")
.build())
.start();
-
- assertThat(logs.getAllAsString()).containsOnlyOnce("Scanning com.foo.project:src/myfile.binary");
+
+ assertThat(logs.getAllAsString()).containsOnlyOnce("- Exclusion pattern 'pattern'");
+ assertThat(logs.getAllAsString()).containsOnlyOnce("'src/myfile.binary' generating issue exclusions");
}
@Test
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java
index 965540c1047..c9c7312fab5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java
@@ -23,6 +23,9 @@ import org.junit.Test;
import org.mockito.Mockito;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
+import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -31,8 +34,9 @@ public class MetadataGeneratorProviderTest {
@Test
public void create_builder() {
StatusDetectionFactory statusDetectionFactory = mock(StatusDetectionFactory.class, Mockito.RETURNS_MOCKS);
+ IssueExclusionsLoader issueExclusionsLoader = new IssueExclusionsLoader(mock(IssueExclusionPatternInitializer.class), mock(PatternMatcher.class));
MetadataGeneratorProvider factory = new MetadataGeneratorProvider();
- assertThat(factory.provide(new DefaultInputModule("module"), statusDetectionFactory, new FileMetadata())).isNotNull();
+ assertThat(factory.provide(new DefaultInputModule("module"), statusDetectionFactory, new FileMetadata(), issueExclusionsLoader)).isNotNull();
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
index 9fddf40b8e1..67b455a9986 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
@@ -20,6 +20,7 @@
package org.sonar.scanner.scan.filesystem;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.nio.charset.StandardCharsets;
@@ -40,6 +41,9 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.utils.PathUtils;
+import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.scanner.issue.ignore.pattern.PatternMatcher;
+import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader;
public class MetadataGeneratorTest {
@Rule
@@ -57,7 +61,8 @@ public class MetadataGeneratorTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
metadata = new FileMetadata();
- generator = new MetadataGenerator(new DefaultInputModule("module"), statusDetection, metadata);
+ IssueExclusionsLoader issueExclusionsLoader = new IssueExclusionsLoader(mock(IssueExclusionPatternInitializer.class), mock(PatternMatcher.class));
+ generator = new MetadataGenerator(new DefaultInputModule("module"), statusDetection, metadata, issueExclusionsLoader);
}
@Test
diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt
new file mode 100644
index 00000000000..ef135ebc50c
--- /dev/null
+++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-last-line.txt
@@ -0,0 +1,33 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * @SONAR-IGNORE-ALL
+ */
+public class LineRange {
+ int from, to;
+
+ public LineRange(int from, int to) {
+ if (to < from) {
+ throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+ }
+ this.from = from;
+ this.to = to;
+ }
+
+ public boolean in(int lineId) {
+ return from <= lineId && lineId <= to;
+ }
+
+ public Set<Integer> toLines() {
+ Set<Integer> lines = Sets.newLinkedHashSet();
+ for (int index = from; index <= to; index++) {
+ lines.add(index);
+ }
+ return lines;
+ }
+
+} \ No newline at end of file
diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt
index ef135ebc50c..88ad675955f 100644
--- a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt
+++ b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt
@@ -4,9 +4,6 @@ import com.google.common.collect.Sets;
import java.util.Set;
-/**
- * @SONAR-IGNORE-ALL
- */
public class LineRange {
int from, to;
@@ -30,4 +27,5 @@ public class LineRange {
return lines;
}
-} \ No newline at end of file
+}
+// @SONAR-IGNORE-ALL \ No newline at end of file