Skip to content

Commit

Permalink
Fix two user reported issues
Browse files Browse the repository at this point in the history
While these are both OpenClover limitations the changes allow for
a reasonable workaround in each case.

The sourceCompatibility function in clover-setup falls back to the
minimum supported Java version instead of the maximum causing newer
version of Java to fail in interesting ways with Java 1.3 level.

The NPE experienced when rendering report with columns might be
worked around by setting the numThreads to 1 instead of the default
2 threads.
  • Loading branch information
Alex-Vol-SV committed Mar 9, 2020
1 parent f2a85c2 commit 9b7c110
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ out
/.project
/.settings/
.DS_Store
/build-eclipse/
42 changes: 30 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ example on how to retrieve it from Bintray:
}

dependencies {
classpath 'com.bmuschko:gradle-clover-plugin:2.2.3'
classpath 'com.bmuschko:gradle-clover-plugin:2.2.5'
}
}

Expand Down Expand Up @@ -84,29 +84,29 @@ define will always be relative to the project's build directory.
to `'**/*.java'` and `'**/*.groovy'` for Groovy projects).
* `excludes`: A list of String Ant Glob Patterns to exclude for instrumentation. By default no files are excluded.
* `testIncludes`: A list of String Ant Glob Patterns to include for instrumentation for
[per-test coverage](http://confluence.atlassian.com/display/CLOVER/Unit+Test+Results+and+Per-Test+Coverage) (defaults to
[per-test coverage](http://openclover.org/doc/manual/latest/ant--test-results-and-per-test-coverage.html) (defaults to
`'**/*Test.java'` for Java projects, defaults to `'**/*Test.java,**/*Test.groovy,**/*Spec.groovy'` for Groovy and Grails3 projects).
* `testExcludes`: A list of String Ant Glob Patterns to exclude from instrumentation for
[per-test coverage](http://confluence.atlassian.com/display/CLOVER/Unit+Test+Results+and+Per-Test+Coverage) (for example mock classes, defaults to
[per-test coverage](http://openclover.org/doc/manual/latest/ant--test-results-and-per-test-coverage.html) (for example mock classes, defaults to
empty list - no excludes).
* `additionalSourceSets`: Defines custom source sets to be added for instrumentation. See example clover closure for details below.
* `additionalTestSourceSets`: Defines custom test source sets to be added for instrumentation. See example clover closure for details below.
* `targetPercentage`: The required target percentage total coverage e.g. "10%". The build fails if that goals is not met.
If not specified no target percentage will be checked.
* `optimizeTests`: If `true`, Clover will try to [optimize your tests](https://confluence.atlassian.com/display/CLOVER/About+Test+Optimization);
* `optimizeTests`: If `true`, Clover will try to [optimize your tests](http://openclover.org/doc/manual/latest/general--what-is-test-optimization.html);
if `false` Clover will not try to optimize your tests. Test optimization is disabled by default. Note that Clover does not
yet fully support test optimization for Groovy code; see [CLOV-1152](https://jira.atlassian.com/browse/CLOV-1152) for more information.
* `snapshotFile`: The location of the Clover snapshot file used for test optimization, relative to the project directory.
The snapshot file should survive clean builds, so it should *not* be placed in the project's build directory. The default
location is `.clover/coverage.db.snapshot`.
* `includeTasks`: A list of task names, allows to explicitly specify which test tasks should be introspected and used to gather coverage information - useful if there are more than one `Test` tasks in a project.
* `excludeTasks`: A list of task names, allows to exclude test tasks from introspection and gathering coverage information - useful if there are more than one `Test` tasks in a project.
* `instrumentLambda`: Controls which lambda types to instrument. [Expression lambdas may cause instrumentation to crash](https://confluence.atlassian.com/cloverkb/java-8-code-instrumented-by-clover-fails-to-compile-442270815.html).
* `instrumentLambda`: Controls which lambda types to instrument. [Expression lambdas may cause instrumentation to crash](http://openclover.org/doc/manual/latest/kb--java-8-code-instrumented-by-clover-fails-to-compile.html).
* `useClover3`: *Deprecated - this is not used anymore*
* `flushpolicy`: This String attribute controls how Clover flushes coverage data during a test run. Valid values are directed, interval, or threaded. [clover-setup Parameters](https://confluence.atlassian.com/clover/clover-setup-71600085.html#clover-setup-parametersParameters)
* `flushinterval`: When the flushpolicy is set to interval or threaded this value is the minimum period between flush operations (in milliseconds). [clover-setup Parameters](https://confluence.atlassian.com/clover/clover-setup-71600085.html#clover-setup-parametersParameters)
* `flushpolicy`: This String attribute controls how Clover flushes coverage data during a test run. Valid values are directed, interval, or threaded. [clover-setup Parameters](http://openclover.org/doc/manual/latest/ant--clover-setup.html#clover-setup-parametersParameters)
* `flushinterval`: When the flushpolicy is set to interval or threaded this value is the minimum period between flush operations (in milliseconds). [clover-setup Parameters](http://openclover.org/doc/manual/latest/ant--clover-setup.html#clover-setup-parametersParameters)

Within `clover` you can define [coverage contexts](http://confluence.atlassian.com/display/CLOVER/Using+Coverage+Contexts)
Within `clover` you can define [coverage contexts](http://openclover.org/doc/manual/latest/ant--using-coverage-contexts.html)
in a closure named `contexts`. There are two types of coverage contexts: statement contexts and method contexts. You can
define as many contexts as you want. Each of the context type closure define the following attributes:

Expand All @@ -122,7 +122,7 @@ Additionally, method contexts can be provided any of the following attributes to
* `maxAggregatedComplexity`: Match a method to this pattern if its aggregated cyclomatic complexity is not greater than maxAggregatedComplexity. In other words - all methods with aggregated complexity <= maxAggregatedComplexity will be filtered out. Aggregated complexity metric is a sum of the method complexity and complexity of all anonymous inline classes declared in the method.
* `maxAggregatedStatements`: Match a method to this pattern if its number of aggregated statements is not greater than maxAggregatedStatements. In other words - all methods with aggregated statements <= maxAggregatedStaments will be filtered out. Aggregated statements metric is a sum of the method statements and statements of all anonymous inline classes declared in the method.

For more information on method contexts, see the [main Clover documentation](https://confluence.atlassian.com/display/CLOVER/methodContext) for this feature.
For more information on method contexts, see the [main Clover documentation](http://openclover.org/doc/manual/latest/ant--methodcontext.html) for this feature.


Within `clover` you can define which report types should be generated in a closure named `report`:
Expand All @@ -132,12 +132,16 @@ Within `clover` you can define which report types should be generated in a closu
* `html`: Generates HTML report (defaults to `false`).
* `pdf`: Generates PDF report (defaults to `false`).
* `filter`: A comma or space separated list of contexts to exclude when generating coverage reports.
See [Using Coverage Contexts](http://confluence.atlassian.com/display/CLOVER/Using+Coverage+Contexts). By default no filter
See [Using Coverage Contexts](http://openclover.org/doc/manual/latest/ant--using-coverage-contexts.html). By default no filter
is applied.
* `testResultsDir`: Specifies the location of the JUnit4 test results XML report. This is necessary when the test use the new JUnit4 @Rule mechanism to declare expected exceptions. Clover fails to detect coverage for methods when this mechanism is used. This solution uses a feature of Clover that takes the coverage information directly from the JUnit XML report.
* `testResultsInclude`: If testResultsDir is specified this must be an Ant file name pattern to select the correct XML files within the directory (defaults to TEST-*.xml).
* `alwaysReport`: See OpenClover documentation for [clover-report current](http://openclover.org/doc/manual/latest/ant--clover-report.html#clover-report-Current)
* `includeFailedTestCoverage`: See OpenClover documentation for [clover-report current](http://openclover.org/doc/manual/latest/ant--clover-report.html#clover-report-Current)
* `numThreads`: See OpenClover documentation for [clover-report current](http://openclover.org/doc/manual/latest/ant--clover-report.html#clover-report-Current)
* `timeout`: See OpenClover documentation for [clover-report current](http://openclover.org/doc/manual/latest/ant--clover-report.html#clover-report-Current)

Within `report` closure you can define a closure named `columns` to enable selection of columns for the report output. This feature implements support for the columns defined in Clover documentation [Clover ReportComumns Nested Element](https://confluence.atlassian.com/clover/clover-report-71600095.html#clover-report-Columns). Each line in the closure must begin with the name of the column to add followed by a Groovy map with the 4 optional attributes for the column. We support `format`, `min`, `max` and `scope`. The format and scope values are checked against the documented supported contents and will throw errors if unsupported values are used. We do not implement support for the `expression` column at this time, if you attempt to use it the plugin will throw an error:
Within `report` closure you can define a closure named `columns` to enable selection of columns for the report output. This feature implements support for the columns defined in Clover documentation [Clover ReportComumns Nested Element](http://openclover.org/doc/manual/latest/ant--columns-element.html). Each line in the closure must begin with the name of the column to add followed by a Groovy map with the 4 optional attributes for the column. We support `format`, `min`, `max` and `scope`. The format and scope values are checked against the documented supported contents and will throw errors if unsupported values are used. We do not implement support for the `expression` column at this time, if you attempt to use it the plugin will throw an error:

* `format`: Determines how the value is rendered. Depending on the column, this may be one of raw, bar, % or longbar.
* `min`: Sets a minimum threshold on the value of the column. If the value is less than this it will be highlighted.
Expand All @@ -154,7 +158,7 @@ Within `report` closure you can define a closure named `historical` to enable Cl
* `to`: Specifies the date after which data points will be ignored (optional, see `to` attribute of Clover historical element)
* `added`: Closure to support nested `added` element from Clover `historical` element. Only the `range` and `interval` attributes are supported (optional, see `added` nested element of Clover historical element)
* `mover`: Closure that can appear multiple times to support the `movers` element from Clover `historical` element. Only the `threshold`, `range` and `interval` attributes are supported (optional, see `movers` nested element of Clover historical element)
See [Clover Report Historical Nested Element](https://confluence.atlassian.com/clover/clover-report-71600095.html#clover-report-<historical>)
See [Clover Report Historical Nested Element](http://openclover.org/doc/manual/latest/ant--clover-report.html#clover-report-%3Chistorical%3E)

Furthermore, within `clover` you can define compiler settings which will be passed to java and groovyc upon compilation of instrumented sources.
This is useful when specific compiler settings have been set on the main Java/Groovy compiler for your buildscript and
Expand All @@ -165,6 +169,10 @@ need to be carried over to the compilation of the instrumented sources. These a
* `debug`: Controls whether to invoke javac with the -g flag. This is useful for Spring MVC code that uses reflection for parameter mapping. (defaults to `false`).
* `additionalArgs`: The (optional) additional command line arguments for the compiler. This is useful for Spring MVC code that uses reflection for parameter mapping. This should be valid command line arguments as a spaces separated string. No attempt is made to validate this line, it is passed verbatim to the <compilerarg> nested element for the Ant `javac` task.
* `additionalGroovycOpts`: The (optional) additional options for the `groovyc` compiler. See [http://groovy-lang.org/groovyc.html#_ant_task]
* `sourceCompatibility`: Overrides the Java Compiler to prevent using compatibility modes not supported by OpenClover
* `targetCompatiility`: Overrides the Java Compiler to prevent using compatibility modes not supported by OpenClover

The `sourceCompatibility` and `targetCompatiility` options will work only as long as your code is compatible with the selections. If your code uses language features above the language level specified OpenClover will fail to compile the code.

The Clover plugin defines the following convention properties in the `clover` closure:

Expand Down Expand Up @@ -209,6 +217,10 @@ The Clover plugin defines the following convention properties in the `clover` cl
compiler {
encoding = 'UTF-8'

// Override the Java Compiler source and target compatibility settings
sourceCompatibility = '1.8'
targetCompatibility = '1.8'

// if the javac executable used by ant should be the same as the one used elsewhere.
executable = file('/usr/local/java/jdk1.8.0_05')
// used to add debug information for Spring applications
Expand Down Expand Up @@ -250,6 +262,12 @@ The Clover plugin defines the following convention properties in the `clover` cl
testResultsDir = project.tasks.getByName('test').reports.junitXml.destination
testResultsInclude = 'TEST-*.xml'

// Support controlling current-report for OpenClover
alwaysReport = false
includeFailedTestCoverage = false
numThreads = 2
timeout = '30 seconds'

// Clover report nested columns support
columns {
coveredMethods format: 'longbar', min: '75'
Expand Down
5 changes: 5 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### Version 2.2.5 (March 9, 2020)

* Add sourceCompatibility override to solve OpenClover limit and fallback to 1.3 Java compatibility
* Fix HTML Reporter throwing NPE - [Issue 146](https://github.com/bmuschko/gradle-clover-plugin/issues/146)

### Version 2.2.4 (October 19, 2019)

* Fix Vulnerable version of Jackson bind dependency - [Issue 142](https://github.com/bmuschko/gradle-clover-plugin/issues/142)
Expand Down
38 changes: 38 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,41 @@ idea.project {
gradleSettings.appendNode('option', [name: 'SDK_HOME', value: gradle.gradleHomeDir])
}
}

eclipse {

classpath {
// default settings for downloading sources and Javadoc:
downloadSources = true
downloadJavadoc = true

// This is a weird requirement that I think is fixed when
// we upgrade to the latest Gradle and the plugin tools.
sourceSets {
main {
resources {
srcDirs += "build/resources/main"
}
}
}

// This makes the Gradle paths and Eclipse paths align so
// that we have a working workspace from the start.
file {
whenMerged { classpath ->
classpath.entries.findAll { entry -> entry.kind == 'src' }.each { entry ->
switch(entry.path) {
case ~'src/main/groovy':
entry.output = "build/classes/groovy/main"
break
case ~'src/test/groovy':
entry.output = "build/classes/groovy/test"
break
case ~"build/resources/main":
entry.output = null
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ package com.bmuschko.gradle.clover
*/
class CloverCompilerConvention {
String encoding = 'UTF-8'
String sourceCompatibility
String targetCompatibility
File executable
boolean debug = false
String additionalArgs = null
Expand Down
28 changes: 26 additions & 2 deletions src/main/groovy/com/bmuschko/gradle/clover/CloverPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ class CloverPlugin implements Plugin<Project> {
map('buildDir') { project.buildDir }
map('sourceSets') { resolver.getSourceSets() }
map('testSourceSets') { resolver.getTestSourceSets() }
map('sourceCompatibility') { project.sourceCompatibility?.toString() }
map('targetCompatibility') { project.targetCompatibility?.toString() }
map('sourceCompatibility') { getSourceCompatibility(project, cloverPluginConvention) }
map('targetCompatibility') { getTargetCompatibility(project, cloverPluginConvention) }
map('includes') { getIncludes(project, cloverPluginConvention) }
map('excludes') { cloverPluginConvention.excludes }
map('testIncludes') { getTestIncludes(project, cloverPluginConvention) }
Expand Down Expand Up @@ -209,6 +209,10 @@ class CloverPlugin implements Plugin<Project> {
map('filter') { cloverPluginConvention.report.filter }
map('testResultsDir') { cloverPluginConvention.report.testResultsDir }
map('testResultsInclude') { cloverPluginConvention.report.testResultsInclude }
map('alwaysReport') { cloverPluginConvention.report.alwaysReport }
map('includeFailedTestCoverage') { cloverPluginConvention.report.includeFailedTestCoverage }
map('numThreads') { cloverPluginConvention.report.numThreads }
map('timeoutInterval') { cloverPluginConvention.report.timeout }
}
setCloverReportConventionMappings(project, cloverPluginConvention, generateCoverageReportTask)
}
Expand All @@ -227,6 +231,10 @@ class CloverPlugin implements Plugin<Project> {
map('filter') { cloverPluginConvention.report.filter }
map('testResultsDir') { cloverPluginConvention.report.testResultsDir }
map('testResultsInclude') { cloverPluginConvention.report.testResultsInclude }
map('alwaysReport') { cloverPluginConvention.report.alwaysReport }
map('includeFailedTestCoverage') { cloverPluginConvention.report.includeFailedTestCoverage }
map('numThreads') { cloverPluginConvention.report.numThreads }
map('timeoutInterval') { cloverPluginConvention.report.timeout }
}
setCloverReportConventionMappings(project, cloverPluginConvention, aggregateReportsTask)
}
Expand Down Expand Up @@ -474,6 +482,22 @@ class CloverPlugin implements Plugin<Project> {
}
}

private String getSourceCompatibility(Project project, CloverPluginConvention cloverPluginConvention) {
if (cloverPluginConvention.compiler.sourceCompatibility) {
return cloverPluginConvention.compiler.sourceCompatibility
}

return project.sourceCompatibility?.toString()
}

private String getTargetCompatibility(Project project, CloverPluginConvention cloverPluginConvention) {
if (cloverPluginConvention.compiler.targetCompatibility) {
return cloverPluginConvention.compiler.targetCompatibility
}

return project.targetCompatibility?.toString()
}

/**
* Gets includes for compilation. Uses includes if set as convention property. Otherwise, use default includes. The
* default includes are determined by the fact if Groovy plugin was applied to project or not.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class CloverReportConvention {
String filter
String testResultsDir
String testResultsInclude = 'TEST-*.xml'
Boolean alwaysReport = false
Boolean includeFailedTestCoverage = false
Integer numThreads = 2
String timeout = ''

CloverReportHistoricalConvention historical = new CloverReportHistoricalConvention()

Expand Down

0 comments on commit 9b7c110

Please sign in to comment.