Skip to content

Commit

Permalink
Merge pull request #1627 from prof18/gradle-conf-cache-compatible
Browse files Browse the repository at this point in the history
Make the Gradle Plugin compatible with Gradle Configuration Cache
  • Loading branch information
rholshausen authored Oct 26, 2022
2 parents 7e2e11a + d1e76e3 commit c77ddf2
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,73 @@ import au.com.dius.pact.core.pactbroker.Latest
import au.com.dius.pact.core.pactbroker.PactBrokerClient
import com.github.ajalt.mordant.TermColors
import org.gradle.api.GradleScriptException
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction

import javax.inject.Inject

/**
* Task to verify the deployment state using a pact broker
*/
@SuppressWarnings(['Println', 'DuplicateStringLiteral'])
class PactCanIDeployTask extends PactCanIDeployBaseTask {
abstract class PactCanIDeployTask extends PactCanIDeployBaseTask {

private static final String PACTICIPANT = 'pacticipant'
private static final String PACTICIPANT_VERSION = 'pacticipantVersion'
private static final String TO = 'toTag'
private static final String LATEST = 'latest'
static final String PACTICIPANT = 'pacticipant'
static final String PACTICIPANT_VERSION = 'pacticipantVersion'
static final String TO = 'toTag'
static final String LATEST = 'latest'

@Internal
PactBrokerClient brokerClient
abstract PactBrokerClient brokerClient

@Input
@Optional
abstract Property<Broker> getBroker()

@Input
@Optional
abstract Property<Object> getPacticipant()

@Input
@Optional
abstract Property<Object> getPacticipantVersion()

@Input
@Optional
abstract Property<Object> getToProp()

@Input
@Optional
abstract Property<Object> getLatestProp()

@TaskAction
void canIDeploy() {
if (!project.pact.broker) {
if (!broker.present) {
throw new GradleScriptException('You must add a pact broker configuration to your build before you can ' +
'use the CanIDeploy task', null)
}

if (brokerClient == null) {
Broker config = project.pact.broker
Broker config = broker.get()
brokerClient = setupBrokerClient(config)
}

if (!project.hasProperty(PACTICIPANT)) {
if (!pacticipant.present) {
throw new GradleScriptException('The CanIDeploy task requires -Ppacticipant=...', null)
}
String pacticipant = project.property(PACTICIPANT)
String pacticipant = pacticipant.get()
Latest latest = setupLatestParam()
if ((latest instanceof Latest.UseLatestTag || latest.latest == false) &&
!project.hasProperty(PACTICIPANT_VERSION)) {
!pacticipantVersion.present) {
throw new GradleScriptException('The CanIDeploy task requires -PpacticipantVersion=... or -Platest=true', null)
}
String pacticipantVersion = project.hasProperty(PACTICIPANT_VERSION) ? project.property(PACTICIPANT_VERSION) : ''
String pacticipantVersion = pacticipantVersion.orElse('').get()
String to = null
if (project.hasProperty(TO)) {
to = project.property(TO)
if (toProp.present) {
to = toProp.get()
}
def t = new TermColors()
logger.debug(
Expand All @@ -69,8 +94,8 @@ class PactCanIDeployTask extends PactCanIDeployBaseTask {

private Latest setupLatestParam() {
Latest latest = new Latest.UseLatest(false)
if (project.hasProperty(LATEST)) {
String latestProp = project.property(LATEST)
if (latestProp.present) {
String latestProp = latestProp.get()
if (latestProp == 'true') {
latest = new Latest.UseLatest(true)
} else if (latestProp == 'false') {
Expand Down
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,15 +14,29 @@ class PactPlugin extends PactPluginBase {
void apply(Project project) {

// Create and install the extension object
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)
project.task('pactPublish', description: 'Publish your pacts to a pact broker', type: PactPublishTask,
group: GROUP)
project.task('canIDeploy', description: 'Check if it is safe to deploy by checking whether or not the ' +
'specified pacticipant versions are compatible', type: PactCanIDeployTask,
group: GROUP)

project.tasks.register('pactPublish', PactPublishTask) {
group = GROUP
description = 'Publish your pacts to a pact broker'
pactPublish.set(extension.publish)
broker.set(extension.broker)
projectVersion.set(project.version)
pactDir.set(project.file("${project.buildDir}/pacts"))
}

project.tasks.register('canIDeploy', PactCanIDeployTask) {
group = GROUP
description = 'Check if it is safe to deploy by checking whether or not the ' +
'specified pacticipant versions are compatible'
broker.set(extension.broker)
pacticipant.set(project.hasProperty(PACTICIPANT) ? project.property(PACTICIPANT) : null)
pacticipantVersion.set(project.hasProperty(PACTICIPANT_VERSION) ? project.property(PACTICIPANT_VERSION) : null)
toProp.set(project.hasProperty(TO) ? project.property(TO) : null)
latestProp.set(project.hasProperty(LATEST) ? project.property(LATEST) : null)
}

project.afterEvaluate {
if (it.pact == null) {
Expand All @@ -35,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 @@ -55,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 @@ -10,28 +10,45 @@ import org.apache.commons.io.FilenameUtils
import org.apache.commons.lang3.StringUtils
import org.gradle.api.DefaultTask
import org.gradle.api.GradleScriptException
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction

/**
* Task to push pact files to a pact broker
*/
@SuppressWarnings(['Println', 'AbcMetric'])
class PactPublishTask extends DefaultTask {
abstract class PactPublishTask extends DefaultTask {

@Input
@Optional
abstract Property<PactPublish> getPactPublish()

@Input
@Optional
abstract Property<Broker> getBroker()

@Input
abstract Property<Object> getProjectVersion()

@Input
abstract Property<File> getPactDir()

@TaskAction
void publishPacts() {
if (!project.pact.publish) {
PactPublish pactPublish = pactPublish.getOrElse(null)
if (pactPublish == null) {
throw new GradleScriptException('You must add a pact publish configuration to your build before you can ' +
'use the pactPublish task', null)
}

PactPublish pactPublish = project.pact.publish
if (pactPublish.pactDirectory == null) {
pactPublish.pactDirectory = project.file("${project.buildDir}/pacts")
pactPublish.pactDirectory = pactDir.get()
}
def version = pactPublish.consumerVersion
if (version == null) {
version = project.version
version = projectVersion.get()
} else if (version instanceof Closure) {
version = version.call()
}
Expand All @@ -40,7 +57,8 @@ class PactPublishTask extends DefaultTask {
throw new GradleScriptException('The consumer version is required to publish Pact files', null)
}

def brokerConfig = project.pact.broker ?: project.pact.publish
Broker broker = broker.getOrElse(null)
def brokerConfig = broker ?: pactPublish
def options = [:]
if (StringUtils.isNotEmpty(brokerConfig.pactBrokerToken)) {
options.authentication = [brokerConfig.pactBrokerAuthenticationScheme ?: 'bearer',
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
Loading

0 comments on commit c77ddf2

Please sign in to comment.