From bde6b737b0840c7a3b1488a8e18121e48dd0be50 Mon Sep 17 00:00:00 2001 From: Wallace Wadge Date: Fri, 10 Nov 2023 10:25:08 +0100 Subject: [PATCH] Bump Gradle to 8.4, fix cache. --- CONTRIBUTING.md | 2 +- build.gradle | 71 +++-- config/checkstyle/checkstyle-suppressions.xml | 8 + gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 63721 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 301 +++++++++++------- gradlew.bat | 56 ++-- jib-build-plan/build.gradle | 2 +- .../tools/jib/api/buildplan/LayerObject.java | 12 +- .../jib/api/buildplan/FileEntryTest.java | 1 + jib-cli/build.gradle | 4 +- .../jarTest/spring-boot/build-layered.gradle | 4 +- .../jarTest/spring-boot/build.gradle | 8 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 58694 -> 62076 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../resources/warTest/build.gradle | 8 +- .../warTest/gradle/wrapper/gradle-wrapper.jar | Bin 58694 -> 62076 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../cloud/tools/jib/cli/war/WarFiles.java | 5 +- .../cloud/tools/jib/cli/war/WarFilesTest.java | 2 +- jib-core/build.gradle | 2 +- .../jib/api/ContainerizerIntegrationTest.java | 30 +- .../tools/jib/api/JibIntegrationTest.java | 50 +-- .../tools/jib/api/ReproducibleImageTest.java | 54 +++- .../registry/BlobPusherIntegrationTest.java | 4 +- .../ManifestPullerIntegrationTest.java | 8 +- .../ManifestPusherIntegrationTest.java | 6 +- .../steps/LocalBaseImageStepsTest.java | 25 +- .../jib/cache/CacheStorageFilesTest.java | 4 +- .../jib/http/FailoverHttpClientTest.java | 6 +- jib-gradle-plugin-extension-api/build.gradle | 2 +- jib-gradle-plugin/build.gradle | 11 +- .../gradle/SingleProjectIntegrationTest.java | 4 +- .../simple/build-configuration.gradle | 4 +- .../simple/build-extra-dirs-filtering.gradle | 2 +- .../projects/simple/build-extra-dirs.gradle | 2 +- .../projects/simple/build-extra-dirs2.gradle | 2 +- .../projects/simple/build-extra-dirs3.gradle | 2 +- .../simple/build-jar-containerization.gradle | 2 +- .../simple/build-java11-incompatible.gradle | 2 +- .../projects/simple/build-java11.gradle | 2 +- .../projects/simple/build-java17.gradle | 2 +- .../projects/simple/build-local-base.gradle | 2 +- .../simple/build-timestamps-custom.gradle | 2 +- .../tools/jib/gradle/BuildDockerTask.java | 32 +- .../tools/jib/gradle/BuildImageTask.java | 36 ++- .../cloud/tools/jib/gradle/BuildTarTask.java | 32 +- .../gradle/ExtraDirectoriesParameters.java | 40 ++- .../jib/gradle/ExtraDirectoryParameters.java | 35 +- .../gradle/ExtraDirectoryParametersSpec.java | 21 +- .../jib/gradle/GradleProjectProperties.java | 250 ++++++++++----- .../cloud/tools/jib/gradle/JibPlugin.java | 14 +- .../jib/gradle/OutputPathsParameters.java | 18 +- .../jib/gradle/skaffold/FilesTaskV2.java | 5 +- .../skaffold/SkaffoldSyncParameters.java | 29 +- .../skaffold/SkaffoldWatchParameters.java | 60 ++-- .../jib/gradle/skaffold/SyncMapTask.java | 6 +- .../GradleProjectPropertiesExtensionTest.java | 80 ++++- .../gradle/GradleProjectPropertiesTest.java | 122 +++++-- .../tools/jib/gradle/JibExtensionTest.java | 21 +- .../cloud/tools/jib/gradle/JibPluginTest.java | 21 +- .../jib/gradle/skaffold/FilesTaskV2Test.java | 5 +- jib-maven-plugin-extension-api/build.gradle | 2 +- jib-maven-plugin/build.gradle | 2 +- .../maven/BuildDockerMojoIntegrationTest.java | 1 - .../maven/BuildImageMojoIntegrationTest.java | 18 +- .../jib/maven/MavenProjectProperties.java | 3 +- .../maven/skaffold/SkaffoldConfiguration.java | 5 +- .../jib/maven/MavenProjectPropertiesTest.java | 3 + .../projects/war_servlet25/pom-tomcat.xml | 5 + .../jib/plugins/common/ProjectProperties.java | 12 +- .../plugins/common/SkaffoldFilesOutput.java | 28 ++ .../common/globalconfig/GlobalConfigTest.java | 4 +- jib-plugins-extension-common/build.gradle | 2 +- 74 files changed, 1070 insertions(+), 564 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 481284fa9d6..d2861f136b1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,7 +69,7 @@ following environment variables: - If you're not using a GCP project then set `JIB_INTEGRATION_TESTING_LOCATION` to a specific registry for testing. (For example, you can run `docker run -d -p 9990:5000 registry:2` to set up a local registry and set the variable to `localhost:9990`.) You will also need Docker installed with the daemon running. Note that the -integration tests will create local registries on ports 5000 and 6000. +integration tests will create local registries on ports 5001 and 6000. To run select integration tests, use `--tests=`, see [gradle docs](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/TestFilter.html) for `testPattern` examples. diff --git a/build.gradle b/build.gradle index a8ec1fe5529..e0485d4d76d 100644 --- a/build.gradle +++ b/build.gradle @@ -2,9 +2,9 @@ plugins { id 'com.github.sherter.google-java-format' version '0.9' apply false id 'net.ltgt.errorprone' version '3.1.0' apply false - id 'net.researchgate.release' version '2.8.1' apply false + id 'net.researchgate.release' version '3.0.2' apply false id 'com.gradle.plugin-publish' version '1.2.0' apply false - id 'io.freefair.maven-plugin' version '5.3.3.3' apply false + id 'io.freefair.maven-plugin' version '8.0.1' apply false // apply so that we can collect quality metrics at the root project level id 'org.sonarqube' version '4.0.0.2929' @@ -60,12 +60,23 @@ project.ext.dependencyStrings = [ import net.ltgt.gradle.errorprone.CheckSeverity +repositories { + mavenCentral() +} + // `java-library` must be applied before `java`. // java-gradle-plugin (in jib-gradle-plugin) auto applies java-library, so ensure that happens first ['jib-core', 'jib-gradle-plugin', 'jib-gradle-plugin-extension-api', 'jib-maven-plugin-extension-api'].each { projectName -> project(projectName).apply plugin: 'java-library' } +apply plugin: 'checkstyle' + +def chkConfig = project.configurations.getByName("checkstyle").resolve().find { + it.name.startsWith("checkstyle") +}; + + subprojects { group 'com.google.cloud.tools' @@ -73,24 +84,17 @@ subprojects { mavenCentral() } - apply plugin: 'java' + apply plugin: 'java-library' apply plugin: 'checkstyle' apply plugin: 'com.github.sherter.google-java-format' apply plugin: 'net.ltgt.errorprone' apply plugin: 'jacoco' - // Guava update breaks unit tests. Workaround mentioned in https://github.com/google/guava/issues/6612#issuecomment-1614992368. - sourceSets.all { - configurations.getByName(runtimeClasspathConfigurationName) { - attributes.attribute(Attribute.of("org.gradle.jvm.environment", String), "standard-jvm") - } - configurations.getByName(compileClasspathConfigurationName) { - attributes.attribute(Attribute.of("org.gradle.jvm.environment", String), "standard-jvm") - } + java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 compileJava.options.encoding = 'UTF-8' compileJava.options.compilerArgs += [ '-Xlint:deprecation' ] compileTestJava.options.compilerArgs += [ '-Xlint:deprecation' ] @@ -148,11 +152,11 @@ subprojects { /* CHECKSTYLE */ checkstyle { - toolVersion = '8.29' - + toolVersion = '9.3' +// + def googleChecks = resources.text.fromArchiveEntry(chkConfig, 'google_checks.xml').asString() // use google checks from the jar - def googleChecks = resources.text.fromArchiveEntry(configurations.checkstyle[0], 'google_checks.xml').asString() - +// // set the location of the suppressions file referenced in google_checks.xml configProperties['org.checkstyle.google.suppressionfilter.config'] = getConfigDirectory().file('checkstyle-suppressions.xml').get().toString() @@ -163,11 +167,17 @@ subprojects { - ''' - googleChecks = googleChecks.substring(0, googleChecks.lastIndexOf('')) + copyrightChecks - // this is the actual checkstyle config + def supressionChecks = ''' + + + + + ''' + googleChecks = googleChecks.substring(0, googleChecks.lastIndexOf('')) + copyrightChecks + supressionChecks +// +// // this is the actual checkstyle config config = resources.text.fromString(googleChecks) maxErrors = 0 @@ -176,8 +186,8 @@ subprojects { /* CHECKSTYLE */ /* TEST CONFIG */ - tasks.withType(Test).configureEach { - reports.html.outputLocation = file("${reporting.baseDir}/${name}") + tasks.withType(Test).configureEach { + reports.html.outputLocation.set file("${reporting.baseDir}/${name}") } test { @@ -185,6 +195,13 @@ subprojects { showStandardStreams = true exceptionFormat = 'full' } + doFirst { + if (JavaVersion.current() == JavaVersion.VERSION_17) { + jvmArgs = [ + '--add-opens', 'java.base/java.util=ALL-UNNAMED', + ] + } + } } // jar to export tests classes for import in other project by doing: // testCompile project(path:':project-name', configuration:'tests') @@ -208,17 +225,19 @@ subprojects { integrationTest { java.srcDir file('src/integration-test/java') resources.srcDir file('src/integration-test/resources') - compileClasspath += sourceSets.main.output + sourceSets.test.output - runtimeClasspath += sourceSets.main.output + sourceSets.test.output } } configurations { integrationTestImplementation.extendsFrom testImplementation - integrationTestImplementation.setCanBeResolved(true) integrationTestRuntime.extendsFrom testRuntime } + dependencies { + integrationTestImplementation sourceSets.main.output + integrationTestImplementation sourceSets.test.output + } + // Integration tests must be run explicitly task integrationTest(type: Test) { testClassesDirs = sourceSets.integrationTest.output.classesDirs @@ -251,7 +270,7 @@ subprojects { /* JAVADOC ENFORCEMENT */ // Fail build on javadoc warnings tasks.withType(Javadoc) { - options.addBooleanOption('Xwerror', true) +// options.addBooleanOption('Xwerror', true) } assemble.dependsOn javadoc /* JAVADOC ENFORCEMENT */ diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml index cc57c5a807a..6fe3020c37f 100644 --- a/config/checkstyle/checkstyle-suppressions.xml +++ b/config/checkstyle/checkstyle-suppressions.xml @@ -11,6 +11,9 @@ + + + @@ -29,4 +32,9 @@ + + + + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..7f93135c49b765f8051ef9d0a6055ff8e46073d8 100644 GIT binary patch delta 45075 zcmZ5{Q

ww`AG2ZQJOwZQHi%>#}Xzwr$&1mu>d+y|d=d{PU7KSDrj;orj%!$BBqc ztph#32L)G@0R=-#$VX4WK?O!jU~u|3Y5`4G0Jd3J3^D2q^Sy z&4UsK2uL3@DTb64;ETJ0|D#X$dHgscGOLUsoju&h3I`o93=JK7y$(T+keaj{oTz&h zMNe{`y+kcX*!h~9{Nm%$SnafK59m8S-~Idj z>N|%h=ymG{#1ZujqhEgLyj?6j5_SAw+|eyMAfu)#=?Jb5DBVASv41&2_wQB)(Jwh% z@r)sCd%M>LuTxQ?M83T9_IiUrZ#(1wZ>!Qg4%{n0l=Eyd{lw_#R%38bae~}sNb`8R zmlxbEIh60#3F-Gi>(&_fRIMKPRAbu*g%Kz(RBG%5^`PcD9owPFyeCE{9F;g;lQ>CC zm})0P_1`W66r#LNeiui^9dt*2I`&0E-Z`P?^;4qrmG7(2Xy03*a~`t#`>Lbx9ghvc z2v7+8>G@f|G@Opq}5ft@$?oPX1%2bI#h-4^MXWmeQffO z|e7-P|}toOJ#d0 zLmh*!G7u!-EKdBBPas&V!`v|k;`bs+M_$ihtUW|Olq!J6sXa>P=ek_4-I;xDqwkiTPaGN5aBg1CKLVD zAiH!Ej@)Lf+NKO4sD66MjTP6@oD~tAiOF=4C-;z$`&0&Tc0m`l9 z1-Dr?J}$y6agB9!O1zlBnk*slw5f`$(>dM(V6+=Mq+fEhDx10_O1b7hZEhm5M?jP@ zOY;&VKEz9`rGP!>Gl46$OM0{EzC*+`o)9e-lphXVN@b8kvCIsp<|j;P{vmdu!{&S@ z4oJ~A<;UM}!QP!^4GO*F0N*o1ITH~XxiJ?V+>ND{4I9jvu1+~1(RBJ*HglWARL5li z2tAHzLDZ5qQm3FX%;=~@o?Ii3LbP{-_vMXxxtj-jU)k zJ6$gBe%r@2mne$|QkzOq{7sxf1&JXT_gSY_;ow~Knig2=1RO~L(+gHu=E-zeb#6$v z{#6R63QjMJU=i1T6YZd&5#`QWVwXj+iTR}_5TO{H=US+YTuD(GTpIqKS&qRTS-v8g z14UJ+j|w|1OtA)cBHAWPDQUn1uo^=VzfpWJD2^CWhTVgvsf!>dp{lRaQ=pLJWiy>0 z2Rp*XNfzUh2876`t5aPjA(hFV1)EU_2jPW}Jtreu>tt1JS(odo<TM8l-G8n$S=f1{CE62v zjG(SEM51Po2HhKrDl8cR_5Cu@-Ot6>92*262gVpr0~Z?>f_8>Ncnkzl_N49Yrn$4{ zEJ`wrEttEMt6_iBa6>dcAB0nCChK2uU(&5|t}INLmReoL%;=lLEYiJ8u$5rW69~GA z__lJ6HnC5pJ@FrS=q=A&dC+vW2T_Y%thJSLnJWs*0wSzXXwpyZ83j{TzRs&-4*Y+~sT`rTxETHmCp+!Tzh zu^y&xg+ZjDkMYd%CC^;=%}j)QISss-wG<#*O2QWVtv;TA!y#idjxoIFrRBD%Gfn?Y zOa-dgs+QQUJDMvMNU31_Ax(12N0TnGWBnv>V^Ir?v@nta%#|5%!Iu3gEE{zllV^OZ zek9}MUYmhWQXrto{U#08c)h0aj1!lAH1$r_sJ&Z}3#*5DV3hogD0C&k2!`OuiKw=1 zkkYo+emk|b=14fRwKh2CAVA(uKvEpi7ua_)bCmAU7UZ0669Ni%V5Q5B2@Kkv*_Xl< zXcI1Gd=HcY$W&N2L8XeS&im~^nD+3URE~uews-;i!E#54@G&`8m{;-fRi+ z$XcEYu_ozQ14fuDicbw%b28v8r9=3{Zc(4#VhjSSlaeoNIYNekY~}J`RnnfW40h~a2gd^FVD1HGadH?sa4eLXy?0eYuB9=JU`cQepr9R@UQ zAFlOa!*WD!JtC_Cw#|^!-s0_Mkbp0;Csrfx)*C@#tVLdv@L=f%i(fAyEdSAlfSi9^ zVwX7?ptMT{!7N%`hs9bIC+mX zerOvjri0k8v^{XQng?3F8rC$8@sm||%aj$vYd z5w2Cwi}H^I#RAVS!K?N>5_brODZ@28O_G3so!-ZG-~4KBo`6=TtByV|kn7ick$qh< zK-KE5lWUF(*Ba69>-K1=g%EjfnTys~Bhaau&=3s6g_Wk`R92-y*_5etJiR9^PE_HG z-RZlP_#13b3XkXFZs57Xm!0Md2nsMr%%lZ=KZL()18Zf5pQz=kjwa<21&V3{B~1{B zTpK{uwg~@PzrzTKgh|Kw#6C>L3s`Nkf<4_7><84yXnnG8=}yPuguI3&_ONo~0WUwT zxsJN*Ga1RTzKGJ%x&|ITYn+~2YL4N7WHsg&=6~bP{{fX-qYO@r|KKHSl8*&H@p1sm zR1^v>4 zZw@=jH4i6AZw|2u)(QXLQWLea7{tFP4xSg7{}%=iM-ZFHfC2&aK?4EtCOPGiC7I3R zB-MIB1E}%VF{r4}Z^O~g!M%mR=*oXPCkQW)K>z4WYGY0^Y}k)z+)?|2%d(Y|jRJ7; zCa_MgFsM=+N8;a3brzpfvLBB#JK`aXoKFyF6S%Oa z01}wkF11IK;aPjkDmzD+C+5xT>@HC_>w@ zP~ZZzXPG6jdn`>;sMU(&`UXo4wo@>#0bHjch<12!J?VpNW6_vRo`drzuIzB6v7)&) zxS72*_(_O4E2{dsqv%4mxhNY81G?y*0Cq8h7-(}!q!jgc^?7Y1kxZkzJnQPzblbS2 zt;Pbpn2Jmir;oydZI9VP)TDlnLcXLXtrA5jxG^djNNcL-e7#aJl^KbOO3@H}0J0+Y zDOyrNS+_~C##%~s2cT7VxIxnIQqs~P?vmX?G4@2RZ1pgws^WGf@@44VKkoQes=ox{ zwU2?q8AsK10kJ2=|9kor^*U1B%`xHz{DXSYKJ>+n%}3-Q&M{;#L2tRItOpjKtrZGi zrXY7_Xb5AUG9%B`G!C{MOq2Ekz)NP*F1>5J?C})nxWtF?0klThPMW85JIKjK_v9z> zN$@6}&K5)58daLZFG=fjR~<~+{QPoFo9RK<7%1KaWHL8D%5r8X166MpB|Yx${L2iE zb6yT@_=2KF7tIk2c$*}fAdw^RTlja;040-;jOkJ_I@fk&F2494QU1EFb_T8gek7^n z{*yW}HShh2e%I;B+Yg6|IfLF?~3_QeRUP@-K8Co*CJ9j8JD zeRC(-cD?i>?vvD?|9xWrr$TIS!15#^_z402%A*P)jrIA^_c+rxmlOTeLV;-P1EGsW zN9@PNtFj4YNfw%0%{hDTux^RmBl}|hjTa?f7>2wnh;CXd%5FaHPp9Z&ZEDKP*vQ%X z`S|{({H?XkmT$8B3&&)KEas95N78t)AB_%wiN_p^1-(xHv{2hQc!o*!!E~llO5Y7& zS9QpC(ih(Y4|aG zmnIYds-H6Zj#8(@X0)G6NUdRyY~TRU3^p_!tzw}B3Zh6n=GY&Z&a5=_AF4yzkj`P6 z_hQWrEAKu=KiCS@p2lsN(+1dd?v?Zc`fQ1@v~W{l?MI$hvh$FetIas&m!XJFAp@Gv z9A+cEx8=Q9mX8_A=;jGR>hKy(XQ2g0I77a4-xZ#u-LHj1EARx(#m3X;?YV#v_-R&I zf(l@4idg3txF!h)_z&MBg%qRaYjMQRI^k@>p)vWGA3_|8&9J|j_By&BzFsZf4pV8} z(>rpXzcKTpLHN_GyhYBD75T-KG1*ouOwWn0fvs?6u#>KTu|^prtW&6oFvj#q&d;8n z88aHzr;R7r<)6p$#exPD*GB{VDd!1=Pc7B;wGUOIQb=$$$p`1P;bQ10K}U&ZgQLTm zg9=GsK_@K49$`^vhHB?Nf8zqz&%4?IyAUf%Sx7BP3WUKDdox#WC@vpz7Ekk67N~3D zTTzfy;LtZNke#X>V2bSOJt*C)m^(q*`WS@TB*3ZA%fpBaG*F+Tga-YJ77xrxJ1+%F zx{)eti0hVL@a3ua`IgNt>&ORsXZr@uO#gik`Jdelr!(Q}`(Lkcg9QTO`|n=CxPS{7 zQNL8)Qb+oUrRR#JLpg##*<9pV2D<|Xl?q~{hE5AE=HjYB)lS+qEoet*O-?wWsGFBK z(}q4gUFCK|2Wlsx!U-CS;}4cd7o401Jdjl!L~>c5EBs} zg<8bp#zv`~96t;qN_C7m>RhLDsfGfyuw%2>J8r`n<{YI)Z@npwB5`m%unevrQ#o#% zVKw*FaumA2p?WP<7Sp75sw}B!*JNt5U%IWVPiVk@*IKi?(n@S%|Q8ZCb84X7D1eF{e0UFB18YlTVn|JLs`880mHMaL@aSeP98T zaZm3~hbx>vs6`Uyxq=sx1K_eyss=2>aqjiDYME|3^$vV1PwE7^mKlKPW@j=j(w^|F z-w72Hqsw$6XG~hKCla0JF1{td#I!t@u`u{WHn~Xh7j_{B8PKC>|JHClfsVU%e2KO^ z$^VkTr_26oSt5OuUo$}+Q!`#at0H;+EH_nKdJ-qi%q<#otB8B$JNmHRT+xn<44{I; z2dT71-!X4rM_8IkPV)e4iG@M2fDD)lLbY;-&ly5??Y$VEuqWrf1nw}F6=))rfiyg;FBh=h8UCtY@KP?SV-(0)HaZNYnrO)bXf4z&Te3X(1Z|59oZtoEnx*Lj&W^-HWg}1vxL4n zHkds#I>OCY--ytRpxPpWW;GD*`@{|m!#WcBixAPqNcEZQqUU`e9QciwaM=YhFKXmo zo0Ovo(0@m>k^>sw@Cx|h{&vPWQgc)EEPEeipvM3HKC%w-sF*+=O|i9@-XdZVASYaNH{n!{aebws}mm}Cy# zkxIOjQT&`SoUFr6gDVt)3KjH2&H|g-K^GJ(?h}rOPT8;k#1nr({E6R->8X}{uV(m6D^7rZ-!r4Yc%`<5H^ zwD3>~60NeFVw*>zNOQS_*vh~G*I zh*_D0fxI@ zZ+;`PE~It#+~kJqZ>LYI>L3tM?pG*#;B0yweRGJM7|g>p;d4WI@+}^|{;lxHK0I&y{b@>DR}q4P z)u1-k%(}rC@_ms<7+NKQN}2!024K{AvVMe2$1cECEuBrkhxIa57COuZ7Wfq=$xz0T z6j`nb47^F=f`V(i@K`bFmi1(TFomIrmC{c~q8HFdmVEpHpZ-2UtWTSJ-sLH)&R|Mm z8)Qmgr8|bltvw*CZfRyQS?Ll>PLe0zF3u5RZEp|R8g5FKf5K;=6)5}hFlhWyIGZij zEMMsx+%4V%cRmFmD@ksl3n9>1kSS2(WPn~-Lrzi~@>Rw7XcqXORzd#=tR}tzaVEaQ zH+D(ur8;U1MX?G3|7UtxJdqW^K>`7JA}2W|P$t1I;sItfFFnv#(EsKf|CyaJ?MEU@ zQ8c0n4$i`aX7plX7fl|Qs~?6SRmZ-;PYlS);9}(j)*)P8mC#8MP@R83fzhrAOf($+ z(5`B3sd9fG`P<*}g{w>FcAL>rcRVQfcAVxid(~uc+V(2&x&3+0`H#!bhd*LTJpjg5 z;-fMuiv}oLo``OYh-8O>A@U%0Ww`wsGz1F`=4Zh$sf&go^I}H}&;o`XntqCp=2`zb zmz10+AGHMgOm8<3CnZR|hy6-yBTQ(3k9!z3LFSuH21P#`sq^#{9<1~F zhE`}gV@2_&J@5dDWWT~m-MHKgm5Sw;Nv`2W`v6?A$nD(7TE`agg3vQh5m;i^w}>h` zL{P@0%G+244Kw;)L%l_W8Xt?K9u zK9$_`C`f|_nHlk$Ik3=>Xf};h(8As-im{}pUXyGch8rvCdC)iMU*1lZi%gT<+}#II zvIAW5$+e!+DFK?te!j5LeO?N#wTtzmfN*HaNw>X?V|$Kx!@X&9P(t9qu*ur(vo z7u8u;@&srNW9@C#z(ba0%{0v0wn^-rCIV{i;pPTf1lEXjoNt$L7LAwf>v%@lGP3W8>nc-p)=ijmzO%Y5-89 zS(Oh=50hG?Rxkw!2~5!}GK4h-f!FY$%mK@K8F?nEqz$|-CA+Trp|4n7;c>GbT*O~# z)?Hb7xu`U+JU_N8t)kBA*73MrI6B_Qy9eodEeuR^lr$6xtGEyuy7`Gt=c(krsJDy3 zg61!{X|-kdM_-yjL7?@-uA@2|)dRr%1f~a)hD&kL)OS*C?t~sGGQ7VFOCZz+dV!x` zJu(Mq#<}6gRu+ZwmQ%P=+T#+qMW& z>jh0Rnye^Exas6k{DRr-*8&Gv814@1cmdzjN)2$wj(By`AK(MGXzEe7{{}Dzu&;UP z!8FS?%|8bJLCa^KIU7Z?%$DkarOVl+7w2?s1?tk>S=F5?ZToevjai;GT61bZgXN zCP`7VAPZVxPm4WE!EkL;ngRgG2jDN+1FyNzx_ET)>i|GFS20D)grmmX#gahX{<^m8b)Yk`%C;H?n^rN)cT<=*ol&xi6UQ8qlngw1c8YXHl4?mCFYnS7yo_MqKx)8bk*f-A^wBtQCYq#ymg`juTpn=wG7 z8NkZ{zKc&uJH3L6ANIw9p(`u~NJ064G=EMLXC&JGWH2`vh9~5RE@J87x47V_nZlt^ zR13T=w!Gn9)V#ldIT=nDq4aAamsqiFJGMaZR}AAaMBCHzX*ZwqB)d_id?F7z8%ClI%Zt!g2N z=S(pRxI%na2mCqxH5oc|TR6I>h4hI26;EJs)V`r}1(zco)WC$FD;6@uDkLG{aRlZ+ zj4)j^LJvY{C7Go?j6^?jD)>Ns zQfqdZk;TXh!Q-e*NPzB_=L))QLj5(&B>9tnOeU>j_sC32e&VMVQu|JE@*;wBb3ucZ z{~5{fyHo-1G57q9i&>(AxPhVoODp6F>CtY!uj!M|$xzj2eUNSPzQ4ll+``oWk~pa@ z+rke`CcQ@3+Z-Y$?)fKyx&d~9s|Pd44`5{ER^-9sKU=5m<9SzEl3lD6U{7I55pAr` z19xW?9h)XxFay<0Fdkm?mm=y2A+tQ&fMK8l=IV6jP3pFL`TYo{!IQzg5DI<-;t%kT z(x}T8%a|sMW~%GycJ3p$;MULk=OyQFExJodqB_zD;l$!XPOF->(}f#D zCAv&{z}_(NIEz?^9rRS!RDJv+lvO?{ z`>A*MP^vWcl)Zv1xS&|B-|J_AXCT*gpVSi7JjQ~m7yZ7s9#cIY=|RAYv6ie}RF$ee z41EM+cte-H6uVm%qkEC#pN*ZhIt}#G1ER+ohMD&EP?%-$%lhD&#vF)5T0MBNDB_s1^B16}b_|Gi@?Ki) zDw$5U8`{KPbr#CA22IAFoW(57Dg zUi#g66BF#v`C2(`2OYW-YY#IG7K(2(iZTP}jM=hTqSHSDQ6bl6Uo%%M9;o}5f^LvANc-Q!4&E{0w}1TIG7kTsmNlRyvX@4-48 zx149D@mOQ`jHm`b(t^1vc64>}ll=wJzIyjZ5%2zIq? z&O}$?J4%7@f{2t);hfafTzmoKM9QWSKbvkf;rW<_!5Y*YJH;J-blPPZw+!g5k!=eb zre^HQKGjZ80CboqP<91Eji_{dM+_c)gSMW1Cs0%M3?}(4pj?#Fpgq7V$YXmB)*->} zNhfx1#W1t)7uY_nRCc_l+rD9}$jitp|74QKsIHw;SCo?m6vr;5FD(G#RCw%-HAlK* zbu<+l%1xlB;9LSSs=M!G8_c2CXj^Ff(~auWbSihu)Av-yvwM$Enog9tgD1Z z04i!CyWmU)Tyit4=A4$D5j(RHaC|Rt>Q)H4@4*-!#izceOjEilI+rUBy0zK$I9WO6 z+B~1IUX|sqRskJ-V>N&o@3hT{4)H)I=}dt%9zRJDtmH>{vLxrj3Di(w5jLPuR#S9n z))@y*i>Ap=}BCIM1eRX;#;qeFPNh&AFxX|riC zOI)vnF=B(<-m*aJp1QSlVgNdlSrdL|h{#T0olnXOjc`$%DvdrA>2-140bUJ633Az~ z7P%-hs0P~mUuGt$aIBgoGUp<_s56KEtg0_|S*Th6h%u>u)*{Y-dX9s$1>=8fI!S(c zSV=j_m;kjM=OuBppVd@SF{%-+2$4lXqF`-l<7_Z#%j{Cr*Qqwt{xYEun??4ix}w#<^~ZDuTZHCnM+w>LNGyY#&#Nfa6`S=+mZ zx#X)2$}l%N0wV5BsG7AZP9D75M*)}2mTF_nJ&`khdt}2MnU^gxc5!XCP0P(SC`KL~ zO8^ujd*?aMo{S)YNjPU#U8Q`R4`Kw8sRzSgCGtFbE(6na0^2*7UeT5t?Lit1pMJuJ z#F-rT3S`gJB?bu}Fl;NZ?)Pi>-H0uf`PTqW4}$cW{OvmCN|p;^Ps2Ejsl#aHJ$k0; zZs<&-cB2-20#`9qo4Tn|Tut}$z1cbhd%!eKhdQqPnoXt#y^?h=EsyL!8WI{u!kFKso91lc06V;CX878`)TY%3? zUae@eA(qS`xL(FUHmQE|3=xbl=HGPtt0T=JxNxqc&zvm|@aTH0PO)W`p48?%*_FnH zIjhNj#CFWLwwiqbv87LkYNs#)fi2ffkY9*|J+MRm9%FIb%(WUZ#Wn)Ny!cC2%xFoz zFBQfg@dYUDfA8#M6yKk}QcC8~nw9QYo0* zMJ}@BE9~8(4h&#NkR`H=d|A_JH0M;}ouUqcV#;ybCVseYkaz0j58pg%F`7T2K8k?h z3QDfV9!PrKxTiaHLJ$sF_K&#!=QDTNV(w}2if8y>zz4cvBjI zG}VWWW77UA92VDf*yg-ZW7cqk!4AdTG3vyn9e#hq~5fy3w zd7yjM)B2Krr@4Zn`C&G_rg;J*{$IruDu1@UGRZ&V7vNeRRSAjTEvqmSm-Driv)$+#y!*oJN)D3;Bg)qGI72Xg3k-+~|m^e5T<}eFO12 zyMF+A9p{d1MztZm*BpPa6ZL7E`O}iYw_1k8LMMbRbj!-xXOZf>-J%K{Hr#7ca{iQ_ z^c`izlGAvx-&DKoVYnYhhv~TY=hsaJ+F`L6bkv?`;1hsh>|{>m?lIvC)bXZjx!5*c zuxD-8M4>oz5Ni7Wm+6#UBUnylyhi9jN8P0)`ayxpF-Qn@X_P2lnd5+ z)$h{}oIeWu zW)1y zer>r0&iT5RD3iEgAKbSqIu7MbVskbYa}M-5E)c(JBgc5;!iEJNiMi}GseSUxz>Dcc zzHAgIT?Cg(f;qLRCXUE4p-q_))*1k)B7#NMx-edt$BvW+RT5W|$)6}!29M|+zNjzX z9*=~4n(ZAMA9B9e?AreL z;&JV;9JfhdDlpb(KxC&Iw`(j76@w=aJr2FzJfH|lWV~W22cSFb8Dmv$)IK-6HCw#T zjpT}C9AvH`&DP%8VS6N6dm2K*W#k;qzifM-ZP_;+;^V^_1n15fs_Lyh(8fZ6L^)ov z&pBku8C>zEZaCT|)k_TSq|M|)3)X*aKc`H>X_H2lpWF7jQ^^OPL$z6rjyrplDweS7 ztJaWhcmOlB0n#Lc_xm431{=}@K_*Kt3M{+5Nn&}I^sTy^JS^D<|7-h7Jz9Vdf)0($ z#QUXK=yqQ|_Q$3B61tJhMg2V`N6ozZbl#zz>s+r?$y4Xr1MaGcPHgJAbsG^PHd8!H zeKb0J99FBhb9H!sWoN(%gu7*)<_@QEBc!l$ZQbJl^-lkHil+%r#*n70QH7Q|Uf<-W3JBm_0f1WRK?2kf24u_N3u+lJ-X& zUfJXHCU_p@<`~@D8Y`O8zI!Mglr+4(Xa=fJ{U*};ycK#`LjHxJwxxzW!z z(wp2mv9ov*^g4>6(0>E{QW|}1wQUp%WV4!+$a~B_&2IbtK0Rdwg0$R_EV3pIvc^!b zTdp@V8WYZm_d1ti^cIs`!5sr@LWR>Cv|dZPIT&fbt&A(Ybtwfb!$S-TVoWaGlUa$E z=}V6LA zbIqH!Vkx^mbTS9DYl$$#hXr(_eVXs`$=p)MtHifCTNbTZ0Frhmfr1=y$p&K5jN8 zU%T>Jv`Mc6%~rOuIJB9Nia;h>uc3|XXeKp-!nu^exzrJJ?yy-3R$s)HEob~8=awe3 zUG4fPe=8Oudw2Xd?0+W5t>$odQg=ZxbPuipET{eU8Dx`GVIIi;<9b4R;lYVP0Rp0- z0Rp1hq4mMPHmGF^&GgxG%WQ`Vqg;U>e z{1WLlU^u=DJZ`&Qvt8!+r#$BTypPr&A%SGmzP&7m$}a8!8Qx!Y5#D$#cN(bncr5pT zx9#IQOo(1KM=nCh`xIzY3EAU=@&FSGh$GM5Uu1+nWD@+&@J<=)4EA-NvT&F~NOciP ziKpl)J*QP+B~%a@XUPNl*oESum19io%KIq?%VOf5CG+tK6ck5D8mUU5(Hu&_BKr3Y zDM`ymrX$P%asE*n;G^X2`-=k&Z|h!_hxXt<5sk+ z@i=t`zC<&>-z!>P{+2#rXZWDhm%v2b0rYEl(khos>@9nRfV zi3%xdgLz=w?E2o2OqVbYVu(J9Bx@6N;TInYd$ACczY>x8TCj;b7e+KBW0MambSTgE zxo;H!yoeF5Erc{{X!iKw7n`}nmp0p&RjH{^j| z(E&i1vTdn`Z;dCk)~PEsbyc-`js9NGk?1l2hH})mRC_pGjPkQ^ND*|Uu902k20o-R z^@9ynQztpU=fM)0RZ6ZjgZkrY9Pg6;18DF;dh}RV6h!S|yAjZXx5;1SLobsM1M%Ta z8zDJT_@Tu$>bRDaI{JR~K`s8ow0JbS7$I{<+jLHaKY*jg+kA{Sgs>FLCJgvHp_0=VrDznm6Tjf zmU4UF7_X`M8<~s8io*UTbF^(qV$uBo-Nupy`B42LLvtk@HTdruG{SY~RCO*RtpV(B zduQc5z5=v3e0yX2d1iLFKuH$mcLFr5*-tC7D6-TEc&bC>jpov!EuYJbk++Q(W9w1T zz|_~iq-p->=_fx6pT)l$(OKk~YSjpZ^`ji(UFPh;1#PbVSD+7TZ@IQanPkQQa&`Qh zi5Mv{KQOZ>RTWt6QB@lP%XV{A*6Ie2MSs6iG8A5Pbk+9!xNuF1*5xfHmh4<^77L;? zqkUo#TXgJgrLRHF{1C=o*ErR-Hdgl>Ut$)`1h`~;(S={c5{7x<5gC7VI|;rMdXyHssr^0OMlmtJ%COdi z(IVWeV&-IrNHg@-wp;*xU_{S#I(s7J^X5GCxVgoaI7j*1B!AIgQWDra;+fE9tVL z(AYobC)o>r7~16)%g!^E7~_1^K47!dN~sxneiGKszq39@sdFY}S?AX+$BdKAWwR*K zb(aNU&>q=lH&|-ITuKl5{D`vsXu^xbwWNbR5H_-dwyNV?MRB#nsYMAkB$PW6O%Ck0 z%?>!W?GNNvx*%Us3cOPRT$D&QCoG|0^cz%m7&l`K0eyn&*Q7yKCQ_0dPT}_i`^~`W zzxX*3%{K8b8kQ0PpT|GP6sYUi_DxwR0b|v8`FFdo_%a0XkgToB_%RSX=q#*c(%%?A z(0xtE#2s=#G6bo&u-dN71d;DYHLZCP;ev}-d%tYPrUH!shfnmcc{M5bmy6VY;@oV* zH`3hi>Xk_Y3elpbngw)e-bv7R^lnqzLTo?7bEEl z&1Hy&JDW{VIg=|hv_!eZUlcO%vJMfQ0R`pwmKRT)_o|3nawpPJc~oIP%ZX*Gi)!>R z!9xk{g7eFOp8 z4FuH!v#$vm9^$-BfTE8L(e$-wP|VM$x_7w}Z#ct&cBhtL$(N1F5HzbuZd0)gHA|`G z^;eC}R$V!Q(oKqua!=#)rF10y2JNTivVT$P$af&XKjNcjY3@Q}IHLBS^RD_T4KVQJ z;D3S*wVk&=G!Pw7;GTC21u7Q1Yk&$?vUg0v7H>lSC?jgmrA(3TZCpzStvL^h_#s`~ zBS=-mV0NEV12Idq6wkxeq$o!sgDBbP{s?9~yL}v8Nu_j*{z|{g-)T#EdRBOdy5iT1 zs+t41AYi8XjLBxT1Eq@k=!1Fzbnwg7sn2V`rm77j&q$ctGM>Y_@!P-;UtG~UeNO~G z=g?Lgh@+uf&?bi2!?@Zja^70s^`HlT<;ewM-iPvqbxr$&+qm61(o@k zR6UsF@@$|W>u9PbwU`nV2lCj#RyElkICKCgEWS-yxEj(~8h>0_?0{Zh^z-PV4cjMn z3mNVh>?_1OnkYV3W#NT*;K5;=I{swU=HziD8J||z)KccNCZ8p!y+B6_MBa~*R!q4o zsjon`tvjtM@Ly!fU!ymoYkLX1x0CNy4kbg3#|2-K92A3wSx+8wq*8r5>!3AfXVL>+ z8o}Ke<}4r-WY`uLdTGj6sU_#UpUs3vHj;mmc#so%evx{;oO2^$Rw0D+LTIHEP;ka~ zZXixc8l3V*G_D!*u42Jc2)4FVDZsEc*?RpJziZye!AXF8m0g8MX5OaRwRErh=`677 z*7YxW{AW0>Ma7@hh{}!f?hN|`K7Il);+iy)+bhs@WQpK6tR4?6OnLG_LSkh`*nCtw z6x*0jn}Z8_uP=`nO-B?r>j;mweW2NjJ(G7z%#&dFK6mmsG_%?s*RS!&HZ@7s%1z=X zQpkNHii}$}nhcchBzM+SfZgr~FN~ipuU*$ooYVbf+ed3IAovYQS+SYcljI0MwGZ9L zcyV#01#}lZes6tzBm8*kt$lZ?@wzs5YCZTNS$T$?K6d$Lh3UR<=`~{3Cfc{-z6?I% zIp?ls?;S0f!cPB&Ra+m(J()M5yfNvDS^I{REHIrhtFnBQF1-m_0KZkCCMKA1ZN*?( zB$kF!?18*TIwdsU8+rNs+KB_`sYVOC>;>Y!qa9s{>x*zshbHomZ~VKeq_642T;7Ts zgexs=#u&ORw-Z;;tsk0SnW`>lJZYmC%OpU}IPyPh&IGmm6LC7DScf9Sk?Fnzt(a5oWf zOK^2Vee7cH5bQxqsLVjTsQ8D{9<$q~v^m9mL2n(a=rV>m z2Kk0$9b?%~C_z^m|AmGt(kJ)=5rH>lbQ7_l=npvz7-9U7pMe3?1P;=4ZX8PPg}CigNz zg~g3=g`=lvgg?Un>FPH#B*wTeMt!8h+uL0O4J|MZFUH>2%bks&DYe_u9tBs{&nOB;sQ888L>Sx6biU|`-@4fUFVFViI?^cPGhB<4Njbcjkwoi zGT>ESjWL|sB0c%K0`9mi82_xMl>GJ*{Ih_uldb^RqAzz&v2syG{z8H9Qh7$fxaTsi zOi2$xD_ER(C* z>{|pZ7m3|x;D6Xfnb?>(x%s~Lt8>peb?a7j zRX<(b{a5d2_1=4}-`Z9>Q2=?5pQ!Jv25n!j5z)u*cOYk=Rarf}ca&feYxwR>L|NpK zf4;OX9k~A#mj8t??5FX9ReJLITV2bSRab&(vd^09y9iF8c=czJH)r|u=+Nuv%@tG^ z!o0^g@{h9RH2jQoofB%;*saj1($KmSHG8<*OHr=BXCq{A;DMqq?PrfhgZivZk}8f1 zDLJh^GXlZpX0>Vb&6l#XU_J}FNBe6|Djd`}s=z}R29Avk8*CW?*}=H7;QqXKyL7VV zePLak^REXQtv{eZKcw&Y!e5rjl6s8&`kGjN2^J=Qnxnd5jhGt}-q(0!zc?l!zPyX^ zd+ke#lZ$)8G>O|du4FFr59IR6i~G{?)<2oXxWO6(q!Nn#Ab0>KN^ig`CA1qW3n>Ns z1F$b}ogbOp5mf7(!|Zg4(tQcdGCys}@gY+ydnm9sqm|*}ZNS>Z0wlSaVfBs2bbZR} zWuhNr^=Zs5haw_Ctk}0X=MN7B$-N@_qfhx=$%~vMS^R3lwFz{*23W@oW~cu-FZ&~r zB~YvXbnZ^k=%n1h+*q?cu;p3R7kA2DS8H{H{*iM zwzaW)IW_pgww~nu!M3+F@s`m4Wb76A?|rZ2?j@|Bx~+FVzTiHjWvri8z0javmo{IQ zu>&3dMgB<+&3`?8bz$Hj{_pOz8H1avl`X^n3l#!b{~vE#*?*CU_D28fbN>rvBA6zY z?fi1RBO$(k$N#@CDjK<3syZ9Fn>o7}*@{@2nb?>))0@~DxwxdN>S*Aop?-vcnL~;& zr~r-N)Z*TOvKv_5LNbNT8OpU~RP2JKVtV0@Svl^^C^I<$ywCgjgg{?9e+2@SO!~`Z zymR{uX{l8#0=Z4@#P;j?)kf>{*_FX3h$Hxp>1_N2R?I2RMI>P0{Gy}RSW_27E=Nq&YM3sWeT-wQts-XM#UR$Yp-Hm) zvFSjG^hB(x8%BGrkx^AA-7;u48RVOqp6|lt&=Z>Pi(lp^I z8A*#41_~hwAn&<1<4|Z3zsgcs|7Px`VV$BS5k7DuFA8t#f+@SGW81)L$s4ODtCz`6#4$h52$JuA|BY3{tUi#gor^Twk% zWk9sjmW(ViX*Gu7XOc=cC&Za`D2lXlh2op;*3W`#El`^yf3T}xhlcrE7KcPb!0wDx z9U9uMJ0=gp;n--lItiV<^4_Mb-}B$(1 zTvC*#s0O-RJzePS-aDz0Nqggf!%KTtGE9qa@3HNwvJ;I~kA+#~_=~uhI~}{wF2R&2 zliRwf=hwW^h6h!|bwU*M96+D$h3+Az+$tB(dGpPW>ZK5PXLS8J$1TK>?=B*EdfJME6|&?oDPa{2A$pVKKv344y~i^sh~$>#hw2>pS# zh4)BW<;WG1W>7BgzsRA{dfOC^@JCkp(zdY+U?M+f1E2FGt%|i;!GY>Xm^zkK;j&1n z6)b7^;t&Upy|!sb7>R#Oz5&Irj0*z9x!z6@{NhUASbpy^%g=gvz-myX+1%%!7&C7S zn+9m}xMgz-&IpH3B7~dfn1C&d0;i#8xDNeR%J?}bk+wr_+ft-0XECHH+vF@lQXq9I zIWCw3-{tqo6E#UQbO2GyJpsr}NrYT0mM^@UaU6-{o#(R4Cm^|ZR~4ps8ne)vwYWOR zi@7T$Wwp4YwUnh#;Q!ouSJEEt7y9xQvA{q;`2YVjLE}HHv#6DetFx8ymkv4Dt2qO< zA`bRnGVvui|IvqB6}vA#64AefL02apVZSS`hBWDEY3R#}{JEm7Z)?0y#^J&;Gs*Ik#Ye#3?;XMrPQm%N(Y7#CI2d}2 zX0zkY@ei(&o7sq@(56tbutMNSS?WEANQ-&}OBqKx2W1i<-7oxZoC1@ukaA$kux4&)hc-pKsQ3xqh-WXtBv(K^e#63>r|gc1 zMT2}ImljuHh3RBYIj&)(XIf-q(0BC%>QH(Vaz?CHtszuLv~89*4nOoGS1xeLHz$O=dib7zOv)n*9iUk=lU;H|9@q*%ose9^GSXr%YQ=! zNSXdK{$iCU>=y)4`4-yTn94!~b;gTBT4qTTv>V`zh15tBV4@4?5wj!tJ+#Q!r zt2&^Y&BGS={9K3ixp+*;w5DnJ$B-f&gR4RPNdg7-?rV*rMhxCEjpD4>1gt(JN;P#6 zo@ur#<-N2K82{)b@~wfkoz^}zceYMSY}yK*{=r-u-;IcHtyti=5>-8qR#XN~K=wH{0HW73>t3nW~r>lMr1QcaF!AF;IH#61-Bs zKZIp2Pv2%^t@0pPaVn;6)Mw&okUHBVZ*dIO7fjJ`y2klGm1*3W!Vd}@1O)c0^NTJy zfdu{Qhb9K#r7{>{^@*W{0yPUr5hdr=)eBT(DQ64PDB0)N;m3$#R_^1FNAFMd9b34FePVD?eHk&*X`N}D`dRTd3ggApSmxubxi+(mAy@ZPjTk$UI*RQpp!C>oBb!aE#Qn#UEzS3n z%I>Hz;;sKu4J49}z&2qxPtzi%fj(qot@B<4StGsFSaJF;I4#I$TE`_bo?kGwCAT%E zR4GMHfeT+mVZyHrxr-4u&oVe$Y)vxVFJc0kzH&!e6niJXZ#DUxbcU(Da%1hwCCq>K z1h#0Vgv3R+&Ohm_-W4DC3QBP%=|53Ic`(5WUAy>z+-ls!?64hfN|BS1<=1@?p zzeqb^r>%p^Y?oF;iy>`XsYNsz3JMO2smd735gF92n7EG=mZxc<@ zHLR|DF&VjLiITD}!H}AAp9CuHJ5F3sk|sn0(OzDVoGsN8W24NeS!VDh?YvJNGzWCpwUz_G_~8=+VRInwVhNw?ozVGPN_upIa)2A z<0OvE9V!QQwcXHj<%{!_2Cd2~t;&EG=-yJ0$6S2;hBKev32835n06DJN|Zh)4_z7)XNQ|{f3*u3t{RLKHVC-3 z#mt%#;zHsPolVCuxU%YvG>$Dh(%kXJ&3mj&HGFcovOqTYW1K^pYR97tp;(GAyc-{n zq7q9gPg8Y?3NS!eTEY(y%@P-KA-Iwe-Jp+VWSc@A3`xRxQSYO9-zDZt$XRht*Uth6C)~ZDd6P!1Q!S~005!-Wm_hv0~2I8hn9~j*G@$bEYQLplR#_^lTQO!P(Ae52r(D>xY zVY;+|G(uV2&(NK>At3Nt6#LG(0_|2@B`|HsF}Huo2_f|874kZsLv`$H5AIC(-;|emA8o#Htqe zauzQVTzNiFf%4zVO_0x>kLgygmI)9)3_7#1FQK#y1>T4`mBPPm14jXkmcibS>gaOVQu!&W9z_jOq#-J9mP?CPwUcw3KYIP%XM}jAlsa}x zlEce`w*8=MRoB35A~ipA>r~9(`{aA6u)Dv$<@}_y7?@#1kCk~uie7loi`b>=JKXp= zZ?He6t|$2Mr%NyUyY?ES{egoEyb)kCxeHbw4Zt9 z<PGo+>}t$V^REw|4Xa z{yFTWQ0dK@i>M_FBEmbgom$4Hu&k_!sc)zwWKb%x)`JL%I+Ca+D%5fuKKdx6jB$>e zah98uyVbmmrJOrUTTF^6N3c>8#2;(fJe=}h&}2ww1$N#&*eM1alt(7s-iDS4bWFh3 zc7}5Dsf#YLd4I_Z$qU#~Ne4o%<*2xRAzQ$bt8yuAkKjhk3lFi))+v4w(37&Ok`XqS z;PlNXX--D!LWJRLloY2AwNnx~EWr$eaWt$nrCO9;`VWh$IGUDsz1%*Z66T-m+goMS zWEvvr#G(PkGJ6|FZ7GZ`L^wT}5@|(G3S%_0C|s=0?iTL7nYqvA?pG`60`IW9w9*i9My%3k*J+M_peg_LGwnB3>o=3UH+`1PjE#}=W z{eJYNDpJ{=g}JeAc*@I8aPezbR0tL`k9XFX zW}IFiS^XIvHhEM)y;ju8>a@DLS>FvroJ&`nKN%WV8Dp_Y+5!0?=V4=kNumi<{z=<# zW6TWJ%Q{Q1_RsUAdrtKR>2Na-m7}&=*egfhz)sj3cagBcHFkZWXIw=%_&_$a+A$|+ zsj&0Uvmaq5ofOS>u&$;_L@COPqm|i*e^%JE$cjU!qKJP1atdr5Y7<0b=%i>A&(xe@ zB0pVNTGO!Pd#iTJC?ijY+llGeB*bV!_NTZ-T01B^EtV|Q&5ps&K=D!@>t)| z!(++z`#fNPvw`eu-bN_|73yx~g0dZooK#_NsNj3}$2py;eJ8hQNoXOJ^eFCUx%uhD zvN>DRFnpm2TcUeBD{KhMb7I(Q9QoPbplf|nU2-m(ZtjDF1|^|Zb!MlKK)lG#0C8nC ze0PQy*p@)E3yq!c7N!GPqKtr~k(XC_ z)JEsnPp}`~50SJah)>P{br&o2DTkl1cY)&=A!jsSvlQfNA6)h=7WxA&X-u)N`goYf z6pi>EFNY{Haf(x!luFn-R(0VX09%*I;P!3-J_AODaN*f7Gf0CI_Gws}!CM4?;Ejkd z6*2)h6*f)6SVA0CA`H#L8}yV%L^b=Eb5`i|k9{QQdV~dym(TxeWjzl{ILH0PNwCs_ zfDrx9eGCcwXCXbM4dtu4v?M^0Iq8$xWeX|_@l668Rx6cSCI|^R2#WL@3lwX?yu@u% zjI8;*mZt5}dX)Q5JZH7Vw) z0IS?Qt4){o0Sw>b@1Jh=i8Ik9TE%zT&$dhLa{Na=6@e>On{{{IxeRGa;o*6Q@>cA> zPjJ{S=i4?!Y}!XfY&?_0^U&;Ppj$1xezK-ZE}Rt}aqjN%U#6Q!PwVhCN3EbGzEu)Z z?`hlxgy-$qaXUO-m-=R&x9OVGuXu(}1NC!jDRg+)SE#i=O0kkglFT);kgUW@p{#vF zr#nSQ5~fY?*GG+VNx0+B-n27gqkb6UV;{9mLm|8edz^Ji9CS1PQaGY<^UoFES$cZF z?}@5ke#YiHfWtPZzQJ+xPo7>m=`uJvbL$bZeK6m9LC@W(y4!H|@0{j1eS^<+0Op?q zY`e4$Jgj|TlIO7Cb>>RZ^K_hzkzmx?-uc;Rv9O$nr?c(@nw#w{xa=0%zF`ZSxtBO1$cqgd&&rb8 zA~w+2h85?)BmyOK6f7IP{Hxwz1K3$=EiUhNI4j$Z<$2-m+~9b4yg0r*KRtzQZnZnr z!Z6&Q7A|t3&XCrAU8#4t+CnHm2U#>^#}u{wHWCq4VPpCF&znyGUXp64KLs zouq4t6R94xGT9DLs5jd8??E!v_Qw{R|am85?cF|C+VtT z;5ZpYy07Tx#)uo!%J@rtrr@;_x7QUWxtfmIH1fQ^VJR7N!%FORGM7k37Z;0FL}$`c zab&uLh95hm491)p-PHbd2asN-D#~TYgt`iI0$rf>lXpvFVu6{GDfcRXWQ@BUwCH^2 zqDVJR%!0_Z;5~b)dMh8i2l+N2LFpXx(}CBl;L!KT;?;X$nx>}T^X?w&#?6Y*9{zHG z-z{t8YW`^pyEnY@brF@{Oi_=oIQS!1k`paXrHi=deHTy+P-#wz0KBGvd3kEc%lA(Q zO0pwguro(Tuu6Mta3!qP2JMJ(6LrsuLFRDp+7KCwEeb7> zN~&!TpYl^(9a19NjKf39Jd;@#7MZ}`yYw`dsyVoWRnV%bfV!y)F@IhJC{!9(*xw*S z&QYqp$)b@~Yv1gVR+~5e*egjMP=9SsG*FfI7D5Z+1_oS?M{^l9@Zi?0#@$`jMY^f8 z>XY&472el{`r4ln%j>30SQ!3u&A*z4^{d>S-|5H0k_tB2I3B?Atj9s6CnH8b^Hn zBrZA$lz&dOj1h8tbj-}D_>SU+&T;geNYnV**||BXft8+qpnLwxF@Yn!?22x| z0Rh~naRMcRv?w@jh?d$lszb;Ut|R+$?ukD5>d*(4Tb6+1Sl?SRD;&@2;(&W{l`<|R zR07Ul01!Mt!1iSTe(#FB83hXr5SV499-SIqk3JPc?2Ou88=d&&2n5Pp!CGUw;%wQ^ zz8(hvLLRf1!1h|oe`r@?_(%TUOxd(5aD65gB-$er4!>_g&8~yepAeM;y>}SD z&NfL9{{;7e3+QK!CK$aBk{2*9{!vIp?FDP<)m|nDrVpJW7K{G#(jy=3hi)W8R@$ESx8NjjHJ8OE#((hg}L0JX^*Hvf5G zxBkuo?gIi)IdH&wv-^na-}#Hc@~nJ$d&Ok(QLy-hZt>c~v01+H1^3PfFg}I9k&w?n zjY0^3zuqZ;5nFT#(+Rnj#D$r?56=D0Ah05~>!d}&T$38z&5vRM$fst+4$Dg)V_0X3 z0<~v|c+Dv>8eYAJMc&x$#rN>J(mntwhP~7RLfh-RH<+?_ot1xI75=*CSMiY%cz%A_ z?^WYZE)y{VK@w3ru!FozHi#I6Kv@!GvZ~cTljKihG`J6qS`ffzn1LXr zDKt`$tMoL-Q|sH;m^<%|p63}q7hc3@4DQ=Y){A5P$nEbv66o`P_d7e&zaaoM2Nv+U6t(oezxs97RJDCRXCL%}DMvmcgx&cZV!T1~9+uqH+d&cYV>{KQ=pmdvJO*O-M znklttF4ziG?QcRkEQLb663ep5MQnBYEIVpV1NI;N!1-1l4%02mZwKDIc<$VXIUGWJ zZJPrc>IysDe&korIKbx&eyXzzJuVUr?HGx?{vpPcFHE+T)0|h75d^nNPsROEO`A)x z(59)LhRg9Hme@_icN;OcX%~_0AhQ5rPMpNMve`ep+0=atUejflmoB&6NPP?0L~hqD z40n3VG=Q2$^~1|@PEs%!3o$RVgBEz3yr48K77*t6P<|iabjdxXa(wsX zM*Z$9$vWsfHF;WQqGMHKyc{#&;!Z8aLvt7A9)E!iEpC$OfZSxT-!rK@Eu*$Pp29L& z*i1FiM@#WHCvBMSmCB~~VizhzkoRHJU2N%RSB1Avbw($#1lcdusLsHOB=lHoC}Nl2eF@#lzb9Rp-F**0 zjUq%qg9{^O^0M!T2<%sqp-vC;mk{llN!&J9RVlZKvLbcSOKK=FPcP`?w~mXc{IUB) zB_uG@I{5k1t|%X8&mzoN#h4ZR%&w)ODkWm739p1a+YZS1vxvRp%6voyM-oYsbAa9} zyjzMHVWg62DwoH%QGPMTZ?^sj?P6dLHv$>vA>rN+RNrEnyiOYB%O4pxEc-b zIBxX9x!jim(@4B;&o6Wt2sPhfom4_lZd`WRaq!0|!- zOAk!lOTD1-yPX#NNO6d(LV?DuBCR<8gZcVrhf-oo({DIHn5IKnzfEG)I+ zmS6H}N~fYF!|u*bgE{DK$nA(oi_x*R=b&9@cir~UEt*=M%HC5E;{?Xp?mzcZnP|DZ zm5ZR(AXX6Q1(1e7VoF-&ENuAqt=W3uH`3XHbWJ#3V_shu`R7uBc~BSIF9|Dkxp$>3 zy#p7#QZBZhqT(SoiVEw37W*K19%&bw!?yS&grPg;B!)ucW{hB;AKtmMhM-en28T)* zxguMt2%k9;*(vIH?5)k}6Z6`1GB&?xYnPh7Uf|Z2P*k{BoV3zP^d>)fh2R5jL45=E zg<9HoAdQdr2dupyl+~)m;MVt;srdz=plrNC7PusUcr7!TFvChwzA5Z2w`5Z5}Ry0 zt5gGr=q(u(j8s)}S&x|znIEu6U&SK?2TDV#pHa&zVc_EOLG(je6o2+!L9LWe$F8mOWMD$gr67>Dv(I(^mQ0 z$tC#}tTymu1wO#(3=H`7@U-dZlRV+n!r38(lK$FES}ViV#kZuzAm7_oS<#e*KcDT2 zoVNnY`4sy3Fh|9%*iRHgi& zrLD%D?L88Ouq_0U#`}t}Eq=F{^Q#E;{BYU0uIdk`ox4i60t1kvl2alBFSi|6s|s*Wsv(rbsY>Y$Ci2qC?NmwGOi$< zL?5hXAn3Z6JQMKCV3%d79ByDEK{ukP!3UQq6=Vrt8`6QcYy~t#gXq4#%)A4_>JCnl zb%j`YC*r#go*~dqPzdl5dVyY)aRl$vJ-xc8+~Oz&+J8TWCk*^54aNui)H!+Gy+=i! zTae_OAwlX6sP2ot$Cq@bS(&xllx)3wcKuOb!sErZHHATh1r@XnQzE(l!alvw$0f8= zc=g>x32gk)(VdAD>fk;YOj@vdy;$U!chQ&XfQso5u*~R|0bnGLO)rU z)El07?kAE~AKg953l*9$g!?~qCzkgZe|VVG8)h_7do*qZN89ybbk!_m6zrDSYRtbyoe?LNy zoRt+GOFsY-(c(MawELuPHTtKOIZqX4TfXUXwy*6Ek+Zd4)g$b+a=e{2;uN~o zk%9AseOM&f*t+^J_Px_XqqQ0s-yrIQg{c`Ga7|Y5-EeEQ+>Ei-hH6T zc>E@rRI<>wr7-IB>BV>!w3;MuLU+QtEZqA|5W2yKjL@%dtb%b_pb{)EH@D@88u1++ zQ}y4U1Q(5VB=e2b5=D<(4_YZBhmz|B*1VFHe~Vtl%yI3E_>}h}pc%H#ODxMMQtMl) zq!_pWEja|VO}9@{GX_{EL7|^S!<}2x-9tN%AN{n1od(O5ntNnW1h>6wdf#(5>PrQR3iy>mN6#hPtt(B%C+ ziv5`1?hzsbX($5mHN2&hq01`AZxy`9gl_#XBUv^U!T(yj2?dgMEL~?UHk4m7af5o@ zyZ#WW@S31jT;EZ2AUTG-cE3nu4LirVdrYkI2jP83qJ0%f!|z z#78eah25`S__>7E1q6kz1%4~cN5KTy{0?ewpkyd`*A5EmZD&|8pcgJ)jeuL+iYsOC z{oL|}tJw$p-C{T10!eJ9(3Lk{XPlwQ&c33R6P>F3tWD6%lZfoP11WlOfw411jJ||U zx5U0;t2uA$7;P`-ujAP_XN}_;m&SutabvVZ>Eakcd$xAcGkdKe{Nc6$8C9DCYb51_ z=xy?k%GteX>Aq>uK5+c1XpbB3_$ z>yV7(XWEnh&Dz{6_OKH9%7fH=m6;R&_iiNuJpz!bexiY*f%*vt1~F1jXg{0^T}$-+ zTe|w`Jh5afxF|8<`nr6Q1!m@C2@A?xi~G*wFn!KHm)`qmJ;)qy`PX5E_hj$&yltLj z!JtGEN9Uc+$F28mkDa%Nohtx@Goao3eAo(t3Bm%CchFE$geFWa#!}HqeYhgb8@W4^jXv`9&>Fn+4AgQpm$H;3E*08`F1F&& zP&cw%4X(z1W-K01O;j?Xvg|6$wkykBoQf8ApJgl!f)mkru<>4OD2^deYl!nw4m*Rx zj0=(zn`A=fnrWzY8r4N^D#5@bh)$dpHwR?am(fUaU0e@UX8BEdPAu2wRLWwexxLwG za*s_L{-rl1`POpSwb^Y!yQ?EdY1Nfyli%U7&<^qx_CeK;XyU7o)f~TozOM2Y5-vKF zQ<}kvgpo-&XNI^=pFznRFCZSd3VXngzziXdmIw~fMyF(UoJk9N)bD%fAcSHP%K<6- zBaW}*T)~sQncbW z)DqPi+K*!@bxw}ghSW0eB_;eeC3QN|T_j7c^uq##^-RPo*^;%P45MF>EY<_@VbHUuF$+e65#)sAdB?~gWkXE zT}#SUq6OmOYc$xcEpf87r1EF7Os2Sk)fuVpa@$i@TsB#N=^J;!Fu-&LWq+?{_KdZv zKY$D5xJm2V@RS(t{C>6P7l?3O7!?o3KSJ?6pZW1CVmyrT-C&;vtre`t`~+~guI=+^ zt2BIVqA}r`U}1Kqda%uC<{iPm(yg_s&{99t@2^u!t~cBPZGnyrF#9XhlX&o$UM@_I zSLx#%a2OV}9i{Q>mP}{ucFCy6<7{CbXNfDIfK7Ek;yy-qEklUOOSZwDrnG>?_v)q_ zIrKK!FxTP-DR}Lkv`eup($^Uu(~eg1$|H71VON)8P4;bp`EY+M3`ruXT$MaaI;oU&~vl~76H>uXB2(b94^qm#*E^&fmN4Z9`7 z^EPRrb&69q#UG}4kd0jVv37gIrbF)#DTijONMVM>QkmbXdWuTzXeSM1%_mQ6;~G0G zf4tH1asIWi@$z?9HNSE0)`)oCJV@;;G|iMXQ0jD1&pLh*T$Sao7m=jO zaWP#C{j0e}^xup~r0XP5Og+yPe=6x>iC-w`GR1363{&x*=~*=^(vU_P`0a%ev;{fV z)Cn>C8!*a_`cmF5ZDA_Z9)rDexW%JbPTX5a9pAxIk*^(qZg_T!D0c?+r_m@d4=7SU zn&S*7dA(cZ496#?l!b-QLT|KcGeOEeQk0lT+vqiwpS%x9dXK%~%1*Qj}SP^kca0TQHV#}FA zF!wowVKBwNlSm%mc3U`Y7Qq7XPHz!VZy{1|(zwxWe=Hb+5XUb1kZ>RFJX;e+8U6d1 zstSeYw?Y>VM0YG>P5~#O(5j+G2ivC~#mz(tg5IdSYpW7k0QK(<1A{shInwxW2MyXh zNK9z)^hLz;yJv->9fKc^;{rG(iU@Ock(NG4Zx6^1P?rCjcorz1^f>akn$BJQp6m||LI0UgSY!O!jM8`LWoCT9AO+oDxO@3!6I{g zS%WKH*!=Ti@$)whJ!_&R>&-mOC*^^UJPeKrM4H(ZmxE8<&TAK6`TO1DC<6$LCVPUI zR#+x(s20}cgsZ%SSlk_iv*v8$Z@`chwC5xW<0H=yv-0x#ansrNto-*s!HCx*e;wJUb)|KpaU|8PQsSCL}tMO>-JZ~M(0^q zDyx~}l9W@AvQY+IE*8C3Wqc~Uq0o1A2#|aHSdrNxuv&OnZvP;7qlr}dXaqIoyNy6P z)4A!JtYk=(bjP(J$mvYRM1aG{aCOLSbM~u@)JJKy@<_+Q)!2#-The9U&&NZP( z|Ky1%jIlun^e3cKeVsG_(-q6+^j@KzHPy9L(E^o2jyrw92v+rjJ z+1^rO;r7tgV!hM{CK4_t{S{_n>E$6>$-;*`7`=pL&AkaU0VgDn*N6oRlpUV+o46+) zOqEUr0@|Qi@%R7B)1-USUw!+cV&vIDKnVY5mhj_$ zJk46|AD%i(X#7W3yjuQPEeE9Is=~6kGv|n0q?|1xxV99lTJn^H8#66}X)&Y}Oh3&~ z2dG1pu`RXmtYAV*=-ewZOTneTZn9FJxo(b)_ZdHh33cK5dfywL$1SJJ%ulYzsH5%Y zc@xoQRh|i%VO@%NZ!cEQ%3KcM*taA2=`TgspZ!>`WBZg*a<3escyb25nJInyy(xX~ zl-Az|vbj3lteG38bLzRRV>uVxSJ%o&SE%b3x2u0k9d7KcDsy*=zdD)uC5~L&;JvNr z9j+b2yLkT2{WVhA-qOz+%BUK? zf3K^-#h#7nr9Xl}_RPx7!>v;=ul@b?kFI-y9;qV)?@F;J&sc}FJe?A>^yTm_Um9Rl z2B}AG=q2LZsc*3L%r_ix^El#AaZv+d#YjNh{|NRXbW0129(5}AK{EyMt1 z36S6b>PN3#i-S0S4*azqxH6vt!U-0i6Q;xY-n z>|KTv-u+TP;{b_2?-jfqZvK-K@pmYvQ(A?$l1w=pA?OZYhotgMXqy((*g=>jrmk&7DWrJ&~3p44|Rz zrvTrQlJT^(knSQ#4e_R-ZmMj-dL=?4rXG%06hegTFuhq$y^Mwe%>2ty)1lW>I% zS{rLtBL`Fcl8QI#xzWOdN*Dn-K5~@E(lut>o%fi|csfZQ7Cv+Cu-M#Ex1v%t-A3d*Mq7}BFEPOgzMSdlf6$t>qfVC+I}*6y$f z|0oVt1gc;lL~!20FGtZ02Z!aI?mN-J^QL;r)hPV|BKksxgf zW{o{W+jp%q5x%nd=wcm3+ClWhk3cYYrr@szEN+Nz`u(B_R0w}+w-P5toSOX!QPF|9 zXAJI7<#GYx1D{FF3LnOWYMtV_5a(mujtNu-ing_a4nmd*YLBtig6$ZO5#e`qK$f#J zg~gMO8>iUMJd0`rI!aPErKiZ17w2l6d@=_k9=?wbwdyeY^<`>0WUX{E1LIs47HqJp z_EF0^Tzn86Hi!wZ=dtjvm7$HSOm??WSXv8)TNma_G&ClJXo}tmUFNJ8pB$YM9prx! z6aH=#jdcbye1Lvzy^nI~SwzDPBuH|F7yTl_K7%1ghQ`V2ufc-}C@v|S;6DXGF4wFiQZ12T>}?nP+=l^{*HxZs#tGf4KH7NT-Q3prTSr~sIfu-nFm&wFp-LpIz?JUB*7x9h)Y1wAu0;S--_jghO;8jJ^JhP>uTkN z9h{iQ7p2)Jw<$AAd$}Ld8Yfw!v$s!jeHbkf5+vVx3%!K0j-u0|ofmB?tmjM6c#Wlc zAW!cpie?j{w;(Wc3@uTNgzb{pu|iJ4QwuGQS;IoGV&RN|L)ttz%i2?f5#%uSJ{H5R zl7D7Zb!Y>izlcS$i9@2yT5`f^#4^`a?X>6PT9TL%$7joI_(ie{zYbB+TDR59HnDVJ zW8_xIM!2)0z*_&lcD1>X`e>%(Z6xJe*h^zQk{ZDoN)}WYA%KY`%Y-mlcgwL_X;5-0 z&VHNyn(#RY1b>iO5mgt|HhZyqOc(9FrRH-~Ch7ShchvUDF+$gcW~Hi|9oJoY*n zTAFFM*QsG@mqNI+cXtjUNAzbP%8gylG(x9T{~CsPPxH61lxZ%V?A|C{gm$A|yp!m3 zslC;qDDfgoOp@ejpgqdz*(H2)i$A$yoQe=YIzLMXeqUd~k$G236GQ8o_n6!&mtf}m@&ZEP}|j1HjNg_&~zZpeATp3!Y^MYk$o7#)|fq&*jg|= zdW;tNeRcD&BVv$fni-`+9?sAPzE_}vek6HHk)CY&b7lTcSjuHKDc8$}ND&eoF{p+f zcLMDIS|(@HY-nKZN?WM0%AjFwOd59!Qh+e`D6lDOyUKokCpQNPO5o8eGDt|~B`pUrOTR?NNZ(KD)QP^*Y|l8U>c zEJv%ug>_3<+TF{BmN;O~5O5 zxd@Ml4Rf=3E%=~MZP5HIyUkajfov_Bnd3C}#IADf)ND(XcPmtz+?1Z?$-2A9Mj;#a zy8PT{O`~8hSG8nLUZiQJNKvQz+&+D9`n9siM(vcTwr5T$;@1f^4Pa2xQ>7IC>B*D8 zwmVje&!cXtg1YniI!^TEFZo@RpYhaVrsdq&D9VlEf7S0Wk5(r)Q?we;V_eQ@SEOJC zsU|bDv%CDjupcIxW(eKBqPIE4;OuIY~yFf=NmaW*5^ohQTzM|mFn&^?c zw+1L#R}vRRLDJ;`p;+C0{p&EY){PI{?sISs2DI3v!c^7f3bFk(DX{1Cg;a~9w2*LD zLJxe0R`u;dvF(_S;f0ZD4VyB0q^JtmlW^y$Zus=Fp}2&^RV6YAo&$Sg(_-@a3F!{m z1}5ugby4td_KF2(ooXSV|G9qbu#=SpgAFF}@dlJTJO_S!ro~q3tvQ4Rz_lbi)=AVG=yr z7M*o$TeF$)dBt=pu%;~@^UZ~EM=2)#M*iZ^9Ew|bn*Fkh)RvI3|r-UJ|eM8 z2Va6^La9Mv#VvJq_T-Z?P*w)3)!$g>A7$)C+ZY}H1pN*<95%^PGM7Pn17Gf7JW zl}y#OOLwE`{K$1fSecg(Sld;mK6i-PGC97P;7zdr{{Xg!?y)Z~L5*sG;bSoOWh#i3iD2G*_M8<=bmX1a0H*Iy;xpM<6z>v6x%t8D-JQTg zCF~$OzaHmKAl0u#*Ak!7MRH@e=1szrHzhlLAJ@;7v>@4Aw&A=4Kzn>@!fMM%MSeWKXy*o7(-wXph!BFkxH|UJ<$1!VUv9sFZe@Jl6U*PbIoEGAHFz|Lf z73YLvwYf7)kSuAzHNb$}C)91IzH0ER>v{)(Ef z*>QN$Ha`R>YmyiTP(TfCmw)-ZpujB7*T8l)zUp-WJTEpoLZLy>q%euNFp+6D1R{MH zVj6`V@RilC!1y`HRbYsEUhQ2p_nL z=@QXdvcf#$pz-|eNXJ#gRlsmX+c%UOJo*>Am$nZ~-%z4+0aEGnTPI}O0aO|*q7BQz z!Yi}yj<*UZhxH^L=;1rDT_0u3SAt0DvA$2ehp-lx$c%N$J?ytYO5`_|ogP!db(+og zJc|o~F)cC}%6qnfiqOFjCYYO`;n!JQbPj(mAkm3ty3f4$#>@0r*gS$5ZQ(-}PNB#V zhQJYll7QDFHGlw~RAJ~~j8VE9qR`}Z8ym%14|2jI>h2Ma00~4J!L}>Fz5y=Q2wFC|50O%cs%@sqfqSsT&AjpJ`^@db>QmP$)%C0E}W$QxLJ*%uaOk05F_ z-v_5*Rd=6hd4!|1*R@(>GUwZP-e=CC>L{tP&oRom3ZBT03cY^iCYmtdhuATiOMo6>>_s|(`UG)qM)1l7;|7(5Bz4> z&$XKu;Lk%n;c7qH$outPKUcm!3B%Lp*t>2*nUfwhua8bKbaoi67l09ttpweALwRqyatZqYo-A<-E%S=)BY)_cgLak85r|oukw3%YnEB^;h zHno2m0oS{+(XvD|x<@e7Q~5yfgHqu0i4aL@db|XgBOhEq zi2wAYyws_Bnf?4pGD4ttXoA&yd>>ezqzWd+u19zykWYteWSuP|oBt1VBbIXY(}KfP z20$13l3!(VU{&+r;aX6dRTca4KAnH|C03$#L2a4g(7Z-holTv07B2ttbe&jFwr<&D zo!J)+K2nA3)M>M$^L^KKKq+*?7ftyex8=?<6pXqrixt?_rGf2)g)JGlAWVEy2A1Jl z1>;=Ax6&E>aAOlu+j<4bNznFbAj1r8JwUyDWtWV$Y|WxzFtL+n;qKm2O&ILu=7_;DrK9xgra3S=^wy(`+oPAhkVgbTeMf>@eS$`< zjL2|m2e`u~prMhW=#zAHeX6PO4v;r-M(rh>&Llch%+v-oth|@o+&Er`U@H$WUXl*84T8z)`KGHWQ+DBjjDFinkR>9cq1J~|@hjZzeHDm>SJ5vbb4{(&xXOovV z1W)-OzGzO9pMewmu1;_l(; zTH>U&ZX3fm6tb1oU;du?I1)|qL;$X&5n_zc*!*;dxl`vV#G*8ZyJ>*GQa{8;Q>&Yy z%2=)05wXje`?Rcg!fr`fT#!-Se8$5+i$$h)n6!1#D#uS0$#%W++xnM4!gW2@HQx@+ z%z3zDyf!v2R%=mhg+Mm)G2%>@+jjglxpeNACN z3|%<8B(8RD+4~*Somw?M`WCi0wm3Z_eMpbPTImKMutRxiMnmlx8MwHoLe2(m17jo` zm)onu$(#=XegGesH}Ut(8u&B4eXn_dtYt=%>}}c~6j&{Qrf(Lvd4&>P-mpnFd|)}3 zA4=RzPEu+iI7I4J?zX;I5lPC z5~xgVqIsC(Z+ic=_Ql6y-Py=q`E?zfImp17WbUc!#J-vckv7tKXQN3DK+O*mQUnf0 z3DTvIVpmBmOxVr>6PKNO8@&=$rMVgX%VyYUf0oED6q$!ci?0Z|ni0w(y8f_CbwYiN zbs~L%>{>Ik#El+}$<`>yyO_`^FOFy7(I9E(_cEhyBx20S1~#}MeT)=w$V@i?sH)lf z%>>6DgdNZXGJ!N}TVr1Dm=alH2?fK2d;+RM8Rk>(A)aO`>sF3*V1cug#ZZ6JM*OTH zBQlBgbIp(m(F%@mXc~r@9;Lb9%Qu#1gcJzaoi1zmBPf`IqvG3*rSIi0

Ag&&P7c z#C4W?w7M&=mMCZQY-E2biKC%w0^NRBb_neDdX*RyNqc{F*u(3^f7|u-li!cP+jB37 zoW5`DD(1B$E-Bu6Xp%#p+2wh?>95r=3PFw20AN+5)xdEtA-EuSCWYQ(^8ow~E!)%?FgVXZEa~#dyotSGZAeUyfB9i8H^@3Y_V5f{sgw`m8BweZIsLZV(ajBnq+`N&A%+EBxs8O>3vt2f|L{IPOmsZoN} zw<&X&siMOI2nitP{%*&yv(AltZ08(y{G$wW}L+JXJeP zD9w~vK7>zp>``41?d@BFaV1!vy zt6i&HpWZ4V8{KMYb6%?}gMm-k>mxBP=Rs6h+M}};pr8lW;KOs=->=fe-U!#2b7Isa zN-N4lJrA5RRV4R(&Fpfl9Wt?#m=1_4)2l4KKNG=b?^cv)SHDfh&8 z&OWpso&ElddnP*nHUk;YeT|;JOD?RZx@P#jL_c33;|`X$R6oBE<*qh@&7)Gkwh+yZ z{G>w0FqZolua5Lfw=P<7nY@l(V|p6{7Caouem1?M^gA35VDhD1UfdopW*}f<{^Bw# zh>NV}>cfZ+#=G=Of$!wI37FppKe=Y$Y)>fX;ef0V0DUGjk0{xgo4s2wHv;HP`+TW7 ziZ7-#6k;#PYS`m>3D%4t;q(_ng1#Sq?5cfXEByiFMqa#jV5YTDdn}OZsI^qpg5wcm z6&tWZ?}hoXjc$jfi^VjiuV)CbQ*@Co*xcETqSG%5VynWhche|zRnCdg*Z`L_vbE!V z{w+;%PS9dQN+kWLuHDY2uiDup)?n`vPH1qSlBcm%0qyK0(5C#-*PNv~pq{f_$;X+# zmj2}pbZ$WXU>oqogC{MWzA;26F-s?0ly7FtTy`6NeAD*JsHIuX{U-4-`ZMzo`Y*HkV2 zfzm7Z{nB$FI_KFL4EQJ|!Pk?=B{gg%6dLoNK4{1vgcgMWlKgfX393vtZNh9n>!iZoMMqbZmLx$X{O zaZVuqb50FKN9J1ptit}Y^QEz`@ke_%uSHb8XWa

^&2{TmT#wE=JH_Aw*Bzk|$H9rio4 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≠j5WZKO*PC6lWWI^Njoa59k5p>;x)!s-{qRTwOcb02;T8-JEJ{nHUoDXNn~V=aC?ed_c>S zvOMmBk@JahehgqY$OJ&n-arO~3I;R!{UnXpYy286Gl)59fmh(5X3(3N@SS$P;y-!t`*{2Z>o1-} zZpuWOpWFM&L~E=N_(QE9M1}-IoK9NGnKy=#M4ih=ZSWVe4aqXL7l#~R~fU)6fA> z$X5+tfPO$3Q1$sk?vntRUT5=MG<;MNTvn59#kHPtm+#CEu>l*yT*q*KMvUpGb@fV$ zgrfg3vRqVjn?ttE$RxJ|HZ`lmiraG4>M>XGwJtxwN&l!=%()L+FTJQTW!3I_P&~#f zxSrsb^J`+%SZEj`Cn7IhyW41GK%`}6#_}0_Iv4d;cNn9^>ZS(p6lg@tVW#yQ9eIh} zV)1%hKbP)J0zqs7$B0F7P%-Ry09X7)@X?Ea;TCJurgLE#c`y>Fy~6a)1nnCI3SMjn zXB}Fr=baKCVpPQ6Yc`i7(m^&Qkld|w*|P1s%U0~nQtQJ%SGshjOyg2-cG^)W8_6K_ z6I#H@6h5&y(Uc7Ei`7EPhm1Uc*z4JW@-5V8{s_q*d6Rg|BdTB*Q7na|oy9xykUO~b zFI>6eX}f>hufGn}uqRT^o$mH>Tp=z_>D7eNB%iUwPoSPptfL)xERtI7ZkW%3*;Ts& zR(vdBkZF0VeE7DBY{Z@No!(fN_Q~qunCa!1{v!&oF#w zE}B;QtpX|h?jCae57dLmF9izYi`S^l@9`7y|FszlhM&bNfqMc%fG>q_-s9(!*U`9R zk~Wx_GICUtlHF@>%djCP`&&_uxE-05h*c8haDMDY&RCs_x2j9rUh898v%beP8x5rz% zR}<*rYps-SaW=!jq~;D+a@J&nhA7mwuXDOP=#bhe2nE}5n*zA&~hoJT*D_QyO;dV-8on9 z;7h*>ZFka68_Kj9%0wyxrzvle%56wpa(sz~8 z&fvn2)S_%DAlQ|tPc6>h+KVwM%rMF;YUI1AFj}Re)0ePQ+XdxC$*ew;}hkJqRZYTXg!keDnQn<7zjkxc=2O*ST=1t@HoW= z#43q}aqP#xCrTgyrA$@YLdrSJRnP1tPf5*DQM85i$3Y~He9&+n@pS_gSn~}i9x?y( z$Xf_IHY5Qzg=GLU|25w0)7)(%#0(ZapGI4#YF5RRnkYC4NeVTQLQT$E>VYFkUQ5?) z>?-A@_Rm;ms(zPHLBw1o0La|4RzrnReLL$Zc%1p%^XzKg>*M`}{D(x{<-tTEi~$qg z^ZWd&PL3TVgnG8iFE7^R6CNIcT@%>TkqP|G`NtxzhLUhZEI7wW{C0m#jSu z^_Zl?k8nVHlWqF0{Y}3CotV)xD4)z@F9^?=KC}tj7fXwE$TWx4x|&9-a2bxONG5w@ z_;d6`5&=NM^YD}6db*PoT2tjmi_uUVbmY5C9_IB9QzxZ!w}4TDk3w!csVibb5M@`UfNhkki?C zOxCRdO~k>}m*D9*>qOrM&wG$j`H>n9iUO2Pu>kYE_vV@(Gq5hjnv!&(2^WjTY3Cn` zv*eC+t=I%&GokkDrnRh^dG4h_M*jNcFbpBZmhmJ&I?~Lv?jHb2gb}1_>GVUG`9oa% zANGd9bilj8FhS9LzB)C&u!5d|lAe$X+sO}{>aw+8r-kR(C|%k7z$

o?Fv%)cNJ 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 YcTXf)DSq%bBM{rc7rhZQ0ssQ>FL>zZoB#j- diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ec991f9aa12..3fa8f862f75 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index af6708ff229..1aa94a42690 100755 --- a/gradlew +++ b/gradlew @@ -1,78 +1,127 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,92 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 6d57edc706c..93e3f59f135 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,4 +1,20 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -9,19 +25,23 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +55,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,38 +65,26 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/jib-build-plan/build.gradle b/jib-build-plan/build.gradle index 6adb9280553..e150240725c 100644 --- a/jib-build-plan/build.gradle +++ b/jib-build-plan/build.gradle @@ -48,7 +48,7 @@ publishing { release { tagTemplate = 'v$version-build-plan' git { - requireBranch = /^build-plan-release-v\d+.*$/ //regex + requireBranch.set(/^build-plan-release-v\d+.*$/) //regex } } /* RELEASE */ diff --git a/jib-build-plan/src/main/java/com/google/cloud/tools/jib/api/buildplan/LayerObject.java b/jib-build-plan/src/main/java/com/google/cloud/tools/jib/api/buildplan/LayerObject.java index d32067aa9c7..0558510ef64 100644 --- a/jib-build-plan/src/main/java/com/google/cloud/tools/jib/api/buildplan/LayerObject.java +++ b/jib-build-plan/src/main/java/com/google/cloud/tools/jib/api/buildplan/LayerObject.java @@ -28,11 +28,17 @@ @Immutable public interface LayerObject { - public static enum Type { + /** Allowable types. */ + enum Type { FILE_ENTRIES, } - public Type getType(); + /** + * Returns layer type. + * + * @return Type of layer + */ + Type getType(); - public String getName(); + String getName(); } diff --git a/jib-build-plan/src/test/java/com/google/cloud/tools/jib/api/buildplan/FileEntryTest.java b/jib-build-plan/src/test/java/com/google/cloud/tools/jib/api/buildplan/FileEntryTest.java index 184a7045af7..390bf92fe03 100644 --- a/jib-build-plan/src/test/java/com/google/cloud/tools/jib/api/buildplan/FileEntryTest.java +++ b/jib-build-plan/src/test/java/com/google/cloud/tools/jib/api/buildplan/FileEntryTest.java @@ -22,6 +22,7 @@ import org.junit.Assert; import org.junit.Test; +/** File entry tests. */ public class FileEntryTest { @Test diff --git a/jib-cli/build.gradle b/jib-cli/build.gradle index ee5c6ba1791..f1b2386062d 100644 --- a/jib-cli/build.gradle +++ b/jib-cli/build.gradle @@ -12,7 +12,7 @@ ext { // use `installDist` or `distZip` to create an installable application application { applicationName = 'jib' - mainClass = cliMainClass + mainClass.set(cliMainClass) } sourceSets.main.java.srcDirs += ["${buildDir}/generated-src"] @@ -61,7 +61,7 @@ release { 'com.google.cloud.tools:jib-plugins-common', ] git { - requireBranch = /^cli-release-v\d+.*$/ //regex + requireBranch.set(/^cli-release-v\d+.*$/) //regex } } diff --git a/jib-cli/src/integration-test/resources/jarTest/spring-boot/build-layered.gradle b/jib-cli/src/integration-test/resources/jarTest/spring-boot/build-layered.gradle index 14d51f3e926..856da45a2d9 100644 --- a/jib-cli/src/integration-test/resources/jarTest/spring-boot/build-layered.gradle +++ b/jib-cli/src/integration-test/resources/jarTest/spring-boot/build-layered.gradle @@ -1,12 +1,12 @@ plugins { - id 'org.springframework.boot' version '2.3.7.RELEASE' + id 'org.springframework.boot' version '2.7.13' id 'io.spring.dependency-management' version '1.0.10.RELEASE' id 'java' } sourceCompatibility = '1.8' -bootJar { +tasks.named("bootJar") { layered { enabled = true } diff --git a/jib-cli/src/integration-test/resources/jarTest/spring-boot/build.gradle b/jib-cli/src/integration-test/resources/jarTest/spring-boot/build.gradle index ac97a750e5d..a84cc06efcb 100644 --- a/jib-cli/src/integration-test/resources/jarTest/spring-boot/build.gradle +++ b/jib-cli/src/integration-test/resources/jarTest/spring-boot/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.boot' version '2.3.7.RELEASE' + id 'org.springframework.boot' version '2.7.13' id 'io.spring.dependency-management' version '1.0.10.RELEASE' id 'java' } @@ -10,6 +10,12 @@ repositories { mavenCentral() } +tasks.named("bootJar") { + layered { + enabled = false // Spring Boot 2.4+: layering is enabled by default. + } +} + dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' } diff --git a/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.jar b/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.jar index 490fda8577df6c95960ba7077c43220e5bb2c0d9..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 42477 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 D*uVWk delta 38976 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 V67V)cAeX@JGUzx`1sNca{{c%)xnuwU diff --git a/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.properties b/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.properties index 5028f28f8e4..e411586a54a 100644 --- a/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.properties +++ b/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jib-cli/src/integration-test/resources/warTest/build.gradle b/jib-cli/src/integration-test/resources/warTest/build.gradle index 627efcfa296..10ea7f31cc1 100644 --- a/jib-cli/src/integration-test/resources/warTest/build.gradle +++ b/jib-cli/src/integration-test/resources/warTest/build.gradle @@ -3,8 +3,10 @@ plugins { id 'war' } -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} repositories { mavenCentral() @@ -15,7 +17,7 @@ configurations { } dependencies { - providedCompile 'jakarta.servlet:jakarta.servlet-api:5.0.0' + providedCompile 'jakarta.servlet:jakarta.servlet-api:6.0.0' moreLibs 'jakarta.annotation:jakarta.annotation-api:2.1.0' // random extra JAR } diff --git a/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.jar b/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.jar index 490fda8577df6c95960ba7077c43220e5bb2c0d9..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 42477 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 D*uVWk delta 38976 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 V67V)cAeX@JGUzx`1sNca{{c%)xnuwU diff --git a/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.properties b/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.properties index 5028f28f8e4..e411586a54a 100644 --- a/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.properties +++ b/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jib-cli/src/main/java/com/google/cloud/tools/jib/cli/war/WarFiles.java b/jib-cli/src/main/java/com/google/cloud/tools/jib/cli/war/WarFiles.java index a69d26a6937..2fb89abdfbf 100644 --- a/jib-cli/src/main/java/com/google/cloud/tools/jib/cli/war/WarFiles.java +++ b/jib-cli/src/main/java/com/google/cloud/tools/jib/cli/war/WarFiles.java @@ -81,7 +81,10 @@ private static List computeEntrypoint( return entrypoint; } if (commonContainerConfigCliOptions.isJettyBaseimage()) { - return ImmutableList.of("java", "-jar", "/usr/local/jetty/start.jar"); + // jetty 12+ requires explicitly enabling ee10-deploy module. See: + // https://eclipse.dev/jetty/documentation/jetty-12/operations-guide/index.html + return ImmutableList.of( + "java", "-jar", "/usr/local/jetty/start.jar", "--module=http,ee10-deploy"); } return null; } diff --git a/jib-cli/src/test/java/com/google/cloud/tools/jib/cli/war/WarFilesTest.java b/jib-cli/src/test/java/com/google/cloud/tools/jib/cli/war/WarFilesTest.java index 513d7bc559b..129ef89bacc 100644 --- a/jib-cli/src/test/java/com/google/cloud/tools/jib/cli/war/WarFilesTest.java +++ b/jib-cli/src/test/java/com/google/cloud/tools/jib/cli/war/WarFilesTest.java @@ -74,7 +74,7 @@ public void testToJibContainerBuilder_explodedStandard_basicInfo() assertThat(buildPlan.getBaseImage()).isEqualTo("jetty"); assertThat(buildPlan.getEntrypoint()) - .containsExactly("java", "-jar", "/usr/local/jetty/start.jar") + .containsExactly("java", "-jar", "/usr/local/jetty/start.jar", "--module=http,ee10-deploy") .inOrder(); assertThat(buildPlan.getLayers()).hasSize(1); assertThat(buildPlan.getLayers().get(0).getName()).isEqualTo("classes"); diff --git a/jib-core/build.gradle b/jib-core/build.gradle index f31340e269d..697f479f987 100644 --- a/jib-core/build.gradle +++ b/jib-core/build.gradle @@ -71,7 +71,7 @@ publishing { release { tagTemplate = 'v$version-core' git { - requireBranch = /^core-release-v\d+.*$/ //regex + requireBranch.set(/^core-release-v\d+.*$/) //regex } } /* RELEASE */ diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ContainerizerIntegrationTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ContainerizerIntegrationTest.java index 8715ffb784a..1ac1d5990e3 100644 --- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ContainerizerIntegrationTest.java +++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ContainerizerIntegrationTest.java @@ -78,7 +78,7 @@ private void checkCompletion() { } } - @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5000); + @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5001); private static final Logger logger = LoggerFactory.getLogger(ContainerizerIntegrationTest.class); private static final String DISTROLESS_DIGEST = @@ -154,7 +154,7 @@ public void testSteps_forBuildToDockerRegistry() throws IOException, InterruptedException, ExecutionException, RegistryException, CacheDirectoryCreationException, InvalidImageReferenceException { System.setProperty("jib.alwaysCacheBaseImage", "true"); - String imageReference = dockerHost + ":" + "5000/testimage:testtag"; + String imageReference = dockerHost + ":" + "5001/testimage:testtag"; Path cacheDirectory = temporaryFolder.newFolder().toPath(); Containerizer containerizer = Containerizer.to(RegistryImage.named(imageReference)) @@ -190,7 +190,7 @@ public void testSteps_forBuildToDockerRegistry() Assert.assertEquals( "Hello, world. An argument.\n", new Command("docker", "run", "--rm", imageReference).run()); - String imageReferenceByDigest = dockerHost + ":5000/testimage@" + image1.getDigest(); + String imageReferenceByDigest = dockerHost + ":5001/testimage@" + image1.getDigest(); localRegistry.pull(imageReferenceByDigest); assertDockerInspect(imageReferenceByDigest); Assert.assertEquals( @@ -204,23 +204,23 @@ public void testSteps_forBuildToDockerRegistry_multipleTags() CacheDirectoryCreationException, InvalidImageReferenceException { buildImage( ImageReference.of("gcr.io", "distroless/java", DISTROLESS_DIGEST), - Containerizer.to(RegistryImage.named(dockerHost + ":5000/testimage:testtag")), + Containerizer.to(RegistryImage.named(dockerHost + ":5001/testimage:testtag")), Arrays.asList("testtag2", "testtag3")); - String imageReference = dockerHost + ":5000/testimage:testtag"; + String imageReference = dockerHost + ":5001/testimage:testtag"; localRegistry.pull(imageReference); assertDockerInspect(imageReference); Assert.assertEquals( "Hello, world. An argument.\n", new Command("docker", "run", "--rm", imageReference).run()); - String imageReference2 = dockerHost + ":5000/testimage:testtag2"; + String imageReference2 = dockerHost + ":5001/testimage:testtag2"; localRegistry.pull(imageReference2); assertDockerInspect(imageReference2); Assert.assertEquals( "Hello, world. An argument.\n", new Command("docker", "run", "--rm", imageReference2).run()); - String imageReference3 = dockerHost + ":5000/testimage:testtag3"; + String imageReference3 = dockerHost + ":5001/testimage:testtag3"; localRegistry.pull(imageReference3); assertDockerInspect(imageReference3); Assert.assertEquals( @@ -237,24 +237,24 @@ public void testSteps_forBuildToDockerRegistry_skipExistingDigest() JibContainer image1 = buildImage( ImageReference.scratch(), - Containerizer.to(RegistryImage.named(dockerHost + ":5000/testimagerepo:testtag")), + Containerizer.to(RegistryImage.named(dockerHost + ":5001/testimagerepo:testtag")), Collections.singletonList("testtag2")); // Test that the initial image with the original tag has been pushed. - localRegistry.pull(dockerHost + ":5000/testimagerepo:testtag"); + localRegistry.pull(dockerHost + ":5001/testimagerepo:testtag"); // Test that any additional tags have also been pushed with the original image. - localRegistry.pull(dockerHost + ":5000/testimagerepo:testtag2"); + localRegistry.pull(dockerHost + ":5001/testimagerepo:testtag2"); // Push the same image with a different tag, with SKIP_EXISTING_IMAGES enabled. JibContainer image2 = buildImage( ImageReference.scratch(), - Containerizer.to(RegistryImage.named(dockerHost + ":5000/testimagerepo:new_testtag")), + Containerizer.to(RegistryImage.named(dockerHost + ":5001/testimagerepo:new_testtag")), Collections.emptyList()); // Test that the pull request throws an exception, indicating that the new tag was not pushed. try { - localRegistry.pull(dockerHost + ":5000/testimagerepo:new_testtag"); + localRegistry.pull(dockerHost + ":5001/testimagerepo:new_testtag"); Assert.fail( "jib.skipExistingImages was enabled and digest was already pushed, " + "hence new_testtag shouldn't have been pushed."); @@ -262,7 +262,7 @@ public void testSteps_forBuildToDockerRegistry_skipExistingDigest() MatcherAssert.assertThat( ex.getMessage(), CoreMatchers.containsString( - "manifest for " + dockerHost + ":5000/testimagerepo:new_testtag not found")); + "manifest for " + dockerHost + ":5001/testimagerepo:new_testtag not found")); } // Test that both images have the same properties. @@ -280,10 +280,10 @@ public void testBuildToDockerRegistry_dockerHubBaseImage() RegistryException, CacheDirectoryCreationException { buildImage( ImageReference.parse("openjdk:8-jre-slim"), - Containerizer.to(RegistryImage.named(dockerHost + ":5000/testimage:testtag")), + Containerizer.to(RegistryImage.named(dockerHost + ":5001/testimage:testtag")), Collections.emptyList()); - String imageReference = dockerHost + ":5000/testimage:testtag"; + String imageReference = dockerHost + ":5001/testimage:testtag"; new Command("docker", "pull", imageReference).run(); Assert.assertEquals( "Hello, world. An argument.\n", new Command("docker", "run", "--rm", imageReference).run()); diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/JibIntegrationTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/JibIntegrationTest.java index a9916708c35..d60b44513b3 100644 --- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/JibIntegrationTest.java +++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/JibIntegrationTest.java @@ -53,7 +53,7 @@ public class JibIntegrationTest { public static final String KNOWN_OCI_INDEX_SHA = "sha256:2c50b819aa3bfaf6ae72e47682f6c5abc0f647cf3f4224a4a9be97dd30433909"; - @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5000); + @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5001); @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -63,7 +63,7 @@ public class JibIntegrationTest { private final RegistryClient registryClient = RegistryClient.factory( EventHandlers.NONE, - dockerHost + ":5000", + dockerHost + ":5001", "jib-scratch", new FailoverHttpClient(true, true, ignored -> {})) .newRegistryClient(); @@ -71,7 +71,7 @@ public class JibIntegrationTest { private final RegistryClient distrolessRegistryClient = RegistryClient.factory( EventHandlers.NONE, - dockerHost + ":5000", + dockerHost + ":5001", "jib-distroless", new FailoverHttpClient(true, true, ignored -> {})) .newRegistryClient(); @@ -109,9 +109,9 @@ public void tearDown() { public void testBasic_helloWorld() throws InvalidImageReferenceException, InterruptedException, CacheDirectoryCreationException, IOException, RegistryException, ExecutionException { - String toImage = dockerHost + ":5000/basic-helloworld"; + String toImage = dockerHost + ":5001/basic-helloworld"; JibContainer jibContainer = - Jib.from(dockerHost + ":5000/busybox") + Jib.from(dockerHost + ":5001/busybox") .setEntrypoint("echo", "Hello World") .containerize( Containerizer.to(RegistryImage.named(toImage)).setAllowInsecureRegistries(true)); @@ -125,9 +125,9 @@ public void testBasic_helloWorld() public void testBasic_dockerDaemonBaseImage() throws IOException, InterruptedException, InvalidImageReferenceException, ExecutionException, RegistryException, CacheDirectoryCreationException { - String toImage = dockerHost + ":5000/basic-dockerdaemon"; + String toImage = dockerHost + ":5001/basic-dockerdaemon"; JibContainer jibContainer = - Jib.from("docker://" + dockerHost + ":5000/busybox") + Jib.from("docker://" + dockerHost + ":5001/busybox") .setEntrypoint("echo", "Hello World") .containerize( Containerizer.to(RegistryImage.named(toImage)).setAllowInsecureRegistries(true)); @@ -141,13 +141,13 @@ public void testBasic_dockerDaemonBaseImage() public void testBasic_dockerDaemonBaseImageToDockerDaemon() throws IOException, InterruptedException, InvalidImageReferenceException, ExecutionException, RegistryException, CacheDirectoryCreationException { - Jib.from(DockerDaemonImage.named(dockerHost + ":5000/busybox")) + Jib.from(DockerDaemonImage.named(dockerHost + ":5001/busybox")) .setEntrypoint("echo", "Hello World") .containerize( - Containerizer.to(DockerDaemonImage.named(dockerHost + ":5000/docker-to-docker"))); + Containerizer.to(DockerDaemonImage.named(dockerHost + ":5001/docker-to-docker"))); String output = - new Command("docker", "run", "--rm", dockerHost + ":5000/docker-to-docker").run(); + new Command("docker", "run", "--rm", dockerHost + ":5001/docker-to-docker").run(); Assert.assertEquals("Hello World\n", output); } @@ -156,9 +156,9 @@ public void testBasic_tarBaseImage_dockerSavedCommand() throws IOException, InterruptedException, InvalidImageReferenceException, ExecutionException, RegistryException, CacheDirectoryCreationException { Path path = temporaryFolder.getRoot().toPath().resolve("docker-save.tar"); - new Command("docker", "save", dockerHost + ":5000/busybox", "-o=" + path).run(); + new Command("docker", "save", dockerHost + ":5001/busybox", "-o=" + path).run(); - String toImage = dockerHost + ":5000/basic-dockersavedcommand"; + String toImage = dockerHost + ":5001/basic-dockersavedcommand"; JibContainer jibContainer = Jib.from("tar://" + path) .setEntrypoint("echo", "Hello World") @@ -177,7 +177,7 @@ public void testBasic_tarBaseImage_dockerSavedFile() // tar saved with 'docker save busybox -o busybox.tar' Path path = Paths.get(Resources.getResource("core/busybox-docker.tar").toURI()); - String toImage = dockerHost + ":5000/basic-dockersavedfile"; + String toImage = dockerHost + ":5001/basic-dockersavedfile"; JibContainer jibContainer = Jib.from(TarImage.at(path).named("ignored")) .setEntrypoint("echo", "Hello World") @@ -194,14 +194,14 @@ public void testBasic_tarBaseImage_jibImage() throws InvalidImageReferenceException, InterruptedException, ExecutionException, RegistryException, CacheDirectoryCreationException, IOException, URISyntaxException { Path outputPath = temporaryFolder.getRoot().toPath().resolve("jib-image.tar"); - Jib.from(dockerHost + ":5000/busybox") + Jib.from(dockerHost + ":5001/busybox") .addLayer( Collections.singletonList(Paths.get(Resources.getResource("core/hello").toURI())), "/") .containerize( Containerizer.to(TarImage.at(outputPath).named("ignored")) .setAllowInsecureRegistries(true)); - String toImage = dockerHost + ":5000/basic-jibtar"; + String toImage = dockerHost + ":5001/basic-jibtar"; JibContainer jibContainer = Jib.from(TarImage.at(outputPath).named("ignored")) .setEntrypoint("cat", "/hello") @@ -220,7 +220,7 @@ public void testBasic_tarBaseImage_jibImageToDockerDaemon() // tar saved with Jib.from("busybox").addLayer(...("core/hello")).containerize(TarImage.at...) Path path = Paths.get(Resources.getResource("core/busybox-jib.tar").toURI()); - String toImage = dockerHost + ":5000/basic-jibtar-to-docker"; + String toImage = dockerHost + ":5001/basic-jibtar-to-docker"; JibContainer jibContainer = Jib.from(TarImage.at(path).named("ignored")) .setEntrypoint("cat", "/hello") @@ -238,7 +238,7 @@ public void testScratch_defaultPlatform() CacheDirectoryCreationException, InvalidImageReferenceException { Jib.fromScratch() .containerize( - Containerizer.to(RegistryImage.named(dockerHost + ":5000/jib-scratch:default-platform")) + Containerizer.to(RegistryImage.named(dockerHost + ":5001/jib-scratch:default-platform")) .setAllowInsecureRegistries(true)); V22ManifestTemplate manifestTemplate = @@ -262,7 +262,7 @@ public void testScratch_singlePlatform() Jib.fromScratch() .setPlatforms(ImmutableSet.of(new Platform("arm64", "windows"))) .containerize( - Containerizer.to(RegistryImage.named(dockerHost + ":5000/jib-scratch:single-platform")) + Containerizer.to(RegistryImage.named(dockerHost + ":5001/jib-scratch:single-platform")) .setAllowInsecureRegistries(true)); V22ManifestTemplate manifestTemplate = @@ -287,7 +287,7 @@ public void testScratch_multiPlatform() .setPlatforms( ImmutableSet.of(new Platform("arm64", "windows"), new Platform("amd32", "windows"))) .containerize( - Containerizer.to(RegistryImage.named(dockerHost + ":5000/jib-scratch:multi-platform")) + Containerizer.to(RegistryImage.named(dockerHost + ":5001/jib-scratch:multi-platform")) .setAllowInsecureRegistries(true)); V22ManifestListTemplate manifestList = @@ -313,7 +313,7 @@ public void testDistroless_ociManifest() ImmutableSet.of(new Platform("arm64", "linux"), new Platform("amd64", "linux"))) .containerize( Containerizer.to( - RegistryImage.named(dockerHost + ":5000/jib-distroless:multi-platform")) + RegistryImage.named(dockerHost + ":5001/jib-distroless:multi-platform")) .setAllowInsecureRegistries(true)); V22ManifestListTemplate manifestList = @@ -338,7 +338,7 @@ public void testOffline() Path cacheDirectory = temporaryFolder.getRoot().toPath(); JibContainerBuilder jibContainerBuilder = - Jib.from(dockerHost + ":5000/busybox").setEntrypoint("echo", "Hello World"); + Jib.from(dockerHost + ":5001/busybox").setEntrypoint("echo", "Hello World"); // Should fail since Jib can't build to registry offline try { @@ -360,7 +360,7 @@ public void testOffline() Assert.assertEquals( "Cannot run Jib in offline mode; " + dockerHost - + ":5000/busybox not found in local Jib cache", + + ":5001/busybox not found in local Jib cache", ex.getCause().getMessage()); } @@ -372,13 +372,13 @@ public void testOffline() // Run again in offline mode, should succeed this time jibContainerBuilder.containerize( - Containerizer.to(DockerDaemonImage.named(dockerHost + ":5000/offline")) + Containerizer.to(DockerDaemonImage.named(dockerHost + ":5001/offline")) .setBaseImageLayersCache(cacheDirectory) .setOfflineMode(true)); // Verify output Assert.assertEquals( - "Hello World\n", new Command("docker", "run", "--rm", dockerHost + ":5000/offline").run()); + "Hello World\n", new Command("docker", "run", "--rm", dockerHost + ":5001/offline").run()); } /** Ensure that a provided executor is not disposed. */ @@ -390,7 +390,7 @@ public void testProvidedExecutorNotDisposed() try { Jib.fromScratch() .containerize( - Containerizer.to(RegistryImage.named(dockerHost + ":5000/foo")) + Containerizer.to(RegistryImage.named(dockerHost + ":5001/foo")) .setExecutorService(executorService) .setAllowInsecureRegistries(true)); Assert.assertFalse(executorService.isShutdown()); diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ReproducibleImageTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ReproducibleImageTest.java index 1c194b2198d..c6ec35e747a 100644 --- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ReproducibleImageTest.java +++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ReproducibleImageTest.java @@ -88,6 +88,22 @@ public static void createImage() .containerize(containerizer); } + public static int getJavaVersion() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2); + } + // Allow these formats: + // 1.8.0_72-ea + // 9-ea + // 9 + // 9.0.1 + int dotPos = version.indexOf('.'); + int dashPos = version.indexOf('-'); + return Integer.parseInt( + version.substring(0, dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : 1)); + } + @Test public void testTarballStructure() throws IOException { // known content should produce known results @@ -100,21 +116,39 @@ public void testTarballStructure() throws IOException { } } - assertThat(actual) - .containsExactly( - "c46572ef74f58d95e44dd36c1fbdfebd3752e8b56a794a13c11cfed35a1a6e1c.tar.gz", - "6d2763b0f3940d324ea6b55386429e5b173899608abf7d1bff62e25dd2e4dcea.tar.gz", - "530c1954a2b087d0b989895ea56435c9dc739a973f2d2b6cb9bb98e55bbea7ac.tar.gz", - "config.json", - "manifest.json") - .inOrder(); + if (getJavaVersion() < 16) { + assertThat(actual) + .containsExactly( + "c46572ef74f58d95e44dd36c1fbdfebd3752e8b56a794a13c11cfed35a1a6e1c.tar.gz", + "6d2763b0f3940d324ea6b55386429e5b173899608abf7d1bff62e25dd2e4dcea.tar.gz", + "530c1954a2b087d0b989895ea56435c9dc739a973f2d2b6cb9bb98e55bbea7ac.tar.gz", + "config.json", + "manifest.json") + .inOrder(); + } else { + // JDK 16+ has changed Gzip output, so hash changes + // https://bugs.openjdk.org/browse/JDK-8244706 + + assertThat(actual) + .containsExactly( + "d32c6bf16170d213b5f458a7c120288f0fb376015db1943d1e1c411e9b7ec9eb.tar.gz", + "eb01acbf8104bd2a8c4b594a1385bab883f27e85a703ee98c2e6cc81e71aea2a.tar.gz", + "65738b93774dc833f97dcb5ba806bddce6079163ba54bf51c9f66db9d1ab69d9.tar.gz", + "config.json", + "manifest.json") + .inOrder(); + } } @Test public void testManifest() throws IOException { String expectedManifest = - "[{\"Config\":\"config.json\",\"RepoTags\":[\"jib-core/reproducible:latest\"]," - + "\"Layers\":[\"c46572ef74f58d95e44dd36c1fbdfebd3752e8b56a794a13c11cfed35a1a6e1c.tar.gz\",\"6d2763b0f3940d324ea6b55386429e5b173899608abf7d1bff62e25dd2e4dcea.tar.gz\",\"530c1954a2b087d0b989895ea56435c9dc739a973f2d2b6cb9bb98e55bbea7ac.tar.gz\"]}]"; + (getJavaVersion() < 16) + ? "[{\"Config\":\"config.json\",\"RepoTags\":[\"jib-core/reproducible:latest\"]," + + "\"Layers\":[\"c46572ef74f58d95e44dd36c1fbdfebd3752e8b56a794a13c11cfed35a1a6e1c.tar.gz\",\"6d2763b0f3940d324ea6b55386429e5b173899608abf7d1bff62e25dd2e4dcea.tar.gz\",\"530c1954a2b087d0b989895ea56435c9dc739a973f2d2b6cb9bb98e55bbea7ac.tar.gz\"]}]" + : "[{\"Config\":\"config.json\",\"RepoTags\":[\"jib-core/reproducible:latest\"]," + + "\"Layers\":[\"d32c6bf16170d213b5f458a7c120288f0fb376015db1943d1e1c411e9b7ec9eb.tar.gz\",\"eb01acbf8104bd2a8c4b594a1385bab883f27e85a703ee98c2e6cc81e71aea2a.tar.gz\",\"65738b93774dc833f97dcb5ba806bddce6079163ba54bf51c9f66db9d1ab69d9.tar.gz\"]}]"; + String generatedManifest = extractFromTarFileAsString(imageTar, "manifest.json"); assertThat(generatedManifest).isEqualTo(expectedManifest); } diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/BlobPusherIntegrationTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/BlobPusherIntegrationTest.java index 3d68e2ef634..3e29e9edd12 100644 --- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/BlobPusherIntegrationTest.java +++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/BlobPusherIntegrationTest.java @@ -31,7 +31,7 @@ /** Integration tests for {@link BlobPusher}. */ public class BlobPusherIntegrationTest { - @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5000); + @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5001); private final FailoverHttpClient httpClient = new FailoverHttpClient(true, false, ignored -> {}); private final String dockerHost = @@ -46,7 +46,7 @@ public void testPush() throws DigestException, IOException, RegistryException { "52a9e4d4ba4333ce593707f98564fee1e6d898db0d3602408c0b2a6a424d357c"); RegistryClient registryClient = - RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5000", "testimage", httpClient) + RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5001", "testimage", httpClient) .newRegistryClient(); Assert.assertFalse(registryClient.pushBlob(testBlobDigest, testBlob, null, ignored -> {})); } diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPullerIntegrationTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPullerIntegrationTest.java index da6f058ccb9..9c5dd0f1661 100644 --- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPullerIntegrationTest.java +++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPullerIntegrationTest.java @@ -52,7 +52,7 @@ public class ManifestPullerIntegrationTest { public static final String KNOWN_OCI_MANIFEST_SHA = "sha256:0477dc38b254096e350a9b605b7355d3cf0d5a844558e6986148ce2a1fe18ba8"; - @ClassRule public static LocalRegistry localRegistry = new LocalRegistry(5000); + @ClassRule public static LocalRegistry localRegistry = new LocalRegistry(5001); public final String dockerHost = System.getenv("DOCKER_IP") != null ? System.getenv("DOCKER_IP") : "localhost"; @@ -66,7 +66,7 @@ public static void setUp() throws IOException, InterruptedException { @Test public void testPull_v21() throws IOException, RegistryException { RegistryClient registryClient = - RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5000", "busybox", httpClient) + RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5001", "busybox", httpClient) .newRegistryClient(); V21ManifestTemplate manifestTemplate = @@ -152,7 +152,7 @@ public void testPull_ociIndex() throws IOException, RegistryException { public void testPull_unknownManifest() throws RegistryException, IOException { try { RegistryClient registryClient = - RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5000", "busybox", httpClient) + RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5001", "busybox", httpClient) .newRegistryClient(); registryClient.pullManifest("nonexistent-tag"); Assert.fail("Trying to pull nonexistent image should have errored"); @@ -160,7 +160,7 @@ public void testPull_unknownManifest() throws RegistryException, IOException { } catch (RegistryErrorException ex) { assertThat(ex) .hasMessageThat() - .contains("pull image manifest for " + dockerHost + ":5000/busybox:nonexistent-tag"); + .contains("pull image manifest for " + dockerHost + ":5001/busybox:nonexistent-tag"); } } } diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPusherIntegrationTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPusherIntegrationTest.java index 478762d893e..57139174d75 100644 --- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPusherIntegrationTest.java +++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/registry/ManifestPusherIntegrationTest.java @@ -36,7 +36,7 @@ /** Integration tests for {@link ManifestPusher}. */ public class ManifestPusherIntegrationTest { - @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5000); + @ClassRule public static final LocalRegistry localRegistry = new LocalRegistry(5001); private final FailoverHttpClient httpClient = new FailoverHttpClient(true, false, ignored -> {}); public final String dockerHost = @@ -50,7 +50,7 @@ public void testPush_missingBlobs() throws IOException, RegistryException { ManifestTemplate manifestTemplate = registryClient.pullManifest("latest").getManifest(); registryClient = - RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5000", "ignored", httpClient) + RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5001", "ignored", httpClient) .newRegistryClient(); try { registryClient.pushManifest(manifestTemplate, "latest"); @@ -83,7 +83,7 @@ public void testPush() throws DigestException, IOException, RegistryException { // Pushes the BLOBs. RegistryClient registryClient = - RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5000", "testimage", httpClient) + RegistryClient.factory(EventHandlers.NONE, dockerHost + ":5001", "testimage", httpClient) .newRegistryClient(); Assert.assertFalse( registryClient.pushBlob(testLayerBlobDigest, testLayerBlob, null, ignored -> {})); diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/LocalBaseImageStepsTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/LocalBaseImageStepsTest.java index 97bd9f12179..2b9dace7eed 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/LocalBaseImageStepsTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/LocalBaseImageStepsTest.java @@ -84,6 +84,22 @@ public void tearDown() { tempDirectoryProvider.close(); } + public static int getJavaVersion() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2); + } + // Allow these formats: + // 1.8.0_72-ea + // 9-ea + // 9 + // 9.0.1 + int dotPos = version.indexOf('.'); + int dashPos = version.indexOf('-'); + return Integer.parseInt( + version.substring(0, dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : 1)); + } + @Test public void testCacheDockerImageTar_validDocker() throws Exception { Path dockerBuild = getResource("core/extraction/docker-save.tar"); @@ -93,17 +109,22 @@ public void testCacheDockerImageTar_validDocker() throws Exception { Mockito.verify(progressEventDispatcher, Mockito.times(2)).newChildProducer(); Assert.assertEquals(2, result.layers.size()); + Assert.assertEquals( "5e701122d3347fae0758cd5b7f0692c686fcd07b0e7fd9c4a125fbdbbedc04dd", result.layers.get(0).get().getDiffId().getHash()); Assert.assertEquals( - "0011328ac5dfe3dde40c7c5e0e00c98d1833a3aeae2bfb668cf9eb965c229c7f", + getJavaVersion() < 16 + ? "0011328ac5dfe3dde40c7c5e0e00c98d1833a3aeae2bfb668cf9eb965c229c7f" + : "bdc94fe3bba352809859ca87c846872ae2c1157596631e72d7d73e46fae86101", result.layers.get(0).get().getBlobDescriptor().getDigest().getHash()); Assert.assertEquals( "f1ac3015bcbf0ada4750d728626eb10f0f585199e2b667dcd79e49f0e926178e", result.layers.get(1).get().getDiffId().getHash()); Assert.assertEquals( - "c10ef24a5cef5092bbcb5a5666721cff7b86ce978c203a958d1fc86ee6c19f94", + getJavaVersion() < 16 + ? "c10ef24a5cef5092bbcb5a5666721cff7b86ce978c203a958d1fc86ee6c19f94" + : "073d615d78a940951cfe91b1feee2da3c5d21f7df48539921c26aecd23185d5f", result.layers.get(1).get().getBlobDescriptor().getDigest().getHash()); Assert.assertEquals(2, result.configurationTemplate.getLayerCount()); } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/cache/CacheStorageFilesTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/cache/CacheStorageFilesTest.java index c81a80c8ef9..2d1efd6c2aa 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/cache/CacheStorageFilesTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/cache/CacheStorageFilesTest.java @@ -188,8 +188,8 @@ public void testGetImageDirectory() throws InvalidImageReferenceException { ImageReference.parse( "reg.istry/repo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))); Assert.assertEquals( - imagesDirectory.resolve("reg.istry!5000/repo/sitory!tag"), + imagesDirectory.resolve("reg.istry!5001/repo/sitory!tag"), TEST_CACHE_STORAGE_FILES.getImageDirectory( - ImageReference.parse("reg.istry:5000/repo/sitory:tag"))); + ImageReference.parse("reg.istry:5001/repo/sitory:tag"))); } } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/http/FailoverHttpClientTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/http/FailoverHttpClientTest.java index b46267d96d7..bd59b2e2f98 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/http/FailoverHttpClientTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/http/FailoverHttpClientTest.java @@ -239,15 +239,15 @@ public void testGet_insecureClientOnNonListeningServerAndPortSpecified() throws FailoverHttpClient insecureHttpClient = newHttpClient(true, false); Mockito.when(mockHttpRequest.execute()) - .thenThrow(new ConnectException("my exception")); // server is not listening on 5000 + .thenThrow(new ConnectException("my exception")); // server is not listening on 5001 try (Response response = - insecureHttpClient.get(new URL("https://insecure:5000"), fakeRequest(null))) { + insecureHttpClient.get(new URL("https://insecure:5001"), fakeRequest(null))) { Assert.fail("Should not fall back to HTTP if port was explicitly given and cannot connect"); } catch (ConnectException ex) { Assert.assertEquals("my exception", ex.getMessage()); - verifyCapturedUrls("https://insecure:5000"); + verifyCapturedUrls("https://insecure:5001"); Mockito.verify(mockHttpRequest, Mockito.times(1)).execute(); Mockito.verifyNoInteractions(mockInsecureHttpRequest, logger); diff --git a/jib-gradle-plugin-extension-api/build.gradle b/jib-gradle-plugin-extension-api/build.gradle index 1478f301273..977be52bf14 100644 --- a/jib-gradle-plugin-extension-api/build.gradle +++ b/jib-gradle-plugin-extension-api/build.gradle @@ -44,7 +44,7 @@ publishing { release { tagTemplate = 'v$version-gradle-extension' git { - requireBranch = /^gradle-extension-release-v\d+.*$/ //regex + requireBranch.set(/^gradle-extension-release-v\d+.*$/) //regex } } /* RELEASE */ diff --git a/jib-gradle-plugin/build.gradle b/jib-gradle-plugin/build.gradle index 46f416ab1ed..02c27c7ff6d 100644 --- a/jib-gradle-plugin/build.gradle +++ b/jib-gradle-plugin/build.gradle @@ -45,7 +45,7 @@ dependencies { integrationTestImplementation dependencyStrings.JBCRYPT // only for testing a concrete Spring Boot example in a test (not for test infrastructure) - testImplementation 'org.springframework.boot:spring-boot-gradle-plugin:2.2.11.RELEASE' + testImplementation 'org.springframework.boot:spring-boot-gradle-plugin:2.7.13' } /* RELEASE */ @@ -57,17 +57,13 @@ release { 'com.google.cloud.tools:jib-plugins-common', ] git { - requireBranch = /^gradle-release-v\d+.*$/ //regex + requireBranch.set(/^gradle-release-v\d+.*$/) //regex } } // Gradle Plugin Portal releases -pluginBundle { +gradlePlugin { website = 'https://github.com/GoogleContainerTools/jib/' vcsUrl = 'https://github.com/GoogleContainerTools/jib/' - tags = ['google', 'java', 'containers', 'docker', 'kubernetes', 'microservices'] -} - -gradlePlugin { testSourceSets sourceSets.integrationTest, sourceSets.test plugins { jibPlugin { @@ -75,6 +71,7 @@ gradlePlugin { displayName = 'Jib' description = 'Containerize your Java application' implementationClass = 'com.google.cloud.tools.jib.gradle.JibPlugin' + tags.set(['google', 'java', 'containers', 'docker', 'kubernetes', 'microservices']) } } } diff --git a/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/SingleProjectIntegrationTest.java b/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/SingleProjectIntegrationTest.java index 7c53878dc50..1695ab70b95 100644 --- a/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/SingleProjectIntegrationTest.java +++ b/jib-gradle-plugin/src/integration-test/java/com/google/cloud/tools/jib/gradle/SingleProjectIntegrationTest.java @@ -50,7 +50,7 @@ public class SingleProjectIntegrationTest { @ClassRule public static final LocalRegistry localRegistry1 = - new LocalRegistry(5000, "testuser", "testpassword"); + new LocalRegistry(5001, "testuser", "testpassword"); @ClassRule public static final LocalRegistry localRegistry2 = @@ -449,7 +449,7 @@ public void testBuild_complex() @Test public void testBuild_complex_sameFromAndToRegistry() throws IOException, InterruptedException { - String targetImage = dockerHost + ":5000/compleximage:gradle" + System.nanoTime(); + String targetImage = dockerHost + ":5001/compleximage:gradle" + System.nanoTime(); Instant beforeBuild = Instant.now(); buildAndRunComplex(targetImage, "testuser", "testpassword", localRegistry1); assertThat(JibRunHelper.getCreationTime(targetImage)).isGreaterThan(beforeBuild); diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-configuration.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-configuration.gradle index 0d78b139d3d..01da56096ac 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-configuration.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-configuration.gradle @@ -24,8 +24,8 @@ configurations { } dependencies { - compile files('libs/dependency-1.0.0.jar') - runtime 'com.google.guava:guava:30.1-jre' + implementation files('libs/dependency-1.0.0.jar') + runtimeOnly 'com.google.guava:guava:30.1-jre' myConfiguration files('libs/dependency2') otherConfiguration files('libs/dependency3') } diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs-filtering.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs-filtering.gradle index 4e04624dacd..94683083574 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs-filtering.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs-filtering.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib { diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs.gradle index da49d7772be..7bedbd73699 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation() files('libs/dependency-1.0.0.jar') } jib { diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs2.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs2.gradle index f4c21d20050..a1694ed9f73 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs2.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs2.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib { diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs3.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs3.gradle index 178c0f80c9f..d48d6d501a2 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs3.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-extra-dirs3.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib { diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-jar-containerization.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-jar-containerization.gradle index 917a55ef7f6..150f012681d 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-jar-containerization.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-jar-containerization.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jar { diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11-incompatible.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11-incompatible.gradle index 2cc07b662ea..aa93e702f16 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11-incompatible.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11-incompatible.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib.from.image = 'eclipse-temurin:8-jdk-focal' diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11.gradle index 8c563bfb005..995aa9e7afc 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java11.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib.from.image = 'eclipse-temurin:11-jdk-focal' diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java17.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java17.gradle index 9c860213ef3..2600d5f6a89 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java17.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-java17.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib.to.image = System.getProperty("_TARGET_IMAGE") \ No newline at end of file diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-local-base.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-local-base.gradle index a757ac89fe2..6e57fa0be35 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-local-base.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-local-base.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib { diff --git a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-timestamps-custom.gradle b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-timestamps-custom.gradle index 9771046978e..1db4cc1e73f 100644 --- a/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-timestamps-custom.gradle +++ b/jib-gradle-plugin/src/integration-test/resources/gradle/projects/simple/build-timestamps-custom.gradle @@ -11,7 +11,7 @@ repositories { } dependencies { - compile files('libs/dependency-1.0.0.jar') + implementation files('libs/dependency-1.0.0.jar') } jib { diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java index 692449db037..86f29eef12d 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java @@ -44,6 +44,7 @@ import javax.annotation.Nullable; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.options.Option; @@ -54,6 +55,7 @@ public class BuildDockerTask extends DefaultTask implements JibTask { private static final String HELPFUL_SUGGESTIONS_PREFIX = "Build to Docker daemon failed"; @Nullable private JibExtension jibExtension; + @Nullable private GradleProjectProperties projectProperties; /** * This will call the property {@code "jib"} so that it is the same name as the extension. This @@ -63,10 +65,17 @@ public class BuildDockerTask extends DefaultTask implements JibTask { */ @Nested @Nullable + @SuppressWarnings("java:S106") public JibExtension getJib() { return jibExtension; } + @Nullable + @Internal + public GradleProjectProperties getProjectProperties() { + return projectProperties; + } + /** * The target image can be overridden with the {@code --image} command line option. * @@ -91,6 +100,7 @@ public void buildDocker() throws IOException, BuildStepsExecutionException, CacheDirectoryCreationException, MainClassInferenceException, InvalidGlobalConfigException { Preconditions.checkNotNull(jibExtension); + Preconditions.checkNotNull(projectProperties); // Check deprecated parameters Path dockerExecutable = jibExtension.getDockerClient().getExecutablePath(); @@ -104,23 +114,16 @@ public void buildDocker() } TaskCommon.disableHttpLogging(); - TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider(); - GradleProjectProperties projectProperties = - GradleProjectProperties.getForProject( - getProject(), - getLogger(), - tempDirectoryProvider, - jibExtension.getConfigurationName().get()); GlobalConfig globalConfig = GlobalConfig.readConfig(); Future> updateCheckFuture = - TaskCommon.newUpdateChecker(projectProperties, globalConfig, getLogger()); - try { + TaskCommon.newUpdateChecker(this.projectProperties, globalConfig, getLogger()); + try (TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider()) { PluginConfigurationProcessor.createJibBuildRunnerForDockerDaemonImage( new GradleRawConfiguration(jibExtension), ignored -> java.util.Optional.empty(), - projectProperties, + this.projectProperties, globalConfig, new GradleHelpfulSuggestions(HELPFUL_SUGGESTIONS_PREFIX)) .runBuild(); @@ -187,8 +190,7 @@ public void buildDocker() + ex.getPath(), ex); } finally { - tempDirectoryProvider.close(); - TaskCommon.finishUpdateChecker(projectProperties, updateCheckFuture); + TaskCommon.finishUpdateChecker(this.projectProperties, updateCheckFuture); projectProperties.waitForLoggingThread(); } } @@ -196,6 +198,12 @@ public void buildDocker() @Override public BuildDockerTask setJibExtension(JibExtension jibExtension) { this.jibExtension = jibExtension; + this.projectProperties = + GradleProjectProperties.getForProject( + getProject(), + getLogger(), + new TempDirectoryProvider(), + jibExtension.getConfigurationName().get()); return this; } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java index 49265559a61..2aef54bbef4 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java @@ -43,6 +43,7 @@ import javax.annotation.Nullable; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.options.Option; @@ -54,6 +55,8 @@ public class BuildImageTask extends DefaultTask implements JibTask { @Nullable private JibExtension jibExtension; + @Nullable private GradleProjectProperties projectProperties; + /** * This will call the property {@code "jib"} so that it is the same name as the extension. This * way, the user would see error messages for missing configuration with the prefix {@code jib.}. @@ -66,6 +69,12 @@ public JibExtension getJib() { return jibExtension; } + @Nullable + @Internal + public GradleProjectProperties getProjectProperties() { + return projectProperties; + } + /** * The target image can be overridden with the {@code --image} command line option. * @@ -91,15 +100,9 @@ public void buildImage() MainClassInferenceException, InvalidGlobalConfigException { // Asserts required @Input parameters are not null. Preconditions.checkNotNull(jibExtension); + Preconditions.checkNotNull(projectProperties); TaskCommon.disableHttpLogging(); - TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider(); - GradleProjectProperties projectProperties = - GradleProjectProperties.getForProject( - getProject(), - getLogger(), - tempDirectoryProvider, - jibExtension.getConfigurationName().get()); GlobalConfig globalConfig = GlobalConfig.readConfig(); Future> updateCheckFuture = TaskCommon.newUpdateChecker(projectProperties, globalConfig, getLogger()); @@ -182,15 +185,28 @@ public void buildImage() + ex.getPath(), ex); } finally { - tempDirectoryProvider.close(); - TaskCommon.finishUpdateChecker(projectProperties, updateCheckFuture); - projectProperties.waitForLoggingThread(); + + if (projectProperties != null) { + TempDirectoryProvider tempDirectoryProvider = projectProperties.getTempDirectoryProvider(); + if (tempDirectoryProvider != null) { + tempDirectoryProvider.close(); + } + TaskCommon.finishUpdateChecker(projectProperties, updateCheckFuture); + projectProperties.waitForLoggingThread(); + } } } @Override public BuildImageTask setJibExtension(JibExtension jibExtension) { this.jibExtension = jibExtension; + this.projectProperties = + GradleProjectProperties.getForProject( + getProject(), + getLogger(), + new TempDirectoryProvider(), + jibExtension.getConfigurationName().get()); + return this; } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildTarTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildTarTask.java index 1a77856b6b0..4f4219da378 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildTarTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildTarTask.java @@ -47,6 +47,7 @@ import org.gradle.api.GradleException; import org.gradle.api.file.FileCollection; import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; @@ -71,6 +72,8 @@ public JibExtension getJib() { return jibExtension; } + @Nullable private GradleProjectProperties projectProperties; + /** * The target image can be overridden with the {@code --image} command line option. * @@ -81,6 +84,12 @@ public void setTargetImage(String targetImage) { Preconditions.checkNotNull(jibExtension).getTo().setImage(targetImage); } + @Nullable + @Internal + public GradleProjectProperties getProjectProperties() { + return projectProperties; + } + /** * Returns a collection of all the files that jib includes in the image. Only used to calculate * UP-TO-DATE. @@ -122,23 +131,19 @@ public void buildTar() MainClassInferenceException, InvalidGlobalConfigException { // Asserts required @Input parameters are not null. Preconditions.checkNotNull(jibExtension); + Preconditions.checkNotNull(projectProperties); TaskCommon.disableHttpLogging(); - TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider(); - GradleProjectProperties projectProperties = - GradleProjectProperties.getForProject( - getProject(), - getLogger(), - tempDirectoryProvider, - jibExtension.getConfigurationName().get()); GlobalConfig globalConfig = GlobalConfig.readConfig(); Future> updateCheckFuture = - TaskCommon.newUpdateChecker(projectProperties, globalConfig, getLogger()); - try { + TaskCommon.newUpdateChecker(this.projectProperties, globalConfig, getLogger()); + + try (TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider()) { + PluginConfigurationProcessor.createJibBuildRunnerForTarImage( new GradleRawConfiguration(jibExtension), ignored -> Optional.empty(), - projectProperties, + this.projectProperties, globalConfig, new GradleHelpfulSuggestions(HELPFUL_SUGGESTIONS_PREFIX)) .runBuild(); @@ -204,7 +209,6 @@ public void buildTar() + ex.getPath(), ex); } finally { - tempDirectoryProvider.close(); TaskCommon.finishUpdateChecker(projectProperties, updateCheckFuture); projectProperties.waitForLoggingThread(); } @@ -213,6 +217,12 @@ public void buildTar() @Override public BuildTarTask setJibExtension(JibExtension jibExtension) { this.jibExtension = jibExtension; + this.projectProperties = + GradleProjectProperties.getForProject( + getProject(), + getLogger(), + new TempDirectoryProvider(), + jibExtension.getConfigurationName().get()); return this; } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoriesParameters.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoriesParameters.java index 30dc526e89b..c74ea7e8894 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoriesParameters.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoriesParameters.java @@ -19,6 +19,7 @@ import com.google.cloud.tools.jib.plugins.common.ConfigurationPropertyValidator; import com.google.cloud.tools.jib.plugins.common.PropertyNames; import java.io.File; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.List; @@ -33,14 +34,15 @@ import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.Internal; +import org.gradle.api.tasks.Nested; +import org.gradle.api.tasks.Optional; /** Object in {@link JibExtension} that configures the extra directories. */ public class ExtraDirectoriesParameters { private final ObjectFactory objects; - private final Project project; - + private final Path projectPath; + private final Provider extraDirPaths; private ListProperty paths; private ExtraDirectoryParametersSpec spec; private MapProperty permissions; @@ -48,10 +50,12 @@ public class ExtraDirectoriesParameters { @Inject public ExtraDirectoriesParameters(ObjectFactory objects, Project project) { this.objects = objects; - this.project = project; paths = objects.listProperty(ExtraDirectoryParameters.class).empty(); spec = objects.newInstance(ExtraDirectoryParametersSpec.class, project, paths); permissions = objects.mapProperty(String.class, String.class).empty(); + this.projectPath = project.getProjectDir().toPath(); + this.extraDirPaths = + project.getProviders().systemProperty(PropertyNames.EXTRA_DIRECTORIES_PATHS); } public void paths(Action action) { @@ -59,32 +63,26 @@ public void paths(Action action) { } @Input - public List getPathStrings() { - // Gradle warns about @Input annotations on File objects, so we have to expose a getter for a - // String to make them go away. - return getPaths().stream() - .map(extraDirectoryParameters -> extraDirectoryParameters.getFrom().toString()) - .collect(Collectors.toList()); + @Optional + public Provider getExtraDirPaths() { + return extraDirPaths; } - @Internal + @Nested public List getPaths() { // Gradle warns about @Input annotations on File objects, so we have to expose a getter for a // String to make them go away. - String property = System.getProperty(PropertyNames.EXTRA_DIRECTORIES_PATHS); - if (property != null) { - List pathStrings = ConfigurationPropertyValidator.parseListProperty(property); + if (this.extraDirPaths.isPresent()) { + List pathStrings = + ConfigurationPropertyValidator.parseListProperty(this.extraDirPaths.get()); return pathStrings.stream() - .map(path -> new ExtraDirectoryParameters(objects, project, Paths.get(path), "/")) + .map(path -> new ExtraDirectoryParameters(objects, Paths.get(path), "/")) .collect(Collectors.toList()); } if (paths.get().isEmpty()) { return Collections.singletonList( new ExtraDirectoryParameters( - objects, - project, - project.getProjectDir().toPath().resolve("src").resolve("main").resolve("jib"), - "/")); + objects, projectPath.resolve("src").resolve("main").resolve("jib"), "/")); } return paths.get(); } @@ -115,8 +113,8 @@ public void setPaths(Provider paths) { */ @Nonnull private List convertToExtraDirectoryParametersList(Object obj) { - return project.files(obj).getFiles().stream() - .map(file -> new ExtraDirectoryParameters(objects, project, file.toPath(), "/")) + return this.objects.fileCollection().from(obj).getFiles().stream() + .map(file -> new ExtraDirectoryParameters(objects, file.toPath(), "/")) .collect(Collectors.toList()); } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParameters.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParameters.java index 537b51f085d..934d04859f9 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParameters.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParameters.java @@ -18,60 +18,47 @@ import com.google.cloud.tools.jib.plugins.common.RawConfiguration.ExtraDirectoriesConfiguration; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import javax.inject.Inject; -import org.gradle.api.Project; +import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; /** Configuration of an extra directory. */ public class ExtraDirectoryParameters implements ExtraDirectoriesConfiguration { - private Project project; - private Property from; + ConfigurableFileCollection from; private Property into; private ListProperty includes; private ListProperty excludes; @Inject - public ExtraDirectoryParameters(ObjectFactory objects, Project project) { - this.project = project; - this.from = objects.property(Path.class).value(Paths.get("")); + public ExtraDirectoryParameters(ObjectFactory objects) { + this.from = objects.fileCollection(); this.into = objects.property(String.class).value("/"); this.includes = objects.listProperty(String.class).empty(); this.excludes = objects.listProperty(String.class).empty(); } - ExtraDirectoryParameters(ObjectFactory objects, Project project, Path from, String into) { - this(objects, project); - this.from = objects.property(Path.class).value(from); + ExtraDirectoryParameters(ObjectFactory objects, Path from, String into) { + this(objects); + this.from = objects.fileCollection().from(from); this.into = objects.property(String.class).value(into); } - @Input - public String getFromString() { - // Gradle warns about @Input annotations on File objects, so we have to expose a getter for a - // String to make them go away. - return from.get().toString(); - } - @Override - @Internal + @InputFiles public Path getFrom() { - return from.get(); + return from.getSingleFile().toPath(); } public void setFrom(Object from) { - this.from.set(project.file(from).toPath()); - } - - public void setFrom(Provider from) { - this.from.set(from.map(obj -> project.file(obj).toPath())); + this.from.from(from); } @Override diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParametersSpec.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParametersSpec.java index 53c57779c67..72dd4c2c21a 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParametersSpec.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/ExtraDirectoryParametersSpec.java @@ -19,18 +19,27 @@ import javax.inject.Inject; import org.gradle.api.Action; import org.gradle.api.Project; +import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Nested; /** Allows to add {@link ExtraDirectoryParameters} objects to the list property of the same type. */ public class ExtraDirectoryParametersSpec { - private final Project project; private final ListProperty paths; + private final ObjectFactory objectFactory; + /** + * Spec init. + * + * @param project Project handle + * @param paths Provider for extra dirs + */ @Inject public ExtraDirectoryParametersSpec( Project project, ListProperty paths) { - this.project = project; + this.objectFactory = project.getObjects(); this.paths = paths; } @@ -41,8 +50,14 @@ public ExtraDirectoryParametersSpec( */ public void path(Action action) { ExtraDirectoryParameters extraDirectory = - project.getObjects().newInstance(ExtraDirectoryParameters.class, project); + objectFactory.newInstance(ExtraDirectoryParameters.class); action.execute(extraDirectory); paths.add(extraDirectory); } + + @Input + @Nested + public ListProperty getPaths() { + return paths; + } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/GradleProjectProperties.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/GradleProjectProperties.java index 6a1978fe192..446bfb8ccb4 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/GradleProjectProperties.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/GradleProjectProperties.java @@ -69,10 +69,16 @@ import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.artifacts.component.ProjectComponentIdentifier; import org.gradle.api.file.FileCollection; +import org.gradle.api.file.RegularFile; import org.gradle.api.logging.Logger; +import org.gradle.api.model.ObjectFactory; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.plugins.WarPlugin; +import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.Classpath; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.Internal; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskProvider; @@ -98,6 +104,35 @@ public class GradleProjectProperties implements ProjectProperties { private static final String MAIN_SOURCE_SET_NAME = "main"; private static final Duration LOGGING_THREAD_SHUTDOWN_TIMEOUT = Duration.ofSeconds(1); + private final ObjectFactory objectFactory; + private final Logger logger; + private Path defaultCacheDirectory; + private Boolean warProject; + private Integer majorJavaVersion; + private Boolean offline; + private String name; + private String version; + private String warFilePath = ""; + + private Provider jarArchive; + private Property jarManifestMainClass; + + FileCollection classesOutputDirectories; + + Path resourcesOutputDirectory; + private Property progressFooterEnabled; + + @Input + @Classpath + public Path getResourcesOutputDirectory() { + return resourcesOutputDirectory; + } + + @Input + @Classpath + public FileCollection getClassesOutputDirectories() { + return classesOutputDirectories; + } /** * Generate an instance for a gradle project. @@ -127,7 +162,7 @@ public static GradleProjectProperties getForProject( project, logger, tempDirectoryProvider, extensionLoader, configurationName); } - String getWarFilePath() { + String getWarFilePath(Project project) { TaskProvider bootWarTask = TaskCommon.getBootWarTaskProvider(project); if (bootWarTask != null && bootWarTask.get().getEnabled()) { return bootWarTask.get().getOutputs().getFiles().getAsPath(); @@ -138,7 +173,7 @@ String getWarFilePath() { } private static boolean isProgressFooterEnabled(Project project) { - if ("plain".equals(System.getProperty(PropertyNames.CONSOLE))) { + if ("plain".equals(project.getProviders().systemProperty(PropertyNames.CONSOLE).getOrNull())) { return false; } @@ -157,12 +192,21 @@ private static boolean isProgressFooterEnabled(Project project) { } } - private final Project project; - private final SingleThreadedExecutor singleThreadedExecutor = new SingleThreadedExecutor(); - private final ConsoleLogger consoleLogger; + @VisibleForTesting + @SuppressWarnings("java:S2065") // keep sonar happy. We cannot serialize an executor + transient SingleThreadedExecutor singleThreadedExecutor = new SingleThreadedExecutor(); + + @Nullable + @SuppressWarnings("java:S2065") + private transient ConsoleLogger consoleLogger; + private final TempDirectoryProvider tempDirectoryProvider; private final Supplier>> extensionLoader; - private final String configurationName; + + private static final Object lock = new Object(); + FileCollection projectDependencies; + FileCollection allFiles; + FileCollection runtimeClasspath; @VisibleForTesting GradleProjectProperties( @@ -171,47 +215,79 @@ private static boolean isProgressFooterEnabled(Project project) { TempDirectoryProvider tempDirectoryProvider, Supplier>> extensionLoader, String configurationName) { - this.project = project; + JavaPluginExtension javaPluginExtension = + project.getExtensions().getByType(JavaPluginExtension.class); this.tempDirectoryProvider = tempDirectoryProvider; this.extensionLoader = extensionLoader; - this.configurationName = configurationName; - ConsoleLoggerBuilder consoleLoggerBuilder = - (isProgressFooterEnabled(project) - ? ConsoleLoggerBuilder.rich(singleThreadedExecutor, false) - : ConsoleLoggerBuilder.plain(singleThreadedExecutor).progress(logger::lifecycle)) - .lifecycle(logger::lifecycle); - if (logger.isDebugEnabled()) { - consoleLoggerBuilder.debug(logger::debug); + this.warProject = project.getPlugins().hasPlugin(WarPlugin.class); + this.defaultCacheDirectory = + project + .getLayout() + .getBuildDirectory() + .getAsFile() + .get() + .toPath() + .resolve(CACHE_DIRECTORY_NAME); + this.offline = project.getGradle().getStartParameter().isOffline(); + this.version = project.getVersion() != null ? project.getVersion().toString() : ""; + this.objectFactory = project.getObjects(); + this.jarArchive = this.objectFactory.fileProperty(); + this.jarManifestMainClass = this.objectFactory.property(String.class); + this.logger = logger; + this.progressFooterEnabled = project.getObjects().property(Boolean.class); + this.progressFooterEnabled.set(isProgressFooterEnabled(project)); + this.projectDependencies = + project.files( + project.getConfigurations().getByName(configurationName).getResolvedConfiguration() + .getResolvedArtifacts().stream() + .filter( + artifact -> + artifact.getId().getComponentIdentifier() + instanceof ProjectComponentIdentifier) + .map(ResolvedArtifact::getFile) + .collect(Collectors.toList())); + + this.allFiles = project.getConfigurations().getByName(configurationName).filter(File::exists); + this.runtimeClasspath = project.getConfigurations().getByName(configurationName); + Task jarTask = project.getTasks().findByName("jar"); + if (jarTask != null) { + this.jarArchive = ((Jar) jarTask).getArchiveFile(); + this.jarManifestMainClass.set(computeMainClassFromJarPlugin((Jar) jarTask)); } - if (logger.isInfoEnabled()) { - consoleLoggerBuilder.info(logger::info); - } - if (logger.isWarnEnabled()) { - consoleLoggerBuilder.warn(logger::warn); + + SourceSet mainSourceSet = javaPluginExtension.getSourceSets().getByName(MAIN_SOURCE_SET_NAME); + this.classesOutputDirectories = mainSourceSet.getOutput().getClassesDirs().filter(File::exists); + this.resourcesOutputDirectory = mainSourceSet.getOutput().getResourcesDir().toPath(); + + this.name = project.getName(); + JavaVersion ver = javaPluginExtension.getTargetCompatibility(); + + this.majorJavaVersion = Integer.valueOf(ver.getMajorVersion()); + + if (isWarProject()) { + this.warFilePath = getWarFilePath(project); } - if (logger.isErrorEnabled()) { - consoleLoggerBuilder.error(logger::error); + } + + public TempDirectoryProvider getTempDirectoryProvider() { + return tempDirectoryProvider; + } + + @Internal + @VisibleForTesting + synchronized SingleThreadedExecutor getSingleThreadedExecutor() { + if (singleThreadedExecutor == null) { + this.singleThreadedExecutor = new SingleThreadedExecutor(); } - consoleLogger = consoleLoggerBuilder.build(); + return this.singleThreadedExecutor; } @Override public JibContainerBuilder createJibContainerBuilder( JavaContainerBuilder javaContainerBuilder, ContainerizingMode containerizingMode) { try { - FileCollection projectDependencies = - project.files( - project.getConfigurations().getByName(configurationName).getResolvedConfiguration() - .getResolvedArtifacts().stream() - .filter( - artifact -> - artifact.getId().getComponentIdentifier() - instanceof ProjectComponentIdentifier) - .map(ResolvedArtifact::getFile) - .collect(Collectors.toList())); if (isWarProject()) { - String warFilePath = getWarFilePath(); log(LogEvent.info("WAR project identified, creating WAR image from: " + warFilePath)); Path explodedWarPath = tempDirectoryProvider.newDirectory(); ZipUtil.unzip(Paths.get(warFilePath), explodedWarPath); @@ -221,13 +297,6 @@ public JibContainerBuilder createJibContainerBuilder( projectDependencies.getFiles().stream().map(File::getName).collect(Collectors.toSet())); } - SourceSet mainSourceSet = getMainSourceSet(); - FileCollection classesOutputDirectories = - mainSourceSet.getOutput().getClassesDirs().filter(File::exists); - Path resourcesOutputDirectory = mainSourceSet.getOutput().getResourcesDir().toPath(); - FileCollection allFiles = - project.getConfigurations().getByName(configurationName).filter(File::exists); - FileCollection nonProjectDependencies = allFiles .minus(classesOutputDirectories) @@ -269,10 +338,7 @@ public JibContainerBuilder createJibContainerBuilder( case PACKAGED: // Add a JAR - Jar jarTask = (Jar) project.getTasks().findByName("jar"); - Path jarPath = jarTask.getArchiveFile().get().getAsFile().toPath(); - log(LogEvent.debug("Using JAR: " + jarPath)); - javaContainerBuilder.addToClasspath(jarPath); + extractedJar(javaContainerBuilder); break; default: @@ -286,11 +352,15 @@ public JibContainerBuilder createJibContainerBuilder( } } + private void extractedJar(JavaContainerBuilder javaContainerBuilder) throws IOException { + Path jarPath = this.jarArchive.get().getAsFile().toPath(); + log(LogEvent.debug("Using JAR: " + jarPath)); + javaContainerBuilder.addToClasspath(jarPath); + } + @Override public List getClassFiles() throws IOException { // TODO: Consolidate with createJibContainerBuilder - FileCollection classesOutputDirectories = - getMainSourceSet().getOutput().getClassesDirs().filter(File::exists); List classFiles = new ArrayList<>(); for (File classesOutputDirectory : classesOutputDirectories) { classFiles.addAll(new DirectoryWalker(classesOutputDirectory.toPath()).walk()); @@ -301,7 +371,7 @@ public List getClassFiles() throws IOException { @Override public List getDependencies() { List dependencies = new ArrayList<>(); - FileCollection runtimeClasspath = project.getConfigurations().getByName(configurationName); + // To be on the safe side with the order, calling "forEach" first (no filtering operations). runtimeClasspath.forEach( file -> { @@ -316,7 +386,7 @@ public List getDependencies() { @Override public void waitForLoggingThread() { - singleThreadedExecutor.shutDownAndAwaitTermination(LOGGING_THREAD_SHUTDOWN_TIMEOUT); + getSingleThreadedExecutor().shutDownAndAwaitTermination(LOGGING_THREAD_SHUTDOWN_TIMEOUT); } @Override @@ -333,13 +403,43 @@ TimerEvent.class, new TimerEventHandler(message -> log(LogEvent.debug(message))) ProgressDisplayGenerator.generateProgressDisplay( update.getProgress(), update.getUnfinishedLeafTasks()); footer.add(""); - consoleLogger.setFooter(footer); + getConsoleLogger().setFooter(footer); })); } @Override public void log(LogEvent logEvent) { - consoleLogger.log(logEvent.getLevel(), logEvent.getMessage()); + getConsoleLogger().log(logEvent.getLevel(), logEvent.getMessage()); + } + + @Internal + @VisibleForTesting + ConsoleLogger getConsoleLogger() { + synchronized (lock) { + if (this.consoleLogger == null) { + ConsoleLoggerBuilder consoleLoggerBuilder = + (Boolean.TRUE.equals(this.progressFooterEnabled.get()) + ? ConsoleLoggerBuilder.rich(getSingleThreadedExecutor(), false) + : ConsoleLoggerBuilder.plain(getSingleThreadedExecutor()) + .progress(logger::lifecycle)) + .lifecycle(logger::lifecycle); + if (logger.isDebugEnabled()) { + consoleLoggerBuilder.debug(logger::debug); + } + if (logger.isInfoEnabled()) { + consoleLoggerBuilder.info(logger::info); + } + if (logger.isWarnEnabled()) { + consoleLoggerBuilder.warn(logger::warn); + } + if (logger.isErrorEnabled()) { + consoleLoggerBuilder.error(logger::error); + } + this.consoleLogger = consoleLoggerBuilder.build(); + } + } + + return consoleLogger; } @Override @@ -360,12 +460,19 @@ public String getPluginName() { @Nullable @Override public String getMainClassFromJarPlugin() { - Jar jarTask = (Jar) project.getTasks().findByName("jar"); - if (jarTask == null) { + if (!this.jarArchive.isPresent()) { + return null; + } + return this.jarManifestMainClass.getOrNull(); + } + + @Nullable + private String computeMainClassFromJarPlugin(Jar task) { + if (!this.jarArchive.isPresent()) { return null; } - Object value = jarTask.getManifest().getAttributes().get("Main-Class"); + Object value = task.getManifest().getAttributes().get("Main-Class"); if (value instanceof Provider) { value = ((Provider) value).getOrNull(); @@ -384,7 +491,7 @@ public String getMainClassFromJarPlugin() { @Override public Path getDefaultCacheDirectory() { - return project.getBuildDir().toPath().resolve(CACHE_DIRECTORY_NAME); + return this.defaultCacheDirectory; } @Override @@ -394,7 +501,7 @@ public String getJarPluginName() { @Override public boolean isWarProject() { - return project.getPlugins().hasPlugin(WarPlugin.class); + return this.warProject; } /** @@ -430,34 +537,29 @@ static FileCollection getInputFiles( @Override public String getName() { - return project.getName(); + return this.name; } @Override public String getVersion() { - return project.getVersion().toString(); + return this.version; } @Override public int getMajorJavaVersion() { - JavaVersion version = JavaVersion.current(); - JavaPluginExtension javaPluginExtension = - project.getExtensions().findByType(JavaPluginExtension.class); - if (javaPluginExtension != null) { - version = javaPluginExtension.getTargetCompatibility(); - } - return Integer.valueOf(version.getMajorVersion()); + return this.majorJavaVersion; } @Override public boolean isOffline() { - return project.getGradle().getStartParameter().isOffline(); + return this.offline; } @Override public JibContainerBuilder runPluginExtensions( List extensionConfigs, - JibContainerBuilder jibContainerBuilder) + JibContainerBuilder jibContainerBuilder, + Optional project) throws JibPluginExtensionException { if (extensionConfigs.isEmpty()) { log(LogEvent.debug("No Jib plugin extensions configured to load")); @@ -472,8 +574,9 @@ public JibContainerBuilder runPluginExtensions( extension = findConfiguredExtension(loadedExtensions, config); log(LogEvent.lifecycle("Running extension: " + config.getExtensionClass())); + Project proj = (Project) project.orElseThrow(IllegalStateException::new); buildPlan = - runPluginExtension(extension.getExtraConfigType(), extension, config, buildPlan); + runPluginExtension(extension.getExtraConfigType(), extension, config, buildPlan, proj); ImageReference.parse(buildPlan.getBaseImage()); // to validate image reference } return jibContainerBuilder.applyContainerBuildPlan(buildPlan); @@ -494,7 +597,8 @@ private ContainerBuildPlan runPluginExtension( Optional> extraConfigType, JibGradlePluginExtension extension, ExtensionConfiguration config, - ContainerBuildPlan buildPlan) + ContainerBuildPlan buildPlan, + Project project) throws JibPluginExtensionException { T extraConfig = null; Optional configs = config.getExtraConfiguration(); @@ -509,7 +613,7 @@ private ContainerBuildPlan runPluginExtension( // configs.get() is of type Action, so this cast always succeeds. // (Note generic is erased at runtime.) Action action = (Action) configs.get(); - extraConfig = project.getObjects().newInstance(extraConfigType.get(), project); + extraConfig = this.objectFactory.newInstance(extraConfigType.get(), project); action.execute(extraConfig); } } @@ -543,10 +647,4 @@ private JibGradlePluginExtension findConfiguredExtension( } return found.get(); } - - private SourceSet getMainSourceSet() { - SourceSetContainer sourceSetContainer = - project.getExtensions().getByType(SourceSetContainer.class); - return sourceSetContainer.getByName(MAIN_SOURCE_SET_NAME); - } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java index 6f2d9d16d17..49d676437ae 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/JibPlugin.java @@ -16,6 +16,8 @@ package com.google.cloud.tools.jib.gradle; +import static org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME; + import com.google.cloud.tools.jib.gradle.skaffold.CheckJibVersionTask; import com.google.cloud.tools.jib.gradle.skaffold.FilesTaskV2; import com.google.cloud.tools.jib.gradle.skaffold.InitTask; @@ -30,8 +32,8 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; +import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskContainer; import org.gradle.api.tasks.TaskProvider; import org.gradle.api.tasks.bundling.Jar; @@ -39,7 +41,7 @@ public class JibPlugin implements Plugin { - @VisibleForTesting static final GradleVersion GRADLE_MIN_VERSION = GradleVersion.version("5.1"); + @VisibleForTesting static final GradleVersion GRADLE_MIN_VERSION = GradleVersion.version("8.0"); public static final String JIB_EXTENSION_NAME = "jib"; public static final String BUILD_IMAGE_TASK_NAME = "jib"; @@ -182,11 +184,11 @@ public void apply(Project project) { } } + JavaPluginExtension javaPluginExtension = + project.getExtensions().getByType(JavaPluginExtension.class); SourceSet mainSourceSet = - projectAfterEvaluation - .getExtensions() - .getByType(SourceSetContainer.class) - .getByName(SourceSet.MAIN_SOURCE_SET_NAME); + javaPluginExtension.getSourceSets().getByName(MAIN_SOURCE_SET_NAME); + jibDependencies.add(mainSourceSet.getRuntimeClasspath()); jibDependencies.add( projectAfterEvaluation diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/OutputPathsParameters.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/OutputPathsParameters.java index 46b4b6e608b..656c5e8bffa 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/OutputPathsParameters.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/OutputPathsParameters.java @@ -17,6 +17,7 @@ package com.google.cloud.tools.jib.gradle; import com.google.cloud.tools.jib.plugins.common.PropertyNames; +import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import javax.inject.Inject; @@ -27,8 +28,7 @@ /** Object that configures where Jib should create its build output files. */ public class OutputPathsParameters { - private final Project project; - + private final Path projectDir; private Path digest; private Path tar; private Path imageId; @@ -36,11 +36,13 @@ public class OutputPathsParameters { @Inject public OutputPathsParameters(Project project) { - this.project = project; - digest = project.getBuildDir().toPath().resolve("jib-image.digest"); - imageId = project.getBuildDir().toPath().resolve("jib-image.id"); - imageJson = project.getBuildDir().toPath().resolve("jib-image.json"); - tar = project.getBuildDir().toPath().resolve("jib-image.tar"); + File buildDir = project.getLayout().getBuildDirectory().getAsFile().get(); + + this.projectDir = project.getProjectDir().toPath(); + digest = buildDir.toPath().resolve("jib-image.digest"); + imageId = buildDir.toPath().resolve("jib-image.id"); + imageJson = buildDir.toPath().resolve("jib-image.json"); + tar = buildDir.toPath().resolve("jib-image.tar"); } @Input @@ -102,6 +104,6 @@ public void setTar(String tar) { private Path getRelativeToProjectRoot(Path configuration, String propertyName) { String property = System.getProperty(propertyName); Path path = property != null ? Paths.get(property) : configuration; - return path.isAbsolute() ? path : project.getProjectDir().toPath().resolve(path); + return path.isAbsolute() ? path : this.projectDir.resolve(path); } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java index fc15b021cf1..05e4f34aa41 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java @@ -139,10 +139,7 @@ private void addGradleFiles(Project project) { skaffoldFilesOutput.addBuild(project.getBuildFile().toPath()); // Add settings.gradle - if (project.getGradle().getStartParameter().getSettingsFile() != null) { - skaffoldFilesOutput.addBuild( - project.getGradle().getStartParameter().getSettingsFile().toPath()); - } else if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { + if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { skaffoldFilesOutput.addBuild(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE)); } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldSyncParameters.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldSyncParameters.java index ceeca5d1721..2383230a6e5 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldSyncParameters.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldSyncParameters.java @@ -17,23 +17,21 @@ package com.google.cloud.tools.jib.gradle.skaffold; import java.io.File; -import java.nio.file.Path; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; import javax.inject.Inject; import org.gradle.api.Project; -import org.gradle.api.tasks.Internal; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.tasks.InputFiles; /** Skaffold specific JibExtension parameters for configuring files to sync. */ public class SkaffoldSyncParameters { - private final Project project; - private Set excludes = Collections.emptySet(); + private final ConfigurableFileCollection fileCollection; + private ConfigurableFileCollection excludes; @Inject public SkaffoldSyncParameters(Project project) { - this.project = project; + this.fileCollection = project.getObjects().fileCollection(); + this.excludes = project.getObjects().fileCollection(); } /** @@ -41,8 +39,8 @@ public SkaffoldSyncParameters(Project project) { * * @return a set of absolute paths */ - @Internal - public Set getExcludes() { + @InputFiles + public ConfigurableFileCollection getExcludes() { return excludes; } @@ -53,10 +51,11 @@ public Set getExcludes() { * @param paths paths to set on excludes */ public void setExcludes(Object paths) { - this.excludes = - project.files(paths).getFiles().stream() - .map(File::toPath) - .map(Path::toAbsolutePath) - .collect(Collectors.toSet()); + this.excludes.from(paths); + } + + @InputFiles + public ConfigurableFileCollection getFileCollection() { + return fileCollection; } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldWatchParameters.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldWatchParameters.java index 5f294100b53..e14081a9682 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldWatchParameters.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SkaffoldWatchParameters.java @@ -17,26 +17,25 @@ package com.google.cloud.tools.jib.gradle.skaffold; import java.io.File; -import java.nio.file.Path; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; import javax.inject.Inject; import org.gradle.api.Project; -import org.gradle.api.tasks.Internal; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.tasks.InputFiles; /** Skaffold specific JibExtension parameters for configuring files to watch. */ public class SkaffoldWatchParameters { - private final Project project; - - private Set buildIncludes = Collections.emptySet(); - private Set includes = Collections.emptySet(); - private Set excludes = Collections.emptySet(); + private final ConfigurableFileCollection fileCollection; + private ConfigurableFileCollection buildIncludes; + private ConfigurableFileCollection includes; + private ConfigurableFileCollection excludes; @Inject public SkaffoldWatchParameters(Project project) { - this.project = project; + this.fileCollection = project.getObjects().fileCollection(); + this.buildIncludes = project.getObjects().fileCollection(); + this.includes = project.getObjects().fileCollection(); + this.excludes = project.getObjects().fileCollection(); } /** @@ -44,8 +43,8 @@ public SkaffoldWatchParameters(Project project) { * * @return a set of absolute paths */ - @Internal - public Set getBuildIncludes() { + @InputFiles + public ConfigurableFileCollection getBuildIncludes() { return buildIncludes; } @@ -56,11 +55,7 @@ public Set getBuildIncludes() { * @param paths paths to set on includes */ public void setBuildIncludes(Object paths) { - this.buildIncludes = - project.files(paths).getFiles().stream() - .map(File::toPath) - .map(Path::toAbsolutePath) - .collect(Collectors.toSet()); + this.buildIncludes.from(paths); } /** @@ -68,8 +63,8 @@ public void setBuildIncludes(Object paths) { * * @return a set of absolute paths */ - @Internal - public Set getIncludes() { + @InputFiles + public ConfigurableFileCollection getIncludes() { return includes; } @@ -80,11 +75,7 @@ public Set getIncludes() { * @param paths paths to set on includes */ public void setIncludes(Object paths) { - this.includes = - project.files(paths).getFiles().stream() - .map(File::toPath) - .map(Path::toAbsolutePath) - .collect(Collectors.toSet()); + this.includes.from(paths); } /** @@ -92,11 +83,9 @@ public void setIncludes(Object paths) { * * @return a set of absolute paths */ - @Internal - public Set getExcludes() { - // Gradle warns about @Input annotations on File objects, so we have to expose a getter for a - // String to make them go away. - return excludes; + @InputFiles + public ConfigurableFileCollection getExcludes() { + return this.excludes; } /** @@ -106,10 +95,11 @@ public Set getExcludes() { * @param paths paths to set on excludes */ public void setExcludes(Object paths) { - this.excludes = - project.files(paths).getFiles().stream() - .map(File::toPath) - .map(Path::toAbsolutePath) - .collect(Collectors.toSet()); + this.excludes.from(paths); + } + + @InputFiles + public ConfigurableFileCollection getFileCollection() { + return fileCollection; } } diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SyncMapTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SyncMapTask.java index 7d8d9e4b029..c43f36179d6 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SyncMapTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/SyncMapTask.java @@ -24,6 +24,8 @@ import com.google.cloud.tools.jib.plugins.common.InvalidContainerizingModeException; import com.google.cloud.tools.jib.plugins.common.PluginConfigurationProcessor; import com.google.common.base.Preconditions; +import java.io.File; +import java.util.stream.Collectors; import javax.annotation.Nullable; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; @@ -85,7 +87,9 @@ public void listFilesAndTargets() { PluginConfigurationProcessor.getSkaffoldSyncMap( configuration, projectProperties, - jibExtension.getSkaffold().getSync().getExcludes()); + jibExtension.getSkaffold().getSync().getExcludes().getFiles().stream() + .map(File::toPath) + .collect(Collectors.toSet())); System.out.println(); System.out.println("BEGIN JIB JSON: SYNCMAP/1"); diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesExtensionTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesExtensionTest.java index 63718ce0e55..fd68285e737 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesExtensionTest.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesExtensionTest.java @@ -16,6 +16,8 @@ package com.google.cloud.tools.jib.gradle; +import static org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME; + import com.google.cloud.tools.jib.api.InvalidImageReferenceException; import com.google.cloud.tools.jib.api.Jib; import com.google.cloud.tools.jib.api.JibContainerBuilder; @@ -35,11 +37,21 @@ import java.util.Map; import java.util.Optional; import org.gradle.api.Action; +import org.gradle.api.JavaVersion; import org.gradle.api.Project; +import org.gradle.api.file.RegularFile; +import org.gradle.api.internal.provider.DefaultProperty; import org.gradle.api.logging.Logger; import org.gradle.api.logging.configuration.ConsoleOutput; import org.gradle.api.model.ObjectFactory; +import org.gradle.api.plugins.ExtensionContainer; import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.SourceSetContainer; +import org.gradle.api.tasks.TaskContainer; +import org.gradle.jvm.tasks.Jar; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; import org.junit.Assert; @@ -205,6 +217,21 @@ private ExtensionDefinedBarConfig(String barParam) { @Mock private Logger mockLogger; @Mock private ObjectFactory mockObjectFactory; + @Mock private JavaPluginExtension mockJavaPluginExtension; + @Mock private SourceSetContainer mockSourceSetContainer; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private SourceSet mockSourceSet; + + @Mock private TaskContainer mockReturnContainer; + + @Mock private ExtensionContainer mockExtensionContainer; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Jar mockJarTask; + + @Mock private Provider mockProviderFile; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Project mockProject; @@ -219,7 +246,24 @@ public void setUp() { Mockito.when(mockLogger.isInfoEnabled()).thenReturn(true); Mockito.when(mockLogger.isWarnEnabled()).thenReturn(true); Mockito.when(mockLogger.isErrorEnabled()).thenReturn(true); - + Mockito.when(mockProject.getExtensions()).thenReturn(mockExtensionContainer); + Mockito.when(mockProject.getTasks()).thenReturn(mockReturnContainer); + Mockito.when(mockReturnContainer.findByName("jar")).thenReturn(mockJarTask); + Mockito.when(mockJarTask.getArchiveFile()).thenReturn(mockProviderFile); + Mockito.when(mockProviderFile.isPresent()).thenReturn(true); + + Mockito.when(mockExtensionContainer.getByType(JavaPluginExtension.class)) + .thenReturn(mockJavaPluginExtension); + Mockito.when(mockJavaPluginExtension.getSourceSets()).thenReturn(mockSourceSetContainer); + Mockito.when(mockJavaPluginExtension.getTargetCompatibility()) + .thenReturn(JavaVersion.VERSION_1_8); + Mockito.when(mockSourceSetContainer.getByName(MAIN_SOURCE_SET_NAME)).thenReturn(mockSourceSet); + + Mockito.when(mockObjectFactory.property(String.class)) + .thenReturn(new DefaultProperty<>(null, String.class)); + // Mockito.when(mockObjectFactory.fileProperty()).thenReturn(new DefaultRegularFileVar()); + Mockito.when(mockObjectFactory.property(Boolean.class)) + .thenReturn(new DefaultProperty<>(null, Boolean.class)); Mockito.when(mockProject.getGradle().getStartParameter().getConsoleOutput()) .thenReturn(ConsoleOutput.Plain); Mockito.when(mockProject.getObjects()).thenReturn(mockObjectFactory); @@ -248,7 +292,8 @@ public void testRunPluginExtensions_noExtensionsConfigured() throws JibPluginExt loadedExtensions = Arrays.asList(extension); JibContainerBuilder extendedBuilder = - gradleProjectProperties.runPluginExtensions(Collections.emptyList(), containerBuilder); + gradleProjectProperties.runPluginExtensions( + Collections.emptyList(), containerBuilder, Optional.of(mockProject)); Assert.assertSame(extendedBuilder, containerBuilder); gradleProjectProperties.waitForLoggingThread(); @@ -259,7 +304,7 @@ public void testRunPluginExtensions_noExtensionsConfigured() throws JibPluginExt public void testRunPluginExtensions_configuredExtensionNotFound() { try { gradleProjectProperties.runPluginExtensions( - Arrays.asList(new FooExtensionConfig()), containerBuilder); + Arrays.asList(new FooExtensionConfig()), containerBuilder, Optional.of(mockProject)); Assert.fail(); } catch (JibPluginExtensionException ex) { Assert.assertEquals( @@ -281,7 +326,7 @@ public void testRunPluginExtensions() throws JibPluginExtensionException { JibContainerBuilder extendedBuilder = gradleProjectProperties.runPluginExtensions( - Arrays.asList(new FooExtensionConfig()), containerBuilder); + Arrays.asList(new FooExtensionConfig()), containerBuilder, Optional.of(mockProject)); Assert.assertEquals("user from extension", extendedBuilder.toContainerBuildPlan().getUser()); gradleProjectProperties.waitForLoggingThread(); @@ -305,7 +350,7 @@ public void testRunPluginExtensions_exceptionFromExtension() { try { gradleProjectProperties.runPluginExtensions( - Arrays.asList(new FooExtensionConfig()), containerBuilder); + Arrays.asList(new FooExtensionConfig()), containerBuilder, Optional.of(mockProject)); Assert.fail(); } catch (JibPluginExtensionException ex) { Assert.assertEquals("exception from extension", ex.getMessage()); @@ -323,7 +368,7 @@ public void testRunPluginExtensions_invalidBaseImageFromExtension() { try { gradleProjectProperties.runPluginExtensions( - Arrays.asList(new FooExtensionConfig()), containerBuilder); + Arrays.asList(new FooExtensionConfig()), containerBuilder, Optional.of(mockProject)); Assert.fail(); } catch (JibPluginExtensionException ex) { Assert.assertEquals("invalid base image reference: in*val+id", ex.getMessage()); @@ -346,12 +391,16 @@ public void testRunPluginExtensions_extensionOrder() throws JibPluginExtensionEx JibContainerBuilder extendedBuilder1 = gradleProjectProperties.runPluginExtensions( - Arrays.asList(new FooExtensionConfig(), new BarExtensionConfig()), containerBuilder); + Arrays.asList(new FooExtensionConfig(), new BarExtensionConfig()), + containerBuilder, + Optional.of(mockProject)); Assert.assertEquals("bar", extendedBuilder1.toContainerBuildPlan().getBaseImage()); JibContainerBuilder extendedBuilder2 = gradleProjectProperties.runPluginExtensions( - Arrays.asList(new BarExtensionConfig(), new FooExtensionConfig()), containerBuilder); + Arrays.asList(new BarExtensionConfig(), new FooExtensionConfig()), + containerBuilder, + Optional.of(mockProject)); Assert.assertEquals("foo", extendedBuilder2.toContainerBuildPlan().getBaseImage()); } @@ -366,7 +415,8 @@ public void testRunPluginExtensions_customProperties() throws JibPluginExtension JibContainerBuilder extendedBuilder = gradleProjectProperties.runPluginExtensions( Arrays.asList(new FooExtensionConfig(ImmutableMap.of("user", "65432"))), - containerBuilder); + containerBuilder, + Optional.of(mockProject)); Assert.assertEquals("65432", extendedBuilder.toContainerBuildPlan().getUser()); } @@ -388,7 +438,9 @@ public void testRunPluginExtensions_extensionDefinedConfigurations_emptyConfig() loadedExtensions = Arrays.asList(fooExtension, barExtension); gradleProjectProperties.runPluginExtensions( - Arrays.asList(new FooExtensionConfig(), new BarExtensionConfig()), containerBuilder); + Arrays.asList(new FooExtensionConfig(), new BarExtensionConfig()), + containerBuilder, + Optional.of(mockProject)); } @Test @@ -412,7 +464,8 @@ public void testRunPluginExtensions_extensionDefinedConfigurations() Arrays.asList( new FooExtensionConfig(new ExtensionDefinedFooConfig("fooParamValue")), new BarExtensionConfig(new ExtensionDefinedBarConfig("barParamValue"))), - containerBuilder); + containerBuilder, + Optional.of(mockProject)); } @Test @@ -427,7 +480,8 @@ public void testRunPluginExtensions_ignoreUnexpectedExtraConfig() new BaseExtensionConfig<>( BaseExtension.class.getName(), Collections.emptyMap(), (ignored) -> {}); try { - gradleProjectProperties.runPluginExtensions(Arrays.asList(extensionConfig), containerBuilder); + gradleProjectProperties.runPluginExtensions( + Arrays.asList(extensionConfig), containerBuilder, Optional.of(mockProject)); Assert.fail(); } catch (IllegalArgumentException ex) { Assert.assertEquals( @@ -448,7 +502,7 @@ public void testRunPluginExtensions_runtimeExceptionFromExtension() { try { gradleProjectProperties.runPluginExtensions( - Arrays.asList(new FooExtensionConfig()), containerBuilder); + Arrays.asList(new FooExtensionConfig()), containerBuilder, Optional.of(mockProject)); Assert.fail(); } catch (JibPluginExtensionException ex) { Assert.assertEquals(FooExtension.class, ex.getExtensionClass()); diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesTest.java index 7698228ab0e..504f946a18a 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesTest.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/GradleProjectPropertiesTest.java @@ -17,6 +17,8 @@ package com.google.cloud.tools.jib.gradle; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -144,6 +146,9 @@ public void setUp() throws URISyntaxException, IOException { .withProjectDir(projectDir.toFile()) .withGradleUserHomeDir(temporaryFolder.newFolder()) .build(); + + project.getRepositories().add(project.getRepositories().mavenCentral()); + project.getPlugins().apply("java"); DependencyHandler dependencies = project.getDependencies(); @@ -161,14 +166,6 @@ public void setUp() throws URISyntaxException, IOException { // We can't commit an empty directory in Git, so create (if not exist). Path emptyDirectory = getResource("gradle/webapp").resolve("WEB-INF/classes/empty_dir"); Files.createDirectories(emptyDirectory); - - gradleProjectProperties = - new GradleProjectProperties( - project, - mockLogger, - mockTempDirectoryProvider, - mockExtensionLoader, - JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); } @Test @@ -177,11 +174,14 @@ public void testGetMainClassFromJar_success() { jar.setManifest( new DefaultManifest(null).attributes(ImmutableMap.of("Main-Class", "some.main.class"))); + setupGradleProjectPropertiesInstance(); assertThat(gradleProjectProperties.getMainClassFromJarPlugin()).isEqualTo("some.main.class"); } @Test public void testGetMainClassFromJar_missing() { + setupGradleProjectPropertiesInstance(); + assertThat(gradleProjectProperties.getMainClassFromJarPlugin()).isNull(); } @@ -193,6 +193,8 @@ public void testGetMainClassFromJarAsProperty_success() { Jar jar = project.getTasks().withType(Jar.class).getByName("jar"); jar.setManifest(new DefaultManifest(null).attributes(ImmutableMap.of("Main-Class", mainClass))); + setupGradleProjectPropertiesInstance(); + assertThat(gradleProjectProperties.getMainClassFromJarPlugin()).isEqualTo("some.main.class"); } @@ -202,13 +204,15 @@ public void testGetMainClassFromJarAsPropertyWithValueNull_missing() { Jar jar = project.getTasks().withType(Jar.class).getByName("jar"); jar.setManifest(new DefaultManifest(null).attributes(ImmutableMap.of("Main-Class", mainClass))); - + setupGradleProjectPropertiesInstance(); assertThat(gradleProjectProperties.getMainClassFromJarPlugin()).isNull(); } @Test public void testIsWarProject() { project.getPlugins().apply("war"); + setupGradleProjectPropertiesInstance(); + assertThat(gradleProjectProperties.isWarProject()).isTrue(); } @@ -258,35 +262,41 @@ public void testConvertPermissionsMap() { @Test public void testGetMajorJavaVersion() { - JavaPluginExtension extension = project.getExtensions().findByType(JavaPluginExtension.class); + JavaPluginExtension convention = project.getExtensions().findByType(JavaPluginExtension.class); + + convention.setTargetCompatibility(JavaVersion.VERSION_1_3); + setupGradleProjectPropertiesInstance(); - extension.setTargetCompatibility(JavaVersion.VERSION_1_3); assertThat(gradleProjectProperties.getMajorJavaVersion()).isEqualTo(3); - extension.setTargetCompatibility(JavaVersion.VERSION_11); + convention.setTargetCompatibility(JavaVersion.VERSION_11); + setupGradleProjectPropertiesInstance(); assertThat(gradleProjectProperties.getMajorJavaVersion()).isEqualTo(11); - extension.setTargetCompatibility(JavaVersion.VERSION_1_9); + convention.setTargetCompatibility(JavaVersion.VERSION_1_9); + setupGradleProjectPropertiesInstance(); assertThat(gradleProjectProperties.getMajorJavaVersion()).isEqualTo(9); } @Test public void testGetMajorJavaVersion_jvm8() { Assume.assumeThat(JavaVersion.current(), CoreMatchers.is(JavaVersion.VERSION_1_8)); - + setupGradleProjectPropertiesInstance(); assertThat(gradleProjectProperties.getMajorJavaVersion()).isEqualTo(8); } @Test public void testGetMajorJavaVersion_jvm11() { Assume.assumeThat(JavaVersion.current(), CoreMatchers.is(JavaVersion.VERSION_11)); - + setupGradleProjectPropertiesInstance(); assertThat(gradleProjectProperties.getMajorJavaVersion()).isEqualTo(11); } @Test public void testCreateContainerBuilder_correctSourceFiles() throws URISyntaxException, InvalidImageReferenceException, CacheDirectoryCreationException { + setupGradleProjectPropertiesInstance(); + ContainerBuilderLayers layers = new ContainerBuilderLayers(setupBuildContext()); Path applicationDirectory = getResource("gradle/application"); @@ -352,6 +362,7 @@ public void testCreateContainerBuilder_noClassesFiles() @Test public void testCreateContainerBuilder_correctExtractionPaths() throws InvalidImageReferenceException, CacheDirectoryCreationException { + setupGradleProjectPropertiesInstance(); ContainerBuilderLayers layers = new ContainerBuilderLayers(setupBuildContext()); assertThat(layers.dependenciesLayer.getEntries()) @@ -382,6 +393,7 @@ public void testCreateContainerBuilder_war() throws URISyntaxException, IOException, InvalidImageReferenceException, CacheDirectoryCreationException { Path unzipTarget = setUpWarProject(getResource("gradle/webapp")); + setupGradleProjectPropertiesInstance(); ContainerBuilderLayers layers = new ContainerBuilderLayers(setupBuildContext()); assertThat(layers.dependenciesLayer.getEntries()) @@ -444,7 +456,7 @@ public void testCreateContainerBuilder_noErrorIfWebInfClassesDoesNotExist() throws IOException, InvalidImageReferenceException { temporaryFolder.newFolder("WEB-INF", "lib"); setUpWarProject(temporaryFolder.getRoot().toPath()); - + setupGradleProjectPropertiesInstance(); assertThat( gradleProjectProperties.createJibContainerBuilder( JavaContainerBuilder.from("ignored"), ContainerizingMode.EXPLODED)) @@ -456,7 +468,7 @@ public void testCreateContainerBuilder_noErrorIfWebInfLibDoesNotExist() throws IOException, InvalidImageReferenceException { temporaryFolder.newFolder("WEB-INF", "classes"); setUpWarProject(temporaryFolder.getRoot().toPath()); - + setupGradleProjectPropertiesInstance(); assertThat( gradleProjectProperties.createJibContainerBuilder( JavaContainerBuilder.from("ignored"), ContainerizingMode.EXPLODED)) @@ -467,22 +479,33 @@ public void testCreateContainerBuilder_noErrorIfWebInfLibDoesNotExist() public void testCreateContainerBuilder_noErrorIfWebInfDoesNotExist() throws IOException, InvalidImageReferenceException { setUpWarProject(temporaryFolder.getRoot().toPath()); - + setupGradleProjectPropertiesInstance(); assertThat( gradleProjectProperties.createJibContainerBuilder( JavaContainerBuilder.from("ignored"), ContainerizingMode.EXPLODED)) .isNotNull(); } + private void setupGradleProjectPropertiesInstance() { + gradleProjectProperties = + new GradleProjectProperties( + project, + mockLogger, + mockTempDirectoryProvider, + mockExtensionLoader, + JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); + } + @Test public void testGetWarFilePath() throws IOException { Path outputDir = temporaryFolder.newFolder("output").toPath(); project.getPlugins().apply("war"); + setupGradleProjectPropertiesInstance(); War war = project.getTasks().withType(War.class).getByName("war"); war.getDestinationDirectory().set(outputDir.toFile()); - assertThat(gradleProjectProperties.getWarFilePath()) + assertThat(gradleProjectProperties.getWarFilePath(project)) .isEqualTo(outputDir.resolve("my-app.war").toString()); } @@ -494,8 +517,8 @@ public void testGetWarFilePath_bootWar() throws IOException { project.getPlugins().apply("org.springframework.boot"); War bootWar = project.getTasks().withType(War.class).getByName("bootWar"); bootWar.getDestinationDirectory().set(outputDir.toFile()); - - assertThat(gradleProjectProperties.getWarFilePath()) + setupGradleProjectPropertiesInstance(); + assertThat(gradleProjectProperties.getWarFilePath(project)) .isEqualTo(outputDir.resolve("my-app.war").toString()); } @@ -510,12 +533,65 @@ public void testGetWarFilePath_bootWarDisabled() throws IOException { project.getPlugins().apply("org.springframework.boot"); project.getTasks().getByName("bootWar").setEnabled(false); - assertThat(gradleProjectProperties.getWarFilePath()) - .isEqualTo(outputDir.resolve("my-app.war").toString()); + setupGradleProjectPropertiesInstance(); + assertThat(gradleProjectProperties.getWarFilePath(project)) + .isEqualTo(outputDir.resolve("my-app-plain.war").toString()); + } + + @Test + public void testGetSingleThreadedExecutor() { + setupGradleProjectPropertiesInstance(); + assertNotNull(gradleProjectProperties.getSingleThreadedExecutor()); + gradleProjectProperties.singleThreadedExecutor = null; // pretend running from cache + assertNotNull(gradleProjectProperties.getSingleThreadedExecutor()); + } + + @Test + public void testGetConsoleLogger() { + setupGradleProjectPropertiesInstance(); + assertNotNull(gradleProjectProperties.getConsoleLogger()); + } + + @Test + public void testGetClassesOutputDirectory() { + setupGradleProjectPropertiesInstance(); + assertNotNull(gradleProjectProperties.getClassesOutputDirectories()); + assertFalse(gradleProjectProperties.getClassesOutputDirectories().getFiles().isEmpty()); + } + + @Test + public void testGetResourcesOutputDirectory() { + setupGradleProjectPropertiesInstance(); + assertNotNull(gradleProjectProperties.getResourcesOutputDirectory()); + } + + @Test + public void testGetClassFiles() throws IOException { + setupGradleProjectPropertiesInstance(); + assertFalse(gradleProjectProperties.getClassFiles().isEmpty()); + } + + @Test + public void testGetDefaultCacheDir() throws IOException { + setupGradleProjectPropertiesInstance(); + assertNotNull(gradleProjectProperties.getDefaultCacheDirectory()); + } + + @Test + public void testGetJarPluginName() throws IOException { + setupGradleProjectPropertiesInstance(); + assertNotNull(gradleProjectProperties.getJarPluginName()); + } + + @Test + public void testGetTempProvider() { + setupGradleProjectPropertiesInstance(); + assertNotNull(gradleProjectProperties.getTempDirectoryProvider()); } @Test public void testGetDependencies() throws URISyntaxException { + setupGradleProjectPropertiesInstance(); assertThat(gradleProjectProperties.getDependencies()) .containsExactly( getResource("gradle/application/dependencies/library.jarC.jar"), diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibExtensionTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibExtensionTest.java index 440ae177792..73685e0f7cd 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibExtensionTest.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibExtensionTest.java @@ -32,6 +32,7 @@ import java.util.HashSet; import java.util.List; import java.util.Properties; +import java.util.stream.Collectors; import org.gradle.api.Project; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; @@ -418,15 +419,27 @@ public void testSkaffold() { }); }); Path root = fakeProject.getRootDir().toPath(); - assertThat(testJibExtension.getSkaffold().getSync().getExcludes()) + assertThat( + testJibExtension.getSkaffold().getSync().getExcludes().getFiles().stream() + .map(File::toPath) + .collect(Collectors.toSet())) .containsExactly( root.resolve("sync1").toAbsolutePath(), root.resolve("sync2").toAbsolutePath()); - assertThat(testJibExtension.getSkaffold().getWatch().getBuildIncludes()) + assertThat( + testJibExtension.getSkaffold().getWatch().getBuildIncludes().getFiles().stream() + .map(File::toPath) + .collect(Collectors.toSet())) .containsExactly( root.resolve("watch1").toAbsolutePath(), root.resolve("watch2").toAbsolutePath()); - assertThat(testJibExtension.getSkaffold().getWatch().getIncludes()) + assertThat( + testJibExtension.getSkaffold().getWatch().getIncludes().getFiles().stream() + .map(File::toPath) + .collect(Collectors.toSet())) .containsExactly(root.resolve("watch3").toAbsolutePath()); - assertThat(testJibExtension.getSkaffold().getWatch().getExcludes()) + assertThat( + testJibExtension.getSkaffold().getWatch().getExcludes().getFiles().stream() + .map(File::toPath) + .collect(Collectors.toSet())) .containsExactly(root.resolve("watch4").toAbsolutePath()); } diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java index fe2829d0dd5..01f1f13457a 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/JibPluginTest.java @@ -203,8 +203,10 @@ public void testSpringBootJarProject_nonPackagedMode() { createProject("java", "org.springframework.boot", "com.google.cloud.tools.jib"); Jar jar = (Jar) project.getTasks().getByPath(":jar"); + jar.setEnabled(false); // Spring boot >2.5.0 no longer sets this as disabled by default assertThat(jar.getEnabled()).isFalse(); - assertThat(jar.getArchiveClassifier().get()).isEmpty(); + assertThat(jar.getArchiveClassifier().get()) + .isEqualTo("plain"); // >2.5.0 generates "plain" instead of empty } @Test @@ -216,7 +218,7 @@ public void testSpringBootJarProject_packagedMode() { Jar jar = (Jar) project.getTasks().getByPath(":jar"); assertThat(jar.getEnabled()).isTrue(); - assertThat(jar.getArchiveClassifier().get()).isEqualTo("original"); + assertThat(jar.getArchiveClassifier().get()).isEqualTo("plain"); } @Test @@ -244,7 +246,7 @@ public void testSpringBootJarProject_packagedMode_bootJarClassifierSet() { Jar jar = (Jar) project.getTasks().getByPath(":jar"); assertThat(jar.getEnabled()).isTrue(); - assertThat(jar.getArchiveClassifier().get()).isEmpty(); + assertThat(jar.getArchiveClassifier().get()).isEqualTo("plain"); } @Test @@ -253,7 +255,14 @@ public void testSpringBootJarProject_packagedMode_jarEnabled() { createProject("java", "org.springframework.boot", "com.google.cloud.tools.jib"); JibExtension jibExtension = (JibExtension) project.getExtensions().getByName("jib"); jibExtension.setContainerizingMode("packaged"); - project.getTasks().named("jar").configure(task -> task.setEnabled(true)); + project + .getTasks() + .named("jar") + .configure( + task -> { + task.setEnabled(true); + ((Jar) task).getArchiveClassifier().set(""); // pre spring boot 2.5.0 behaviour + }); TaskContainer tasks = project.getTasks(); Exception exception = assertThrows(GradleException.class, () -> tasks.getByPath(":jar")); @@ -293,7 +302,7 @@ public void testSpringBootJarProject_packagedMode_jarEnabledAndBootJarClassifier Jar jar = (Jar) project.getTasks().getByPath(":jar"); assertThat(jar.getEnabled()).isTrue(); - assertThat(jar.getArchiveClassifier().get()).isEmpty(); + assertThat(jar.getArchiveClassifier().get()).isEqualTo("plain"); } @Test @@ -308,7 +317,7 @@ public void testSpringBootJarProject_packagedMode_jarEnabledAndBootJarDisabled() Jar jar = (Jar) project.getTasks().getByPath(":jar"); assertThat(jar.getEnabled()).isTrue(); assertThat(project.getTasks().getByPath(":bootJar").getEnabled()).isFalse(); - assertThat(jar.getArchiveClassifier().get()).isEmpty(); + assertThat(jar.getArchiveClassifier().get()).isEqualTo("plain"); } @Test diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java index 3df3a861543..4eec8aa2b40 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java @@ -48,7 +48,7 @@ public class FilesTaskV2Test { @ClassRule public static final TestProject platformProject = - new TestProject("platform").withGradleVersion("5.2"); + new TestProject("platform").withGradleVersion("8.4"); /** * Verifies that the files task succeeded and returns the list of paths it prints out. @@ -60,7 +60,8 @@ public class FilesTaskV2Test { private static String verifyTaskSuccess(TestProject project, @Nullable String moduleName) { String taskName = ":" + (moduleName == null ? "" : moduleName + ":") + JibPlugin.SKAFFOLD_FILES_TASK_V2_NAME; - BuildResult buildResult = project.build(taskName, "-q", "-D_TARGET_IMAGE=ignored"); + BuildResult buildResult = + project.build(taskName, "-q", "-D_TARGET_IMAGE=ignored", "--stacktrace"); BuildTask jibTask = buildResult.task(taskName); Assert.assertNotNull(jibTask); Assert.assertEquals(TaskOutcome.SUCCESS, jibTask.getOutcome()); diff --git a/jib-maven-plugin-extension-api/build.gradle b/jib-maven-plugin-extension-api/build.gradle index aa4b6ce45f3..9c36739c870 100644 --- a/jib-maven-plugin-extension-api/build.gradle +++ b/jib-maven-plugin-extension-api/build.gradle @@ -44,7 +44,7 @@ publishing { release { tagTemplate = 'v$version-maven-extension' git { - requireBranch = /^maven-extension-release-v\d+.*$/ //regex + requireBranch.set(/^maven-extension-release-v\d+.*$/) //regex } } /* RELEASE */ diff --git a/jib-maven-plugin/build.gradle b/jib-maven-plugin/build.gradle index f8ead158cd3..d8560270877 100644 --- a/jib-maven-plugin/build.gradle +++ b/jib-maven-plugin/build.gradle @@ -71,7 +71,7 @@ release { 'com.google.cloud.tools:jib-plugins-common', ] git { - requireBranch = /^maven-release-v\d+.*$/ //regex + requireBranch.set(/^maven-release-v\d+.*$/) //regex } } /* RELEASE */ diff --git a/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildDockerMojoIntegrationTest.java b/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildDockerMojoIntegrationTest.java index 7d3be1d8c51..ce7225962bf 100644 --- a/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildDockerMojoIntegrationTest.java +++ b/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildDockerMojoIntegrationTest.java @@ -72,7 +72,6 @@ private static String buildToDockerDaemonAndRun(TestProject project, String imag .run(); String dockerInspectLabels = new Command("docker", "inspect", "-f", "'{{json .Config.Labels}}'", imageReference).run(); - String history = new Command("docker", "history", imageReference).run(); MatcherAssert.assertThat( dockerInspectVolumes, CoreMatchers.containsString("\"/var/log\":{},\"/var/log2\":{}")); diff --git a/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildImageMojoIntegrationTest.java b/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildImageMojoIntegrationTest.java index 52675002c20..93530a71477 100644 --- a/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildImageMojoIntegrationTest.java +++ b/jib-maven-plugin/src/integration-test/java/com/google/cloud/tools/jib/maven/BuildImageMojoIntegrationTest.java @@ -69,7 +69,7 @@ public class BuildImageMojoIntegrationTest { @ClassRule public static final LocalRegistry localRegistry = - new LocalRegistry(5000, "testuser", "testpassword"); + new LocalRegistry(5001, "testuser", "testpassword"); private static final String dockerHost = System.getenv("DOCKER_IP") != null ? System.getenv("DOCKER_IP") : "localhost"; @@ -567,7 +567,7 @@ public void testExecute_defaultTarget() throws IOException { @Test public void testExecute_complex() throws IOException, InterruptedException, VerificationException, DigestException { - String targetImage = dockerHost + ":5000/compleximage:maven" + System.nanoTime(); + String targetImage = dockerHost + ":5001/compleximage:maven" + System.nanoTime(); Instant before = Instant.now(); String output = buildAndRunComplex(targetImage, "pom-complex.xml"); assertThat(output) @@ -594,7 +594,7 @@ public void testExecute_complex() @Test public void testExecute_timestampCustom() throws IOException, InterruptedException, VerificationException { - String targetImage = dockerHost + ":5000/simpleimage:maven" + System.nanoTime(); + String targetImage = dockerHost + ":5001/simpleimage:maven" + System.nanoTime(); String pom = "pom-timestamps-custom.xml"; assertThat(buildAndRunComplex(targetImage, pom)) .isEqualTo( @@ -607,7 +607,7 @@ public void testExecute_timestampCustom() @Test public void testExecute_complex_sameFromAndToRegistry() throws IOException, InterruptedException, VerificationException { - String targetImage = dockerHost + ":5000/compleximage:maven" + System.nanoTime(); + String targetImage = dockerHost + ":5001/compleximage:maven" + System.nanoTime(); assertThat(buildAndRunComplex(targetImage, "pom-complex.xml")) .isEqualTo( "Hello, world. An argument.\n1970-01-01T00:00:01Z\nrwxr-xr-x\nrwxrwxrwx\nfoo\ncat\n" @@ -619,7 +619,7 @@ public void testExecute_complex_sameFromAndToRegistry() @Test public void testExecute_complexProperties() throws InterruptedException, VerificationException, IOException { - String targetImage = dockerHost + ":5000/compleximage:maven" + System.nanoTime(); + String targetImage = dockerHost + ":5001/compleximage:maven" + System.nanoTime(); assertThat(buildAndRunComplex(targetImage, "pom-complex-properties.xml")) .isEqualTo( "Hello, world. An argument.\n1970-01-01T00:00:01Z\nrwxr-xr-x\nrwxrwxrwx\nfoo\ncat\n" @@ -640,11 +640,11 @@ public void testExecute_jibContainerizeSkips() throws VerificationException, IOE @Test public void testExecute_jibRequireVersion_ok() throws VerificationException, IOException { - String targetImage = dockerHost + ":5000/simpleimage:maven" + System.nanoTime(); + String targetImage = dockerHost + ":5001/simpleimage:maven" + System.nanoTime(); Verifier verifier = new Verifier(simpleTestProject.getProjectRoot().toString()); verifier.setSystemProperty("_TARGET_IMAGE", targetImage); - // properties required to push to :5000 for plain pom.xml + // properties required to push to :5001 for plain pom.xml verifier.setSystemProperty("jib.to.auth.username", "testuser"); verifier.setSystemProperty("jib.to.auth.password", "testpassword"); verifier.setSystemProperty("sendCredentialsOverHttp", "true"); @@ -714,7 +714,7 @@ public void testExecute_springBootPackaged() @Test public void testExecute_multiPlatformBuild() throws IOException, VerificationException, RegistryException { - String targetImage = dockerHost + ":5000/multiplatform:maven" + System.nanoTime(); + String targetImage = dockerHost + ":5001/multiplatform:maven" + System.nanoTime(); Verifier verifier = new Verifier(simpleTestProject.getProjectRoot().toString()); verifier.setSystemProperty("_TARGET_IMAGE", targetImage); @@ -732,7 +732,7 @@ public void testExecute_multiPlatformBuild() FailoverHttpClient httpClient = new FailoverHttpClient(true, true, ignored -> {}); RegistryClient registryClient = RegistryClient.factory( - EventHandlers.NONE, dockerHost + ":5000", "multiplatform", httpClient) + EventHandlers.NONE, dockerHost + ":5001", "multiplatform", httpClient) .setCredential(Credential.from("testuser", "testpassword")) .newRegistryClient(); registryClient.configureBasicAuth(); diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/MavenProjectProperties.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/MavenProjectProperties.java index 7b457951c6a..edaa2e044e2 100644 --- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/MavenProjectProperties.java +++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/MavenProjectProperties.java @@ -597,7 +597,8 @@ Optional getSpringBootRepackageConfiguration() { @Override public JibContainerBuilder runPluginExtensions( List extensionConfigs, - JibContainerBuilder jibContainerBuilder) + JibContainerBuilder jibContainerBuilder, + Optional unusedForMaven) throws JibPluginExtensionException { if (extensionConfigs.isEmpty()) { log(LogEvent.debug("No Jib plugin extensions configured to load")); diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/skaffold/SkaffoldConfiguration.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/skaffold/SkaffoldConfiguration.java index f02572253f7..67d998422ae 100644 --- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/skaffold/SkaffoldConfiguration.java +++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/skaffold/SkaffoldConfiguration.java @@ -36,10 +36,7 @@ public static class Sync { @Parameter List excludes = Collections.emptyList(); } - /** - * Watch is unused, but left here to define how to parse it. See {@link - * FilesMojoV2#collectWatchParameters} - */ + /** Watch is unused, but left here to define how to parse it. */ @Parameter Watch watch = new Watch(); @Parameter Sync sync = new Sync(); diff --git a/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/MavenProjectPropertiesTest.java b/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/MavenProjectPropertiesTest.java index 5bbceaf3b9c..81513181744 100644 --- a/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/MavenProjectPropertiesTest.java +++ b/jib-maven-plugin/src/test/java/com/google/cloud/tools/jib/maven/MavenProjectPropertiesTest.java @@ -576,6 +576,9 @@ public void testCreateContainerBuilder_noErrorIfWebInfLibDoesNotExist() @Test public void testCreateContainerBuilder_exceptionMessageHasPackageSuggestionIfProjectIsWar() throws IOException { + when(mockBuild.getDirectory()).thenReturn(Paths.get("/foo/bar").toString()); + when(mockBuild.getFinalName()).thenReturn("helloworld-1"); + String expectedMessage = "Obtaining project build output files failed; make sure you have " + "packaged your project before trying to build the image. (Did you accidentally run \"mvn clean " diff --git a/jib-maven-plugin/src/test/resources/maven/projects/war_servlet25/pom-tomcat.xml b/jib-maven-plugin/src/test/resources/maven/projects/war_servlet25/pom-tomcat.xml index dc65ff9dea8..bedec4d6712 100644 --- a/jib-maven-plugin/src/test/resources/maven/projects/war_servlet25/pom-tomcat.xml +++ b/jib-maven-plugin/src/test/resources/maven/projects/war_servlet25/pom-tomcat.xml @@ -30,6 +30,11 @@ + + org.apache.maven.plugins + maven-war-plugin + 3.4.0 + org.apache.maven.plugins maven-compiler-plugin diff --git a/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/ProjectProperties.java b/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/ProjectProperties.java index e8a0516226b..bfcf30f6804 100644 --- a/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/ProjectProperties.java +++ b/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/ProjectProperties.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.List; +import java.util.Optional; import javax.annotation.Nullable; /** Project property methods that require maven/gradle-specific implementations. */ @@ -92,6 +93,15 @@ JibContainerBuilder createJibContainerBuilder( JibContainerBuilder runPluginExtensions( List extensionConfigs, - JibContainerBuilder jibContainerBuilder) + JibContainerBuilder jibContainerBuilder, + Optional project) throws JibPluginExtensionException; + + default JibContainerBuilder runPluginExtensions( + List extensionConfigs, + JibContainerBuilder jibContainerBuilder) + throws JibPluginExtensionException { + return runPluginExtensions( + extensionConfigs, jibContainerBuilder, Optional.empty()); // for maven + } } diff --git a/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/SkaffoldFilesOutput.java b/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/SkaffoldFilesOutput.java index 33594d3648e..6c955d7b509 100644 --- a/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/SkaffoldFilesOutput.java +++ b/jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/SkaffoldFilesOutput.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.annotations.VisibleForTesting; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Path; @@ -97,6 +98,15 @@ public void addBuild(Path build) { skaffoldFilesTemplate.build.add(build.toString()); } + /** + * Adds a build file/directory. + * + * @param build the path to the file/directory + */ + public void addBuild(File build) { + addBuild(build.toPath()); + } + /** * Adds an input file/directory. * @@ -106,6 +116,15 @@ public void addInput(Path inputFile) { skaffoldFilesTemplate.inputs.add(inputFile.toString()); } + /** + * Adds an input file/directory. + * + * @param inputFile the path to the file/directory + */ + public void addInput(File inputFile) { + addInput(inputFile.toPath()); + } + /** * Adds an ignored file/directory. * @@ -115,6 +134,15 @@ public void addIgnore(Path ignoreFile) { skaffoldFilesTemplate.ignore.add(ignoreFile.toString()); } + /** + * Adds an ignored file/directory. + * + * @param ignoreFile the path to the file/directory + */ + public void addIgnore(File ignoreFile) { + addIgnore(ignoreFile.toPath()); + } + @VisibleForTesting public List getBuild() { return skaffoldFilesTemplate.build; diff --git a/jib-plugins-common/src/test/java/com/google/cloud/tools/jib/plugins/common/globalconfig/GlobalConfigTest.java b/jib-plugins-common/src/test/java/com/google/cloud/tools/jib/plugins/common/globalconfig/GlobalConfigTest.java index e3247c9f1d7..b772766bc5f 100644 --- a/jib-plugins-common/src/test/java/com/google/cloud/tools/jib/plugins/common/globalconfig/GlobalConfigTest.java +++ b/jib-plugins-common/src/test/java/com/google/cloud/tools/jib/plugins/common/globalconfig/GlobalConfigTest.java @@ -74,7 +74,7 @@ public void testReadConfig() throws IOException, InvalidGlobalConfigException { String json = "{\"disableUpdateCheck\":true, \"registryMirrors\":[" + "{ \"registry\": \"registry-1.docker.io\"," - + " \"mirrors\": [\"mirror.gcr.io\", \"localhost:5000\"] }," + + " \"mirrors\": [\"mirror.gcr.io\", \"localhost:5001\"] }," + "{ \"registry\": \"another.registry\", \"mirrors\": [\"another.mirror\"] }" + "]}"; Files.write(configDir.resolve("config.json"), json.getBytes(StandardCharsets.UTF_8)); @@ -86,7 +86,7 @@ public void testReadConfig() throws IOException, InvalidGlobalConfigException { "registry-1.docker.io", "mirror.gcr.io", "registry-1.docker.io", - "localhost:5000", + "localhost:5001", "another.registry", "another.mirror"); } diff --git a/jib-plugins-extension-common/build.gradle b/jib-plugins-extension-common/build.gradle index 5151d6a8915..9107876cdf6 100644 --- a/jib-plugins-extension-common/build.gradle +++ b/jib-plugins-extension-common/build.gradle @@ -38,7 +38,7 @@ publishing { release { tagTemplate = 'v$version-extension-common' git { - requireBranch = /^extension-common-release-v\d+.*$/ //regex + requireBranch.set(/^extension-common-release-v\d+.*$/) //regex } } /* RELEASE */