diff --git a/build.gradle b/build.gradle index a8ec1fe5529..8554a37c349 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' @@ -51,6 +51,7 @@ project.ext.dependencyStrings = [ MAVEN_TESTING_HARNESS: 'org.apache.maven.plugin-testing:maven-plugin-testing-harness:3.3.0', MAVEN_VERIFIER: 'org.apache.maven.shared:maven-verifier:1.8.0', MOCKITO_CORE: 'org.mockito:mockito-core:4.11.0', + MOCKITO_INLINE: 'org.mockito:mockito-inline:4.11.0', SISU_PLEXUS: 'org.eclipse.sisu:org.eclipse.sisu.plexus:0.3.5', SLF4J_API: 'org.slf4j:slf4j-api:2.0.7', SLF4J_SIMPLE: 'org.slf4j:slf4j-simple:2.0.9', @@ -60,12 +61,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 +85,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 +153,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 +168,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 +187,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 +196,13 @@ subprojects { showStandardStreams = true exceptionFormat = 'full' } + doFirst { + if (JavaVersion.current().getMajorVersion().toInteger() >= 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 +226,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 +271,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 87b738cbd05..7f93135c49b 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ 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 490fda8577d..c1962a79e29 100644 Binary files a/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.jar and b/jib-cli/src/integration-test/resources/jarTest/spring-boot/gradle/wrapper/gradle-wrapper.jar differ 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 490fda8577d..c1962a79e29 100644 Binary files a/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.jar and b/jib-cli/src/integration-test/resources/warTest/gradle/wrapper/gradle-wrapper.jar differ 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/ReproducibleImageTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/api/ReproducibleImageTest.java index 1c194b2198d..75cd9906bca 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 @@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; import com.google.common.io.CharStreams; +import com.google.gson.internal.JavaVersion; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; @@ -100,21 +101,39 @@ public void testTarballStructure() throws IOException { } } - assertThat(actual) - .containsExactly( - "c46572ef74f58d95e44dd36c1fbdfebd3752e8b56a794a13c11cfed35a1a6e1c.tar.gz", - "6d2763b0f3940d324ea6b55386429e5b173899608abf7d1bff62e25dd2e4dcea.tar.gz", - "530c1954a2b087d0b989895ea56435c9dc739a973f2d2b6cb9bb98e55bbea7ac.tar.gz", - "config.json", - "manifest.json") - .inOrder(); + if (JavaVersion.getMajorJavaVersion() < 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\"]}]"; + (JavaVersion.getMajorJavaVersion() < 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/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..dc23b3e5a7e 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 @@ -29,6 +29,7 @@ import com.google.cloud.tools.jib.json.JsonTemplateMapper; import com.google.common.io.Resources; import com.google.common.util.concurrent.MoreExecutors; +import com.google.gson.internal.JavaVersion; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; @@ -93,17 +94,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", + JavaVersion.getMajorJavaVersion() < 16 + ? "0011328ac5dfe3dde40c7c5e0e00c98d1833a3aeae2bfb668cf9eb965c229c7f" + : "bdc94fe3bba352809859ca87c846872ae2c1157596631e72d7d73e46fae86101", result.layers.get(0).get().getBlobDescriptor().getDigest().getHash()); Assert.assertEquals( "f1ac3015bcbf0ada4750d728626eb10f0f585199e2b667dcd79e49f0e926178e", result.layers.get(1).get().getDiffId().getHash()); Assert.assertEquals( - "c10ef24a5cef5092bbcb5a5666721cff7b86ce978c203a958d1fc86ee6c19f94", + JavaVersion.getMajorJavaVersion() < 16 + ? "c10ef24a5cef5092bbcb5a5666721cff7b86ce978c203a958d1fc86ee6c19f94" + : "073d615d78a940951cfe91b1feee2da3c5d21f7df48539921c26aecd23185d5f", result.layers.get(1).get().getBlobDescriptor().getDigest().getHash()); Assert.assertEquals(2, result.configurationTemplate.getLayerCount()); } 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..7c5f9b9f6a6 100644 --- a/jib-gradle-plugin/build.gradle +++ b/jib-gradle-plugin/build.gradle @@ -36,6 +36,7 @@ dependencies { testImplementation dependencyStrings.TRUTH testImplementation dependencyStrings.TRUTH8 testImplementation dependencyStrings.MOCKITO_CORE + testImplementation dependencyStrings.MOCKITO_INLINE testImplementation dependencyStrings.SLF4J_API testImplementation dependencyStrings.SYSTEM_RULES @@ -45,7 +46,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 +58,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 +72,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/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..9b1528671f1 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..1a5616afd3f 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 @@ -67,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,6 +99,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 +113,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 +189,7 @@ public void buildDocker() + ex.getPath(), ex); } finally { - tempDirectoryProvider.close(); - TaskCommon.finishUpdateChecker(projectProperties, updateCheckFuture); + TaskCommon.finishUpdateChecker(this.projectProperties, updateCheckFuture); projectProperties.waitForLoggingThread(); } } @@ -196,6 +197,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/BuildDockerTaskTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildDockerTaskTest.java new file mode 100644 index 00000000000..817636350c4 --- /dev/null +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildDockerTaskTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2019 Google LLC. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.cloud.tools.jib.gradle; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +import com.google.cloud.tools.jib.docker.CliDockerClient; +import com.google.cloud.tools.jib.plugins.common.JibBuildRunner; +import com.google.cloud.tools.jib.plugins.common.PluginConfigurationProcessor; +import org.gradle.api.Project; +import org.gradle.api.provider.Property; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** Tests for {@link TaskCommon}. */ +@RunWith(MockitoJUnitRunner.class) +public class BuildDockerTaskTest { + + @Mock JibExtension mockJibExtension; + + @Mock GradleProjectProperties mockProjectProperties; + @Mock private TargetImageParameters mockTargetImage; + @Mock private JibBuildRunner mockJibBuildRunner; + @Mock private DockerClientParameters mockDockerClientParams; + + @Test + public void testBuildDockerTask() { + Project project = ProjectBuilder.builder().build(); + BuildDockerTask task = project.getTasks().register("test", BuildDockerTask.class).get(); + assertNull(task.getJib()); + assertNull(task.getProjectProperties()); + + Property property = project.getObjects().property(String.class); + property.set("test"); + + try (MockedStatic gpp = + Mockito.mockStatic(GradleProjectProperties.class)) { + gpp.when(() -> GradleProjectProperties.getForProject(any(), any(), any(), anyString())) + .thenReturn(mockProjectProperties); + when(mockJibExtension.getConfigurationName()).thenReturn(property); + // when(mockTargetImage.getImage()).thenReturn("test"); + when(mockJibExtension.getDockerClient()).thenReturn(mockDockerClientParams); + when(mockDockerClientParams.getExecutablePath()).thenReturn(null); + + try (MockedStatic cdc = Mockito.mockStatic(CliDockerClient.class)) { + cdc.when(() -> CliDockerClient.isDefaultDockerInstalled()).thenReturn(true); + + task.setJibExtension(mockJibExtension); + assertNotNull(task.getJib()); + assertNotNull(task.getProjectProperties()); + + try (MockedStatic pcp = + Mockito.mockStatic(PluginConfigurationProcessor.class)) { + pcp.when( + () -> + PluginConfigurationProcessor.createJibBuildRunnerForDockerDaemonImage( + any(), any(), any(), any(), any())) + .thenReturn(mockJibBuildRunner); + + try { + task.buildDocker(); + pcp.verify( + () -> + PluginConfigurationProcessor.createJibBuildRunnerForDockerDaemonImage( + any(), any(), any(), any(), any()), + times(1)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } + } +} diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildImageTaskTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildImageTaskTest.java new file mode 100644 index 00000000000..29887f3e817 --- /dev/null +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildImageTaskTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2019 Google LLC. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.cloud.tools.jib.gradle; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +import com.google.cloud.tools.jib.plugins.common.JibBuildRunner; +import com.google.cloud.tools.jib.plugins.common.PluginConfigurationProcessor; +import org.gradle.api.Project; +import org.gradle.api.provider.Property; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** Tests for {@link TaskCommon}. */ +@RunWith(MockitoJUnitRunner.class) +public class BuildImageTaskTest { + + @Mock JibExtension mockJibExtension; + + @Mock GradleProjectProperties mockProjectProperties; + @Mock private TargetImageParameters mockTargetImage; + @Mock private JibBuildRunner mockJibBuildRunner; + + @Test + public void testCoverageGetter() { + Project project = ProjectBuilder.builder().build(); + BuildImageTask task = project.getTasks().register("test", BuildImageTask.class).get(); + assertNull(task.getJib()); + assertNull(task.getProjectProperties()); + + Property property = project.getObjects().property(String.class); + property.set("test"); + + try (MockedStatic gpp = + Mockito.mockStatic(GradleProjectProperties.class)) { + gpp.when(() -> GradleProjectProperties.getForProject(any(), any(), any(), anyString())) + .thenReturn(mockProjectProperties); + when(mockJibExtension.getConfigurationName()).thenReturn(property); + when(mockTargetImage.getImage()).thenReturn("test"); + when(mockJibExtension.getTo()).thenReturn(mockTargetImage); + task.setJibExtension(mockJibExtension); + assertNotNull(task.getJib()); + assertNotNull(task.getProjectProperties()); + + try (MockedStatic pcp = + Mockito.mockStatic(PluginConfigurationProcessor.class)) { + pcp.when( + () -> + PluginConfigurationProcessor.createJibBuildRunnerForRegistryImage( + any(), any(), any(), any(), any())) + .thenReturn(mockJibBuildRunner); + + try { + task.buildImage(); + pcp.verify( + () -> + PluginConfigurationProcessor.createJibBuildRunnerForRegistryImage( + any(), any(), any(), any(), any()), + times(1)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } +} diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildTarTaskTest.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildTarTaskTest.java new file mode 100644 index 00000000000..340dc968331 --- /dev/null +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/BuildTarTaskTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2019 Google LLC. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.cloud.tools.jib.gradle; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +import com.google.cloud.tools.jib.plugins.common.JibBuildRunner; +import com.google.cloud.tools.jib.plugins.common.PluginConfigurationProcessor; +import org.gradle.api.Project; +import org.gradle.api.provider.Property; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** Tests for {@link TaskCommon}. */ +@RunWith(MockitoJUnitRunner.class) +public class BuildTarTaskTest { + + @Mock JibExtension mockJibExtension; + + @Mock GradleProjectProperties mockProjectProperties; + @Mock private TargetImageParameters mockTargetImage; + @Mock private JibBuildRunner mockJibBuildRunner; + + @Test + public void testBuildTarTask() { + Project project = ProjectBuilder.builder().build(); + BuildTarTask task = project.getTasks().register("test", BuildTarTask.class).get(); + assertNull(task.getJib()); + assertNull(task.getProjectProperties()); + + Property property = project.getObjects().property(String.class); + property.set("test"); + + try (MockedStatic gpp = + Mockito.mockStatic(GradleProjectProperties.class)) { + gpp.when(() -> GradleProjectProperties.getForProject(any(), any(), any(), anyString())) + .thenReturn(mockProjectProperties); + when(mockJibExtension.getConfigurationName()).thenReturn(property); + // when(mockTargetImage.getImage()).thenReturn("test"); + // when(mockJibExtension.getTo()).thenReturn(mockTargetImage); + task.setJibExtension(mockJibExtension); + assertNotNull(task.getJib()); + assertNotNull(task.getProjectProperties()); + + try (MockedStatic pcp = + Mockito.mockStatic(PluginConfigurationProcessor.class)) { + pcp.when( + () -> + PluginConfigurationProcessor.createJibBuildRunnerForTarImage( + any(), any(), any(), any(), any())) + .thenReturn(mockJibBuildRunner); + + try { + task.buildTar(); + pcp.verify( + () -> + PluginConfigurationProcessor.createJibBuildRunnerForTarImage( + any(), any(), any(), any(), any()), + times(1)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } +} 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/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..b124ef5ca2d 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; @@ -63,11 +64,11 @@ public class SkaffoldFilesOutput { @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) private static class SkaffoldFilesTemplate { - private final List build = new ArrayList<>(); + @VisibleForTesting protected final List build = new ArrayList<>(); - private final List inputs = new ArrayList<>(); + @VisibleForTesting protected final List inputs = new ArrayList<>(); - private final List ignore = new ArrayList<>(); + @VisibleForTesting protected final List ignore = new ArrayList<>(); } private final SkaffoldFilesTemplate skaffoldFilesTemplate; @@ -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/SkaffoldFilesOutputTest.java b/jib-plugins-common/src/test/java/com/google/cloud/tools/jib/plugins/common/SkaffoldFilesOutputTest.java index e25d2070f2d..4707c71b65a 100644 --- a/jib-plugins-common/src/test/java/com/google/cloud/tools/jib/plugins/common/SkaffoldFilesOutputTest.java +++ b/jib-plugins-common/src/test/java/com/google/cloud/tools/jib/plugins/common/SkaffoldFilesOutputTest.java @@ -17,6 +17,7 @@ package com.google.cloud.tools.jib.plugins.common; import com.google.common.collect.ImmutableList; +import java.io.File; import java.io.IOException; import java.nio.file.Paths; import org.junit.Assert; @@ -55,4 +56,19 @@ public void testConstructor_json() throws IOException { Assert.assertEquals(ImmutableList.of("input1", "input2"), skaffoldFilesOutput.getInputs()); Assert.assertEquals(ImmutableList.of("ignore1", "ignore2"), skaffoldFilesOutput.getIgnore()); } + + @Test + public void testCoverage() throws IOException { + SkaffoldFilesOutput skaffoldFilesOutput = new SkaffoldFilesOutput(); + File f = File.createTempFile("temp", "jib"); + + skaffoldFilesOutput.addBuild(f); + skaffoldFilesOutput.addInput(f); + skaffoldFilesOutput.addIgnore(f); + + Assert.assertEquals(f.getPath(), skaffoldFilesOutput.getIgnore().get(0)); + Assert.assertEquals(f.getPath(), skaffoldFilesOutput.getBuild().get(0)); + Assert.assertEquals(f.getPath(), skaffoldFilesOutput.getInputs().get(0)); + f.delete(); + } } 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 */