All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.umd.cs.findbugs.anttask.FindBugsTask Maven / Gradle / Ivy

There is a newer version: 4.8.6
Show newest version
/*
 * FindBugs - Find Bugs in Java programs
 * Copyright (C) 2003-2013 University of Maryland
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs.anttask;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.DirSet;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;

import edu.umd.cs.findbugs.BugRanker;
import edu.umd.cs.findbugs.ExitCodes;

/**
 * FindBugs in Java class files. This task can take the following arguments:
 * 
    *
  • adjustExperimental (boolean default false)
  • *
  • adjustPriority (passed to -adjustPriority)
  • *
  • applySuppression (exclude any warnings that match a suppression filter * supplied in a project file)
  • *
  • auxAnalyzepath (class, jar, zip files or directories containing classes * to analyze)
  • *
  • auxClasspath (classpath or classpathRef)
  • *
  • baselineBugs (xml file containing baseline bugs)
  • *
  • class (class, jar, zip or directory containing classes to analyze)
  • *
  • classpath (classpath for running FindBugs)
  • *
  • conserveSpace (boolean - default false)
  • *
  • debug (boolean default false)
  • *
  • effort (enum min|default|max)
  • *
  • excludeFilter (filter filename)
  • *
  • excludePath (classpath or classpathRef to filters)
  • *
  • failOnError (boolean - default false)
  • *
  • home (findbugs install dir)
  • *
  • includeFilter (filter filename)
  • *
  • includePath (classpath or classpathRef to filters)
  • *
  • maxRank (maximum rank issue to be reported)
  • *
  • jvm (Set the command used to start the VM)
  • *
  • jvmargs (any additional jvm arguments)
  • *
  • omitVisitors (collection - comma separated)
  • *
  • onlyAnalyze (restrict analysis to find bugs to given comma-separated list * of classes and packages - See the textui argument description for details)
  • *
  • output (enum text|xml|xml:withMessages|html - default xml)
  • *
  • outputFile (name of output file to create)
  • *
  • nested (boolean default true)
  • *
  • noClassOk (boolean default false)
  • *
  • pluginList (list of plugin Jar files to load)
  • *
  • projectFile (project filename)
  • *
  • projectName (project name, for display in generated HTML)
  • *
  • userPreferencesFile (user preferences filename)
  • *
  • quietErrors (boolean - default false)
  • *
  • relaxed (boolean - default false)
  • *
  • reportLevel (enum experimental|low|medium|high)
  • *
  • sort (boolean default true)
  • *
  • stylesheet (name of stylesheet to generate HTML: default is * "default.xsl")
  • *
  • systemProperty (a system property to set)
  • *
  • timestampNow (boolean - default false)
  • *
  • visitors (collection - comma separated)
  • *
  • chooseVisitors (selectively enable/disable visitors)
  • *
  • workHard (boolean default false)
  • *
  • setSetExitCode (boolean default true)
  • *
*

Of these arguments, the home is required. projectFile is * required if nested <class> or <auxAnalyzepath> elements are not * specified. the <class> tag defines the location of either a class, jar * file, zip file, or directory containing classes. *

* * @author Mike Fagan [email protected] * @author Michael Tamm [email protected] * @author Scott Wolk * @version $Revision: 1.56 $ * * @since Ant 1.5 * * @ant.task category="utility" */ public class FindBugsTask extends AbstractFindBugsTask { private String effort; private boolean conserveSpace; private boolean sorted = true; private boolean timestampNow = true; private boolean quietErrors; private String warningsProperty; private int maxRank; private String projectName; private boolean workHard; private boolean relaxed; private boolean adjustExperimental; private String adjustPriority; private File projectFile; private File userPreferencesFile; private File baselineBugs; private boolean applySuppression; private File excludeFile; private Path excludePath; private File includeFile; private Path includePath; private Path auxClasspath; private Path auxAnalyzepath; private Path sourcePath; private String outputFormat = "xml"; private String reportLevel; private String visitors; private String chooseVisitors; private String omitVisitors; private String outputFileName; private String stylesheet; private final List classLocations = new ArrayList<>(); private String onlyAnalyze; private boolean noClassOk; private boolean nested = true; private boolean setExitCode = true; private final List filesets = new ArrayList<>(); private final List dirsets = new ArrayList<>(); public FindBugsTask() { super("edu.umd.cs.findbugs.FindBugs2"); } // define the inner class to store class locations public static class ClassLocation { File classLocation = null; public void setLocation(File location) { classLocation = location; } public File getLocation() { return classLocation; } @Override public String toString() { return classLocation != null ? classLocation.toString() : ""; } } /** * Set the workHard flag. * * @param workHard * true if we want findbugs to run with workHard option enabled */ public void setWorkHard(boolean workHard) { this.workHard = workHard; } /** * Set the exit code flag. * * @param setExitCode * If true then the exit code will be returned to * the main ant job */ public void setSetExitCode(boolean setExitCode) { this.setExitCode = setExitCode; } /** * Set the nested flag. * * @param nested * This option enables or disables scanning of * nested jar and zip files found in the list of files * and directories to be analyzed. By default, scanning * of nested jar/zip files is enabled */ public void setNested(boolean nested) { this.nested = nested; } /** * Set the noClassOk flag. * * @param noClassOk * true if we should generate no-error output if no classfiles * are specified */ public void setNoClassOk(boolean noClassOk) { this.noClassOk = noClassOk; } /** * Set the relaxed flag. * * @param relaxed * true if we want findbugs to run with relaxed option enabled */ public void setRelaxed(boolean relaxed) { this.relaxed = relaxed; } /** * Set the adjustExperimental flag * * @param adjustExperimental * true if we want experimental bug patterns to have lower * priority */ public void setAdjustExperimental(boolean adjustExperimental) { this.adjustExperimental = adjustExperimental; } public void setAdjustPriority(String adjustPriorityString) { adjustPriority = adjustPriorityString; } /** * Set the specific visitors to use * * @param commaSeperatedString * visitors to use */ public void setVisitors(String commaSeperatedString) { visitors = commaSeperatedString; } /** * Set the specific visitors to use * * @param commaSeperatedString * visitors to use */ public void setChooseVisitors(String commaSeperatedString) { chooseVisitors = commaSeperatedString; } /** * Set the specific visitors to use * * @param commaSeperatedString * visitors to use */ public void setOmitVisitors(String commaSeperatedString) { omitVisitors = commaSeperatedString; } /** * Set the output format * * @param format * output format */ public void setOutput(String format) { outputFormat = format; } /** * Set the stylesheet filename for HTML generation. * * @param stylesheet * stylesheet filename for HTML generation */ public void setStylesheet(String stylesheet) { this.stylesheet = stylesheet; } /** * Set the report level * * @param level * the report level */ public void setReportLevel(String level) { reportLevel = level; } /** * Set the sorted flag * * @param flag * sorted */ public void setSort(boolean flag) { sorted = flag; } /** * Set the timestampNow flag * * @param flag * timestampNow */ public void setTimestampNow(boolean flag) { timestampNow = flag; } /** * Set the quietErrors flag * * @param flag * quietErrors */ public void setQuietErrors(boolean flag) { quietErrors = flag; } /** * Set the applySuppression flag * * @param flag * applySuppression */ public void setApplySuppression(boolean flag) { applySuppression = flag; } /** * Tells this task to set the property with the given name to "true" when bugs were found. * * @param name * property with the given name */ public void setWarningsProperty(String name) { warningsProperty = name; } /** * Set effort level. * * @param effort * the effort level */ public void setEffort(String effort) { this.effort = effort; } public void setMaxRank(int maxRank) { this.maxRank = maxRank; } /** * Set project name * * @param projectName * the project name */ public void setProjectName(String projectName) { this.projectName = projectName; } /** * Set the conserveSpace flag. * * @param flag * conserveSpace */ public void setConserveSpace(boolean flag) { conserveSpace = flag; } /** * Set the exclude filter file * * @param filterFile * exclude filter file */ public void setExcludeFilter(File filterFile) { if (filterFile != null && filterFile.length() > 0) { excludeFile = filterFile; } else { if (filterFile != null) { log("Warning: exclude filter file " + filterFile + (filterFile.exists() ? " is empty" : " does not exist")); } excludeFile = null; } } /** * Set the include filter file * * @param filterFile * include filter file */ public void setIncludeFilter(File filterFile) { if (filterFile != null && filterFile.length() > 0) { includeFile = filterFile; } else { if (filterFile != null) { log("Warning: include filter file " + filterFile + (filterFile.exists() ? " is empty" : " does not exist")); } includeFile = null; } } /** * Set the baseline bugs file * * @param baselineBugs * baseline bugs file */ public void setBaselineBugs(File baselineBugs) { if (baselineBugs != null && baselineBugs.length() > 0) { this.baselineBugs = baselineBugs; } else { if (baselineBugs != null) { log("Warning: baseline bugs file " + baselineBugs + (baselineBugs.exists() ? " is empty" : " does not exist")); } this.baselineBugs = null; } } /** * Set the project file * * @param projectFile * project file */ public void setProjectFile(File projectFile) { this.projectFile = projectFile; } /** * Set the user preferences file * * @param userPreferencesFile * user preferences file */ public void setUserPreferencesFile(File userPreferencesFile) { this.userPreferencesFile = userPreferencesFile; } /** * the auxclasspath to use. * * @param src * auxclasspath to use */ public void setAuxClasspath(Path src) { boolean nonEmpty = false; String[] elementList = src.list(); for (String anElementList : elementList) { if (!"".equals(anElementList)) { nonEmpty = true; break; } } if (nonEmpty) { if (auxClasspath == null) { auxClasspath = src; } else { auxClasspath.append(src); } } } /** * Path to use for auxclasspath. * * @return auxclasspath */ public Path createAuxClasspath() { if (auxClasspath == null) { auxClasspath = new Path(getProject()); } return auxClasspath.createPath(); } /** * Adds a reference to a sourcepath defined elsewhere. * * @param r * reference to a sourcepath defined elsewhere */ public void setAuxClasspathRef(Reference r) { Path path = createAuxClasspath(); path.setRefid(r); path.toString(); // Evaluated for its side-effects (throwing a // BuildException) } /** * the auxAnalyzepath to use. * * @param src * auxAnalyzepath */ public void setAuxAnalyzepath(Path src) { boolean nonEmpty = false; String[] elementList = src.list(); for (String anElementList : elementList) { if (!"".equals(anElementList)) { nonEmpty = true; break; } } if (nonEmpty) { if (auxAnalyzepath == null) { auxAnalyzepath = src; } else { auxAnalyzepath.append(src); } } } /** * Path to use for auxAnalyzepath. * * @return auxAnalyzepath */ public Path createAuxAnalyzepath() { if (auxAnalyzepath == null) { auxAnalyzepath = new Path(getProject()); } return auxAnalyzepath.createPath(); } /** * Adds a reference to a auxAnalyzepath defined elsewhere. * * @param r * reference to a auxAnalyzepath defined elsewhe */ public void setAuxAnalyzepathRef(Reference r) { createAuxAnalyzepath().setRefid(r); } /** * the sourcepath to use. * * @param src * sourcepath */ public void setSourcePath(Path src) { if (sourcePath == null) { sourcePath = src; } else { sourcePath.append(src); } } /** * Path to use for sourcepath. * * @return sourcepath */ public Path createSourcePath() { if (sourcePath == null) { sourcePath = new Path(getProject()); } return sourcePath.createPath(); } /** * Adds a reference to a source path defined elsewhere. * * @param r * reference to a source path defined elsewhere */ public void setSourcePathRef(Reference r) { createSourcePath().setRefid(r); } /** * the excludepath to use. * * @param src * excludepath */ public void setExcludePath(Path src) { if (excludePath == null) { excludePath = src; } else { excludePath.append(src); } } /** * Path to use for excludepath. * * @return excludepath */ public Path createExcludePath() { if (excludePath == null) { excludePath = new Path(getProject()); } return excludePath.createPath(); } /** * Adds a reference to a source path defined elsewhere. * * @param r * reference to a exclude path defined elsewhe */ public void setExcludePathRef(Reference r) { createExcludePath().setRefid(r); } /** * the includepath to use. * * @param src * includepath */ public void setIncludePath(Path src) { if (includePath == null) { includePath = src; } else { includePath.append(src); } } /** * Path to use for includepath. * * @return includepath */ public Path createIncludePath() { if (includePath == null) { includePath = new Path(getProject()); } return includePath.createPath(); } /** * Adds a reference to a include path defined elsewhere. * * @param r * reference to a include path defined elsewher */ public void setIncludePathRef(Reference r) { createIncludePath().setRefid(r); } /** * Add a class location * * @return class location */ public ClassLocation createClass() { ClassLocation cl = new ClassLocation(); classLocations.add(cl); return cl; } /** * Set name of output file. * * @param outputFileName * name of output file */ public void setOutputFile(String outputFileName) { if (outputFileName != null && outputFileName.length() > 0) { this.outputFileName = outputFileName; } } /** * Set the packages or classes to analyze * * @param filter * packages or classes to analyze */ public void setOnlyAnalyze(String filter) { onlyAnalyze = filter; } /** * Add a nested fileset of classes or jar files. * * @param fs * nested fileset of classes or jar files */ public void addFileset(FileSet fs) { filesets.add(fs); } /** * Add a nested dirset of classes dirs. * * @param fs * nested dirset of classes dirs */ public void addDirset(DirSet fs) { dirsets.add(fs); } /** * Check that all required attributes have been set */ @Override protected void checkParameters() { super.checkParameters(); if (projectFile == null && classLocations.size() == 0 && filesets.size() == 0 && dirsets.size() == 0 && auxAnalyzepath == null) { throw new BuildException("either projectfile, , or child " + "elements must be defined for task <" + getTaskName() + "/>", getLocation()); } if (outputFormat != null && !("xml".equalsIgnoreCase(outputFormat.trim()) || "xml:withMessages".equalsIgnoreCase(outputFormat.trim()) || "html".equalsIgnoreCase(outputFormat.trim()) || "text".equalsIgnoreCase(outputFormat.trim()) || "xdocs".equalsIgnoreCase(outputFormat.trim()) || "emacs".equalsIgnoreCase(outputFormat.trim()))) { throw new BuildException("output attribute must be either " + "'text', 'xml', 'html', 'xdocs' or 'emacs' for task <" + getTaskName() + "/>", getLocation()); } if (reportLevel != null && !("experimental".equalsIgnoreCase(reportLevel.trim()) || "low".equalsIgnoreCase(reportLevel.trim()) || "medium".equalsIgnoreCase(reportLevel.trim()) || "high".equalsIgnoreCase(reportLevel.trim()))) { throw new BuildException("reportlevel attribute must be either " + "'experimental' or 'low' or 'medium' or 'high' for task <" + getTaskName() + "/>", getLocation()); } // FindBugs allows both, so there's no apparent reason for this check // if ( excludeFile != null && includeFile != null ) { // throw new BuildException("only one of excludeFile and includeFile " + // " attributes may be used in task <" + getTaskName() + "/>", // getLocation()); // } List efforts = Arrays.asList("min", "less", "default", "more", "max"); if (effort != null && !efforts.contains(effort)) { throw new BuildException("effort attribute must be one of " + efforts); } } /* * (non-Javadoc) * * @see * edu.umd.cs.findbugs.anttask.AbstractFindBugsTask#beforeExecuteJavaProcess * () */ @Override protected void beforeExecuteJavaProcess() { log("Running SpotBugs..."); } /* * (non-Javadoc) * * @see * edu.umd.cs.findbugs.anttask.AbstractFindBugsTask#afterExecuteJavaProcess * (int) */ @Override protected void afterExecuteJavaProcess(int rc) { if ((rc & ExitCodes.ERROR_FLAG) != 0) { throw new BuildException("Execution of SpotBugs failed."); } if ((rc & ExitCodes.MISSING_CLASS_FLAG) != 0) { log("Classes needed for analysis were missing"); } if (warningsProperty != null && (rc & ExitCodes.BUGS_FOUND_FLAG) != 0) { getProject().setProperty(warningsProperty, "true"); } if (outputFileName != null) { log("Output saved to " + outputFileName); } } @Override protected void configureFindbugsEngine() { if (projectName != null) { addArg("-projectName"); addArg(projectName); } if (adjustExperimental) { addArg("-adjustExperimental"); } if (conserveSpace) { addArg("-conserveSpace"); } if (workHard) { addArg("-workHard"); } if (effort != null) { addArg("-effort:" + effort); } if (maxRank >= BugRanker.VISIBLE_RANK_MIN && maxRank <= BugRanker.VISIBLE_RANK_MAX) { addArg("-maxRank "); addArg(Integer.toString(maxRank)); } if (adjustPriority != null) { addArg("-adjustPriority"); addArg(adjustPriority); } if (sorted) { addArg("-sortByClass"); } if (timestampNow) { addArg("-timestampNow"); } if (outputFormat != null && !"text".equalsIgnoreCase(outputFormat.trim())) { outputFormat = outputFormat.trim(); String outputArg = "-"; int colon = outputFormat.indexOf(':'); if (colon >= 0) { outputArg += outputFormat.substring(0, colon).toLowerCase(); outputArg += ":"; outputArg += outputFormat.substring(colon + 1); } else { outputArg += outputFormat.toLowerCase(); if (stylesheet != null) { outputArg += ":"; outputArg += stylesheet.trim(); } } addArg(outputArg); } if (quietErrors) { addArg("-quiet"); } if (reportLevel != null) { addArg("-" + reportLevel.trim().toLowerCase()); } if (projectFile != null) { addArg("-project"); addArg(projectFile.getPath()); } if (userPreferencesFile != null) { addArg("-userPrefs"); addArg(userPreferencesFile.getPath()); } if (applySuppression) { addArg("-applySuppression"); } if (baselineBugs != null) { addArg("-excludeBugs"); addArg(baselineBugs.getPath()); } if (excludeFile != null) { addArg("-exclude"); addArg(excludeFile.getPath()); } if (excludePath != null) { String[] result = excludePath.toString().split(java.io.File.pathSeparator); for (String element : result) { addArg("-exclude"); addArg(element); } } if (includeFile != null) { addArg("-include"); addArg(includeFile.getPath()); } if (includePath != null) { String[] result = includePath.toString().split(java.io.File.pathSeparator); for (String element : result) { addArg("-include"); addArg(element); } } if (visitors != null) { addArg("-visitors"); addArg(visitors); } if (omitVisitors != null) { addArg("-omitVisitors"); addArg(omitVisitors); } if (chooseVisitors != null) { addArg("-chooseVisitors"); addArg(chooseVisitors); } if (auxClasspath != null) { try { // Try to dereference the auxClasspath. // If it throws an exception, we know it // has an invalid path entry, so we complain // and tolerate it. @SuppressWarnings("unused") String unreadReference = auxClasspath.toString(); String auxClasspathString = auxClasspath.toString(); if (!auxClasspathString.isEmpty()) { if (auxClasspathString.length() > 100) { addArg("-auxclasspathFromInput"); setInputString(auxClasspathString); } else { addArg("-auxclasspath"); addArg(auxClasspathString); } } } catch (Throwable t) { log("Warning: auxClasspath " + t + " not found."); } } if (sourcePath != null) { addArg("-sourcepath"); addArg(sourcePath.toString()); } if (outputFileName != null) { addArg("-outputFile"); addArg(outputFileName); } if (relaxed) { addArg("-relaxed"); } if (!nested) { addArg("-nested:false"); } if (noClassOk) { addArg("-noClassOk"); } if (onlyAnalyze != null) { addArg("-onlyAnalyze"); addArg(onlyAnalyze); } if (setExitCode) { addArg("-exitcode"); } for (ClassLocation classLocation : classLocations) { addArg(classLocation.toString()); } for (FileSet fs : filesets) { DirectoryScanner ds = fs.getDirectoryScanner(); for (String fileName : ds.getIncludedFiles()) { File file = new File(ds.getBasedir(), fileName); addArg(file.toString()); } } for (DirSet fs : dirsets) { DirectoryScanner ds = fs.getDirectoryScanner(); for (String fileName : ds.getIncludedDirectories()) { File file = new File(ds.getBasedir(), fileName); addArg(file.toString()); } } if (auxAnalyzepath != null) { String[] result = auxAnalyzepath.toString().split(java.io.File.pathSeparator); for (String element : result) { addArg(element); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy