Giter Site home page Giter Site logo

sbt-findbugs's Introduction

sbt-findbugs Linux Build Status Windows Build Status

An sbt 1.x and 0.13.x plugin for running SpotBugs/FindBugs on Java classes. For more information about SpotBugs, see https://spotbugs.github.io.

This plugin currently uses SpotBugs version 3.1.12.

Getting started

Add sbt-findbugs as a plugin in your projects project/plugins.sbt:

addSbtPlugin("uk.co.josephearl" % "sbt-findbugs" % "<version>")

The plugin version depends on the sbt version you are using (you can check this with sbt sbt-version):

sbt version sbt-findbugs version
1.x 2.5.0
0.13.x 2.4.3

sbt-findbugs is an AutoPlugin, so there is no need to modify the build.sbt file to enable it.

Usage

You can run SpotBugs over your Java classes with the findbugs task. You can run SpotBugs over your Java test classes with the test:findbugs task.

The SpotBugs report is output to target/findbugs-report.xml by default. This can be changed by setting the value of findbugsReportPath. By default test:findbugs outputs to target/findbugs-test-report.xml, this can be changed by setting the value of findbugsReportPath in Test.

You can define include/exclude filters either inline in the build.sbt or in an external XML file.

Defining filters inline

You can include or exclude bug detection for particular classes and methods using filters with the settings findbugsIncludeFilters and findbugsExcludeFilters.

Just use Scala inline XML for the setting, for example:

findbugsIncludeFilters := Some(<FindBugsFilter>
  <Match>
    <Class name="uk.co.josephearl.example.Example" />
  </Match>
</FindBugsFilter>)

Defining filters using filter files

You can also read the filter settings from files in a more conventional way:

findbugsIncludeFilters := Some(scala.xml.XML.loadFile(baseDirectory.value / "findbugs-include-filters.xml"))

Plugins

To use SpotBugs plugins such as fb-contrib or find-sec-bugs use the findbugsPluginList setting:

libraryDependencies += "com.mebigfatguy.fb-contrib" % "fb-contrib" % "7.4.6"

findbugsPluginList += s"${ivyPaths.value.ivyHome.get.absolutePath}/cache/com.mebigfatguy.fb-contrib/fb-contrib/jars/fb-contrib-7.4.6.jar"

Or download the plugins to your projects lib directory:

findbugsPluginList += file("lib/fb-contrib-7.4.6.jar").absolutePath

Running SpotBugs automatically

To run SpotBugs automatically after compilation add the following to your build.sbt:

(findbugs in Compile) := ((findbugs in Compile) triggeredBy (compile in Compile)).value

To run SpotBugs automatically after test compilation:

(findbugs in Test) := ((findbugs in Test) triggeredBy (compile in Test)).value

Failing the build

You can set SpotBugs to fail the build if any bugs are found by setting findbugsFailOnError in your your build.sbt:

findbugsFailOnError := true

This setting is only compatible with findbugsReportType := Some(FindBugsReportType.Xml) (the default) or Some(FindBugsReportType.XmlWithMessages).

Generating an HTML report and failing the build

Although you cannot currently use findbugsFailOnError := true in combination with findbugsReportType := Some(FindBugsReportType.Html), you can use the XSLT transformations functionality to achieve the same result:

findbugsReportType := Some(FindBugsReportType.XmlWithMessages)
findbugsXsltTransformations := Some(Set(FindBugsXSLTTransformation(baseDirectory(_ / "xsl" / "default.xsl").value, target(_ / "findbugs-report.html").value)))
findbugsFailOnError := true

XSLT transformations

The findbugsXsltTransformations setting allows applying XSLT transformations to the XML report generated by SpotBugs. For instance, this could be used to generate a more readable HTML report. This setting takes values of Option[Set[FindBugsXSLTTransformation]], so multiple transformations can be applied.

You can set findbugsXsltTransformations in your build.sbt, for example to generate an HTML report:

findbugsXsltTransformations := Some(Set(FindBugsXSLTTransformation(baseDirectory(_ / "xsl" / "default.xsl").value, target(_ / "findbugs-report.html").value)))

This setting is only compatible with findbugsReportType := Some(FindBugsReportType.Xml) (the default) or Some(FindBugsReportType.XmlWithMessages).

SpotBugs comes with a number of default XSL files which you can use, these are found in findbugs/src/xsl.

Integration tests

If you want to run SpotBugs on your integration tests add the following to your build.sbt:

lazy val root = (project in file(".")).configs(IntegrationTest)

Defaults.itSettings

findbugs in IntegrationTest := findbugsTask(IntegrationTest).value,
findbugsReportPath in IntegrationTest := Some(target(_ / "findbugs-integration-test-report.xml").value)
findbugsAnalyzedPath in IntegrationTest := Seq((classDirectory in IntegrationTest).value)
findbugsAuxiliaryPath in IntegrationTest := (dependencyClasspath in IntegrationTest).value.files

Settings

findbugsReportType

  • Description: Optionally selects the output format for the SpotBugs report.
  • Accepts: Some(FindBugsReportType.{Xml, XmlWithMessages, Html, PlainHtml, FancyHtml, FancyHistHtml, Emacs, Xdoc})
  • Default: Some(FindBugsReportType.Xml)

findbugsReportPath

  • Description: Target path of the report file to generate (optional).
  • Accepts: any legal file path
  • Default: Some(target.value / "findbugs-report.xml")

findbugsPriority

  • Description: Suppress reporting of bugs based on priority.
  • Accepts: FindBugsPriority.{Relaxed, Low, Medium, High}
  • Default: FindBugsPriority.Medium

findbugsEffort

  • Description: Decide how much effort to put into analysis.
  • Accepts: FindBugsEffort.{Minimum, Default, Maximum}
  • Default: FindBugsEffort.Default

findbugsOnlyAnalyze

  • Description: Optionally, define which packages/classes should be analyzed.
  • Accepts: An option containing a List[String] of packages and classes.
  • Default: None (meaning: analyze everything).

findbugsMaxMemory

  • Description: Maximum amount of memory to allow for SpotBugs (in MB).
  • Accepts: any reasonable amount of memory as an integer value
  • Default: 1024

findbugsAnalyzeNestedArchives

  • Description: Whether SpotBugs should analyze nested archives or not.
  • Accepts: true and false
  • Default: true

findbugsSortReportByClassNames

  • Description: Whether the reported bug instances should be sorted by class name or not.
  • Accepts: true and false
  • Default: false

findbugsFailOnError

  • Description: Whether the build should be failed if there are any reported bug instances. Only compatible with findbugsReportType := Some(FindBugsReportType.Xml) or Some(FindBugsReportType.XmlWithMessages).
  • Accepts: true and false
  • Default: false

findbugsIncludeFilters

  • Description: Optional filter file XML content defining which bug instances to include in the static analysis.
  • Accepts: None and Option[Node]
  • Default: None (no include filters).

findbugsExcludeFilters

  • Description: Optional filter file XML content defining which bug instances to exclude in the static analysis.
  • Accepts: None and Some[Node]
  • Default: None (no exclude filters).

findbugsAnalyzedPath

  • Description: The path to the classes to be analyzed.
  • Accepts: any sbt.Path
  • Default: Seq(classDirectory in Compile value)

findbugsPluginList

  • Description: A list of SpotBugs plugins to enable, can be an absolute path to a plugin or the name of a plugin in the SpotBugs optional plugins directory ~/.findbugs/optionalPlugin.
  • Accepts: any Seq[String]
  • Default: Seq()

findbugsXsltTransformations

  • Description: A set of XSLT transformations to apply to the report. Only compatible with findbugsReportType := Some(FindBugsReportType.Xml) or Some(FindBugsReportType.XmlWithMessages).
  • Accepts: any Option[Set[FindBugsXSLTTransformation]]
  • Default: None

sbt-findbugs's People

Contributors

anishathalye avatar asflierl avatar brandonarp avatar felixpageau avatar hairyfotr avatar jmhofer avatar josephearl avatar jotomo avatar lpfeup avatar nigredo-tori avatar sokrahta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sbt-findbugs's Issues

Findbugs doesn't work on Windows

There're two problems:

  1. Windows uses back slash as path separator which is disappears when plugin builds class path command line argument. Back slashes needed to be converted to forward slashes.
  2. Windows eats empty space from arguments, this is a problem for -pluginList argument when no plugins defined. -pluginList should be removed from command line if there's no findbugs plugins defined.

Attached patch fixes both issues and was tested on OSX and Windows.
001-make-findbugs-work-on-Windows.txt

sbt.ResolveException: unresolved dependency: uk.co.josephearl#sbt-findbugs;2.5.0: not found

[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: uk.co.josephearl#sbt-findbugs;2.5.0: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.
[warn] uk.co.josephearl:sbt-findbugs:2.5.0 (scalaVersion=2.10, sbtVersion=0.13)
[warn]
[warn] Note: Unresolved dependencies path:
[warn] uk.co.josephearl:sbt-findbugs:2.5.0 (scalaVersion=2.10, sbtVersion=0.13) (/Users/eric.kolotyluk/perforceRoot/nds/servers/projects/pci-enclave/project/plugins.sbt#L20-21)
[warn] +- default:pci-enclave-build:0.1-SNAPSHOT (scalaVersion=2.10, sbtVersion=0.13)
sbt.ResolveException: unresolved dependency: uk.co.josephearl#sbt-findbugs;2.5.0: not found
at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:313)
at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:191)
at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:168)
at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:156)
at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:156)
at sbt.IvySbt$$anonfun$withIvy$1.apply(Ivy.scala:133)
at sbt.IvySbt.sbt$IvySbt$$action$1(Ivy.scala:57)
at sbt.IvySbt$$anon$4.call(Ivy.scala:65)
at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:95)
at xsbt.boot.Locks$GlobalLock.xsbt$boot$Locks$GlobalLock$$withChannelRetries$1(Locks.scala:80)
at xsbt.boot.Locks$GlobalLock$$anonfun$withFileLock$1.apply(Locks.scala:99)
at xsbt.boot.Using$.withResource(Using.scala:10)
at xsbt.boot.Using$.apply(Using.scala:9)
at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:60)
at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:50)
at xsbt.boot.Locks$.apply0(Locks.scala:31)
at xsbt.boot.Locks$.apply(Locks.scala:28)
at sbt.IvySbt.withDefaultLogger(Ivy.scala:65)
at sbt.IvySbt.withIvy(Ivy.scala:128)
at sbt.IvySbt.withIvy(Ivy.scala:125)
at sbt.IvySbt$Module.withModule(Ivy.scala:156)
at sbt.IvyActions$.updateEither(IvyActions.scala:168)
at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1488)
at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1484)
at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$121.apply(Defaults.scala:1519)
at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$121.apply(Defaults.scala:1517)
at sbt.Tracked$$anonfun$lastOutput$1.apply(Tracked.scala:37)
at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1522)
at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1516)
at sbt.Tracked$$anonfun$inputChanged$1.apply(Tracked.scala:60)
at sbt.Classpaths$.cachedUpdate(Defaults.scala:1539)
at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1466)
at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1418)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$4.work(System.scala:63)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.Execute.work(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
[error] (*:update) sbt.ResolveException: unresolved dependency: uk.co.josephearl#sbt-findbugs;2.5.0: not found

Add XmlWithMessages report type

Findbugs supports xml report with messages via -xml:withMessages command line switch.
With attached patch applied I can use plugin with

findbugsFailOnError := true
findbugsReportType := Some(FindBugsReportType.XmlWithMessages)
findbugsXsltTransformations := Some(Set(FindBugsXSLTTransformation(baseDirectory(_ / "findbugs" / "fancy.xsl").value, target(_ / "findbugs/report.html").value)))

to generate meaningful reports and fail build at the same time.
001-add-FindBugsReportType.XmlWithMessages.txt

HTML Report file generation not working

Or at least I don't understand how it is supposed to work.

Adding this line to build.sbt

findbugsReportType := Some(FindBugsReportType.FancyHtml)

gets me an xml report but no HTML report.

Update README.md to include FindBugsReportType.XmlWithMessages

Plugin now supports XmlWithMessages report type and README.md was updated accordingly.
However XSLT transformations section (https://github.com/JosephEarl/sbt-findbugs#xslt-transformations) was not updated, it says:

"This setting is only compatible with findbugsReportType := Some(FindBugsReportType.Xml) (the default)."

Should be

"This setting is only compatible with findbugsReportType := Some(FindBugsReportType.Xml) (the default) or Some(FindBugsReportType.XmlWithMessages)"

SAXParseException if findbugsFailOnError := true only

Hi (sorry for the early enter-hit)

I have the follwing settings using 2.4.0:

findbugsReportType := Some(FindBugsReportType.Html)

findbugsFailOnError := true

and get this stacktrace:

org.xml.sax.SAXParseException; lineNumber: 80; columnNumber: 324; The content of elements must consist of well-formed character data or markup. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203) at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441) at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368) at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1436) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.startOfMarkup(XMLDocumentFragmentScannerImpl.java:2636) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2734) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:333) at scala.xml.factory.XMLLoader$class.loadXML(XMLLoader.scala:40) at scala.xml.XML$.loadXML(XML.scala:57) at scala.xml.factory.XMLLoader$class.loadFile(XMLLoader.scala:47) at scala.xml.XML$.loadFile(XML.scala:57) at uk.co.josephearl.sbt.findbugs.FindBugs$.uk$co$josephearl$sbt$findbugs$FindBugs$$processIssues(FindBugs.scala:52) at uk.co.josephearl.sbt.findbugs.FindBugs$$anonfun$1.apply(FindBugs.scala:40) at uk.co.josephearl.sbt.findbugs.FindBugs$$anonfun$1.apply(FindBugs.scala:40) at scala.Option.map(Option.scala:145) at uk.co.josephearl.sbt.findbugs.FindBugs$.findbugs(FindBugs.scala:40) at uk.co.josephearl.sbt.findbugs.FindBugsPlugin$autoImport$$anonfun$findbugsTask$1.apply(FindBugsPlugin.scala:81) at uk.co.josephearl.sbt.findbugs.FindBugsPlugin$autoImport$$anonfun$findbugsTask$1.apply(FindBugsPlugin.scala:74) at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47) at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40) at sbt.std.Transform$$anon$4.work(System.scala:63) at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17) at sbt.Execute.work(Execute.scala:235) at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159) at sbt.CompletionService$$anon$2.call(CompletionService.scala:28) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

weirdly it's only there if the findbugsFailOnError := true is set

findbugsPluginList not working for more than one plugin on Windows

findbugsPluginList setting works correctly if I use either findsecbugs-plugin or fb-contrib. If I try to specify both of them, as below, neither is executed. Am I missing something here?

plugins.sbt:

addSbtPlugin("uk.co.josephearl" % "sbt-findbugs" % "2.4.3")

build.sbt:

findbugsReportPath := Some(target.value / "findbugsXml.xml")

libraryDependencies += "com.h3xstream.findsecbugs" % "findsecbugs-plugin" % "1.8.0"
findbugsPluginList += s"${ivyPaths.value.ivyHome.get.absolutePath}/cache/com.h3xstream.findsecbugs/findsecbugs-plugin/jars/findsecbugs-plugin-1.8.0.jar"

libraryDependencies += "com.mebigfatguy.fb-contrib" % "fb-contrib" % "7.4.3"
findbugsPluginList += s"${ivyPaths.value.ivyHome.get.absolutePath}/cache/com.mebigfatguy.fb-contrib/fb-contrib/jars/fb-contrib-7.4.3.jar"

OS: Windows 10
sbt: 0.13.11

Thanks in advance

I can't get findbugsExcludeFilters to work (including an xml file)

This line in build.sbt:
findbugsExcludeFilters := Some(baseDirectory.value / "findbugs-exclude-filters.xml")

Leads to this error message:

error: type mismatch;
 found   : java.io.File
 required: scala.xml.Node
findbugsExcludeFilters := Some(baseDirectory.value / "findbugs-exclude-filters.xml")
                                                   ^

Support findbugsFailOnError for report types other than Xml

Currently only XML is supported because sbt-findbugs reads the XML report to see what bugs (and how many) have been found.

One option could be use the exit code or other just to tell whether FindBugs has been successful and remove any reporting.

Another option could be to always have FindBugs generate the XML format, then generate the HTML or other report type from the XML using XSL.

Improve Reporting of FindBugs Errors

The plugin should print a readable list of bugs/errors found, similar to the sbt-checkstyle-plugin, to avoid the user having the check and parse the findbugs report.

README is devoid of working examples

I would really nice to have some examples in the README that show tested, working, examples of build.sbt and plugins.sbt files.

There seems to be a trend in in GitHub README.md files these days to be example adverse. If you ever had it working in the first place, why not provide a WORKING example for the rest of us?


sbt.ResolveException: unresolved dependency: uk.co.josephearl#sbt-findbugs;2.5.0: not found

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.