-
-
Save miguel-vila/e96efe3af7eaa1f687104e8c8eaabd62 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import edu.umd.cs.findbugs.{Project => SpotBugsProject} | |
import edu.umd.cs.findbugs.{SystemProperties => FindBugsSystemProperties} | |
import edu.umd.cs.findbugs.config.UserPreferences | |
import edu.umd.cs.findbugs.BugCollectionBugReporter | |
import edu.umd.cs.findbugs.DetectorFactoryCollection | |
import edu.umd.cs.findbugs.FindBugs2 | |
import edu.umd.cs.findbugs.PrintingBugReporter | |
import edu.umd.cs.findbugs.Priorities | |
import sbt.Keys._ | |
import scala.util.control.NonFatal | |
import _root_.sbt._ | |
object SxmJavaSpotBugsPlugin extends AutoPlugin { | |
object PriorityThreshold extends Enumeration { | |
type PriorityThreshold = Value | |
val Ignore, Experimental, Low, Normal, High = Value | |
} | |
object autoImport { | |
lazy val spotbugs = taskKey[Unit]("Runs SpotBugs over Java code") | |
lazy val spotbugsExcludeFilter = settingKey[File]("SpotBugs exclude filter file") | |
lazy val spotbugsPriorityThreshold = settingKey[PriorityThreshold.Value]("SpotBugs priority threshold") | |
lazy val spotbugsRelaxed = settingKey[Boolean]("SpotBugs relaxed mode") | |
lazy val spotbugsSystemProperties = settingKey[Map[String, String]]("SpotBugs system properties") | |
} | |
import autoImport._ | |
override lazy val projectSettings = Seq( | |
spotbugsExcludeFilter := file("exclude-filter.xml"), | |
spotbugsPriorityThreshold := PriorityThreshold.Normal, | |
spotbugsRelaxed := true, | |
spotbugsSystemProperties := Map.empty, | |
spotbugs := { | |
val classFiles = (Compile / classDirectory).value | |
val log = streams.value.log | |
log.info("Running SpotBugs analysis...") | |
val project = new SpotBugsProject() | |
project.addFile(classFiles.getAbsolutePath) | |
val classpath = (Compile / fullClasspath).value | |
classpath.map(_.data.getAbsolutePath).foreach(project.addAuxClasspathEntry) | |
// the location of this setting is important. Seems it might be better | |
// to set it before instantiating things that might use it. | |
setSystemProperties(spotbugsSystemProperties.value) | |
val bugReporter = new BugCollectionBugReporter(project) | |
bugReporter.setPriorityThreshold(priorityThresholdToSpotBugsPriority(spotbugsPriorityThreshold.value)) | |
bugReporter.setIsRelaxed(spotbugsRelaxed.value) | |
val findBugs = new FindBugs2() | |
findBugs.setBugReporter(bugReporter) | |
findBugs.setProject(project) | |
findBugs.setDetectorFactoryCollection(new DetectorFactoryCollection()) | |
val excludeFilterFile = spotbugsExcludeFilter.value | |
if (excludeFilterFile.exists()) { | |
findBugs.addFilter(excludeFilterFile.getAbsolutePath, false) | |
} | |
val preferences = UserPreferences.createDefaultUserPreferences() | |
findBugs.setUserPreferences(preferences) | |
try { | |
findBugs.execute() | |
log.info("SpotBugs analysis completed.") | |
val printingBugReporter = new PrintingBugReporter() | |
printingBugReporter.setPriorityThreshold(priorityThresholdToSpotBugsPriority(spotbugsPriorityThreshold.value)) | |
printingBugReporter.setIsRelaxed(spotbugsRelaxed.value) | |
printingBugReporter.setUseLongBugCodes(true) | |
val bugCollection = bugReporter.getBugCollection() | |
bugCollection.forEach { bug => | |
printingBugReporter.reportBug(bug) | |
} | |
if (bugCollection.getCollection().size() > 0) { | |
sys.error("SpotBugs found issues in the codebase.") | |
} | |
} catch { | |
case NonFatal(e) => | |
log.error("Error running SpotBugs analysis: " + e.getMessage) | |
e.printStackTrace() | |
sys.error("SpotBugs analysis failed.") | |
} | |
}, | |
) | |
private def priorityThresholdToSpotBugsPriority(priorityThreshold: PriorityThreshold.Value): Int = { | |
priorityThreshold match { | |
case PriorityThreshold.Ignore => Priorities.IGNORE_PRIORITY | |
case PriorityThreshold.Experimental => Priorities.EXP_PRIORITY | |
case PriorityThreshold.Low => Priorities.LOW_PRIORITY | |
case PriorityThreshold.Normal => Priorities.NORMAL_PRIORITY | |
case PriorityThreshold.High => Priorities.HIGH_PRIORITY | |
} | |
} | |
private def setSystemProperties(systemProperties: Map[String, String]): Unit = { | |
systemProperties.foreach { case (key, value) => | |
FindBugsSystemProperties.setProperty(key, value) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment