Skip to content

Commit

Permalink
Make PactVerificationTask as much ready as possible for configuration…
Browse files Browse the repository at this point in the history
… cache
  • Loading branch information
prof18 committed Oct 16, 2022
1 parent 0a23cab commit d1e76e3
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package au.com.dius.pact.provider.gradle
import groovy.transform.CompileStatic
import org.gradle.api.GradleScriptException
import org.gradle.api.Project
import org.gradle.api.tasks.GradleBuild

/**
* Main plugin class
Expand All @@ -13,8 +14,7 @@ class PactPlugin extends PactPluginBase {
void apply(Project project) {

// Create and install the extension object
def extension = project.extensions.create('pact', PactPluginExtension, project.container(GradleProviderInfo,
new ProviderInfoFactory(project)))
def extension = project.extensions.create('pact', PactPluginExtension, project.container(GradleProviderInfo))

project.task(PACT_VERIFY, description: 'Verify your pacts against your providers', group: GROUP)

Expand Down Expand Up @@ -50,7 +50,7 @@ class PactPlugin extends PactPluginBase {
it.pact.serviceProviders.all { GradleProviderInfo provider ->
setupPactConsumersFromBroker(provider, project, it.pact)

def taskName = {
String taskName = {
def defaultName = "pactVerify_${provider.name.replaceAll(/\s+/, '_')}".toString()
try {
def clazz = this.getClass().classLoader.loadClass('org.gradle.util.NameValidator').metaClass
Expand All @@ -70,22 +70,45 @@ class PactPlugin extends PactPluginBase {
}
} ()

def providerTask = project.task(taskName,
description: "Verify the pacts against ${provider.name}", type: PactVerificationTask,
group: GROUP) {
provider.taskNames = project.gradle.startParameter.taskNames

def providerTask = project.tasks.register(taskName, PactVerificationTask) {
group = GROUP
description = "Verify the pacts against ${provider.name}"

notCompatibleWithConfigurationCache("Configuration Cache is disabled for this task because of `executeStateChangeTask`")

providerToVerify = provider

taskContainer.addAll(project.tasks)
List<URL> classPathUrl = []
try {
classPathUrl = project.sourceSets.test.runtimeClasspath*.toURL()
} catch (MissingPropertyException ignored) {
// do nothing, the list will be empty
}
testClasspathURL.set(classPathUrl)
projectVersion.set(project.version)
report.set(extension.reports)
buildDir.set(project.buildDir)
}

if (project.tasks.findByName(TEST_CLASSES)) {
providerTask.dependsOn TEST_CLASSES
providerTask.configure {
dependsOn TEST_CLASSES
}
}

if (provider.startProviderTask != null) {
providerTask.dependsOn(provider.startProviderTask)
providerTask.configure {
dependsOn(provider.startProviderTask)
}
}

if (provider.terminateProviderTask != null) {
providerTask.finalizedBy(provider.terminateProviderTask)
providerTask.configure {
finalizedBy(provider.terminateProviderTask)
}
}

if (provider.dependencyForPactVerify) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,61 @@ package au.com.dius.pact.provider.gradle

import au.com.dius.pact.provider.IProviderVerifier
import au.com.dius.pact.provider.ProviderVerifier
import javax.inject.Inject
import org.gradle.api.GradleScriptException
import org.gradle.api.Task
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.GradleBuild
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction

/**
* Task to verify a pact against a provider
*/
class PactVerificationTask extends PactVerificationBaseTask {
abstract class PactVerificationTask extends PactVerificationBaseTask {
@Internal
IProviderVerifier verifier = new ProviderVerifier()
@Internal
GradleProviderInfo providerToVerify

@Inject
protected abstract ProviderFactory getProviderFactory();

@Input
@Optional
abstract ListProperty<URL> getTestClasspathURL()

@Input
abstract SetProperty<Task> getTaskContainer()

@Input
abstract Property<Object> getProjectVersion()

@Input
@Optional
abstract Property<VerificationReports> getReport()

@Input
abstract Property<File> getBuildDir()

@TaskAction
void verifyPact() {
verifier.with {
verificationSource = 'gradle'
projectHasProperty = { project.hasProperty(it) }
projectGetProperty = { project.property(it) }
projectHasProperty = { providerFactory.gradleProperty(it).present }
projectGetProperty = { providerFactory.gradleProperty(it).get() }
pactLoadFailureMessage = { 'You must specify the pact file to execute (use pactSource = file(...) etc.)' }
checkBuildSpecificTask = { it instanceof Task || it instanceof String && project.tasks.findByName(it) }
checkBuildSpecificTask = { it instanceof Task || it instanceof String && taskContainer.get().find { t -> t.name == it } }
executeBuildSpecificTask = this.&executeStateChangeTask
projectClasspath = {
project.sourceSets.test.runtimeClasspath*.toURL()
testClasspathURL.get()
}
providerVersion = providerToVerify.providerVersion ?: { project.version }
providerVersion = providerToVerify.providerVersion ?: { projectVersion.get() }
if (providerToVerify.providerTags) {
if (providerToVerify.providerTags instanceof Closure ) {
providerTags = providerToVerify.providerTags
Expand All @@ -43,9 +70,10 @@ class PactVerificationTask extends PactVerificationBaseTask {
}
}

if (project.pact.reports) {
def reportsDir = new File(project.buildDir, 'reports/pact')
reporters = project.pact.reports.toVerifierReporters(reportsDir, it)
def report = report.getOrElse(null)
if (report != null) {
def reportsDir = new File(buildDir.get(), 'reports/pact')
reporters = report.toVerifierReporters(reportsDir, it)
}
}

Expand All @@ -57,7 +85,8 @@ class PactVerificationTask extends PactVerificationBaseTask {
}

def executeStateChangeTask(t, state) {
def task = t instanceof String ? project.tasks.getByName(t) : t
def taskSet = taskContainer.get()
def task = t instanceof String ? taskSet.find {it.name == t } : t
task.setProperty('providerState', state)
task.ext.providerState = state
def build = project.task(type: GradleBuild) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,23 @@ import groovy.lang.Closure
import mu.KLogging
import org.gradle.api.GradleScriptException
import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory
import java.io.File
import java.net.URL
import javax.inject.Inject

/**
* Extends the provider info to be setup in a gradle build
*/
open class GradleProviderInfo(override var name: String, val project: Project) : IProviderInfo {
open class GradleProviderInfo @Inject constructor(
override var name: String,
private val objectFactory: ObjectFactory,
) : IProviderInfo {
var providerVersion: Any? = null
var providerTags: Any? = null
var brokerConfig: PactBrokerConsumerConfig = PactBrokerConsumerConfig(project.objects)
var brokerConfig: PactBrokerConsumerConfig = PactBrokerConsumerConfig(objectFactory)
val provider = ProviderInfo(name)
var taskNames: List<String> = emptyList()

override var protocol: String by provider::protocol
override var host: Any? by provider::host
Expand All @@ -46,7 +52,7 @@ open class GradleProviderInfo(override var name: String, val project: Project) :
var isDependencyForPactVerify: Boolean by provider::isDependencyForPactVerify

open fun hasPactWith(consumer: String, closure: Closure<GradleConsumerInfo>): IConsumerInfo {
val consumerInfo = project.objects.newInstance(GradleConsumerInfo::class.java, consumer)
val consumerInfo = objectFactory.newInstance(GradleConsumerInfo::class.java, consumer)
consumerInfo.name = consumer
consumerInfo.verificationType = this.verificationType

Expand Down Expand Up @@ -92,7 +98,7 @@ open class GradleProviderInfo(override var name: String, val project: Project) :
provider.hasPactsFromPactBroker(options, pactBrokerUrl)
} catch (e: Exception) {
val verifyTaskName = PACT_VERIFY.lowercase()
if (project.gradle.startParameter.taskNames.any { it.lowercase().contains(verifyTaskName) }) {
if (taskNames.any { it.lowercase().contains(verifyTaskName) }) {
logger.error(e) { "Failed to access Pact Broker" }
throw e
} else {
Expand Down Expand Up @@ -130,7 +136,7 @@ open class GradleProviderInfo(override var name: String, val project: Project) :
provider.hasPactsFromPactBrokerWithSelectors(options, pactBrokerUrl, selectors)
} catch (e: Exception) {
val verifyTaskName = PACT_VERIFY.lowercase()
if (project.gradle.startParameter.taskNames.any { it.lowercase().contains(verifyTaskName) }) {
if (taskNames.any { it.lowercase().contains(verifyTaskName) }) {
logger.error(e) { "Failed to access Pact Broker" }
throw e
} else {
Expand All @@ -149,7 +155,7 @@ open class GradleProviderInfo(override var name: String, val project: Project) :
provider.hasPactsFromPactBrokerWithSelectorsV2(options, pactBrokerUrl, selectors)
} catch (e: Exception) {
val verifyTaskName = PACT_VERIFY.lowercase()
if (project.gradle.startParameter.taskNames.any { it.lowercase().contains(verifyTaskName) }) {
if (taskNames.any { it.lowercase().contains(verifyTaskName) }) {
logger.error(e) { "Failed to access Pact Broker" }
throw e
} else {
Expand All @@ -162,7 +168,7 @@ open class GradleProviderInfo(override var name: String, val project: Project) :
open fun url(path: String) = URL(path)

open fun fromPactBroker(closure: Closure<PactBrokerConsumerConfig>) {
brokerConfig = project.objects.newInstance(PactBrokerConsumerConfig::class.java)
brokerConfig = objectFactory.newInstance(PactBrokerConsumerConfig::class.java)
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure.delegate = brokerConfig
closure.call(brokerConfig)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class GradleProviderInfoSpec extends Specification {

def 'hasPactWith - defaults the consumer verification type to what is set on the provider'() {
given:
def provider = new GradleProviderInfo('provider', project)
def provider = new GradleProviderInfo('provider', project.objects)
provider.verificationType = PactVerification.ANNOTATED_METHOD

when:
Expand All @@ -45,7 +45,7 @@ class GradleProviderInfoSpec extends Specification {

def 'fromPactBroker configures the pact broker options'() {
given:
def provider = new GradleProviderInfo('provider', project)
def provider = new GradleProviderInfo('provider', project.objects)

when:
provider.fromPactBroker {
Expand All @@ -67,7 +67,7 @@ class GradleProviderInfoSpec extends Specification {
@Unroll
def 'fromPactBroker throws an exception if pending pacts is enabled but there are no provider tags or provider branch'() {
given:
def provider = new GradleProviderInfo('provider', project)
def provider = new GradleProviderInfo('provider', project.objects)

when:
provider.fromPactBroker {
Expand All @@ -90,7 +90,7 @@ class GradleProviderInfoSpec extends Specification {

def 'supports specifying a fallback tag'() {
given:
def provider = new GradleProviderInfo('provider', project)
def provider = new GradleProviderInfo('provider', project.objects)

when:
provider.fromPactBroker {
Expand All @@ -109,7 +109,7 @@ class GradleProviderInfoSpec extends Specification {
def 'supports specifying selectors with a block'() {
given:
def project = ProjectBuilder.builder().build()
def provider = new GradleProviderInfo('provider', project)
def provider = new GradleProviderInfo('provider', project.objects)

when:
provider.fromPactBroker {
Expand Down

0 comments on commit d1e76e3

Please sign in to comment.