From 48ecf30f654873d7427b843c469b1022f7828b8f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 26 Sep 2019 12:18:58 +0200 Subject: [PATCH] Updated docs with the new plugins api for Gradle fixes gh-1217 --- docs/src/main/asciidoc/gradle-project.adoc | 106 ++++++++++++------ .../standalone/dsl/http-server/build.gradle | 21 ++++ .../webclient/http-server/build.gradle | 31 ++--- .../gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 55616 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../standalone/webclient/http-server/gradlew | 22 +++- .../webclient/http-server/gradlew.bat | 18 ++- .../webclient/http-server/settings.gradle | 25 +++++ spring-cloud-contract-tools/pom.xml | 1 + .../gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 55616 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradlew | 22 +++- .../gradlew.bat | 18 ++- .../verifier/plugin/ContractsCopyTask.groovy | 43 +++++-- .../plugin/ContractVerifierSpec.groovy | 16 +++ ...GradleContractsDownloaderHelperSpec.groovy | 23 +++- .../pom.xml | 27 +++++ 17 files changed, 296 insertions(+), 81 deletions(-) create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-gradle-portal-plugin/pom.xml diff --git a/docs/src/main/asciidoc/gradle-project.adoc b/docs/src/main/asciidoc/gradle-project.adoc index 03c93c86b5..ab32951619 100644 --- a/docs/src/main/asciidoc/gradle-project.adoc +++ b/docs/src/main/asciidoc/gradle-project.adoc @@ -35,8 +35,75 @@ To add a Gradle plugin with dependencies, you can use code similar to the follow ==== [source,groovy,indent=0,subs="verbatim,attributes",role="primary"] -.Plugin DSL +.Plugin DSL GA versions ---- +// build.gradle +plugins { + id "groovy" + // this will work only for GA versions of Spring Cloud Contract + id "org.springframework.cloud.contract" version "${GAVerifierVersion}" +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${GAVerifierVersion}" + } +} + +dependencies { + testCompile "org.codehaus.groovy:groovy-all:${groovyVersion}" + // example with adding Spock core and Spock Spring + testCompile "org.spockframework:spock-core:${spockVersion}" + testCompile "org.spockframework:spock-spring:${spockVersion}" + testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier' +} +---- + +[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"] +.Plugin DSL non GA versions +---- +// settings.gradle +pluginManagement { + plugins { + id "org.springframework.cloud.contract" version "${verifierVersion}" + } + repositories { + // to pick from local .m2 + mavenLocal() + // for snapshots + maven { url "https://repo.spring.io/snapshot" } + // for milestones + maven { url "https://repo.spring.io/milestone" } + // for GA versions + gradlePluginPortal() + } +} + +// build.gradle +plugins { + id "groovy" + id "org.springframework.cloud.contract" +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${verifierVersion}" + } +} + +dependencies { + testCompile "org.codehaus.groovy:groovy-all:${groovyVersion}" + // example with adding Spock core and Spock Spring + testCompile "org.spockframework:spock-core:${spockVersion}" + testCompile "org.spockframework:spock-spring:${spockVersion}" + testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier' +} +---- + +[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"] +.Legacy Plugin Application +---- +// build.gradle buildscript { repositories { mavenCentral() @@ -44,6 +111,8 @@ buildscript { dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:${springboot_version}" classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${verifier_version}" + // here you can also pass additional dependencies such as Pact or Kotlin spec e.g.: + // classpath "org.springframework.cloud:spring-cloud-contract-spec-kotlin:${verifier_version}" } } @@ -56,39 +125,6 @@ dependencyManagement { } } -dependencies { - testCompile "org.codehaus.groovy:groovy-all:${groovyVersion}" - // example with adding Spock core and Spock Spring - testCompile "org.spockframework:spock-core:${spockVersion}" - testCompile "org.spockframework:spock-spring:${spockVersion}" - testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier' -} ----- - -[source,groovy,indent=0,subs="verbatim,attributes",role="secondary"] -.Legacy Plugin Application ----- -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath "org.springframework.boot:spring-boot-gradle-plugin:${springboot_version}" - } -} - -apply plugin: 'groovy' - -plugins { - id "org.springframework.cloud.contract" version "${GAVerifierVersion}" -} - -dependencyManagement { - imports { - mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${verifier_version}" - } -} - dependencies { testCompile "org.codehaus.groovy:groovy-all:${groovyVersion}" // example with adding Spock core and Spock Spring @@ -99,8 +135,6 @@ dependencies { ---- ==== -IMPORTANT: The Plugin DSL option will only work for GA (General Availability) releases (i.e. `2.2.0.RELEASE` etc.). - [[gradle-and-rest-assured]] == Gradle and Rest Assured 2.0 diff --git a/samples/standalone/dsl/http-server/build.gradle b/samples/standalone/dsl/http-server/build.gradle index 9a82dcc928..99b1b82d1a 100644 --- a/samples/standalone/dsl/http-server/build.gradle +++ b/samples/standalone/dsl/http-server/build.gradle @@ -1,4 +1,25 @@ // tag::repos[] +/* + We need to use the [buildscript {}] section when we have to modify + the classpath for the plugins. If that's not the case this section + can be skipped. + + If you don't need to modify the classpath (e.g. add a Pact dependency), + then you can just set the [pluginManagement {}] section in [settings.gradle] file. + + // settings.gradle + pluginManagement { + repositories { + // for snapshots + maven {url "https://repo.spring.io/snapshot"} + // for milestones + maven {url "https://repo.spring.io/milestone"} + // for GA versions + gradlePluginPortal() + } + } + + */ buildscript { repositories { mavenCentral() diff --git a/samples/standalone/webclient/http-server/build.gradle b/samples/standalone/webclient/http-server/build.gradle index 83d8c67d4d..3131a01d12 100644 --- a/samples/standalone/webclient/http-server/build.gradle +++ b/samples/standalone/webclient/http-server/build.gradle @@ -1,17 +1,10 @@ -buildscript { - repositories { - mavenCentral() - mavenLocal() - maven { url "https://repo.spring.io/snapshot" } - maven { url "https://repo.spring.io/milestone" } - maven { url "https://repo.spring.io/release" } - maven { url 'https://repo.spring.io/plugins-snapshot' } - maven { url "https://repo.spring.io/plugins-release-local" } - maven { url "https://repo.spring.io/plugins-staging-local/" } - } - dependencies { - classpath "org.springframework.boot:spring-boot-gradle-plugin:${findProperty('bootVersion') ?: bootVersion}" - } +plugins { + id "groovy" + id "org.springframework.boot" + id "io.spring.dependency-management" + id "maven-publish" + id "maven" + id "org.springframework.cloud.contract" } group = 'com.example' @@ -25,12 +18,6 @@ repositories { maven { url "https://repo.spring.io/release" } } -apply plugin: 'groovy' -apply plugin: 'org.springframework.boot' -apply plugin: 'io.spring.dependency-management' -apply plugin: 'maven-publish' -apply plugin: 'maven' - dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:$BOM_VERSION" @@ -47,6 +34,10 @@ dependencies { testCompile 'org.springframework.cloud:spring-cloud-contract-wiremock' } +contracts { + failOnNoContracts = false +} + test { systemProperty 'spring.profiles.active', 'gradle' testLogging { diff --git a/samples/standalone/webclient/http-server/gradle/wrapper/gradle-wrapper.jar b/samples/standalone/webclient/http-server/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..5c2d1cf016b3885f6930543d57b744ea8c220a1a 100644 GIT binary patch delta 3320 zcmai0c|2768`iN!wwN(!Oxeo5?`tVU3{m#%jC~noTx!q_nHtNnR`zAgWC@krB#b55 znJk4YA);()+(!K-w|npJuix)IpYu7-^SqzuJ>T~|?;j_-ma(;-@!<_I_B>B@4FVej z11CRtM@$8afpkN^v*te{ycR9yTldxXJbmio?@}x{9}zaw&=aQt(a^ZXN9S3i8a+Z% zGc@&(5}jplZjJKk2wNlTp(mbeKL5J9Gjo==yT{-eVKj?*rT1%bQ@%#Xce~~1f{19^ zoD75QEoSzDVh@!9qG4yl`;9=Ysp?rRX=(8$VDRz=R+oA3>jLxjW-H!-2biNSYuy)U z7-B-qC5l;>qjMTg!DbWPY}h7qxi6xp)_T)_O2+*&NDg?v;RyY@5XtWHx%(ImQ_3E% zA%$s3xrxE0Fk>DhG!pG)4}I!pWJl~QtV_3Jl2W4PuWWssMq^UpGatK+4CING9pB#5 z_NDc)aonVrZuXsr5!RcE#?aXFZQjt2VMd)-p00K$EheT?H!m_D2Mdqq;0moaO=C&y zgJnvzgUn!wkx^{r049pU#gsIMhl`%{MDNl;}JRbneC zSTB=5f;o9=2Rt24_lt&%%f~m{Ts)zu8H9j`INrgMp>l-|k%Kj%U`OXL1J2e+CJHJxreHLD_#o*ZeuXE4uGDQAJS_PpEGt7hmd7psmLEBL^h zD#JbHiklZEXkk9(6uF$ErsUu^jg7c~1oRS&CuTq*Xg_cOvGw~FZ&1#p(6|jz9lJnP zSIJ)sX_W2$PSksX&}*_ejz+t*X)xK|JcakaMRGd%c*R)cQcT|?sM^#{fdjh5_I$iK zBX_d;wz+cf>b}r!i3yo6eaua)d`|Mi_|Q3mAz5Qn?#~xgE9In<;TwYN^~mtaYy#WU z*ffWtxwlk&!e@UfqQ$bn23RDFV3o-H_WM}44yQpYw;JuRf$at#XX-qmuVnKqg-Bo# zJjZE39)!{i$qJh?oJzVzWFDlSW;{Wf`Z)33Y$Fh^+qasrsEJsfy9yhyTFe?Lej&3n zEAS(D8WCt(ew(SGD z-J#7@l?KI*ZbS)AVQ23qV&{c=$@zUp0@6=kZp+5by+gnAWdB||7e=!yJ|WTpG0OC7 zKlKWFv6#(>nrEq@d1i-#L9SVxTDNb1DaY%2$=@)`k&3s8wz$M*;THa&!2Isj%6CQS zY>A4HtmWY3@9e@F)mCHJQzBz~Lt(wcJE{!CAr=wxn4|5n(jslTy)~IF?tNK zD^2#hTM0d6MDg>`9;s5*(4W1V8y}F8OT6Xap{`=h1XVKO3zrBh=;JnIs*RB>@7t5T zwV=G^T)L=(9P7tS={6`tEBBBm^u~_!-#m75G*h}y_Jj7|STtiY_LDR5UUHI@awWmB zDn6q9{2M-EHaTm53ln%ENJ$HpLwRcL>7^hUrM=}&`qmWTgtr{Ul*Lqcd_9S0xZ1s>F2dVd(s)3&$`gxFAu6jXYIS ze#M~w@=X@lm)sFI4EEiqKh7JxN=_?+}D=iHCc&S2<^VPZ6 zYKXZgvi(Yne9}k6o=ezgquABVB77}x$nKXh`@LjH&lQPqm_;MTL>4RGO|E#_7AS4@43rz=ij?gcMZalnd-JK4ILhL)Ee(3G zN}g99HmhxoBjHR~y@b>-7{f+`p zIZ<^8%d;wCA#xfwSc6$DNVPjAX6FCkb|MQ|6hFyz9UhoLF0^xUd#*^2Ofn zOJgmwDyb1=Z8T)ArRy|VQOM+BrhZ>W_ELJ6u(d^JTu|j%*6g8JKZ-ewoj)sXJCdS= zHOo?HscL;Z`H18}%WnE1&o42KZ+=fg(*VN>t>kRkcd{mP9NF6;MnzH&m2WsD)sX~h zbhv|Ux$w2avQwoI`IKiGMLrL;Z>R}Y_0K*L=63V z)ut+5tM74Glzb?92kbu5@3M#1Hi7K3$c)?TL$}`aKf0hC3`r!>Xy3!f{ z`}Y#@$`|mG1JlKzVE!vD04aX}x#hV*+AC>bQ|%XJ1<&;=0?uX!RM?CIB=+!tgkB-w zu*HF--^U4#nG1mXz0v^0@|UCs1lt}!1zTaTwoe+k?sPym`pyB-F25ivXx)#1|1%|e zJ7Vpujkk#Lu%U{v6xiQ5LW2`~QXrR`ja@*L=b0ejT977v%C)0WAik0gV7U z6a-7##p#p>>>3a{^Z}e3Z~?A|foBFU12bqaEE*0vqdCCVLFq%{;F%$Dkb6i8;Qo!C z&;zkU(!i5zbSMd)zQzg8(kU^HPQ^flVIzR)<^jwbwget09YD?zV*rx+mx@0IN{#S< zsB|8Ve>>sJI7sHE!@=(((ttqL0ks%C4M^r5!0H?rJ;MV|jtT)1cMl{|9xo_Okp@Ka ze^CzbCPf?IDFWLlE`V1FDDpZ0C@7~VMZt%!6%SFtxz{!Tb1UfBDEg~49x!4|2#_L! zX=6UXeh28_?VY*suC^Sy!?XXp?9-G{ zEbF`ELqycMcTK-$-pw|Jox9S^<_NX$7{PI7aX1p5N>aOyj&D01H#;3?=q^!=_mq@k zUHheWO_|CDYA~8r<-%q8&Gm$uPSx4S`reKPnv?Nif4kS)^smTg&m@kLYT87txGxGxw+Qc zTAi=`vzavOlyLrgf2A~;1~Gx$jcb|fkhfctRt6CjRooL|#wr)(*8D4n;2cBe>p9_T zCeJf!IgCH0h1m)UPLk3hZz120oe5YH$oXjSMHcPv@#wX;OP5bBSJMavm2}5Q8(V&# zXGA!+dAwOiXuQ)|+XwF2HW1@_MPm3*v{M86V_~+xk1K7cI7mxBKU5#bofCjZqqjs$ z(sipv#Ul%KJ)h?ua}a3Dg(6yaxeJ(HD-&`AT9kZJVLJTz?WIfgao$bYwEhXh+&GA= zkpI03HVxtWc*H!~z~9%DC;;Qej=WppOD!i1$MO1`&8LW%IWd2sbnS7j+<0b`v1%qx!owUU+ZIHJFp1yH9BFvUYI^up=ZYX$K_YM|Bn2fCG3sq#(EpRB$|A9~9*^M%Sq)EAjr0&W`hHyz96Z9h*odHK|Ju$JQ0c zO9oayZQv;2b{pLJo`T)C%yS@sAKO*WC%22XDmrdRTd;uFr*sb_{GDl=*Y`l*;>lNWh=XCbn#V}C&jmw3>t zNH(fnG%j@AI$TSggf(e3DxrpHjnpeKExsb|hC`kxjD4HUSmu)&aJNt&DtCWh#51*} zS!qfplP(f0`hJ)VHrXFD_uB7ia4#%U)3S8lGY9^(T1)M8xQxP*3w4&QJr~O`$A&N5 z_taom$34zt+reJDV?oZ*qr5ERUH7#~xm7)D(u#q#m`~~-F+TZ6Q*L)s_#T3GZUuZM zhCH9!{qXnD)9jln$|GDeDPqo=+D6#vQkAjdHtT>{VxU#AQJW-je=UWN5*R>v5vWF6 zK_6z?#thq>&%@fu5epvO$rfx`v9GojdOLGFaQ2V8?Ri z(?L2JBK(;G)bIF7r5T6Ahzst5k4j#hvhl3a`@Ksfyj3^Cx}zGE)vm$ecB$?~2`S&e zE)Nx6TiDO*JO6UmWWc+zLDmnII+)ROEvW3_{*%Fjs8Q^k4+Z&cJ0lp=@p*N!fw0>L zPSWrxar=HPDCwZnmN%orA-K2142{bJ0el>N{KM(xoHJu_HWSQihq^y%SEmj>CsBjl zj6)jxqm7NwiVHh-xQ`ex^02-y_ZO`A`P(1UwLK5G_T8=uI8@e%Kh31Xay z>H$7OG8cQ%>c_RjXhRA|Yh=93MnM)V0JlD#yP-1YNx}5`sg}-vE%slfve&}e$*L>+ zSAq_CMc5SYx6N)5h%-)?JOAhiVM5`TWT7?<9 zKKxMMb9GXHpQ1ajAr?!hxcauobJLf{IpvJ=9ny}FwdGCYmwgj?0qhIG{5zbTTVc2b zo+3h|{F_Yg96k{?rVn`m`%d??#avI-eh^XnTH2r*o>5n>`UuIsuCIeN5Br62W!Yy#8)0uWcVG%-QnMHczpWoe zftoSf-WJq~x8`|ws<-9{Va9@s#SoH3uw`>4!~uyB-(lV)SD9f(TPNa!o7JLL%!a)@gUmedno%~}$ z#zZLYah$5mf@Z2}a(oDDM^$qq>*nb;?aVn?D`($Om=?j+T%S?eSgR1t=zzwGw|kvM zt~WiOO&UVW=7N=8ERxM<4?Wbj4bPIP4z3=hjp(uuT}ne*E9ct0)Lsk?bG=1nNo=oB z0JEoKzAw45q-lB!IbJKsY=Lpru48qY6ql!Z#J13ywC&7??l&AtxiowZ|Cg(k*UE#@ zrJm|m^EV_6jz}f($PrOb`S;imdEwtu`#cCu3aMXBgUUH4t2j_qu=KmOO645(v(_DL z^G5PF%RR0@X5D{(V%x5L{xD1Sa>^wR+$0j(DeVfwk;tp3<@i$~qOsvx^uUy!zV8G0~0`$f?VV=?vm zOwYnZB>UV_b#sh6ibtN`5I+l%mTE9T%*J!xaz}cWisUNLg@>nEiKv4hgmv`5C)GIDbBOgq{?5K-!=>z{CLJ$wIBkL-~yV{}~e*^#eZ1f%)RR;DgcM zfOqnA#42!t$D;@!QT3n50ve1d0$Zl^m}ABc){bz2HDhq#o&{ZLlQ=*lO9Alv7y_uW z`bTL2KkVsP<{%6$`1yeL}DmCZuxPZRJp*( z*Kk1M23@g@UjhQ6PEZ{58CL@Aqv>cB0|#ltT;SR`95{}ptMe0@zz&v<>j{GNDt-bE zn5EFw?u0e)Ee+J0^aq@C>E_j>A%MyU^@?Rcohe{^TCd{d<=ub5$bWAhspring-cloud-contract-pact spring-cloud-contract-maven-plugin spring-cloud-contract-gradle-plugin + spring-cloud-contract-gradle-portal-plugin diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..5c2d1cf016b3885f6930543d57b744ea8c220a1a 100644 GIT binary patch delta 3320 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 excludeBuildFolders @Input Provider failOnNoContracts + String contractsDirectoryPath Provider contractsDirectory // All fields inside `@Nested` one are properly marked as an `@Input` to work with incremental build: @Nested @@ -95,32 +96,42 @@ class ContractsCopyTask extends DefaultTask { @Input @Optional Property contractsPath + @Input @Optional Instant getForceDownloadOfTheLatestContracts() { // If we have `dynamic` version (`+` or `SNAPSHOT`) - we should mark this task as out of date for every run: if (shouldDownloadContracts() && getStubConfiguration().isVersionChanging()) { return Instant.now() // This will trigger re-download of contracts - } else { + } + else { return null // This will not trigger re-download of contracts } } + @Optional @InputDirectory Provider getContractsDirectory() { - if (shouldDownloadContracts()) { + contractsDirectoryPath = contractsDirectory.get().asFile.absolutePath + if (shouldDownloadContracts() || contractFolderMissing()) { return null - } else { + } + else { return contractsDirectory } } + private boolean contractFolderMissing() { + contractsDirectory.isPresent() && !contractsDirectory.get().asFile.exists() + } + @Internal boolean shouldDownloadContracts() { return StringUtils.hasText(contractDependency.getArtifactId().getOrNull()) || StringUtils.hasText(contractDependency.getStringNotation().getOrNull()) || StringUtils.hasText(contractRepository.repositoryUrl.getOrNull()) } + @Internal StubConfiguration getStubConfiguration() { return GradleContractsDownloaderHelper.stubConfiguration(contractDependency) @@ -141,14 +152,22 @@ class ContractsCopyTask extends DefaultTask { if (downloadedData) { contractsDirectory = downloadedData.downloadedContracts antPattern = "${downloadedData.inclusionProperties.includedRootFolderAntPattern}*.*" - } else { + logger.info("Contracts got downloaded to [" + contractsDirectory + "]") + } + else if (config.contractsDirectory != null && config.contractsDirectory.isPresent()) { contractsDirectory = config.contractsDirectory.get().asFile antPattern = "**/" } + else { + contractsDirectory = null + } logger.info("For project [{}] will use contracts provided in the folder [{}]", project.name, contractsDirectory) final String contractsRepository = config.contractRepository.repositoryUrl.isPresent() ? config.contractRepository.repositoryUrl : "" throwExceptionWhenFailOnNoContracts(contractsDirectory, contractsRepository) - + if (contractsDirectory == null) { + logger.info("Contracts directory not set and contracts weren't downloaded. There's nothing to copy") + return + } final String slashSeparatedGroupId = project.group.toString().replace(".", File.separator) final String slashSeparatedAntPattern = antPattern.replace(slashSeparatedGroupId, project.group.toString()) final File output = config.copiedContractsFolder.get().asFile @@ -225,7 +244,8 @@ class ContractsCopyTask extends DefaultTask { downloadedContracts: contractsSubDirIfPresent(downloadedContracts, logger), inclusionProperties: inclusionProperties ) - } else { + } + else { return null } } @@ -251,10 +271,9 @@ class ContractsCopyTask extends DefaultTask { } return } - if (config.failOnNoContracts.get() && (!file.exists() || file.listFiles().length == 0)) { - throw new GradleException("Contracts could not be found: [" - + file.getAbsolutePath() - + "] .\nPlease make sure that the contracts were defined, or set the [failOnNoContracts] flag to [false]") + if (config.failOnNoContracts.get() && (file == null || !file.exists() || file.listFiles().length == 0)) { + String path = file != null ? file.getAbsolutePath() : config.contractsDirectoryPath + throw new GradleException("Contracts could not be found: [" + path + "]\nPlease make sure that the contracts were defined, or set the [failOnNoContracts] flag to [false]") } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy index 626da379fe..472fb5b584 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.contract.verifier.plugin import org.gradle.api.Project diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderHelperSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderHelperSpec.groovy index aadb5eb074..a7d83c6f50 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderHelperSpec.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/GradleContractsDownloaderHelperSpec.groovy @@ -1,11 +1,28 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.springframework.cloud.contract.verifier.plugin -import org.gradle.api.internal.provider.DefaultPropertyState +import org.gradle.api.internal.provider.DefaultProperty import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property -import org.springframework.cloud.contract.stubrunner.StubConfiguration import spock.lang.Specification +import org.springframework.cloud.contract.stubrunner.StubConfiguration + /** * @author Marcin Grzejszczak * @author Anatoliy Balakirev @@ -81,6 +98,6 @@ class GradleContractsDownloaderHelperSpec extends Specification { // Have to use this internal property impl here. Is there some better way? static Property prop(Class aClass) { - return new DefaultPropertyState(aClass) + return new DefaultProperty(aClass) } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-portal-plugin/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-portal-plugin/pom.xml new file mode 100644 index 0000000000..b0dd8da39c --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-portal-plugin/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + + org.springframework.cloud + spring-cloud-contract-tools + 2.2.0.BUILD-SNAPSHOT + .. + + + org.springframework.cloud.contract + org.springframework.cloud.contract.gradle.plugin + jar + + Spring Cloud Contract Gradle Portal Plugin + Spring Cloud Contract Gradle Portal Plugin + + + + org.springframework.cloud + spring-cloud-contract-gradle-plugin + + + +