Skip to content

Commit

Permalink
Enhance compatibility with Gradle 8.x
Browse files Browse the repository at this point in the history
Cleanup the code to eliminate the uses of the soon to be removed
ConfigureUtil class. Replaced with properly configured Groovy classes
where needed.

Fixup some more test details to keep from failing builds on 4.8 Gradle.
  • Loading branch information
Alex-Vol committed Dec 29, 2021
1 parent fb8b2a6 commit f836299
Show file tree
Hide file tree
Showing 20 changed files with 358 additions and 123 deletions.
25 changes: 16 additions & 9 deletions README.md
Expand Up @@ -28,17 +28,19 @@ Built for OpenJDK JDK8
Tested with OpenJDK JDK8

| Gradle Version | Works |
| :------------: | :---: |
| 4.10.2 | yes |
| 5.6.4 | yes |
| 6.9.1 | yes |
| 7.2 | yes |
|:--------------:| :---: |
| 4.8 | yes |
| 5.6.4 | yes |
| 6.9.2 | yes |
| 7.3.3 | yes |

# Gradle version 4.6 and older
# Gradle version 4.7 and older

For all versions of Gradle older than 4.7 use the 2.2.5 version of this plugin. Version 3.0.0 and newer only support Gradle 4.7 or later.
For all versions of Gradle older than 4.8 use the 2.2.5 version of this plugin.
Version 3.0.0 and newer only support Gradle 4.8 or later.

We are switching the build to run on JDK 11 which means we cannot test with Gradle 4.7 anymore so I cannot guarantee that the 4.7 compatibilty will be available after 3.0.2 release.
We are switching the build to run on JDK 11 which means we cannot test with Gradle 4.8
anymore, so I cannot guarantee that the 4.8 compatibility will be available after 3.0.2 release.

## Usage

Expand All @@ -57,7 +59,7 @@ example on how to retrieve it from Gradle Plugins Portal:
}

dependencies {
classpath 'com.bmuschko:gradle-clover-plugin:3.0.2'
classpath 'com.bmuschko:gradle-clover-plugin:3.0.3'
}
}

Expand All @@ -71,6 +73,11 @@ with a multi-module project make sure you apply the plugin and declare the `clov
With the introduction of the OpenClover support the `licenseLocation` clover convention is
now unused. For compatibility with existing clover Gradle configurations the plugin will accept a value set but will do nothing with it.


## GroovyDoc for API

The GroovyDoc for the plugin API can be found here: [GroovyDoc](https://bmuschko.github.io/gradle-clover-plugin/docs/groovydoc/index.html?overview-summary.html)

## Tasks

The Clover plugin defines the following tasks:
Expand Down
4 changes: 4 additions & 0 deletions RELEASE_NOTES.md
@@ -1,3 +1,7 @@
### Version 3.0.3

* Enhanced compatibility with Gradle 8.x

### Version 3.0.2 (October 5, 2021)

* Compatibility with Gradle 7.2
Expand Down
3 changes: 1 addition & 2 deletions gradle.properties
@@ -1,7 +1,6 @@
# Allow easy configuration of Gradle versions
gradleCurrentVersion = 6.9.1
gradleTestingVersions = 4.10.2,5.6.4,6.9.1,7.2
gradleTestingVersions = 4.8,5.6.4,6.9.2,7.3.3

# Set default behavior for Reckon version plugin
reckon.scope=patch

8 changes: 4 additions & 4 deletions gradle/functional-test.gradle
Expand Up @@ -20,8 +20,8 @@ task functionalTest(type: Test) {
systemProperty 'gradleTestingVersions', gradleTestingVersions

reports {
html.destination = project.file("$html.destination/functional")
junitXml.destination = project.file("$junitXml.destination/functional")
html.outputLocation = project.file("$buildDir/reports/tests/functionalTest")
junitXml.outputLocation = project.file("$buildDir/reports/tests/functionalTestXml")
}
}

Expand All @@ -38,12 +38,12 @@ idea.module {
testSourceDirs += it
}

scopes.TEST.plus += [configurations.functionalTestRuntime]
scopes.TEST.plus += [configurations.functionalTestRuntimeClasspath]
}

eclipse {
classpath {
plusConfigurations += [ configurations.functionalTestRuntime ]
plusConfigurations += [ configurations.functionalTestRuntimeClasspath ]

//customizing the classes output directory:
defaultOutputDir = file('build-eclipse')
Expand Down
6 changes: 3 additions & 3 deletions gradle/integration-test.gradle
Expand Up @@ -16,8 +16,8 @@ task integrationTest(type: Test) {
check.dependsOn it

reports {
html.destination = project.file("$html.destination/integration")
junitXml.destination = project.file("$junitXml.destination/integration")
html.outputLocation = project.file("$buildDir/reports/tests/integrationTest")
junitXml.outputLocation = project.file("$buildDir/reports/tests/integrationTestXml")
}
}

Expand All @@ -26,5 +26,5 @@ idea.module {
testSourceDirs += it
}

scopes.TEST.plus += [configurations.integrationTestRuntime]
scopes.TEST.plus += [configurations.integrationTestRuntimeClasspath]
}
Expand Up @@ -9,7 +9,9 @@ repositories {
mavenCentral()
}

boolean isGradle6OrLess = gradle.gradleVersion.split('\\.')[0].toInteger() < 7
import org.gradle.util.GradleVersion

boolean isGradle6OrLess = GradleVersion.version('7.0') > GradleVersion.current()
def spockVersion = isGradle6OrLess ? '1.0-groovy-2.4' : '2.0-groovy-3.0'

test {
Expand Down
Expand Up @@ -25,8 +25,10 @@ sourceSets {
}
}

import org.gradle.util.GradleVersion

task customTest(type: Test) {
if (gradle.gradleVersion.split('\\.')[0].toInteger() < 4)
if (GradleVersion.version('4.0') >= GradleVersion.current())
testClassesDir = sourceSets.customTest.output.classesDir
else
testClassesDirs = sourceSets.customTest.output.classesDirs
Expand Down
Expand Up @@ -9,7 +9,9 @@ repositories {
mavenCentral()
}

boolean isGradle6OrLess = gradle.gradleVersion.split('\\.')[0].toInteger() < 7
import org.gradle.util.GradleVersion

boolean isGradle6OrLess = GradleVersion.version('7.0') > GradleVersion.current()
def spockVersion = isGradle6OrLess ? '1.0-groovy-2.4' : '2.0-groovy-3.0'

test {
Expand Down
Expand Up @@ -27,10 +27,12 @@ processIntegTestResources {
duplicatesStrategy = 'exclude'
}

import org.gradle.util.GradleVersion

task integrationTest(type: Test, dependsOn: test) {
description = 'Runs the integration tests.'
group = 'verification'
if (gradle.gradleVersion.split('\\.')[0].toInteger() < 4)
if (GradleVersion.version('4.0') >= GradleVersion.current())
testClassesDir = sourceSets.integTest.output.classesDir
else
testClassesDirs = sourceSets.integTest.output.classesDirs
Expand All @@ -51,16 +53,18 @@ tasks.withType(GroovyCompile) {
sourceCompatibility = '1.8'

// Need to wire the instrumentation task to the compile task when
// using the aditional tests facility because we loose visibility
// using the additional tests facility because we loose visibility
// into the task dependencies of the source sets injected
tasks.matching { it.name == 'cloverInstrumentCodeForTest' }.configureEach {
dependsOn 'compileIntegTestJava'
afterEvaluate {
cloverInstrumentCodeForTest {
dependsOn 'compileIntegTestJava'
}
}

clover {
additionalTestSourceSet {
srcDirs = sourceSets.integTest.java.srcDirs
if (gradle.gradleVersion.split('\\.')[0].toInteger() < 4)
if (GradleVersion.version('4.0') >= GradleVersion.current())
classesDir = sourceSets.integTest.output.classesDir
else
classesDir = sourceSets.integTest.java.outputDir
Expand Down
37 changes: 21 additions & 16 deletions src/main/groovy/com/bmuschko/gradle/clover/CloverPlugin.groovy
Expand Up @@ -19,14 +19,11 @@ import static com.bmuschko.gradle.clover.CloverUtils.*

import java.util.concurrent.Callable

import javax.inject.Inject

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTreeElement
import org.gradle.api.internal.project.IsolatedAntBuilder
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SourceSet
Expand Down Expand Up @@ -59,7 +56,7 @@ class CloverPlugin implements Plugin<Project> {
project.configurations.create(CONFIGURATION_NAME).setVisible(false).setTransitive(true)
.setDescription('The Clover library to be used for this project.')

CloverPluginConvention cloverPluginConvention = new CloverPluginConvention()
CloverPluginConvention cloverPluginConvention = project.objects.newInstance(CloverPluginConvention)
project.convention.plugins.clover = cloverPluginConvention

AggregateDatabasesTask aggregateDatabasesTask = configureAggregateDatabasesTask(project, cloverPluginConvention)
Expand Down Expand Up @@ -360,8 +357,9 @@ class CloverPlugin implements Plugin<Project> {

project.sourceSets.each { SourceSet sourceSet ->
if (hasJavaPlugin(project) && isJavaSourceSetOf(sourceSet, testTask)) {
CloverSourceSet cloverSourceSet = new CloverSourceSet(false)
CloverSourceSet cloverSourceSet = project.objects.newInstance(CloverSourceSet)
cloverSourceSet.with {
groovy = false
name = 'java'
srcDirs.addAll(sourceSet.java.srcDirs)
classesDir = sourceSet.java.outputDir
Expand All @@ -372,8 +370,9 @@ class CloverPlugin implements Plugin<Project> {
}

if (hasGroovyPlugin(project) && isGroovySourceSetOf(sourceSet, testTask)) {
CloverSourceSet cloverSourceSet = new CloverSourceSet(true)
CloverSourceSet cloverSourceSet = project.objects.newInstance(CloverSourceSet)
cloverSourceSet.with {
groovy = true
name = 'groovy'
srcDirs.addAll(sourceSet.groovy.srcDirs)
classesDir = sourceSet.groovy.outputDir
Expand All @@ -386,10 +385,12 @@ class CloverPlugin implements Plugin<Project> {

if (cloverPluginConvention.additionalSourceSets) {
cloverPluginConvention.additionalSourceSets.each { sourceSet ->
CloverSourceSet additionalSourceSet = CloverSourceSet.from(sourceSet)
additionalSourceSet.groovy = hasGroovySource(additionalSourceSet.srcDirs)
additionalSourceSet.classpathProvider = classpathCallable
additionalSourceSet.instrumentedClassesDir = project.layout.buildDirectory.dir("${instrumentedDirPath}/${additionalSourceSet.name}").get().asFile
CloverSourceSet additionalSourceSet = CloverSourceSet.from(project.objects, sourceSet)
additionalSourceSet.with {
groovy = hasGroovySource(additionalSourceSet.srcDirs)
instrumentedClassesDir = project.layout.buildDirectory.dir("${instrumentedDirPath}/${additionalSourceSet.name}").get().asFile
classpathProvider = classpathCallable
}
sourceSets[testTask.name] << additionalSourceSet
}
}
Expand Down Expand Up @@ -425,8 +426,9 @@ class CloverPlugin implements Plugin<Project> {

project.sourceSets.each { SourceSet sourceSet ->
if (hasJavaPlugin(project) && isJavaTestSourceSetOf(sourceSet, testTask)) {
CloverSourceSet cloverSourceSet = new CloverSourceSet(false)
CloverSourceSet cloverSourceSet = project.objects.newInstance(CloverSourceSet)
cloverSourceSet.with {
groovy = false
name = 'java'
srcDirs.addAll(sourceSet.java.srcDirs)
classesDir = sourceSet.java.outputDir
Expand All @@ -437,8 +439,9 @@ class CloverPlugin implements Plugin<Project> {
}

if (hasGroovyPlugin(project) && isGroovyTestSourceSetOf(sourceSet, testTask)) {
CloverSourceSet cloverSourceSet = new CloverSourceSet(true)
CloverSourceSet cloverSourceSet = project.objects.newInstance(CloverSourceSet)
cloverSourceSet.with {
groovy = true
name = 'groovy'
srcDirs.addAll(sourceSet.groovy.srcDirs)
classesDir = sourceSet.groovy.outputDir
Expand All @@ -451,10 +454,12 @@ class CloverPlugin implements Plugin<Project> {

if (cloverPluginConvention.additionalTestSourceSets) {
cloverPluginConvention.additionalTestSourceSets.each { testSourceSet ->
CloverSourceSet additionalTestSourceSet = CloverSourceSet.from(testSourceSet)
additionalTestSourceSet.groovy = hasGroovySource(additionalTestSourceSet.srcDirs)
additionalTestSourceSet.classpathProvider = classpathCallable
additionalTestSourceSet.instrumentedClassesDir = project.layout.buildDirectory.dir("${instrumentedDirPath}/${additionalTestSourceSet.name}").get().asFile
CloverSourceSet additionalTestSourceSet = CloverSourceSet.from(project.objects, testSourceSet)
additionalTestSourceSet.with {
groovy = hasGroovySource(additionalTestSourceSet.srcDirs)
instrumentedClassesDir = project.layout.buildDirectory.dir("${instrumentedDirPath}/${additionalTestSourceSet.name}").get().asFile
classpathProvider = classpathCallable
}
testSourceSets[testTask.name] << additionalTestSourceSet
}
}
Expand Down
Expand Up @@ -15,8 +15,10 @@
*/
package com.bmuschko.gradle.clover

import org.gradle.api.tasks.Internal
import org.gradle.util.ConfigureUtil
import org.gradle.api.Action
import org.gradle.api.model.ObjectFactory

import javax.inject.Inject

/**
* Defines Clover plugin convention.
Expand All @@ -40,61 +42,63 @@ class CloverPluginConvention {
List<String> excludes
List<String> testIncludes
List<String> testExcludes
CloverReportConvention report = new CloverReportConvention()
CloverContextsConvention contexts = new CloverContextsConvention()
CloverCompilerConvention compiler = new CloverCompilerConvention()
final CloverReportConvention report
final CloverContextsConvention contexts
final CloverCompilerConvention compiler
List<String> includeTasks
List<String> excludeTasks
String instrumentLambda
boolean debug = false
int flushinterval = 1000
FlushPolicy flushpolicy = FlushPolicy.directed

def clover(Closure closure) {
ConfigureUtil.configure(closure, this)
private final ObjectFactory objectFactory

@Inject
CloverPluginConvention(ObjectFactory objectFactory) {
this.objectFactory = objectFactory
report = objectFactory.newInstance(CloverReportConvention)
contexts = objectFactory.newInstance(CloverContextsConvention)
compiler = objectFactory.newInstance(CloverCompilerConvention)
}

def clover(Action<CloverPluginConvention> action) {
action.execute(this)
}

def contexts(Closure closure) {
ConfigureUtil.configure(closure, contexts)
def contexts(Action<CloverContextsConvention> action) {
action.execute(contexts)
}

def statement(Closure closure) {
closure.resolveStrategy = Closure.DELEGATE_FIRST
CloverContextConvention statementContext = new CloverContextConvention()
closure.delegate = statementContext
def statement(Action<CloverContextConvention> action) {
CloverContextConvention statementContext = objectFactory.newInstance(CloverContextConvention)
contexts.statements << statementContext
closure()
action.execute(statementContext)
}

def method(Closure closure) {
closure.resolveStrategy = Closure.DELEGATE_FIRST
CloverMethodContextConvention methodContext = new CloverMethodContextConvention()
closure.delegate = methodContext
def method(Action<CloverMethodContextConvention> action) {
CloverMethodContextConvention methodContext = objectFactory.newInstance(CloverMethodContextConvention)
contexts.methods << methodContext
closure()
action.execute(methodContext)
}

def additionalSourceSet(Closure closure) {
closure.resolveStrategy = Closure.DELEGATE_FIRST
CloverSourceSet additionalSourceSet = new CloverSourceSet()
closure.delegate = additionalSourceSet
def additionalSourceSet(Action<CloverSourceSet> action) {
CloverSourceSet additionalSourceSet = objectFactory.newInstance(CloverSourceSet)
additionalSourceSets << additionalSourceSet
closure()
action.execute(additionalSourceSet)
}

def additionalTestSourceSet(Closure closure) {
closure.resolveStrategy = Closure.DELEGATE_FIRST
CloverSourceSet additionalTestSourceSet = new CloverSourceSet()
closure.delegate = additionalTestSourceSet
def additionalTestSourceSet(Action<CloverSourceSet> action) {
CloverSourceSet additionalTestSourceSet = objectFactory.newInstance(CloverSourceSet)
additionalTestSourceSets << additionalTestSourceSet
closure()
action.execute(additionalTestSourceSet)
}

def report(Closure closure) {
ConfigureUtil.configure(closure, report)
def report(Action<CloverReportConvention> action) {
action.execute(report)
}

def compiler(Closure closure) {
ConfigureUtil.configure(closure, compiler)
def compiler(Action<CloverCompilerConvention> action) {
action.execute(compiler)
}
}

0 comments on commit f836299

Please sign in to comment.