diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc new file mode 120000 index 0000000000..3abe7caccd --- /dev/null +++ b/docs/src/main/asciidoc/index.adoc @@ -0,0 +1 @@ +spring-cloud-contract.adoc \ No newline at end of file diff --git a/specs/spring-cloud-contract-spec-java/src/main/java/org/springframework/cloud/contract/spec/internal/Request.java b/specs/spring-cloud-contract-spec-java/src/main/java/org/springframework/cloud/contract/spec/internal/Request.java index db1750c747..6972e5f428 100644 --- a/specs/spring-cloud-contract-spec-java/src/main/java/org/springframework/cloud/contract/spec/internal/Request.java +++ b/specs/spring-cloud-contract-spec-java/src/main/java/org/springframework/cloud/contract/spec/internal/Request.java @@ -670,18 +670,18 @@ public class Request extends Common implements RegexCreatingProperty consumer) { + public void headers(Consumer consumer) { this.headers = new Request.RequestHeaders(); - consumer.accept((RequestHeaders) this.headers); + consumer.accept(this.headers); } /** * Allows to configure HTTP cookies. * @param consumer function to manipulate the cookies */ - public void cookies(Consumer consumer) { + public void cookies(Consumer consumer) { this.cookies = new Request.RequestCookies(); - consumer.accept((RequestCookies) this.cookies); + consumer.accept(this.cookies); } /** @@ -755,7 +755,7 @@ public class Request extends Common implements RegexCreatingProperty consumer) { + public void headers(Consumer consumer) { this.headers = new Response.ResponseHeaders(); - consumer.accept((ResponseHeaders) this.headers); + consumer.accept(this.headers); } /** * Allows to configure HTTP cookies. * @param consumer function to manipulate the URL */ - public void cookies(Consumer consumer) { + public void cookies(Consumer consumer) { this.cookies = new Response.ResponseCookies(); - consumer.accept((ResponseCookies) this.cookies); + consumer.accept(this.cookies); } /** @@ -771,7 +771,7 @@ public class Response extends Common implements RegexCreatingProperty @@ -63,9 +66,30 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { Task copyContracts = createAndConfigureCopyContractsTask(stubsJar, downloader, extension) createAndConfigureMavenPublishPlugin(stubsJar, extension) createGenerateTestsTask(extension, copyContracts, downloader) - createAndConfigureGenerateClientStubs(extension, copyContracts) + createAndConfigureGenerateClientStubs(extension, copyContracts, downloader) createAndConfigurePublishStubsToScmTask(extension, downloader) addIdeaTestSources(project, extension) + applyDefaultSourceSets(extension) + } + + private void applyDefaultSourceSets(ContractVerifierExtension extension) { + def sourceSetType = extension.getTestFramework() == TestFramework.SPOCK ? + "groovy" : "java" + applySourceSets(extension, sourceSetType) + } + + @CompileDynamic + private void applySourceSets(ContractVerifierExtension extension, sourceSetType) { + project.sourceSets.test."${sourceSetType}" { + project.logger. + info("Registering ${extension.generatedTestSourcesDir} as test source directory") + srcDir extension.getGeneratedTestSourcesDir() + } + project.sourceSets.test.resources { + project.logger. + info("Registering ${extension.generatedTestResourcesDir} as test resource directory") + srcDir extension.getGeneratedTestResourcesDir() + } } @CompileDynamic @@ -108,49 +132,46 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { @CompileDynamic private void createGenerateTestsTask(ContractVerifierExtension extension, Task copyContracts, GradleContractsDownloader gradleContractsDownloader) { - Task task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) + GenerateServerTestsTask task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) task.description = "Generate server tests from the contracts" task.group = GROUP_NAME - task.conventionMapping.with { - downloader = { gradleContractsDownloader } - generatedTestSourcesDir = { extension.generatedTestSourcesDir } - configProperties = { extension } + task.with { + downloader = gradleContractsDownloader + generatedTestSourcesDir = extension.generatedTestSourcesDir + configProperties = extension } task.enabled = !project.gradle.startParameter.excludedTaskNames.contains("test") task.dependsOn copyContracts project.tasks.findByName("compileTestJava").dependsOn(task) } - @CompileDynamic private void createAndConfigurePublishStubsToScmTask(ContractVerifierExtension extension, GradleContractsDownloader gradleContractsDownloader) { - Task task = project.tasks.create(PUBLISH_STUBS_TO_SCM_TASK_NAME, PublishStubsToScmTask) + PublishStubsToScmTask task = project.tasks.create(PUBLISH_STUBS_TO_SCM_TASK_NAME, PublishStubsToScmTask) task.description = "The generated stubs get committed to the SCM repo and pushed to origin" task.group = GROUP_NAME - task.conventionMapping.with { - downloader = { gradleContractsDownloader } - configProperties = { extension } - stubsOutputDir = { extension.stubsOutputDir } + task.with { + downloader = gradleContractsDownloader + configProperties = extension + stubsOutputDir = extension.stubsOutputDir } task.dependsOn DSL_TO_CLIENT_TASK_NAME } - @CompileDynamic private Task createAndConfigureGenerateClientStubs(ContractVerifierExtension extension, - Task copyContracts) { - Task task = project.tasks.create(DSL_TO_CLIENT_TASK_NAME, GenerateClientStubsFromDslTask) + Task copyContracts, GradleContractsDownloader gradleContractsDownloader) { + GenerateClientStubsFromDslTask task = project.tasks.create(DSL_TO_CLIENT_TASK_NAME, GenerateClientStubsFromDslTask) task.description = "Generate client stubs from the contracts" task.group = GROUP_NAME - task.conventionMapping.with { - downloader = { gradleContractsDownloader } - stubsOutputDir = { extension.stubsOutputDir } - configProperties = { extension } + task.with { + downloader = gradleContractsDownloader + stubsOutputDir = extension.stubsOutputDir + configProperties = extension } task.dependsOn copyContracts return task } - @CompileDynamic private Task createAndConfigureStubsJarTasks(ContractVerifierExtension extension) { Task task = stubsTask() if (task) { @@ -158,21 +179,31 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { return task } else { - task = project.tasks.create(type: Jar, name: VERIFIER_STUBS_JAR_TASK_NAME, - dependsOn: DSL_TO_CLIENT_TASK_NAME) { - baseName = project.name - classifier = extension.stubsSuffix - from { extension.stubsOutputDir ?: project.file("${project.buildDir}/stubs") } - } + task = createStubsJarTask(extension) task.description = "Creates the stubs JAR task" task.group = GROUP_NAME - project.artifacts { - archives task - } + setArchives(task) return task } } + @CompileDynamic + private Task createStubsJarTask(ContractVerifierExtension extension) { + return project.tasks.create(type: Jar, name: VERIFIER_STUBS_JAR_TASK_NAME, + dependsOn: DSL_TO_CLIENT_TASK_NAME) { + getArchiveBaseName().set(project.name) + getArchiveClassifier().set(extension.stubsSuffix) + from { extension.stubsOutputDir ?: project.file("${project.buildDir}/stubs") } + } + } + + @CompileDynamic + private void setArchives(Task task) { + project.artifacts { + archives task + } + } + private Task stubsTask() { try { return project.tasks.getByName(VERIFIER_STUBS_JAR_TASK_NAME) @@ -182,22 +213,20 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { } } - @CompileDynamic private Task createAndConfigureCopyContractsTask(Task stubs, GradleContractsDownloader gradleContractsDownloader, ContractVerifierExtension contractVerifierExtension) { - Task task = project.tasks.create(COPY_CONTRACTS_TASK_NAME, ContractsCopyTask) + ContractsCopyTask task = project.tasks.create(COPY_CONTRACTS_TASK_NAME, ContractsCopyTask) task.description = "Copies contracts to the output folder" task.group = GROUP_NAME - task.conventionMapping.with { - downloader = { gradleContractsDownloader } - extension = { contractVerifierExtension } + task.with { + downloader = gradleContractsDownloader + extension = contractVerifierExtension } stubs.dependsOn task return task } - @CompileDynamic private void createAndConfigureMavenPublishPlugin(Task stubsTask, ContractVerifierExtension extension) { if (!classIsOnClasspath("org.gradle.api.publish.maven.plugins.MavenPublishPlugin")) { project.logger.debug("Maven Publish Plugin is not present - won't add default publication") @@ -213,12 +242,7 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { def publishingExtension = project.extensions.findByName('publishing') if (!hasPublication(publishingExtension)) { project.logger.debug("Spring Cloud Contract Verifier Plugin: Stubs publication is not present - will create one") - publishingExtension.publications { - stubs(MavenPublication) { - artifactId "${project.name}" - artifact stubsTask - } - } + setPublications(publishingExtension, stubsTask) } else { project.logger.info("Spring Cloud Contract Verifier Plugin: Stubs publication was present - won't create a new one. Remember about passing stubs as artifact") @@ -227,6 +251,16 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { } } + @CompileDynamic + private void setPublications(def publishingExtension, Task stubsTask) { + publishingExtension.publications { + stubs(MavenPublication) { + artifactId "${project.name}" + artifact stubsTask + } + } + } + @CompileDynamic private boolean hasPublication(def publishingExtension) { try { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy index 552fe5173f..d59cb7b6e8 100755 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy @@ -19,6 +19,8 @@ package org.springframework.cloud.contract.verifier.plugin import org.junit.Ignore import spock.lang.Stepwise +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + @Stepwise @Ignore class SampleProjectSpec extends ContractVerifierIntegrationSpec { @@ -32,22 +34,33 @@ class SampleProjectSpec extends ContractVerifierIntegrationSpec { def "should pass basic flow for Spock"() { given: assert fileExists('build.gradle') - expect: + when: String[] args = ["check", "publishToMavenLocal", "--debug"] as String[] if (WORK_OFFLINE) { args << "--offline" } runTasksSuccessfully(args) + then: jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + when: "running generation without change inputs" + def secondExecutionResult = runTasksSuccessfully() + then: "tasks should be up-to-date" + validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateClientStubs', 'generateContractTests', 'copyContracts') + } def "should pass basic flow for JUnit"() { given: switchToJunitTestFramework() assert fileExists('build.gradle') - expect: + when: runTasksSuccessfully(checkAndPublishToMavenLocal()) + then: jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + when: "running generation without change inputs" + def secondExecutionResult = runTasksSuccessfully() + then: "tasks should be up-to-date" + validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateClientStubs', 'generateContractTests', 'copyContracts') } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index 0b1c78981f..9d6e180da1 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -43,6 +43,7 @@ subprojects { sourceCompatibility = 1.8 targetCompatibility = 1.8 + version = "1.0.0" repositories { mavenCentral() diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java index 3693d49a62..e05edd65be 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java @@ -18,8 +18,10 @@ package org.springframework.cloud.contract.verifier.config; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.StringJoiner; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -366,4 +368,33 @@ public class ContractVerifierConfigProperties { this.excludeBuildFolders = excludeBuildFolders; } + @Override + public String toString() { + return new StringJoiner(", ", + ContractVerifierConfigProperties.class.getSimpleName() + "[", "]") + .add("targetFramework=" + targetFramework) + .add("testFramework=" + testFramework).add("testMode=" + testMode) + .add("basePackageForTests='" + basePackageForTests + "'") + .add("baseClassForTests='" + baseClassForTests + "'") + .add("nameSuffixForTests='" + nameSuffixForTests + "'") + .add("ruleClassForTests='" + ruleClassForTests + "'") + .add("excludedFiles=" + excludedFiles) + .add("includedFiles=" + includedFiles) + .add("ignoredFiles=" + ignoredFiles) + .add("imports=" + Arrays.toString(imports)) + .add("staticImports=" + Arrays.toString(staticImports)) + .add("contractsDslDir=" + contractsDslDir) + .add("generatedTestSourcesDir=" + generatedTestSourcesDir) + .add("generatedTestResourcesDir=" + generatedTestResourcesDir) + .add("stubsOutputDir=" + stubsOutputDir) + .add("stubsSuffix='" + stubsSuffix + "'") + .add("assertJsonSize=" + assertJsonSize) + .add("includedContracts='" + includedContracts + "'") + .add("includedRootFolderAntPattern='" + + includedRootFolderAntPattern + "'") + .add("packageWithBaseClasses='" + packageWithBaseClasses + "'") + .add("baseClassMappings=" + baseClassMappings) + .add("excludeBuildFolders=" + excludeBuildFolders).toString(); + } + }