Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
[JENKINS-9090] Added project configuration option to activate
scanning of workspace for build.xml and pom.xml files to detect
the module names of warnings.
  • Loading branch information
uhafner committed Apr 7, 2011
1 parent 325c962 commit 0c4c162be8819627b0526bfd182eb60992fc0d98
Showing 9 changed files with 127 additions and 23 deletions.
2 go.sh
@@ -4,4 +4,4 @@ mvn install
cp -f target/analysis-core.hpi $HUDSON_HOME/plugins/

cd $HUDSON_HOME
java -jar hudson.war
java -jar jenkins.war
@@ -3,21 +3,16 @@
import java.io.File;
import java.io.IOException;

import org.apache.commons.lang.StringUtils;

import hudson.FilePath.FileCallable;

import hudson.plugins.analysis.util.ContextHashCode;
import hudson.plugins.analysis.util.ModuleDetector;
import hudson.plugins.analysis.util.model.FileAnnotation;

import hudson.remoting.VirtualChannel;

/**
* Scans the workspace for maven pom.xml files and ant build.xml files and maps
* all annotations to corresponding modules. Additionally, the content of each
* file with warnings is read and a hash code of the warning is created to
* enable a more flexible new and fixed warnings detection.
* Reads the content of each file with warnings and creates a unique hash code
* of the warning to enable a more flexible new and fixed warnings detection.
*
* @author Ulli Hafner
*/
@@ -44,13 +39,9 @@ public AnnotationsClassifier(final ParserResult result, final String defaultEnco

/** {@inheritDoc} */
public ParserResult invoke(final File workspace, final VirtualChannel channel) throws IOException {
ModuleDetector detector = new ModuleDetector(workspace);
ContextHashCode contextHashCode = new ContextHashCode();
for (FileAnnotation annotation : result.getAnnotations()) {
try {
if (StringUtils.isBlank(annotation.getModuleName())) {
annotation.setModuleName(detector.guessModuleName(annotation.getFileName()));
}
annotation.setContextHashCode(contextHashCode.create(
annotation.getFileName(), annotation.getPrimaryLineNumber(), defaultEncoding));
}
@@ -60,5 +51,4 @@ public ParserResult invoke(final File workspace, final VirtualChannel channel) t
}
return result;
}

}
@@ -15,6 +15,7 @@
import hudson.plugins.analysis.Messages;
import hudson.plugins.analysis.util.FileFinder;
import hudson.plugins.analysis.util.ModuleDetector;
import hudson.plugins.analysis.util.NullModuleDetector;
import hudson.plugins.analysis.util.PluginLogger;
import hudson.plugins.analysis.util.model.FileAnnotation;

@@ -42,6 +43,8 @@ public class FilesParser implements FileCallable<ParserResult> {
private final boolean isAntBuild;
/** The predefined module name, might be empty. */
private final String moduleName;
/** Determines whether module names should be derived from Maven or Ant. */
private boolean shouldDetectModules = true;

/**
* Creates a new instance of {@link FilesParser}.
@@ -101,6 +104,23 @@ public FilesParser(final PluginLogger logger, final String filePattern, final An
this(logger, filePattern, parser, true, false, moduleName);
}

/**
* Creates a new instance of {@link FilesParser}. Assumes that this is a
* Maven build with the specified module name.
*
* @param logger
* the logger
* @param filePattern
* ant file-set pattern to scan for files to parse
* @param parser
* the parser to apply on the found files
*/
public FilesParser(final PluginLogger logger, final String filePattern, final AnnotationParser parser) {
this(logger, filePattern, parser, true, false, StringUtils.EMPTY);

shouldDetectModules = false;
}

/**
* Logs the specified message.
*
@@ -147,18 +167,12 @@ public ParserResult invoke(final File workspace, final VirtualChannel channel) t
* if the user cancels the parsing
*/
private void parseFiles(final File workspace, final String[] fileNames, final ParserResult result) throws InterruptedException {
ModuleDetector detector = new ModuleDetector();
ModuleDetector detector = createModuleDetector();

for (String fileName : fileNames) {
File file = new File(workspace, fileName);

String module;
if (StringUtils.isBlank(moduleName)) {
module = detector.guessModuleName(file.getAbsolutePath(), isMavenBuild, isAntBuild);
}
else {
module = moduleName;
}
String module = getModuleName(detector, file);

if (!file.canRead()) {
String message = Messages.FilesParser_Error_NoPermission(module, file);
@@ -179,6 +193,26 @@ private void parseFiles(final File workspace, final String[] fileNames, final Pa
}
}

private ModuleDetector createModuleDetector() {
if (shouldDetectModules) {
return new ModuleDetector();
}
else {
return new NullModuleDetector();
}
}

private String getModuleName(final ModuleDetector detector, final File file) {
String module;
if (StringUtils.isBlank(moduleName)) {
module = detector.guessModuleName(file.getAbsolutePath(), isMavenBuild, isAntBuild);
}
else {
module = moduleName;
}
return module;
}

/**
* Parses the specified file and stores all found annotations. If the file
* could not be parsed then an error message is appended to the result.
@@ -88,6 +88,13 @@ public abstract class HealthAwarePublisher extends Recorder implements HealthDes
*/
private Thresholds thresholds = new Thresholds();

/**
* Determines whether module names should be derived from Maven POM or Ant build files.
*
* @since 1.19
*/
private final boolean shouldDetectModules;

/**
* Creates a new instance of {@link HealthAwarePublisher}.
*
@@ -140,6 +147,8 @@ public abstract class HealthAwarePublisher extends Recorder implements HealthDes
* annotation threshold
* @param canRunOnFailed
* determines whether the plug-in can run for failed builds, too
* @param shouldDetectModules
* determines whether module names should be derived from Maven POM or Ant build files
* @param pluginName
* the name of the plug-in
*/
@@ -151,7 +160,7 @@ public HealthAwarePublisher(final String healthy, final String unHealthy, final
final String unstableNewAll, final String unstableNewHigh, final String unstableNewNormal, final String unstableNewLow,
final String failedTotalAll, final String failedTotalHigh, final String failedTotalNormal, final String failedTotalLow,
final String failedNewAll, final String failedNewHigh, final String failedNewNormal, final String failedNewLow,
final boolean canRunOnFailed, final String pluginName) {
final boolean canRunOnFailed, final boolean shouldDetectModules, final String pluginName) {
super();
this.healthy = healthy;
this.unHealthy = unHealthy;
@@ -178,9 +187,27 @@ public HealthAwarePublisher(final String healthy, final String unHealthy, final
thresholds.failedNewLow = failedNewLow;

this.canRunOnFailed = canRunOnFailed;
this.shouldDetectModules = shouldDetectModules;
this.pluginName = "[" + pluginName + "] ";
}

@Deprecated
public HealthAwarePublisher(final String healthy, final String unHealthy, final String thresholdLimit,
final String defaultEncoding, final boolean useDeltaValues,
final String unstableTotalAll, final String unstableTotalHigh, final String unstableTotalNormal, final String unstableTotalLow,
final String unstableNewAll, final String unstableNewHigh, final String unstableNewNormal, final String unstableNewLow,
final String failedTotalAll, final String failedTotalHigh, final String failedTotalNormal, final String failedTotalLow,
final String failedNewAll, final String failedNewHigh, final String failedNewNormal, final String failedNewLow,
final boolean canRunOnFailed, final String pluginName) {
this(healthy, unHealthy, thresholdLimit,
defaultEncoding, useDeltaValues,
unstableTotalAll, unstableTotalHigh, unstableTotalNormal, unstableTotalLow,
unstableNewAll, unstableNewHigh, unstableNewNormal, unstableNewLow,
failedTotalAll, failedTotalHigh, failedTotalNormal, failedTotalLow,
failedNewAll, failedNewHigh, failedNewNormal, failedNewLow,
canRunOnFailed, false, pluginName);
}

/**
* Creates a new instance of <code>HealthAwarePublisher</code>.
*
@@ -237,6 +264,7 @@ public HealthAwarePublisher(final String threshold, final String newThreshold,
this.defaultEncoding = defaultEncoding;
this.useDeltaValues = useDeltaValues;
this.canRunOnFailed = canRunOnFailed;
shouldDetectModules = false;
this.pluginName = "[" + pluginName + "] ";
}

@@ -393,6 +421,24 @@ public boolean getCanRunOnFailed() {
return canRunOnFailed;
}

/**
* Returns whether module names should be derived from Maven POM or Ant build files.
*
* @return the can run on failed
*/
public boolean getShouldDetectModules() {
return shouldDetectModules;
}

/**
* Returns whether module names should be derived from Maven POM or Ant build files.
*
* @return the can run on failed
*/
public boolean shouldDetectModules() {
return shouldDetectModules;
}

/**
* Returns whether this publisher can continue processing. This default
* implementation returns <code>true</code> if the property
@@ -292,7 +292,7 @@ else if (fileName.contains(TARGET)) {
}

/**
* A input stream factory based on a {@link FileInputStream}.
* An input stream factory based on a {@link FileInputStream}.
*/
private static final class DefaultFileInputStreamFactory implements FileInputStreamFactory {
/** {@inheritDoc} */
@@ -0,0 +1,23 @@
package hudson.plugins.analysis.util;

import org.apache.commons.lang.StringUtils;

/**
* Null object that always returns the empty string as module name.
*
* @author Ulli Hafner
*/
public class NullModuleDetector extends ModuleDetector {
/** {@inheritDoc} */
@Override
public String guessModuleName(final String fileName, final boolean isMavenBuild, final boolean isAntBuild) {
return StringUtils.EMPTY;
}

/** {@inheritDoc} */
@Override
public String guessModuleName(final String originalFileName) {
return StringUtils.EMPTY;
}
}

@@ -8,6 +8,10 @@

<u:failed/>

<f:entry title="${%Detect modules}" description="${%description.detectModules}">
<f:checkbox name="shouldDetectModules" checked="${instance.shouldDetectModules}"/>
</f:entry>

<u:health id="${id}"/>
<u:thresholds id="${id}"/>
<u:defaultEncoding id="${id}"/>
@@ -0,0 +1,3 @@
description.detectModules=Determines if Ant or Maven modules should be detected for all files that contain \
warnings. Activating this option may increase your build time since the detector scans the whole \
workspace for ''build.xml'' or ''pom.xml'' files in order to assign the correct module names.
@@ -0,0 +1,4 @@
description.detectModules=Bestimmt ob Dateien, die Warnungen enthalten, nach Projekten gruppiert werden sollen. \
Die Projektnamen werden aus den Ant oder Maven Konfigurationsdateien ermittelt und den Warnungen zugeordnet. \
Da dazu der gesamte Arbeitsbereich nach ''build.xml'' oder ''pom.xml'' Dateien durchsucht wird, kann je \
nach Größe des Arbeitsbereichs die Dauer eines Builds erheblich erhöht werden.

0 comments on commit 0c4c162

Please sign in to comment.