Skip to content
This repository has been archived by the owner on Apr 6, 2022. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-24011] Apply include/exclude filters after path expans…
…ion.

Also use JenkinsRule for all integration tests.
  • Loading branch information
uhafner committed Sep 21, 2014
1 parent 59b9da7 commit 4f2bbc2
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 136 deletions.
20 changes: 16 additions & 4 deletions src/main/java/hudson/plugins/warnings/WarningsPublisher.java
Expand Up @@ -36,6 +36,7 @@
import hudson.plugins.warnings.parser.FileWarningsParser;
import hudson.plugins.warnings.parser.ParserRegistry;
import hudson.plugins.warnings.parser.ParsingCanceledException;
import hudson.plugins.warnings.parser.WarningsFilter;

/**
* Publishes the results of the warnings analysis (freestyle project type).
Expand Down Expand Up @@ -396,17 +397,28 @@ private List<ParserResult> parseConsoleLog(final AbstractBuild<?, ?> build,
logger.log("Parsing warnings in console log with parser " + parserName);

Collection<FileAnnotation> warnings = new ParserRegistry(ParserRegistry.getParsers(parserName),
getDefaultEncoding(), getIncludePattern(), getExcludePattern()).parse(build.getLogFile());
getDefaultEncoding()).parse(build.getLogFile());
if (!build.getWorkspace().isRemote()) {
guessModuleNames(build, warnings);
}
ParserResult project = new ParserResult(build.getWorkspace(), canResolveRelativePaths());
project.addAnnotations(warnings);
results.add(annotate(build, project, parserName));

results.add(annotate(build, filterWarnings(project, logger), parserName));
}
return results;
}

private ParserResult filterWarnings(final ParserResult project, final PluginLogger logger) {
WarningsFilter filter = new WarningsFilter();
if (filter.isActive(getIncludePattern(), getExcludePattern())) {
Collection<FileAnnotation> filtered = filter.apply(project.getAnnotations(),
getIncludePattern(), getExcludePattern(), logger);
return new ParserResult(filtered);
}
return project;
}

private void guessModuleNames(final AbstractBuild<?, ?> build, final Collection<FileAnnotation> warnings) {
String workspace = build.getWorkspace().getRemote();
ModuleDetector detector = createModuleDetector(workspace);
Expand All @@ -426,13 +438,13 @@ private List<ParserResult> parseFiles(final AbstractBuild<?, ?> build, final Plu
logger.log("Parsing warnings in files '" + filePattern + "' with parser " + parserName);

FilesParser parser = new FilesParser(PLUGIN_NAME, filePattern,
new FileWarningsParser(ParserRegistry.getParsers(parserName), getDefaultEncoding(), getIncludePattern(), getExcludePattern()),
new FileWarningsParser(ParserRegistry.getParsers(parserName), getDefaultEncoding()),
shouldDetectModules(), isMavenBuild(build), canResolveRelativePaths());
ParserResult project = build.getWorkspace().act(parser);
logger.logLines(project.getLogMessages());

returnIfCanceled();
results.add(annotate(build, project, configuration.getParserName()));
results.add(annotate(build, filterWarnings(project, logger), configuration.getParserName()));
}
return results;
}
Expand Down
Expand Up @@ -17,11 +17,6 @@
public class FileWarningsParser implements AnnotationParser {
private static final long serialVersionUID = -262047528431480332L;

/** Ant file-set pattern of files to include in report. */
private final String includePattern;
/** Ant file-set pattern of files to exclude from report. */
private final String excludePattern;

/** The parsers to scan the files with. */
@edu.umd.cs.findbugs.annotations.SuppressWarnings("Se")
private final List<AbstractWarningsParser> parsers;
Expand All @@ -35,22 +30,16 @@ public class FileWarningsParser implements AnnotationParser {
* the parsers to scan the files with
* @param defaultEncoding
* the default encoding to be used when reading and parsing files
* @param includePattern
* ant file-set pattern of files to include in report
* @param excludePattern
* ant file-set pattern of files to exclude from report
*/
public FileWarningsParser(final List<AbstractWarningsParser> parsers, final String defaultEncoding, final String includePattern, final String excludePattern) {
public FileWarningsParser(final List<AbstractWarningsParser> parsers, final String defaultEncoding) {
this.parsers = parsers;
this.includePattern = includePattern;
this.excludePattern = excludePattern;
this.defaultEncoding = defaultEncoding;
}

@Override
public Collection<FileAnnotation> parse(final File file, final String moduleName) throws InvocationTargetException {
try {
Collection<FileAnnotation> annotations = new ParserRegistry(parsers, defaultEncoding, includePattern, excludePattern).parse(file);
Collection<FileAnnotation> annotations = new ParserRegistry(parsers, defaultEncoding).parse(file);
for (FileAnnotation annotation : annotations) {
annotation.setModuleName(moduleName);
}
Expand Down
85 changes: 4 additions & 81 deletions src/main/java/hudson/plugins/warnings/parser/ParserRegistry.java
@@ -1,5 +1,6 @@
package hudson.plugins.warnings.parser; // NOPMD

import javax.annotation.CheckForNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
Expand All @@ -14,9 +15,6 @@
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.regex.Pattern;

import javax.annotation.CheckForNull;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
Expand All @@ -27,15 +25,13 @@
import com.google.common.collect.Sets;

import hudson.model.Hudson;

import hudson.plugins.analysis.core.PluginDescriptor;
import hudson.plugins.analysis.util.EncodingValidator;
import hudson.plugins.analysis.util.NullLogger;
import hudson.plugins.analysis.util.PluginLogger;
import hudson.plugins.analysis.util.model.FileAnnotation;
import hudson.plugins.warnings.WarningsDescriptor;
import hudson.plugins.warnings.GroovyParser;

import hudson.plugins.warnings.WarningsDescriptor;
import hudson.util.ListBoxModel;

/**
Expand All @@ -47,8 +43,6 @@
public class ParserRegistry {
private final List<AbstractWarningsParser> parsers;
private final Charset defaultCharset;
private final Set<Pattern> includePatterns = Sets.newHashSet();
private final Set<Pattern> excludePatterns = Sets.newHashSet();

/**
* Returns all warning parsers registered by extension points
Expand Down Expand Up @@ -245,43 +239,11 @@ static List<AbstractWarningsParser> getDynamicParsers(final Iterable<GroovyParse
* the default encoding to be used when reading and parsing files
*/
public ParserRegistry(final List<? extends AbstractWarningsParser> parsers, final String defaultEncoding) {
this(parsers, defaultEncoding, StringUtils.EMPTY, StringUtils.EMPTY);
}

/**
* Creates a new instance of <code>ParserRegistry</code>.
*
* @param parsers
* the parsers to use when scanning a file
* @param includePattern
* Ant file-set pattern of files to include in report,
* <code>null</code> or an empty string do not filter the output
* @param excludePattern
* Ant file-set pattern of files to exclude from report,
* <code>null</code> or an empty string do not filter the output
* @param defaultEncoding
* the default encoding to be used when reading and parsing files
*/
public ParserRegistry(final List<? extends AbstractWarningsParser> parsers, final String defaultEncoding,
final String includePattern, final String excludePattern) {
defaultCharset = EncodingValidator.defaultCharset(defaultEncoding);
this.parsers = new ArrayList<AbstractWarningsParser>(parsers);
if (this.parsers.isEmpty()) {
this.parsers.addAll(getAllParsers());
}
addPatterns(includePatterns, includePattern);
addPatterns(excludePatterns, excludePattern);
}

private void addPatterns(final Set<Pattern> patterns, final String pattern) {
if (StringUtils.isNotBlank(pattern)) {
String[] split = StringUtils.split(pattern, ',');
for (String singlePattern : split) {
String trimmed = StringUtils.trim(singlePattern);
String directoriesReplaced = StringUtils.replace(trimmed, "**", "*"); // NOCHECKSTYLE
patterns.add(Pattern.compile(StringUtils.replace(directoriesReplaced, "*", ".*"))); // NOCHECKSTYLE
}
}
}

/**
Expand Down Expand Up @@ -323,7 +285,7 @@ public Collection<FileAnnotation> parse(final File file, final PluginLogger logg
IOUtils.closeQuietly(input);
}
}
return applyExcludeFilter(allAnnotations, logger);
return allAnnotations;
}

/**
Expand All @@ -341,52 +303,13 @@ public Set<FileAnnotation> parse(final InputStream file) throws IOException {
for (AbstractWarningsParser parser : parsers) {
allAnnotations.addAll(parser.parse(createReader(file)));
}
return applyExcludeFilter(allAnnotations, new NullLogger());
return allAnnotations;
}
finally {
IOUtils.closeQuietly(file);
}
}

/**
* Applies the exclude filter to the found annotations.
*
* @param allAnnotations
* all annotations
* @return the filtered annotations if there is a filter defined
*/
private Set<FileAnnotation> applyExcludeFilter(final Set<FileAnnotation> allAnnotations, final PluginLogger logger) {
Set<FileAnnotation> includedAnnotations;
if (includePatterns.isEmpty()) {
includedAnnotations = allAnnotations;
}
else {
includedAnnotations = Sets.newHashSet();
for (FileAnnotation annotation : allAnnotations) {
for (Pattern include : includePatterns) {
if (include.matcher(annotation.getFileName()).matches()) {
includedAnnotations.add(annotation);
}
}
}
}
if (excludePatterns.isEmpty()) {
return includedAnnotations;
}
else {
Set<FileAnnotation> excludedAnnotations = Sets.newHashSet(includedAnnotations);
for (FileAnnotation annotation : includedAnnotations) {
for (Pattern exclude : excludePatterns) {
if (exclude.matcher(annotation.getFileName()).matches()) {
excludedAnnotations.remove(annotation);
}
}
}
logger.log(String.format("Found %d warnings after exclusion.", excludedAnnotations.size()));
return excludedAnnotations;
}
}

/**
* Creates a reader from the specified file. Uses the defined character set to
* read the content of the input stream.
Expand Down
91 changes: 91 additions & 0 deletions src/main/java/hudson/plugins/warnings/parser/WarningsFilter.java
@@ -0,0 +1,91 @@
package hudson.plugins.warnings.parser;

import javax.annotation.CheckForNull;
import java.util.Collection;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

import com.google.common.collect.Sets;

import hudson.plugins.analysis.util.PluginLogger;
import hudson.plugins.analysis.util.model.FileAnnotation;

/**
* Filters warnings by exclude and include patterns.
*
* @author Ullrich Hafner
*/
public class WarningsFilter {
private final Set<Pattern> includePatterns = Sets.newHashSet();
private final Set<Pattern> excludePatterns = Sets.newHashSet();

private Set<Pattern> addPatterns(final @CheckForNull String pattern) {
Set<Pattern> patterns = Sets.newHashSet();
if (StringUtils.isNotBlank(pattern)) {
String[] split = StringUtils.split(pattern, ',');
for (String singlePattern : split) {
String trimmed = StringUtils.trim(singlePattern);
String directoriesReplaced = StringUtils.replace(trimmed, "**", "*"); // NOCHECKSTYLE
patterns.add(Pattern.compile(StringUtils.replace(directoriesReplaced, "*", ".*"))); // NOCHECKSTYLE
}
}
return patterns;
}

/**
* Filters te specified warnings by exclude and include patterns.
*
* @param allAnnotations
* all annotations
* @param includePattern
* regexp pattern of files to include in report,
* <code>null</code> or an empty string do not filter the output
* @param excludePattern
* regexp pattern of files to exclude from report,
* <code>null</code> or an empty string do not filter the output
* @return the filtered annotations if there is a filter defined
*/
public Collection<FileAnnotation> apply(final Collection<FileAnnotation> allAnnotations,
final @CheckForNull String includePattern,
final @CheckForNull String excludePattern,
final PluginLogger logger) {
Collection<Pattern> includePatterns = addPatterns(includePattern);
Collection<Pattern> excludePatterns = addPatterns(excludePattern);

Collection<FileAnnotation> includedAnnotations;
if (includePatterns.isEmpty()) {
includedAnnotations = allAnnotations;
}
else {
includedAnnotations = Sets.newHashSet();
for (FileAnnotation annotation : allAnnotations) {
for (Pattern include : includePatterns) {
if (include.matcher(annotation.getFileName()).matches()) {
includedAnnotations.add(annotation);
}
}
}
}
if (excludePatterns.isEmpty()) {
return includedAnnotations;
}
else {
Set<FileAnnotation> excludedAnnotations = Sets.newHashSet(includedAnnotations);
for (FileAnnotation annotation : includedAnnotations) {
for (Pattern exclude : excludePatterns) {
if (exclude.matcher(annotation.getFileName()).matches()) {
excludedAnnotations.remove(annotation);
}
}
}
logger.log(String.format("Found %d warnings after exclusion.", excludedAnnotations.size()));
return excludedAnnotations;
}
}

public boolean isActive(final String includePattern, final String excludePattern) {
return StringUtils.isNotBlank(includePattern) || StringUtils.isNotBlank(excludePattern);
}
}
12 changes: 8 additions & 4 deletions src/test/java/hudson/plugins/warnings/ConsoleParserTest.java
@@ -1,20 +1,24 @@
package hudson.plugins.warnings;

import static org.junit.Assert.*;

import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.JenkinsRule;

import com.google.common.collect.Lists;

import static org.junit.Assert.*;

import hudson.plugins.warnings.parser.JavacParser;

/**
* Tests the class {@link ConsoleParser}.
*
* @author Ulli Hafner
*/
public class ConsoleParserTest extends HudsonTestCase {
public class ConsoleParserTest {
@Rule
public JenkinsRule jenkins = new JenkinsRule();

/**
* Verifies that filtering of non-existing parsers works.
*/
Expand Down
@@ -1,22 +1,26 @@
package hudson.plugins.warnings;

import static org.junit.Assert.*;

import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.JenkinsRule;

import com.google.common.collect.Lists;

import static org.junit.Assert.*;

import hudson.plugins.warnings.parser.JavacParser;

/**
* Tests the class {@link ParserConfiguration}.
*
* @author Ulli Hafner
*/
public class ParserConfigurationTest extends HudsonTestCase {
public class ParserConfigurationTest {
private static final String PATTERN = "**/*.java";

@Rule
public JenkinsRule jenkins = new JenkinsRule();

/**
* Verifies that filtering of non-existing parsers works.
*/
Expand Down

0 comments on commit 4f2bbc2

Please sign in to comment.