diff --git a/CHANGELOG.md b/CHANGELOG.md index 73fdccc..2e7349e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log ========== +[Version 0.5.1](https://github.com/novoda/gradle-static-analysis-plugin/releases/tag/v0.5.1) +-------------------------- + +- Add `Violations` to public API ([PR#69](https://github.com/novoda/gradle-static-analysis-plugin/pull/69)) +- Custom violations evaluators ([PR#68](https://github.com/novoda/gradle-static-analysis-plugin/pull/68)) + [Version 0.5](https://github.com/novoda/gradle-static-analysis-plugin/releases/tag/v0.5) -------------------------- diff --git a/README.md b/README.md index 31f40da..4af3ae9 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.novoda:gradle-static-analysis-plugin:0.5' + classpath 'com.novoda:gradle-static-analysis-plugin:0.5.1' } } ``` diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 1a73cfa..8c99006 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -8,6 +8,7 @@ the build will not fail, which is very useful for legacy projects. * [Improve the report with a base URL](#improve-the-report-with-a-base-URL) * [Add exclusions with `exclude` filters](#add-exclusions-with-exclude-filters) * [Add exclusions with Android build variants](#add-exclusions-with-Android-build-variants) + * [Custom violations evaluator (**incubating**)](incubating/custom-evaluator.md#custom-violations-evaluator-incubating) --- @@ -27,6 +28,9 @@ Violations are then collected while running all the static analysis tools enable Only in the end they are cumulatively evaluated against the thresholds provided in the configuration to decide whether the build should fail or not. +If you don't specify a `penalty` configuration, the plugin will use the [default threshold values][penaltyextensioncode], which are to +allow any warning, but break the build on any error. + ## Improve the report with a base URL Build logs will show an overall report of how many violations have been found during the analysis and the links to the relevant HTML reports, for instance: @@ -97,3 +101,5 @@ staticAnalysis { ``` Please note that this is not supported for Detekt & Android Lint yet. + +[penaltyextensioncode]: https://github.com/novoda/gradle-static-analysis-plugin/blob/master/plugin/src/main/groovy/com/novoda/staticanalysis/PenaltyExtension.groovy diff --git a/docs/incubating/custom-evaluator.md b/docs/incubating/custom-evaluator.md new file mode 100644 index 0000000..98c261c --- /dev/null +++ b/docs/incubating/custom-evaluator.md @@ -0,0 +1,70 @@ +# Custom violations evaluator (incubating) + +> Since: [`0.5.1`](https://github.com/novoda/gradle-static-analysis-plugin/releases/tag/v0.5.1) +> +> :warning: This is an **experimental**, incubating feature that may be subject to breaking API changes at any time! + +The plugin uses a [`ViolationsEvaluator`][violationsevaluatorcode] to determine what to do with the results collected from all the active +tools (if any). The built-in behaviour is provided by the [`DefaultViolationsEvaluator`][defaultviolationsevaluatorcode], which you can +read more about [below](#the-defaultviolationsevaluator). The plugin's violations evaluation behaviour is not fixed, and it can be +customised by providing an implementation of the [`ViolationsEvaluator`][violationsevaluatorcode] interface. + +## Table of contents + * [The `DefaultViolationsEvaluator`](#the-defaultviolationsevaluator) + * [Creating a custom violations evaluator](#creating-a-custom-violations-evaluator) + +--- + +## The `DefaultViolationsEvaluator` +The plugin has a default mechanism to decide whether to consider a build as passing or failed. The mechanism is manifesting itself +as the `penalty` closure: + +```gradle +staticAnalysis { + penalty { + maxErrors = 0 + maxWarnings = 10 + } + //... +} +``` + +This closure instructs the plugin to use a [`DefaultViolationsEvaluator`][defaultviolationsevaluatorcode] that will count the number of +errors and warnings and compare them against the set thresholds. For more details, see the +[Configurable failure thresholds](../advanced-usage.md#configurable-failure-thresholds) documentation. + +## Creating a custom violations evaluator +In order to provide a custom evaluator, you can implement the [`ViolationsEvaluator`][violationsevaluatorcode] interface and provide +that implementation to the `evaluator` property of the `staticAnalysis` closure. The [`ViolationsEvaluator`][violationsevaluatorcode] +can be provided as a closure as well: + +```gradle +staticAnalysis { + evaluator { Set allViolations -> + // add your evaluation logic here + } + //... +} +``` + +The `evaluator` is invoked after all the `collectViolations` tasks have been completed, and is the last step in executing the plugin's +main task, `evaluateViolations`. + +The evaluation logic can be any arbitrary function that respects this contract: + * The evaluator receives a set containing all the [`Violations`][violationscode] that have been collected by the tools (one per tool) + * If the build is to be considered successful, then the evaluator will run to completion without throwing exceptions + * If the build is to be considered failed, then the evaluator will throw a `GradleException` + +Anything that respect such contract is valid. For example, a custom evaluator might: + * Collect all the report files and upload them somewhere, or send them to Slack or an email address + * Use the GitHub API to report the issues on the PR that the build is running on, à la [GNAG](https://github.com/btkelly/gnag) + * Only break the build if there are errors or warnings in one specific report + * Or anything else that you can think of + +Please note that the presence of an `evaluator` property will make the plugin ignore the `penalty` closure and its thresholds. If you +want to provide behaviour on top of the default [`DefaultViolationsEvaluator`][defaultviolationsevaluatorcode], you can have your own +evaluator run its logic and then delegate the thresholds counting to an instance of `DefaultViolationsEvaluator` you create. + +[violationsevaluatorcode]: https://github.com/novoda/gradle-static-analysis-plugin/blob/master/plugin/src/main/groovy/com/novoda/staticanalysis/ViolationsEvaluator.groovy +[defaultviolationsevaluatorcode]: https://github.com/novoda/gradle-static-analysis-plugin/blob/master/plugin/src/main/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluator.groovy +[violationscode]: https://github.com/novoda/gradle-static-analysis-plugin/blob/master/plugin/src/main/groovy/com/novoda/staticanalysis/internal/Violations.groovy diff --git a/gradle/publish.gradle b/gradle/publish.gradle index 3ebe9f4..df8c5e4 100644 --- a/gradle/publish.gradle +++ b/gradle/publish.gradle @@ -1,4 +1,4 @@ -version = '0.5' +version = '0.5.1' String tag = "v$project.version" groovydoc.docTitle = 'Static Analysis Plugin' diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluator.groovy index c178d46..d2b7761 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluator.groovy @@ -1,6 +1,5 @@ package com.novoda.staticanalysis -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.GradleException import org.gradle.api.logging.Logger diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/EvaluateViolationsTask.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/EvaluateViolationsTask.groovy index b36d2e7..f9a958f 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/EvaluateViolationsTask.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/EvaluateViolationsTask.groovy @@ -1,6 +1,5 @@ package com.novoda.staticanalysis -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisExtension.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisExtension.groovy index 99d5bee..8dc233a 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisExtension.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisExtension.groovy @@ -1,6 +1,5 @@ package com.novoda.staticanalysis -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.Action import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.NamedDomainObjectFactory diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisPlugin.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisPlugin.groovy index d412e2a..d639148 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisPlugin.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/StaticAnalysisPlugin.groovy @@ -1,7 +1,6 @@ package com.novoda.staticanalysis import com.novoda.staticanalysis.internal.CodeQualityConfigurator -import com.novoda.staticanalysis.internal.Violations import com.novoda.staticanalysis.internal.checkstyle.CheckstyleConfigurator import com.novoda.staticanalysis.internal.detekt.DetektConfigurator import com.novoda.staticanalysis.internal.findbugs.FindbugsConfigurator diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/Violations.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/Violations.groovy similarity index 94% rename from plugin/src/main/groovy/com/novoda/staticanalysis/internal/Violations.groovy rename to plugin/src/main/groovy/com/novoda/staticanalysis/Violations.groovy index 639367f..5f19a9c 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/Violations.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/Violations.groovy @@ -1,4 +1,4 @@ -package com.novoda.staticanalysis.internal; +package com.novoda.staticanalysis; class Violations { private final String toolName diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/ViolationsEvaluator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/ViolationsEvaluator.groovy index 8671150..0f5a77d 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/ViolationsEvaluator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/ViolationsEvaluator.groovy @@ -1,7 +1,5 @@ package com.novoda.staticanalysis -import com.novoda.staticanalysis.internal.Violations - interface ViolationsEvaluator { void evaluate(Set allViolations) diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CodeQualityConfigurator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CodeQualityConfigurator.groovy index e8fe42f..f167795 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CodeQualityConfigurator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CodeQualityConfigurator.groovy @@ -1,6 +1,7 @@ package com.novoda.staticanalysis.internal import com.novoda.staticanalysis.StaticAnalysisExtension +import com.novoda.staticanalysis.Violations import org.gradle.api.Action import org.gradle.api.NamedDomainObjectSet import org.gradle.api.Project diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CollectViolationsTask.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CollectViolationsTask.groovy index 987fded..6d1cd91 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CollectViolationsTask.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/CollectViolationsTask.groovy @@ -1,5 +1,6 @@ package com.novoda.staticanalysis.internal +import com.novoda.staticanalysis.Violations import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CheckstyleConfigurator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CheckstyleConfigurator.groovy index b530549..5c158e2 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CheckstyleConfigurator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CheckstyleConfigurator.groovy @@ -1,8 +1,8 @@ package com.novoda.staticanalysis.internal.checkstyle +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CodeQualityConfigurator import com.novoda.staticanalysis.internal.QuietLogger -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.* import org.gradle.api.plugins.quality.Checkstyle import org.gradle.api.plugins.quality.CheckstyleExtension diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CollectCheckstyleViolationsTask.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CollectCheckstyleViolationsTask.groovy index 90beb29..3d0727b 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CollectCheckstyleViolationsTask.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/checkstyle/CollectCheckstyleViolationsTask.groovy @@ -1,7 +1,7 @@ package com.novoda.staticanalysis.internal.checkstyle +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CollectViolationsTask -import com.novoda.staticanalysis.internal.Violations import groovy.util.slurpersupport.GPathResult class CollectCheckstyleViolationsTask extends CollectViolationsTask { diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/CollectDetektViolationsTask.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/CollectDetektViolationsTask.groovy index 326007f..845bc04 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/CollectDetektViolationsTask.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/CollectDetektViolationsTask.groovy @@ -1,7 +1,7 @@ package com.novoda.staticanalysis.internal.detekt +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CollectViolationsTask -import com.novoda.staticanalysis.internal.Violations import groovy.util.slurpersupport.GPathResult class CollectDetektViolationsTask extends CollectViolationsTask { diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/DetektConfigurator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/DetektConfigurator.groovy index 8e7ef69..1ff7116 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/DetektConfigurator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/detekt/DetektConfigurator.groovy @@ -1,8 +1,8 @@ package com.novoda.staticanalysis.internal.detekt import com.novoda.staticanalysis.StaticAnalysisExtension +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.Configurator -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.GradleException import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/CollectFindbugsViolationsTask.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/CollectFindbugsViolationsTask.groovy index 0248d15..50e9fcf 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/CollectFindbugsViolationsTask.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/CollectFindbugsViolationsTask.groovy @@ -1,7 +1,7 @@ package com.novoda.staticanalysis.internal.findbugs +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CollectViolationsTask -import com.novoda.staticanalysis.internal.Violations class CollectFindbugsViolationsTask extends CollectViolationsTask { diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/FindbugsConfigurator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/FindbugsConfigurator.groovy index 0250999..bac2ba9 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/FindbugsConfigurator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/findbugs/FindbugsConfigurator.groovy @@ -1,7 +1,7 @@ package com.novoda.staticanalysis.internal.findbugs +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CodeQualityConfigurator -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.* import org.gradle.api.file.ConfigurableFileTree import org.gradle.api.file.FileCollection diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTask.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTask.groovy index 8f4dccb..ed128e9 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTask.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTask.groovy @@ -1,7 +1,7 @@ package com.novoda.staticanalysis.internal.lint +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CollectViolationsTask -import com.novoda.staticanalysis.internal.Violations import groovy.util.slurpersupport.GPathResult class CollectLintViolationsTask extends CollectViolationsTask { diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/LintConfigurator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/LintConfigurator.groovy index cf58b35..a90b59b 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/LintConfigurator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/lint/LintConfigurator.groovy @@ -1,8 +1,8 @@ package com.novoda.staticanalysis.internal.lint import com.novoda.staticanalysis.StaticAnalysisExtension +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.Configurator -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.Task diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/CollectPmdViolationsTask.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/CollectPmdViolationsTask.groovy index 7b9dc35..6186b18 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/CollectPmdViolationsTask.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/CollectPmdViolationsTask.groovy @@ -1,7 +1,7 @@ package com.novoda.staticanalysis.internal.pmd +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CollectViolationsTask -import com.novoda.staticanalysis.internal.Violations class CollectPmdViolationsTask extends CollectViolationsTask { diff --git a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/PmdConfigurator.groovy b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/PmdConfigurator.groovy index 4a55822..f01d6f7 100644 --- a/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/PmdConfigurator.groovy +++ b/plugin/src/main/groovy/com/novoda/staticanalysis/internal/pmd/PmdConfigurator.groovy @@ -1,8 +1,8 @@ package com.novoda.staticanalysis.internal.pmd +import com.novoda.staticanalysis.Violations import com.novoda.staticanalysis.internal.CodeQualityConfigurator import com.novoda.staticanalysis.internal.QuietLogger -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.* import org.gradle.api.plugins.quality.Pmd import org.gradle.api.plugins.quality.PmdExtension diff --git a/plugin/src/test/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluatorTest.groovy b/plugin/src/test/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluatorTest.groovy index 1a5a4be..5093183 100644 --- a/plugin/src/test/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluatorTest.groovy +++ b/plugin/src/test/groovy/com/novoda/staticanalysis/DefaultViolationsEvaluatorTest.groovy @@ -1,6 +1,5 @@ package com.novoda.staticanalysis -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.GradleException import org.gradle.api.logging.Logger import org.junit.Before diff --git a/plugin/src/test/groovy/com/novoda/staticanalysis/StaticAnalysisExtensionTest.groovy b/plugin/src/test/groovy/com/novoda/staticanalysis/StaticAnalysisExtensionTest.groovy index b6bf39a..0ddb6d4 100644 --- a/plugin/src/test/groovy/com/novoda/staticanalysis/StaticAnalysisExtensionTest.groovy +++ b/plugin/src/test/groovy/com/novoda/staticanalysis/StaticAnalysisExtensionTest.groovy @@ -1,6 +1,5 @@ package com.novoda.staticanalysis -import com.novoda.staticanalysis.internal.Violations import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder diff --git a/plugin/src/test/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTaskTest.groovy b/plugin/src/test/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTaskTest.groovy index c390487..f970bec 100644 --- a/plugin/src/test/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTaskTest.groovy +++ b/plugin/src/test/groovy/com/novoda/staticanalysis/internal/lint/CollectLintViolationsTaskTest.groovy @@ -1,6 +1,6 @@ package com.novoda.staticanalysis.internal.lint -import com.novoda.staticanalysis.internal.Violations +import com.novoda.staticanalysis.Violations import com.novoda.test.Fixtures import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder