From 2c7e41245f685a5e860104a8ecde691b44b43662 Mon Sep 17 00:00:00 2001 From: Chris White Date: Thu, 18 Jun 2020 03:23:36 -0700 Subject: [PATCH] feat: allow stack trace suppression (#266) (#275) * feat: allow stack trace suppression (#266) * feat: addressed review comments --- README.md | 1 + .../snom/StandardFunctionalTest.groovy | 38 +++++++++++++++++++ .../spotbugs/snom/SpotBugsExtension.groovy | 4 ++ .../github/spotbugs/snom/SpotBugsTask.groovy | 17 +++++++++ .../internal/SpotBugsRunnerForJavaExec.java | 2 +- .../internal/SpotBugsRunnerForWorker.java | 7 +++- 6 files changed, 67 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 88efb687..9009f725 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Configure `spotbugs` extension to configure the behaviour of tasks: ```groovy spotbugs { ignoreFailures = false + showStackTraces = true showProgress = true effort = 'default' reportLevel = 'default' diff --git a/src/functionalTest/groovy/com/github/spotbugs/snom/StandardFunctionalTest.groovy b/src/functionalTest/groovy/com/github/spotbugs/snom/StandardFunctionalTest.groovy index fa416ae1..8997b706 100644 --- a/src/functionalTest/groovy/com/github/spotbugs/snom/StandardFunctionalTest.groovy +++ b/src/functionalTest/groovy/com/github/spotbugs/snom/StandardFunctionalTest.groovy @@ -251,6 +251,44 @@ spotbugs { then: result.task(':spotbugsMain').outcome == TaskOutcome.SUCCESS + result.output.contains('\tat ') + + where: + isWorkerApi << [true, false] + } + + @Unroll + def 'build does not show stack traces when bugs are found with `showStacktraces = false` (Worker API? #isWorkerApi)'() { + given: + def badCode = new File(rootDir, 'src/main/java/Bar.java') + badCode << ''' + |public class Bar { + | public int unreadField = 42; // warning: URF_UNREAD_FIELD + |} + |'''.stripMargin() + + buildFile << """ +spotbugs { + ignoreFailures = true + showStackTraces = false +}""" + when: + def arguments = [':spotbugsMain', '-is'] + if(!isWorkerApi) { + arguments.add('-Pcom.github.spotbugs.snom.worker=false') + } + def runner = GradleRunner.create() + .withProjectDir(rootDir) + .withArguments(arguments) + .withPluginClasspath() + .forwardOutput() + .withGradleVersion(version) + + def result = runner. build() + + then: + result.task(':spotbugsMain').outcome == TaskOutcome.SUCCESS + !(result.output.contains('\tat ')) where: isWorkerApi << [true, false] diff --git a/src/main/groovy/com/github/spotbugs/snom/SpotBugsExtension.groovy b/src/main/groovy/com/github/spotbugs/snom/SpotBugsExtension.groovy index 13887c55..22b1e746 100644 --- a/src/main/groovy/com/github/spotbugs/snom/SpotBugsExtension.groovy +++ b/src/main/groovy/com/github/spotbugs/snom/SpotBugsExtension.groovy @@ -34,6 +34,7 @@ import org.gradle.api.provider.Property; *

After you apply the SpotBugs Gradle plugin to project, write extension like below:

* spotbugs {
*     ignoreFailures = false
+ *     showStackTraces = true
*     showProgress = false
*     reportLevel = 'default'
*     effort = 'default'
@@ -57,6 +58,8 @@ class SpotBugsExtension { @NonNull final Property ignoreFailures; + @NonNull + final Property showStackTraces; /** * Property to enable progress reporting during the analysis. Default value is {@code false}. */ @@ -150,6 +153,7 @@ class SpotBugsExtension { @Inject SpotBugsExtension(Project project, ObjectFactory objects) { ignoreFailures = objects.property(Boolean).convention(false); + showStackTraces = objects.property(Boolean).convention(true); showProgress = objects.property(Boolean); reportLevel = objects.property(Confidence); effort = objects.property(Effort); diff --git a/src/main/groovy/com/github/spotbugs/snom/SpotBugsTask.groovy b/src/main/groovy/com/github/spotbugs/snom/SpotBugsTask.groovy index 8d831b51..67ac0135 100644 --- a/src/main/groovy/com/github/spotbugs/snom/SpotBugsTask.groovy +++ b/src/main/groovy/com/github/spotbugs/snom/SpotBugsTask.groovy @@ -65,6 +65,7 @@ import javax.inject.Inject *     auxClassPaths = sourceSets.main.compileClasspath
*
*     ignoreFailures = false
+ *     showStackTraces = true
*     showProgress = false
*     reportLevel = 'default'
*     effort = 'default'
@@ -92,6 +93,7 @@ class SpotBugsTask extends DefaultTask implements VerificationTask { private final WorkerExecutor workerExecutor; @NonNull final Property ignoreFailures; + @NonNull final Property showStackTraces; /** * Property to enable progress reporting during the analysis. Default value is {@code false}. */ @@ -279,6 +281,7 @@ class SpotBugsTask extends DefaultTask implements VerificationTask { sourceDirs = objects.fileCollection() auxClassPaths = objects.fileCollection() ignoreFailures = objects.property(Boolean) + showStackTraces = objects.property(Boolean) showProgress = objects.property(Boolean); reportLevel = objects.property(Confidence); effort = objects.property(Effort); @@ -318,6 +321,7 @@ class SpotBugsTask extends DefaultTask implements VerificationTask { */ void init(SpotBugsExtension extension) { ignoreFailures.convention(extension.ignoreFailures) + showStackTraces.convention(extension.showStackTraces) showProgress.convention(extension.showProgress) reportLevel.convention(extension.reportLevel) effort.convention(extension.effort) @@ -410,11 +414,24 @@ class SpotBugsTask extends DefaultTask implements VerificationTask { ignoreFailures.set(b); } + void setShowStackTraces(Provider b) { + showStackTraces.set(b); + } + + void setShowStackTraces(boolean b) { + showStackTraces.set(b) + } + @Input boolean getIgnoreFailures() { ignoreFailures.get(); } + @Input + boolean getShowStackTraces() { + showStackTraces.get(); + } + @Internal String getBaseName() { String prunedName = name.replaceFirst("spotbugs", "") diff --git a/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForJavaExec.java b/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForJavaExec.java index 5f8a1c66..d532586a 100644 --- a/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForJavaExec.java +++ b/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForJavaExec.java @@ -36,7 +36,7 @@ public void run(@NonNull SpotBugsTask task) { task.getProject().javaexec(configureJavaExec(task)).rethrowFailure().assertNormalExitValue(); } catch (ExecException e) { if (task.getIgnoreFailures()) { - log.warn("SpotBugs reported failures", e); + log.warn("SpotBugs reported failures", task.getShowStackTraces() ? e : null); } else { String errorMessage = "Verification failed: SpotBugs execution thrown exception."; List reportPaths = diff --git a/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForWorker.java b/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForWorker.java index e0c0e4f8..6aed1cbe 100644 --- a/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForWorker.java +++ b/src/main/groovy/com/github/spotbugs/snom/internal/SpotBugsRunnerForWorker.java @@ -67,6 +67,7 @@ private Action configureWorkParameters(SpotBugsTask task return params -> { params.getArguments().addAll(buildArguments(task)); params.getIgnoreFailures().set(task.getIgnoreFailures()); + params.getShowStackTraces().set(task.getShowStackTraces()); }; } @@ -74,6 +75,8 @@ interface SpotBugsWorkParameters extends WorkParameters { ListProperty getArguments(); Property getIgnoreFailures(); + + Property getShowStackTraces(); } public abstract static class SpotBugsExecutor implements WorkAction { @@ -107,7 +110,9 @@ public void execute() { } } catch (GradleException e) { if (params.getIgnoreFailures().getOrElse(Boolean.FALSE).booleanValue()) { - log.warn("SpotBugs reported failures", e); + final boolean showStackTraces = + params.getShowStackTraces().getOrElse(Boolean.TRUE).booleanValue(); + log.warn("SpotBugs reported failures", showStackTraces ? e : null); } else { throw e; }