From ef22be2128cea802848c4feaf4ce5b22cfa4fff9 Mon Sep 17 00:00:00 2001 From: Falko Modler Date: Sat, 16 May 2020 19:35:13 +0200 Subject: [PATCH 1/2] CheckMojo: parse outputFile only once --- .../SpotbugsViolationCheckMojo.groovy | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy b/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy index a04af08a..f73942c1 100644 --- a/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy +++ b/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy @@ -466,10 +466,6 @@ class SpotbugsViolationCheckMojo extends AbstractMojo { @Parameter(property = "spotbugs.jvmArgs") String jvmArgs - int bugCount - - int errorCount - /** *

* specified max number of violations which can be ignored by the spotbugs. @@ -507,31 +503,26 @@ class SpotbugsViolationCheckMojo extends AbstractMojo { if (outputFile.exists()) { - def path = new XmlSlurper().parse(outputFile) - - def allNodes = path.depthFirst().collect { it } + def xml = new XmlParser().parse(outputFile) - bugCount = allNodes.findAll {it.name() == 'BugInstance'}.size() + def bugs = xml.BugInstance + def bugCount = bugs.size() log.info("BugInstance size is ${bugCount}") - errorCount = allNodes.findAll {it.name() == 'Error'}.size() + def errorCount = xml.Error.size() log.info("Error size is ${errorCount}") - def xml = new XmlParser().parse(outputFile) - def bugs = xml.BugInstance - def total = bugs.size() - - if (total <= 0) { + if (bugCount <= 0) { log.info('No errors/warnings found') return - }else if( maxAllowedViolations > 0 && total <= maxAllowedViolations){ - log.info("total ${total} violations are found which is set to be acceptable using configured property maxAllowedViolations :"+maxAllowedViolations +".\nBelow are list of bugs ignored :\n") - printBugs(total, bugs) + } else if (maxAllowedViolations > 0 && bugCount <= maxAllowedViolations) { + log.info("total ${bugCount} violations are found which is set to be acceptable using configured property maxAllowedViolations :"+maxAllowedViolations +".\nBelow are list of bugs ignored :\n") + printBugs(bugCount, bugs) return; } - log.info('Total bugs: ' + total) - for (i in 0..total-1) { + log.info('Total bugs: ' + bugCount) + for (i in 0..bugCount-1) { def bug = bugs[i] log.error( bug.LongMessage.text() + SpotBugsInfo.BLANK + bug.SourceLine.'@classname' + SpotBugsInfo.BLANK + bug.SourceLine.Message.text() + SpotBugsInfo.BLANK + bug.'@type') } From 0cea25a591970f8aa53ee152f690ab7316d17a8a Mon Sep 17 00:00:00 2001 From: Falko Modler Date: Mon, 25 May 2020 22:04:20 +0200 Subject: [PATCH 2/2] CheckMojo: introduce failThreshold --- src/it/check-fail/verify.groovy | 18 ++++++++ src/it/check-failThreshold/invoker.properties | 4 ++ src/it/check-failThreshold/pom.xml | 44 +++++++++++++++++++ src/it/check-failThreshold/verify.groovy | 19 ++++++++ .../SpotbugsViolationCheckMojo.groovy | 31 +++++++++++-- 5 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/it/check-fail/verify.groovy create mode 100644 src/it/check-failThreshold/invoker.properties create mode 100644 src/it/check-failThreshold/pom.xml create mode 100644 src/it/check-failThreshold/verify.groovy diff --git a/src/it/check-fail/verify.groovy b/src/it/check-fail/verify.groovy new file mode 100644 index 00000000..c509ec22 --- /dev/null +++ b/src/it/check-fail/verify.groovy @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2006-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +File buildLog = new File( basedir, 'build.log' ) +assert buildLog.text.contains( '[ERROR] High: Found reliance on default encoding in UserMistakes' ) diff --git a/src/it/check-failThreshold/invoker.properties b/src/it/check-failThreshold/invoker.properties new file mode 100644 index 00000000..14379f58 --- /dev/null +++ b/src/it/check-failThreshold/invoker.properties @@ -0,0 +1,4 @@ +invoker.goals = clean compile spotbugs:check + +# The expected result of the build, possible values are "success" (default) and "failure" +invoker.buildResult = failure diff --git a/src/it/check-failThreshold/pom.xml b/src/it/check-failThreshold/pom.xml new file mode 100644 index 00000000..6a365d6a --- /dev/null +++ b/src/it/check-failThreshold/pom.xml @@ -0,0 +1,44 @@ + + + + + 4.0.0 + + spotbugs-maven-plugin.it + common + testing + ../common.xml + + check + check + jar + + + + com.github.spotbugs + spotbugs-maven-plugin + + true + true + @spotbugsTestDebug@ + High + + + + + diff --git a/src/it/check-failThreshold/verify.groovy b/src/it/check-failThreshold/verify.groovy new file mode 100644 index 00000000..cc50632c --- /dev/null +++ b/src/it/check-failThreshold/verify.groovy @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2006-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +File buildLog = new File( basedir, 'build.log' ) +assert buildLog.text.contains( '[WARNING] Medium: Unused public or protected field:' ) +assert buildLog.text.contains( '[ERROR] High: Found reliance on default encoding in UserMistakes' ) diff --git a/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy b/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy index f73942c1..bc97b2b6 100644 --- a/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy +++ b/src/main/groovy/org/codehaus/mojo/spotbugs/SpotbugsViolationCheckMojo.groovy @@ -428,6 +428,15 @@ class SpotbugsViolationCheckMojo extends AbstractMojo { @Parameter(property = "spotbugs.failOnError", defaultValue = "true") boolean failOnError + /** + * Prioritiy threshold which bugs have to reach to cause a failure. Valid values are High, Medium or Low. + * Bugs below this threshold will just issue a warning log entry. + * + * @since 4.0.1 + */ + @Parameter(property = "spotbugs.failThreshold") + String failThreshold + /** * Fork a VM for Spotbugs analysis. This will allow you to set timeouts and heap size. * @@ -522,15 +531,31 @@ class SpotbugsViolationCheckMojo extends AbstractMojo { } log.info('Total bugs: ' + bugCount) + def bugCountAboveThreshold = 0 + def priorityThresholdNum = failThreshold ? SpotBugsInfo.spotbugsPriority.indexOf(failThreshold) : Integer.MAX_VALUE + if (priorityThresholdNum == -1) { + throw new MojoExecutionException("Invalid value for failThreshold: ${failThreshold}") + } + for (i in 0..bugCount-1) { def bug = bugs[i] - log.error( bug.LongMessage.text() + SpotBugsInfo.BLANK + bug.SourceLine.'@classname' + SpotBugsInfo.BLANK + bug.SourceLine.Message.text() + SpotBugsInfo.BLANK + bug.'@type') + def priorityNum = bug.'@priority' as int + def priorityName = SpotBugsInfo.spotbugsPriority[priorityNum] + def logMsg = priorityName + ': ' + bug.LongMessage.text() + SpotBugsInfo.BLANK + bug.SourceLine.'@classname' + SpotBugsInfo.BLANK + + bug.SourceLine.Message.text() + SpotBugsInfo.BLANK + bug.'@type' + + if (priorityNum <= priorityThresholdNum) { // lower is more severe + bugCountAboveThreshold += 1 + log.error(logMsg) + } else { + log.warn(logMsg) + } } log.info('\n\n\nTo see bug detail using the Spotbugs GUI, use the following command "mvn spotbugs:gui"\n\n\n') - if ( (bugCount || errorCount) && failOnError ) { - throw new MojoExecutionException("failed with ${bugCount} bugs and ${errorCount} errors ") + if ( (bugCountAboveThreshold || errorCount) && failOnError ) { + throw new MojoExecutionException("failed with ${bugCountAboveThreshold} bugs and ${errorCount} errors ") } } }