diff --git a/.circleci/config.yml b/.circleci/config.yml index e8a658754..270148055 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ defaults: &defaults working_directory: ~/shadow docker: - - image: circleci/openjdk:11-jdk + - image: cimg/openjdk:17.0 environment: - TERM: "dumb" - GRADLE_OPTS: "-Xmx1024m" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..7e3c475f2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +* text=auto eol=lf + +gradlew binary +gradlew.bat binary \ No newline at end of file diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 405a2b306..e18701c6e 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -1,10 +1,20 @@ name: "Validate Gradle Wrapper" -on: [push, pull_request] +on: + push: + paths: + - 'gradlew' + - 'gradlew.bat' + - 'gradle/wrapper/' + pull_request: + paths: + - 'gradlew' + - 'gradlew.bat' + - 'gradle/wrapper/' jobs: validation: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: gradle/wrapper-validation-action@v1 diff --git a/.gitignore b/.gitignore index c7be03627..646e97241 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ yarn-error.log src/docs/.vuepress/dist/ .DS_Store jd-gui.cfg +bin/ +.vscode/ diff --git a/README.md b/README.md index 5518409b9..6056f4f62 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,9 @@ Read the [User Guide](https://imperceptiblethoughts.com/shadow/)! | Gradle Version | Shadow Version | |----------------|----------------| -| 5.x | 5.2.0 - 6.0.0 | -| 6.x | 5.2.0 - 6.1.0 | -| 7.x | 7.0.0+ | +| 5.x | 5.2.0 - 6.0.0 | +| 6.x | 5.2.0 - 6.1.0 | +| 7.x | 7.0.0+ | +| 8.x | 8.0.0+ | **NOTE**: Shadow v5.+ is compatible with Gradle 5.x - 6.x and Java 7 - 15 _only_, v6.1.0+ requires Java 8+. diff --git a/build.gradle b/build.gradle index c538f5ccd..b98d8a9b0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,16 +1,5 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation - -buildscript { - repositories { - gradlePluginPortal() - mavenCentral() - } - dependencies { - classpath "com.gradle.publish:plugin-publish-plugin:0.16.0" - classpath 'org.ajoberstar:gradle-git-publish:3.0.0' - classpath "com.github.node-gradle:gradle-node-plugin:3.1.1" - } -} +import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id 'groovy' @@ -18,6 +7,9 @@ plugins { id 'idea' id 'java-gradle-plugin' id 'signing' + id 'com.gradle.plugin-publish' version '1.1.0' + id 'org.ajoberstar.git-publish' version '4.1.1' + id 'com.github.node-gradle.node' version '3.5.1' } // Remove the gradleApi so it isn't merged into the jar file. @@ -25,28 +17,7 @@ configurations.named(JavaPlugin.API_CONFIGURATION_NAME) { dependencies.remove(project.dependencies.gradleApi()) } -gradlePlugin { - automatedPublishing = false -} - -apply plugin: 'com.github.johnrengelman.shadow' - -buildScan { - termsOfServiceUrl = 'https://gradle.com/terms-of-service' - termsOfServiceAgree = 'yes' - if (System.env.CI == 'true') { - tag 'CI' - if (System.env.CIRCLE_TAG) { - link 'VCS', "https://github.com/johnrengelman/shadow/tree/${System.env.CIRCLE_TAG}" - } else { - link 'VCS', "https://github.com/johnrengelman/shadow/tree/${System.env.CIRCLE_BRANCH}" - } - link 'VCS Commit', "https://github.com/johnrengelman/shadow/commit/${System.env.CIRCLE_SHA1}" - if (System.env.CI_PULL_REQUEST) { - link 'Pull Request', "${System.env.CI_PULL_REQUEST}" - } - } -} +apply plugin: ShadowPlugin apply from: file('gradle/docs.gradle') apply from: file('gradle/publish.gradle') @@ -79,7 +50,7 @@ jar { jar.enabled = false shadowJar { - classifier = '' + archiveClassifier = '' } idea { @@ -88,32 +59,34 @@ idea { } } +tasks.named('ideaModule') { + notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/13480") +} + sourceCompatibility = '1.8' targetCompatibility = '1.8' -task downloadDependencies(type: Exec) { +tasks.register('downloadDependencies', Exec) { dependsOn configurations.testRuntimeClasspath commandLine 'echo', 'Downloaded all dependencies' } -tasks.build.dependsOn tasks.shadowJar +tasks.named('build') { dependsOn tasks.named('shadowJar') } -project.tasks.withType(JavaCompile) { +tasks.withType(JavaCompile).configureEach { // This will be the default in Gradle 5.0 if (!options.compilerArgs.contains("-processor")) { options.compilerArgs << '-proc:none' } } -project.tasks.withType(GroovyCompile) { +tasks.withType(GroovyCompile).configureEach { // This will be the default in Gradle 5.0 if (!options.compilerArgs.contains("-processor")) { options.compilerArgs << '-proc:none' } } -task relocateShadowJar(type: ConfigureShadowRelocation) { - target = tasks.shadowJar +tasks.named('shadowJar', ShadowJar) { + enableRelocation true } - -tasks.shadowJar.dependsOn tasks.relocateShadowJar diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 395af0a91..689ee9bcc 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -53,14 +53,14 @@ sourceSets { } } -project.tasks.withType(JavaCompile) { +tasks.withType(JavaCompile).configureEach { // This will be the default in Gradle 5.0 if (!options.compilerArgs.contains("-processor")) { options.compilerArgs << '-proc:none' } } -project.tasks.withType(GroovyCompile) { +tasks.withType(GroovyCompile).configureEach { // This will be the default in Gradle 5.0 if (!options.compilerArgs.contains("-processor")) { options.compilerArgs << '-proc:none' diff --git a/gradle.properties b/gradle.properties index 40ca366b2..c4cb586e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,4 @@ +org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=2g org.gradle.parallel=true -org.gradle.daemon=true +org.gradle.caching=true +org.gradle.unsafe.configuration-cache=true \ No newline at end of file diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 48746f644..46d57b906 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -4,24 +4,24 @@ dependencies { shadow gradleApi() shadow 'org.codehaus.groovy:groovy-backports-compat23:3.0.8' - implementation 'org.jdom:jdom2:2.0.6' - implementation 'org.ow2.asm:asm:9.3' - implementation 'org.ow2.asm:asm-commons:9.3' + implementation 'org.jdom:jdom2:2.0.6.1' + implementation 'org.ow2.asm:asm:9.4' + implementation 'org.ow2.asm:asm-commons:9.4' implementation 'commons-io:commons-io:2.11.0' - implementation 'org.apache.ant:ant:1.10.11' - implementation 'org.codehaus.plexus:plexus-utils:3.4.1' - implementation "org.apache.logging.log4j:log4j-core:2.17.1" - implementation('org.vafer:jdependency:2.7.0') { + implementation 'org.apache.ant:ant:1.10.13' + implementation 'org.codehaus.plexus:plexus-utils:3.5.0' + implementation "org.apache.logging.log4j:log4j-core:2.20.0" + implementation('org.vafer:jdependency:2.8.0') { exclude group: 'org.ow2.asm' } - testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') { + testImplementation('org.spockframework:spock-core:2.3-groovy-3.0') { exclude group: 'org.codehaus.groovy' } - testImplementation 'org.spockframework:spock-junit4:2.0-groovy-3.0' + testImplementation 'org.spockframework:spock-junit4:2.3-groovy-3.0' testImplementation 'xmlunit:xmlunit:1.6' testImplementation 'org.apache.commons:commons-lang3:3.12.0' - testImplementation 'com.google.guava:guava:31.0.1-jre' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' - testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.8.1' + testImplementation 'com.google.guava:guava:31.1-jre' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' + testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.9.2' } diff --git a/gradle/docs.gradle b/gradle/docs.gradle index 1f8150538..10c1eaaff 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -1,7 +1,7 @@ -def javaApiUrl = 'http://docs.oracle.com/javase/1.7.0/docs/api' -def groovyApiUrl = "http://docs.groovy-lang.org/2.4.7/html/gapi/" +def javaApiUrl = 'https://docs.oracle.com/javase/17/docs/api' +def groovyApiUrl = "https://docs.groovy-lang.org/2.4.7/html/gapi/" -tasks.withType(Javadoc) { +tasks.withType(Javadoc).configureEach { classpath += project.configurations.shadow options.links(javaApiUrl, groovyApiUrl) if (JavaVersion.current().java8Compatible) { @@ -9,18 +9,19 @@ tasks.withType(Javadoc) { } } -task javadocJar(type: Jar, dependsOn: javadoc) { +tasks.register('javadocJar', Jar) { + dependsOn javadoc archiveClassifier.set('javadoc') from 'build/docs/javadoc' } -task sourcesJar(type: Jar) { +tasks.register('sourcesJar', Jar) { archiveClassifier.set('sources') from sourceSets.main.allSource } -project.tasks.groovydoc { +tasks.named('groovydoc') { classpath += project.configurations.shadow } -build.dependsOn javadocJar, sourcesJar +tasks.named('build') { dependsOn javadocJar, sourcesJar } diff --git a/gradle/ghPages.gradle b/gradle/ghPages.gradle index 2910f2ef1..fa1526860 100644 --- a/gradle/ghPages.gradle +++ b/gradle/ghPages.gradle @@ -3,7 +3,7 @@ import org.apache.tools.ant.filters.ReplaceTokens apply plugin: 'org.ajoberstar.git-publish' if (project.hasProperty('githubToken')) { - System.setProperty('org.ajoberstar.grgit.auth.username', project.githubToken) + System.setProperty('org.ajoberstar.grgit.auth.username', project.githubToken) } gitPublish { @@ -23,5 +23,5 @@ gitPublish { } } -tasks.gitPublishCopy.dependsOn yarn_build -tasks.gitPublishCopy.dependsOn groovydoc +tasks.named('gitPublishCopy') { dependsOn yarn_build } +tasks.named('gitPublishCopy') { dependsOn groovydoc } diff --git a/gradle/publish.gradle b/gradle/publish.gradle index 4a946ba00..404d76a59 100644 --- a/gradle/publish.gradle +++ b/gradle/publish.gradle @@ -1,101 +1,44 @@ -apply plugin: 'maven-publish' apply plugin: "com.gradle.plugin-publish" group = 'com.github.johnrengelman' -def versionString = file('src/main/resources/shadow-version.txt').text.trim() if (System.env.CIRCLE_TAG && System.env.CIRCLE_TAG =~ /^\d\.\d\.\d$/) { version = System.env.CIRCLE_TAG } else { - version = versionString + version = file('src/main/resources/shadow-version.txt').text.trim() if (!version.endsWith("-SNAPSHOT")) { version = version + "-SNAPSHOT" } } -ext.isSnapshot = version.endsWith("SNAPSHOT") - -def pomConfig = { - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - developers { - developer { - id 'jengelman' - name 'John Engelman' - email 'john.r.engelman@gmail.com' - } - } -} - -publishing { - publications { - plugin(MavenPublication) { - shadow.component(it) - artifact sourcesJar - artifact javadocJar - - pom.withXml { - def root = asNode() - root.appendNode('description', 'Gradle plugin to combine/relocate dependencies in a single Jar.') - root.children().last() + pomConfig - } - } - } -} - -// Workaround for configuring the artifact that publish-plugins uses: https://github.com/JLLeitschuh/ktlint-gradle/blob/master/plugin/build.gradle.kts -// Need to move publishing configuration into afterEvaluate {} -// to override changes done by "com.gradle.plugin-publish" plugin in afterEvaluate {} block -// See PublishPlugin class for details -afterEvaluate { - publishing { - publications { - withType(MavenPublication) { - // Special workaround to publish shadow jar instead of normal one. Name to override peeked here: - // https://github.com/gradle/gradle/blob/master/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/MavenPluginPublishPlugin.java#L73 - if (name == "pluginMaven") { - setArtifacts([ - tasks.shadowJar, - tasks.sourcesJar, - tasks.javadocJar - ]) - } - } - } - } -} - -tasks.whenTaskAdded { +tasks.configureEach { if (name == "publishPluginJar" || name == "generateMetadataFileForPluginMavenPublication") { dependsOn(tasks.named("shadowJar")) } } -pluginBundle { +gradlePlugin { website = 'https://github.com/johnrengelman/shadow' vcsUrl = 'https://github.com/johnrengelman/shadow' - tags = ['onejar', 'shade', 'fatjar', 'uberjar'] plugins { shadowPlugin { id = 'com.github.johnrengelman.shadow' + implementationClass = 'com.github.jengelman.gradle.plugins.shadow.ShadowPlugin' displayName = 'Shadow Plugin' description = "Gradle plugin to create fat/uber JARs, apply file transforms, and relocate packages for applications and libraries. Gradle version of Maven's Shade plugin." + tags.set(['onejar', 'shade', 'fatjar', 'uberjar']) } } } -publishPlugins { task -> +tasks.named('publishPlugins') { doFirst { - if (isSnapshot) { + if (version.endsWith("SNAPSHOT")) { throw new GradleException('Cannot publish SNAPSHOT versions to Plugin Portal!') } } + notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/21283") } signing { @@ -105,12 +48,14 @@ signing { def signingPassword = findProperty("signingPassword") useInMemoryPgpKeys(signingKey, signingPassword) } - required { - gradle.taskGraph.hasTask("artifactoryPublish") - } - sign publishing.publications.plugin + required = gradle.taskGraph.hasTask("artifactoryPublish") + sign(publishing.publications) +} + +tasks.withType(Sign).configureEach { + notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/13470") } -task release() { +tasks.register('release') { dependsOn 'assemble', 'publishPlugins', 'gitPublishPush' } diff --git a/gradle/vuepress.gradle b/gradle/vuepress.gradle index de87a4a16..da01b2f1c 100644 --- a/gradle/vuepress.gradle +++ b/gradle/vuepress.gradle @@ -4,5 +4,7 @@ node { yarnVersion = '1.5.1' } -tasks.yarn_build.inputs.files project.fileTree('src/docs') -tasks.yarn_build.outputs.dir project.file('build/site') \ No newline at end of file +tasks.named('yarn_build') { + inputs.files project.fileTree('src/docs') + outputs.dir project.file('build/site') +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c02..ccebba771 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 f371643ee..fc10b601f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c8..79a61d421 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# 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. @@ -17,67 +17,101 @@ # ############################################################################## -## -## 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"` +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # 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"' # 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 @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 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 @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + 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. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,105 @@ location of your Java installation." 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=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=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" = "true" -o "$msys" = "true" ] ; 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 +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # 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=`expr $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; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +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. +# -# 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" +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 ac1b06f93..6689b85be 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ 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% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :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/renovate.json b/renovate.json new file mode 100644 index 000000000..39a2b6e9a --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base" + ] +} diff --git a/settings.gradle b/settings.gradle index f82018015..afcef171e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,34 @@ +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + } +} + plugins { - id 'com.gradle.enterprise' version '3.1.1' + id 'com.gradle.enterprise' version '3.12.3' } +gradleEnterprise { + buildScan { + termsOfServiceUrl = 'https://gradle.com/terms-of-service' + termsOfServiceAgree = 'yes' + publishAlways() + if (System.env.CI == 'true') { + tag 'CI' + if (System.env.CIRCLE_TAG) { + link 'VCS', "https://github.com/johnrengelman/shadow/tree/${System.env.CIRCLE_TAG}" + } else { + link 'VCS', "https://github.com/johnrengelman/shadow/tree/${System.env.CIRCLE_BRANCH}" + } + link 'VCS Commit', "https://github.com/johnrengelman/shadow/commit/${System.env.CIRCLE_SHA1}" + if (System.env.CI_PULL_REQUEST) { + link 'Pull Request', "${System.env.CI_PULL_REQUEST}" + } + } + } +} + +enableFeaturePreview("STABLE_CONFIGURATION_CACHE") + rootProject.name = 'shadow' \ No newline at end of file diff --git a/src/docs/changes/README.md b/src/docs/changes/README.md index 16434a1b8..971ab3fe5 100644 --- a/src/docs/changes/README.md +++ b/src/docs/changes/README.md @@ -1,30 +1,45 @@ # Change Log + +## v8.1.0 (2023-02-26) + +[Release Notes](https://github.com/johnrengelman/shadow/releases/tag/8.1.0) + +## v8.0.0 (2023-02-24) + +[Release Notes](https://github.com/johnrengelman/shadow/releases/tag/8.0.0) + ## v7.1.3 (unreleased) -* The GroovyExtensionModuleTransformer now also works for Groovy 2.5+. + +- The GroovyExtensionModuleTransformer now also works for Groovy 2.5+. ## v7.1.2 (2021-12-28) -* Upgrade log4j to 2.17.1 due to CVE-2021-45105 and CVE-2021-44832 + +- Upgrade log4j to 2.17.1 due to CVE-2021-45105 and CVE-2021-44832 ## v7.1.1 (2021-12-14) -* Upgrade log4j to 2.16.0 due to CVE-2021-44228 and CVE-2021-45046 + +- Upgrade log4j to 2.16.0 due to CVE-2021-44228 and CVE-2021-45046 ## v7.1.0 (2021-10-04) -* **BREAKING** - The maven coordinates for the plugins have changed as of this version. The proper `group:artifact` is `gradle.plugin.com.github.johnrengelman:shadow` -* [Jeff](https://github.com/mathjeff) - Fix `shadowJar` Out-Of-Date with configuration caching [#708](https://github.com/johnrengelman/shadow/pull/708) -* [Fiouz](https://github.com/Fiouz) - Better support for statically typed languages. This change may require code changes if you are utilizing the Groovy generated getters for properties in some Shadow transformers [#706](https://github.com/johnrengelman/shadow/pull/706) -* [Helder Pereira](https://github.com/helfper) - Various cleanups [#672](https://github.com/johnrengelman/shadow/pull/672), [#700](https://github.com/johnrengelman/shadow/pull/700), [#701](https://github.com/johnrengelman/shadow/pull/701), [#702](https://github.com/johnrengelman/shadow/pull/702) -* [Roberto Perez Alcolea](https://github.com/rpalcolea) - Support JVM Toolchains [#691](https://github.com/johnrengelman/shadow/pull/691) -* [mjulianotq](https://github.com/mjulianotq) - Fix `Project.afterEvaluate` conflicts [#675](https://github.com/johnrengelman/shadow/pull/675) -* [Ilya Muradyan](https://github.com/ileasile) - Fix relocation for `ComponentsXmlResourceTransformer` [#678](https://github.com/johnrengelman/shadow/pull/678) -* [Vaidotas Valuckas](https://github.com/rieske) - Fix `JavaExec.main` deprecation [#686](https://github.com/johnrengelman/shadow/pull/686) -* [Dmitry Vyazelenko](https://github.com/vyazelenko) - Support Java 18 with ASM 9.2 [#698](https://github.com/johnrengelman/shadow/pull/698) -* [Jason](https://github.com/jpenilla) - Support Records with JDependency 2.7.0 [#681](https://github.com/johnrengelman/shadow/pull/681) + +- **BREAKING** - The maven coordinates for the plugins have changed as of this version. The proper `group:artifact` is `gradle.plugin.com.github.johnrengelman:shadow` +- [Jeff](https://github.com/mathjeff) - Fix `shadowJar` Out-Of-Date with configuration caching [#708](https://github.com/johnrengelman/shadow/pull/708) +- [Fiouz](https://github.com/Fiouz) - Better support for statically typed languages. This change may require code changes if you are utilizing the Groovy generated getters for properties in some Shadow transformers [#706](https://github.com/johnrengelman/shadow/pull/706) +- [Helder Pereira](https://github.com/helfper) - Various cleanups [#672](https://github.com/johnrengelman/shadow/pull/672), [#700](https://github.com/johnrengelman/shadow/pull/700), [#701](https://github.com/johnrengelman/shadow/pull/701), [#702](https://github.com/johnrengelman/shadow/pull/702) +- [Roberto Perez Alcolea](https://github.com/rpalcolea) - Support JVM Toolchains [#691](https://github.com/johnrengelman/shadow/pull/691) +- [mjulianotq](https://github.com/mjulianotq) - Fix `Project.afterEvaluate` conflicts [#675](https://github.com/johnrengelman/shadow/pull/675) +- [Ilya Muradyan](https://github.com/ileasile) - Fix relocation for `ComponentsXmlResourceTransformer` [#678](https://github.com/johnrengelman/shadow/pull/678) +- [Vaidotas Valuckas](https://github.com/rieske) - Fix `JavaExec.main` deprecation [#686](https://github.com/johnrengelman/shadow/pull/686) +- [Dmitry Vyazelenko](https://github.com/vyazelenko) - Support Java 18 with ASM 9.2 [#698](https://github.com/johnrengelman/shadow/pull/698) +- [Jason](https://github.com/jpenilla) - Support Records with JDependency 2.7.0 [#681](https://github.com/johnrengelman/shadow/pull/681) ## v7.0.0 (2021-04-26) -* Required Gradle 7.0+ -* Support for Java 16 -* Removes JCenter references -* **Breaking Change!** - The maven group coordinate has changed to be `gradle.plugin.com.github.jengelman.gradle.plugins`. Users explicitly declaring the buildscript classpath will need to update their configuration. + +- Required Gradle 7.0+ +- Support for Java 16 +- Removes JCenter references +- **Breaking Change!** - The maven group coordinate has changed to be `gradle.plugin.com.github.jengelman.gradle.plugins`. Users explicitly declaring the buildscript classpath will need to update their configuration. + ``` buildscript { repositories { @@ -39,263 +54,274 @@ apply plugin: "com.github.johnrengelman.shadow" ``` -* [Cédric Champeau](https://github.com/melix) - Support Gradle 7 [#624](https://github.com/johnrengelman/shadow/pull/624) -* [Daniel Oakey](https://github.com/danieloakey) - Close `FileInputStream` when remapping close to avoid classloader locks [#642](https://github.com/johnrengelman/shadow/pull/642) -* [Maximilian Müller](https://github.com/maxm123) - Groovy error in `ServiceFileTransformer` in Gradle 3 [#655](https://github.com/johnrengelman/shadow/pull/655) -* [Helder Pereira](https://github.com/helfper) - Fix deprecations errors in transformers and add CI testing around future deprecations [#647](https://github.com/johnrengelman/shadow/pull/647) -* [Nicolas Humblot](https://github.com/nhumblot) - Handle deprecation of `mainClassName` configuration [#609](https://github.com/johnrengelman/shadow/pull/609), [#612](https://github.com/johnrengelman/shadow/pull/612) -* [Bernie Schelberg](https://github.com/bschelberg) - Exclude `api` and `implementations` from legacy `maven` POM [#615](https://github.com/johnrengelman/shadow/pull/615) + +- [Cédric Champeau](https://github.com/melix) - Support Gradle 7 [#624](https://github.com/johnrengelman/shadow/pull/624) +- [Daniel Oakey](https://github.com/danieloakey) - Close `FileInputStream` when remapping close to avoid classloader locks [#642](https://github.com/johnrengelman/shadow/pull/642) +- [Maximilian Müller](https://github.com/maxm123) - Groovy error in `ServiceFileTransformer` in Gradle 3 [#655](https://github.com/johnrengelman/shadow/pull/655) +- [Helder Pereira](https://github.com/helfper) - Fix deprecations errors in transformers and add CI testing around future deprecations [#647](https://github.com/johnrengelman/shadow/pull/647) +- [Nicolas Humblot](https://github.com/nhumblot) - Handle deprecation of `mainClassName` configuration [#609](https://github.com/johnrengelman/shadow/pull/609), [#612](https://github.com/johnrengelman/shadow/pull/612) +- [Bernie Schelberg](https://github.com/bschelberg) - Exclude `api` and `implementations` from legacy `maven` POM [#615](https://github.com/johnrengelman/shadow/pull/615) ## v6.1.0 (2020-10-05) -* As of this version, Shadow is compiled with Java 8 source and target compatibility. This aligns the plugin with the minimum required Java version + +- As of this version, Shadow is compiled with Java 8 source and target compatibility. This aligns the plugin with the minimum required Java version for Gradle 6.0 (https://docs.gradle.org/6.0/release-notes.html). -* Update ASM to 9.0 to support JDK 16. -* [Tim Yates](https://github.com/timyates), [Benedikt Ritter](https://github.com/britter) - Enable Configuration Caching for Gradle 6.6+ [#591](https://github.com/johnrengelman/shadow/pull/591) -* [Caleb Larsen](https://github.com/MuffinTheMan) - doc updates [#583](https://github.com/johnrengelman/shadow/pull/593) -* [Schalk W. Cronjé](https://github.com/ysb33r) - log4j version update for CVE-2020-9488 [#590](https://github.com/johnrengelman/shadow/pull/590) -* [Victor Tso](https://github.com/roxchkplusony) - Input stream handling for large projects [#587](https://github.com/johnrengelman/shadow/pull/587) -* [Matthew Haughton](https://github.com/3flex) - Implement Task Configuration Avoidance pattern [#597](https://github.com/johnrengelman/shadow/pull/597) +- Update ASM to 9.0 to support JDK 16. +- [Tim Yates](https://github.com/timyates), [Benedikt Ritter](https://github.com/britter) - Enable Configuration Caching for Gradle 6.6+ [#591](https://github.com/johnrengelman/shadow/pull/591) +- [Caleb Larsen](https://github.com/MuffinTheMan) - doc updates [#583](https://github.com/johnrengelman/shadow/pull/593) +- [Schalk W. Cronjé](https://github.com/ysb33r) - log4j version update for CVE-2020-9488 [#590](https://github.com/johnrengelman/shadow/pull/590) +- [Victor Tso](https://github.com/roxchkplusony) - Input stream handling for large projects [#587](https://github.com/johnrengelman/shadow/pull/587) +- [Matthew Haughton](https://github.com/3flex) - Implement Task Configuration Avoidance pattern [#597](https://github.com/johnrengelman/shadow/pull/597) ## v6.0.0 (2020-06-15) -* Required Gradle 6.0+ -* *NEW*: Support for Gradle Metadata publication via the `shadowRuntimeElements` configuration. This is a _beta_ feature + +- Required Gradle 6.0+ +- _NEW_: Support for Gradle Metadata publication via the `shadowRuntimeElements` configuration. This is a _beta_ feature the hasn't been tested extensively. Feedback is appreciated. -* Fix Gradle 7 deprecation warnings [#530](https://github.com/johnrengelman/shadow/issues/530) -* Fix to generated start script to correctly use `optsEnvironmentVar`[#518](https://github.com/johnrengelman/shadow/commit/7e99c02957773205c3babdd23f4bbf883330c975) -* [Yahor Berdnikau](https://github.com/Tapchicoma) - Fix issues with Gradle API being embedded into published JAR [#527](https://github.com/johnrengelman/shadow/issues/527) -* [Dmitry Vyazelenko](https://github.com/vyazelenko) - ASM updates to support latest Java versions [#549](https://github.com/johnrengelman/shadow/pull/549) -* [ejjcase](https://github.com/ejjcase) - Support exposing shadowed project dependencies via POM [#543](https://github.com/johnrengelman/shadow/pull/543) -* [Artem Chubaryan](https://github.com/Armaxis) - Performance optimizations [#535](https://github.com/johnrengelman/shadow/pull/535) -* [Trask Stalnaker](https://github.com/trask) - Fix exclude patterns on Windows [#539](https://github.com/johnrengelman/shadow/pull/539) -* [Artem Chubaryan](https://github.com/Armaxis) - Allow usage of true regex patterns for include/exclude by the `%regex[]` syntax [#536](https://github.com/johnrengelman/shadow/pull/536) +- Fix Gradle 7 deprecation warnings [#530](https://github.com/johnrengelman/shadow/issues/530) +- Fix to generated start script to correctly use `optsEnvironmentVar`[#518](https://github.com/johnrengelman/shadow/commit/7e99c02957773205c3babdd23f4bbf883330c975) +- [Yahor Berdnikau](https://github.com/Tapchicoma) - Fix issues with Gradle API being embedded into published JAR [#527](https://github.com/johnrengelman/shadow/issues/527) +- [Dmitry Vyazelenko](https://github.com/vyazelenko) - ASM updates to support latest Java versions [#549](https://github.com/johnrengelman/shadow/pull/549) +- [ejjcase](https://github.com/ejjcase) - Support exposing shadowed project dependencies via POM [#543](https://github.com/johnrengelman/shadow/pull/543) +- [Artem Chubaryan](https://github.com/Armaxis) - Performance optimizations [#535](https://github.com/johnrengelman/shadow/pull/535) +- [Trask Stalnaker](https://github.com/trask) - Fix exclude patterns on Windows [#539](https://github.com/johnrengelman/shadow/pull/539) +- [Artem Chubaryan](https://github.com/Armaxis) - Allow usage of true regex patterns for include/exclude by the `%regex[]` syntax [#536](https://github.com/johnrengelman/shadow/pull/536) ## v5.2.0 (2019-11-10) -* [Inez Korczyński](https://github.com/inez) - Performance optimization when evaluating relocation paths [#507](https://github.com/johnrengelman/shadow/pull/507) -* [Jeff Adler](https://github.com/jeffalder) - Fix remapping issues with multi release JARS [#526](https://github.com/johnrengelman/shadow/pull/526) -* [Gary Hale](https://github.com/ghale) - Implement support for Gradle build cache [#524](https://github.com/johnrengelman/shadow/pull/524) -* [Roberto Perez Alcolea](https://github.com/rpalcolea) - Gradle 6.x support [#517](https://github.com/johnrengelman/shadow/pull/517) -* [Konstantin Gribov](https://github.com/grossws) - Return support for 5.0 for convention mapping [#502](https://github.com/johnrengelman/shadow/pull/502) -* [Lai Jiang](https://github.com/jianglai) - Documentation updates on how to reconfigure `classifier` and `version` [#512](https://github.com/johnrengelman/shadow/pull/512) + +- [Inez Korczyński](https://github.com/inez) - Performance optimization when evaluating relocation paths [#507](https://github.com/johnrengelman/shadow/pull/507) +- [Jeff Adler](https://github.com/jeffalder) - Fix remapping issues with multi release JARS [#526](https://github.com/johnrengelman/shadow/pull/526) +- [Gary Hale](https://github.com/ghale) - Implement support for Gradle build cache [#524](https://github.com/johnrengelman/shadow/pull/524) +- [Roberto Perez Alcolea](https://github.com/rpalcolea) - Gradle 6.x support [#517](https://github.com/johnrengelman/shadow/pull/517) +- [Konstantin Gribov](https://github.com/grossws) - Return support for 5.0 for convention mapping [#502](https://github.com/johnrengelman/shadow/pull/502) +- [Lai Jiang](https://github.com/jianglai) - Documentation updates on how to reconfigure `classifier` and `version` [#512](https://github.com/johnrengelman/shadow/pull/512) ## v5.1.0 (2019-06-29) -* [Chris Rankin](https://github.com/chrisr3) - Add `ManifestAppenderTransformer` to support appending to Jar manifest [#474](https://github.com/johnrengelman/shadow/pull/474) -* [Min-Ken Lai](https://github.com/minkenlai) - Additional escaping fixes in start script [#487](https://github.com/johnrengelman/shadow/pull/487) -* [Alan D. Cabrera](https://github.com/maguro) - Automatically remove `gradleApi` from `compile` scope in the presence of `shadow` [#459](https://github.com/johnrengelman/shadow/pull/459) -* [Christian Stein](https://github.com/sormuras) - Do not initialize `UnusedTracker` when not requested [#480](https://github.com/johnrengelman/shadow/pull/480), [#479](https://github.com/johnrengelman/shadow/issues/479) -* [Attila Kelemen](https://github.com/kelemen) - Fix `NullPointerException` when using java minimization and api project dependency with version [#477](https://github.com/johnrengelman/shadow/pull/477) + +- [Chris Rankin](https://github.com/chrisr3) - Add `ManifestAppenderTransformer` to support appending to Jar manifest [#474](https://github.com/johnrengelman/shadow/pull/474) +- [Min-Ken Lai](https://github.com/minkenlai) - Additional escaping fixes in start script [#487](https://github.com/johnrengelman/shadow/pull/487) +- [Alan D. Cabrera](https://github.com/maguro) - Automatically remove `gradleApi` from `compile` scope in the presence of `shadow` [#459](https://github.com/johnrengelman/shadow/pull/459) +- [Christian Stein](https://github.com/sormuras) - Do not initialize `UnusedTracker` when not requested [#480](https://github.com/johnrengelman/shadow/pull/480), [#479](https://github.com/johnrengelman/shadow/issues/479) +- [Attila Kelemen](https://github.com/kelemen) - Fix `NullPointerException` when using java minimization and api project dependency with version [#477](https://github.com/johnrengelman/shadow/pull/477) ## v5.0.0 (2019-02-28) -* Require Gradle 5.0+ -* Fix issue with build classifier `-all` being dropped in Gradle 5.1+ -* [Roberto Perez Alcolea](https://github.com/rpalcolea) - Exclude project dependencies from minimization [#420](https://github.com/johnrengelman/shadow/pull/420) -* [Matt King](https://github.com/kyrrigle), [Richard Marbach](https://github.com/RichardMarbach) - Fix escaping in start script [#453](https://github.com/johnrengelman/shadow/pull/454), [#455](https://github.com/johnrengelman/shadow/pull/455) -* [Dennis Schumann](https://github.com/Hillkorn) - Fix Gradle 5.2 incompatibility with `ShadowJar.getMetaClass()` [#456](https://github.com/johnrengelman/shadow/pull/456) -* [Brane F. Gračnar](https://github.com/bfg) - Fix compatibility with `com.palantir.docker` [#460](https://github.com/johnrengelman/shadow/pull/460) + +- Require Gradle 5.0+ +- Fix issue with build classifier `-all` being dropped in Gradle 5.1+ +- [Roberto Perez Alcolea](https://github.com/rpalcolea) - Exclude project dependencies from minimization [#420](https://github.com/johnrengelman/shadow/pull/420) +- [Matt King](https://github.com/kyrrigle), [Richard Marbach](https://github.com/RichardMarbach) - Fix escaping in start script [#453](https://github.com/johnrengelman/shadow/pull/454), [#455](https://github.com/johnrengelman/shadow/pull/455) +- [Dennis Schumann](https://github.com/Hillkorn) - Fix Gradle 5.2 incompatibility with `ShadowJar.getMetaClass()` [#456](https://github.com/johnrengelman/shadow/pull/456) +- [Brane F. Gračnar](https://github.com/bfg) - Fix compatibility with `com.palantir.docker` [#460](https://github.com/johnrengelman/shadow/pull/460) ## v4.0.4 (2019-01-19) -* When using `shadow`, `application`, and `maven` plugins together, remove `shadowDistZip` and `shadowDistTar` from + +- When using `shadow`, `application`, and `maven` plugins together, remove `shadowDistZip` and `shadowDistTar` from `configurations.archives` so they are not published or installed by default with the `uploadArchives` or `install` - tasks. [#347](https://github.com/johnrengelman/shadow/issues/347) -* [James Nelson](https://github.com/JamesXNelson) - Fix `null` path when using Jar minimization and Gradle's `api` configuration. [#424](https://github.com/johnrengelman/shadow/issues/424), [#425](https://github.com/johnrengelman/shadow/issues/425) - + tasks. [#347](https://github.com/johnrengelman/shadow/issues/347) +- [James Nelson](https://github.com/JamesXNelson) - Fix `null` path when using Jar minimization and Gradle's `api` configuration. [#424](https://github.com/johnrengelman/shadow/issues/424), [#425](https://github.com/johnrengelman/shadow/issues/425) + ## v4.0.3 (2018-11-21) -* [Mark Vieira](https://github.com/mark-vieira) - Don't leak plugin classes to Gradle's Spec cache [#430](https://github.com/johnrengelman/shadow/pull/430) + +- [Mark Vieira](https://github.com/mark-vieira) - Don't leak plugin classes to Gradle's Spec cache [#430](https://github.com/johnrengelman/shadow/pull/430) ## v4.0.2 (2018-10-27) -* [Petar Petrov](https://github.com/petarov) - Update to ASM 7.0-beta and jdependency 2.1.1 to support Java 11, [#415](https://github.com/johnrengelman/shadow/pull/415) -* [Victor Tso](https://github.com/roxchkplusony) - Ensure input streams are closed, [#411](https://github.com/johnrengelman/shadow/pull/411) -* [Osip Fatkullin](https://github.com/osipxd) - Exclude `api` configuration from minimization, [#405](https://github.com/johnrengelman/shadow/pull/405) + +- [Petar Petrov](https://github.com/petarov) - Update to ASM 7.0-beta and jdependency 2.1.1 to support Java 11, [#415](https://github.com/johnrengelman/shadow/pull/415) +- [Victor Tso](https://github.com/roxchkplusony) - Ensure input streams are closed, [#411](https://github.com/johnrengelman/shadow/pull/411) +- [Osip Fatkullin](https://github.com/osipxd) - Exclude `api` configuration from minimization, [#405](https://github.com/johnrengelman/shadow/pull/405) ## v4.0.1 (2018-09-30) -* **Breaking Change!** `Transform.modifyOutputStream(ZipOutputStream os)` to `Transform.modifyOutputStream(ZipOutputStream jos, boolean preserveFileTimestamps)`. + +- **Breaking Change!** `Transform.modifyOutputStream(ZipOutputStream os)` to `Transform.modifyOutputStream(ZipOutputStream jos, boolean preserveFileTimestamps)`. Typically breaking changes are reserved for major version releases, but this change was necessary for `preserverFileTimestamps` (introduced in v4.0.0) to work correctly in the presence of transformers, [#404](https://github.com/johnrengelman/shadow/issues/404) -* Fix regression in support Java 10+ during relocation, [#403](https://github.com/johnrengelman/shadow/issues/403) +- Fix regression in support Java 10+ during relocation, [#403](https://github.com/johnrengelman/shadow/issues/403) ## v4.0.0 (2018-09-25) -* **Breaking Change!** Restrict Plugin to Gradle 4.0+. Shadow major versions will align with Gradle major versions going forward. -* **Breaking Change!** For clarity purposes `com.github.johnrengelman.plugin-shadow` has been removed. If you intend to use this feature, you will need to declare your own `ConfigureShadowRelocation` task. See section [2.9.2](http://imperceptiblethoughts.com/shadow/#automatically_relocating_dependencies) of the User Guide -* [Sergey Tselovalnikov](https://github.com/SerCeMan) - Upgrade to ASM 6.2.1 to support Java 11 -* [Chris Cowan](https://github.com/Macil) - Add support for `shadowJar.preserveFileTimestamps` property. See [Jar.preserveFileTimestamps](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:preserveFileTimestamps) -* [Paul N. Baker](https://github.com/paul-nelson-baker) - Add `Log4j2PluginsCacheFileTransformer` to process Log4j DAT files during merge. -* [Felipe Lima](https://github.com/felipecsl) - Fix the long standing "No property `mainClassName`" issue. -* [debanne](https://github.com/debanne) - Implement JAR minimization actions. This will attempt to exclude unused classes in your shadowed JAR. -* Configure exclusion of `module-info.class` from `shadowJar` when using the Shadow the Java plugin, [#352](https://github.com/johnrengelman/shadow/issues/352) +- **Breaking Change!** Restrict Plugin to Gradle 4.0+. Shadow major versions will align with Gradle major versions going forward. +- **Breaking Change!** For clarity purposes `com.github.johnrengelman.plugin-shadow` has been removed. If you intend to use this feature, you will need to declare your own `ConfigureShadowRelocation` task. See section [2.9.2](http://imperceptiblethoughts.com/shadow/#automatically_relocating_dependencies) of the User Guide +- [Sergey Tselovalnikov](https://github.com/SerCeMan) - Upgrade to ASM 6.2.1 to support Java 11 +- [Chris Cowan](https://github.com/Macil) - Add support for `shadowJar.preserveFileTimestamps` property. See [Jar.preserveFileTimestamps](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:preserveFileTimestamps) +- [Paul N. Baker](https://github.com/paul-nelson-baker) - Add `Log4j2PluginsCacheFileTransformer` to process Log4j DAT files during merge. +- [Felipe Lima](https://github.com/felipecsl) - Fix the long standing "No property `mainClassName`" issue. +- [debanne](https://github.com/debanne) - Implement JAR minimization actions. This will attempt to exclude unused classes in your shadowed JAR. +- Configure exclusion of `module-info.class` from `shadowJar` when using the Shadow the Java plugin, [#352](https://github.com/johnrengelman/shadow/issues/352) ## v2.0.4 (2018-04-27) -* Update to ASM 6.1.1 to address performance issues - [ASM Issue 317816](https://gitlab.ow2.org/asm/asm/issues/317816) -* Close InputStreams after using them, [#364](https://github.com/johnrengelman/shadow/issues/364) -* Remove usage of Gradle internal `AbstractFileCollection`. -* Add task annotations to remove warnings when validating plugin. +- Update to ASM 6.1.1 to address performance issues - [ASM Issue 317816](https://gitlab.ow2.org/asm/asm/issues/317816) +- Close InputStreams after using them, [#364](https://github.com/johnrengelman/shadow/issues/364) +- Remove usage of Gradle internal `AbstractFileCollection`. +- Add task annotations to remove warnings when validating plugin. ## v2.0.3 (2018-03-24) -* [Martin Sadowski](https://github.com/ttsiebzehntt) - Update to ASM 6.1 -* [Scott Newson](https://github.com/sgnewson) - Fix deprecated Gradle warnings, [#356](https://github.com/johnrengelman/shadow/pull/356) +- [Martin Sadowski](https://github.com/ttsiebzehntt) - Update to ASM 6.1 +- [Scott Newson](https://github.com/sgnewson) - Fix deprecated Gradle warnings, [#356](https://github.com/johnrengelman/shadow/pull/356) ## v2.0.2 (2017-12-12) -* [Ben Adazza](https://github.com/ben-adazza), [Tyler Benson](https://github.com/tylerbenson) - documentation -* [Marke Vieira](https://github.com/mark-vieira) - Support multi-project builds with Build-Scan integration -* Upgrade to ASM 6, [#294]https://github.com/johnrengelman/shadow/issues/294, [#303](https://github.com/johnrengelman/shadow/issues/303) -* [Rob Spieldenner](https://github.com/rspieldenner) - Fix integration with `application` plugin in Gradle 4.3, [#339](https://github.com/johnrengelman/shadow/issues/339) -* Fixed deprecation warning from Gradle 4.2+, [#326](https://github.com/johnrengelman/shadow/issues/326) +- [Ben Adazza](https://github.com/ben-adazza), [Tyler Benson](https://github.com/tylerbenson) - documentation +- [Marke Vieira](https://github.com/mark-vieira) - Support multi-project builds with Build-Scan integration +- Upgrade to ASM 6, [#294]https://github.com/johnrengelman/shadow/issues/294, [#303](https://github.com/johnrengelman/shadow/issues/303) +- [Rob Spieldenner](https://github.com/rspieldenner) - Fix integration with `application` plugin in Gradle 4.3, [#339](https://github.com/johnrengelman/shadow/issues/339) +- Fixed deprecation warning from Gradle 4.2+, [#326](https://github.com/johnrengelman/shadow/issues/326) ## v2.0.1 (2017-06-23) -* Fix `null+configuration` error, [#297](https://github.com/johnrengelman/shadow/issues/297) +- Fix `null+configuration` error, [#297](https://github.com/johnrengelman/shadow/issues/297) ## v2.0.0 (2017-05-09) -* **Breaking Change!** Restrict Plugin to Gradle 3.0+ -* **Breaking Change!** Build with Java 7 -* **Breaking Change!** Updated `Transformer` interface to accept `TransformerContext` object instead of individual values -* **Breaking Change!** Updated `Relocator` interface to accept `RelocatePathContext` and `RelocateClassContext` objects -* **Breaking Change!** Distribution tasks `distShadowZip` and `distShadowTar` have been removed and replaced with the standard `shadowDistZip` and `shadowDistTar` from the Gradle Distribution plugin. -* **Breaking Change!** The `installShadowApp` task has been removed and replaced with the standard `installShadowDist` task from the Gradle Distribution plugin. -* **Breaking Change!** The new `installShadowDist` task outputs to `build/install/-shadow` per the standard (formerly was `build/installShadow`) -* **Breaking Change!** `component.shadow` removed in favor of `project.shadow.component(publication)` so as to remove dependency on internal Gradle APIs. -* _NEW_ Introducing `ConfigureShadowRelocation` task and `com.github.johnrengelman.plugin-shadow` plugin to automatically configure package relocation for Gradle plugins. -* _NEW_ Integration with Gradle Build Scans. When running a `ShadowJar` task with Build Scans, custom values including dependencies merged anc package relocations are published in the scan. -* Build Shadow w/ Shadow. This will help prevent any future classpath conflicts with Gradle. -* Replace `startShadowScripts` tasks with Gradle's built-in `CreateStartScripts` type. -* Build with Gradle 3.1 -* [Marc Philipp](https://github.com/marcphilipp) - Add `keyTransformer` property to `PropertiesFileTransformer` -* Update to ASM 5.2 -* [Piotr Kubowicz](https://github.com/pkubowicz) - Support `api`, `implementation`, `runtimeOnly` dependency configurations introdcued in Gradle 3.3 +- **Breaking Change!** Restrict Plugin to Gradle 3.0+ +- **Breaking Change!** Build with Java 7 +- **Breaking Change!** Updated `Transformer` interface to accept `TransformerContext` object instead of individual values +- **Breaking Change!** Updated `Relocator` interface to accept `RelocatePathContext` and `RelocateClassContext` objects +- **Breaking Change!** Distribution tasks `distShadowZip` and `distShadowTar` have been removed and replaced with the standard `shadowDistZip` and `shadowDistTar` from the Gradle Distribution plugin. +- **Breaking Change!** The `installShadowApp` task has been removed and replaced with the standard `installShadowDist` task from the Gradle Distribution plugin. +- **Breaking Change!** The new `installShadowDist` task outputs to `build/install/-shadow` per the standard (formerly was `build/installShadow`) +- **Breaking Change!** `component.shadow` removed in favor of `project.shadow.component(publication)` so as to remove dependency on internal Gradle APIs. +- _NEW_ Introducing `ConfigureShadowRelocation` task and `com.github.johnrengelman.plugin-shadow` plugin to automatically configure package relocation for Gradle plugins. +- _NEW_ Integration with Gradle Build Scans. When running a `ShadowJar` task with Build Scans, custom values including dependencies merged anc package relocations are published in the scan. +- Build Shadow w/ Shadow. This will help prevent any future classpath conflicts with Gradle. +- Replace `startShadowScripts` tasks with Gradle's built-in `CreateStartScripts` type. +- Build with Gradle 3.1 +- [Marc Philipp](https://github.com/marcphilipp) - Add `keyTransformer` property to `PropertiesFileTransformer` +- Update to ASM 5.2 +- [Piotr Kubowicz](https://github.com/pkubowicz) - Support `api`, `implementation`, `runtimeOnly` dependency configurations introdcued in Gradle 3.3 ## v1.2.4 (2016-11-03) -* Don't resolve dependency configurations during config phase, [#128](https://github.com/johnrengelman/shadow/issues/129) -* Build plugin with Gradle 2.14 -* Fix docs regarding inheriting Jar manifest, [#251](https://github.com/johnrengelman/shadow/issues/251) -* [Ethan Hall](https://github.com/ethankhall) - Support projects that configure uploading to Ivy repositories, [#256](https://github.com/johnrengelman/shadow/pull/256) -* Force task to depend on dependency configuration, [#152](https://github.com/johnrengelman/shadow/issues/152) -* Do not explode ZIP files into shadow jar, [#196](https://github.com/johnrengelman/shadow/issues/196) -* [John Szakmeister](https://github.com/jszakmeister) - Preserve timestamps on merged jar entries, [#260](https://github.com/johnrengelman/shadow/pull/260) + +- Don't resolve dependency configurations during config phase, [#128](https://github.com/johnrengelman/shadow/issues/129) +- Build plugin with Gradle 2.14 +- Fix docs regarding inheriting Jar manifest, [#251](https://github.com/johnrengelman/shadow/issues/251) +- [Ethan Hall](https://github.com/ethankhall) - Support projects that configure uploading to Ivy repositories, [#256](https://github.com/johnrengelman/shadow/pull/256) +- Force task to depend on dependency configuration, [#152](https://github.com/johnrengelman/shadow/issues/152) +- Do not explode ZIP files into shadow jar, [#196](https://github.com/johnrengelman/shadow/issues/196) +- [John Szakmeister](https://github.com/jszakmeister) - Preserve timestamps on merged jar entries, [#260](https://github.com/johnrengelman/shadow/pull/260) ## v1.2.3 (2016-01-25) -* Support for Gradle 2.11-rc-1, [#177](https://github.com/johnrengelman/shadow/issues/177) -* Convert internal framework to [Gradle TestKit](https://docs.gradle.org/current/userguide/test_kit.html) -* [Fedor Korotkov](https://github.com/fkorotkov) - Use BufferedOutputStream when writing the Zip file, [#171](https://github.com/johnrengelman/shadow/pull/171[) -* [Haw-Bin Chai](https://github.com/hbchai) - Quote Jar path in Windows start script as it may contain spaces, [#170](https://github.com/johnrengelman/shadow/pull/170) -* [Serban Iordache](https://github.com/siordache) - Evaluate relocation specs when merging service descriptors, [#165](https://github.com/johnrengelman/shadow/pull/165) +- Support for Gradle 2.11-rc-1, [#177](https://github.com/johnrengelman/shadow/issues/177) +- Convert internal framework to [Gradle TestKit](https://docs.gradle.org/current/userguide/test_kit.html) +- [Fedor Korotkov](https://github.com/fkorotkov) - Use BufferedOutputStream when writing the Zip file, [#171](https://github.com/johnrengelman/shadow/pull/171[) +- [Haw-Bin Chai](https://github.com/hbchai) - Quote Jar path in Windows start script as it may contain spaces, [#170](https://github.com/johnrengelman/shadow/pull/170) +- [Serban Iordache](https://github.com/siordache) - Evaluate relocation specs when merging service descriptors, [#165](https://github.com/johnrengelman/shadow/pull/165) ## v1.2.2 (2015-07-17) -* [Minecrell](https://github.com/Minecrell) - Gradle 2.5 compatibility, [#147](https://github.com/johnrengelman/shadow/issues/147) +- [Minecrell](https://github.com/Minecrell) - Gradle 2.5 compatibility, [#147](https://github.com/johnrengelman/shadow/issues/147) ## v1.2.1 (2015-01-23) -* Apply package relocations to dependency resources, [#114](https://github.com/johnrengelman/shadow/issues/114) +- Apply package relocations to dependency resources, [#114](https://github.com/johnrengelman/shadow/issues/114) ## v1.2.0 (2014-11-24) -* Re-organize some code to remove need for forcing the Gradle API ClassLoader to allow the `org.apache.tools.zip` package. -* Upgrade JDOM library from 1.1 to 2.0.5 (change dependency from `jdom:jdom:1.1` to `org.jdom:jdom2:2.0.5`), [#98](https://github.com/johnrengelman/shadow/issues/98) -* Convert ShadowJar.groovy to ShadowJar.java to workaround binary incompatibility introduced by Gradle 2.2, [#106](https://github.com/johnrengelman/shadow/issues/106) -* Updated ASM library to `5.0.3` to support JDK8, [#97](https://github.com/johnrengelman/shadow/issues/97) -* Allows for regex pattern matching in the `dependency` string when including/excluding, [#83](https://github.com/johnrengelman/shadow/issues/83) -* Apply package relocations to resource files, [#93](https://github.com/johnrengelman/shadow/issues/93) +- Re-organize some code to remove need for forcing the Gradle API ClassLoader to allow the `org.apache.tools.zip` package. +- Upgrade JDOM library from 1.1 to 2.0.5 (change dependency from `jdom:jdom:1.1` to `org.jdom:jdom2:2.0.5`), [#98](https://github.com/johnrengelman/shadow/issues/98) +- Convert ShadowJar.groovy to ShadowJar.java to workaround binary incompatibility introduced by Gradle 2.2, [#106](https://github.com/johnrengelman/shadow/issues/106) +- Updated ASM library to `5.0.3` to support JDK8, [#97](https://github.com/johnrengelman/shadow/issues/97) +- Allows for regex pattern matching in the `dependency` string when including/excluding, [#83](https://github.com/johnrengelman/shadow/issues/83) +- Apply package relocations to resource files, [#93](https://github.com/johnrengelman/shadow/issues/93) ## v1.1.2 (2014-09-09) -* fix bug in `runShadow` where dependencies from the `shadow` configuration are not available, [#94](https://github.com/johnrengelman/shadow/issues/94) +- fix bug in `runShadow` where dependencies from the `shadow` configuration are not available, [#94](https://github.com/johnrengelman/shadow/issues/94) ## v1.1.1 (2014-08-27) -* Fix bug in `'createStartScripts'` task that was causing it to not execute `'shadowJar'` task, [#90](https://github.com/johnrengelman/shadow/issues/90) -* Do not include `null` in ShadowJar Manifest `'Class-Path'` value when `jar` task does not specify a value for it, [#92](https://github.com/johnrengelman/shadow/issues/92) -* ShadowJar Manifest `'Class-Path'` should reference jars from `'shadow'` config as relative to location of `shadowJar` output, [#91](https://github.com/johnrengelman/shadow/issues/91) +- Fix bug in `'createStartScripts'` task that was causing it to not execute `'shadowJar'` task, [#90](https://github.com/johnrengelman/shadow/issues/90) +- Do not include `null` in ShadowJar Manifest `'Class-Path'` value when `jar` task does not specify a value for it, [#92](https://github.com/johnrengelman/shadow/issues/92) +- ShadowJar Manifest `'Class-Path'` should reference jars from `'shadow'` config as relative to location of `shadowJar` output, [#91](https://github.com/johnrengelman/shadow/issues/91) ## v1.1.0 (2014-08-26) -* **Breaking Change!** Fix leaking of `shadowJar.manifest` into `jar.manifest`, [#82](https://github.com/johnrengelman/shadow/issues/82) +- **Breaking Change!** Fix leaking of `shadowJar.manifest` into `jar.manifest`, [#82](https://github.com/johnrengelman/shadow/issues/82) To simplify behavior, the `shadowJar.appendManifest` method has been removed. Replace uses with `shadowJar.manifest` -* `ShadowTask` now has a `configurations` property that is resolved to the files in the resolved configuration before +- `ShadowTask` now has a `configurations` property that is resolved to the files in the resolved configuration before being added to the copy spec. This allows for an easier implementation for filtering. The default 'shadowJar' task has the convention of adding the `'runtime'` scope to this list. Manually created instances of `ShadowTask` have no configurations added by default and can be configured by setting `task.configurations`. -* Properly configure integration with the `'maven'` plugin when added. When adding `'maven'` the `'uploadShadow'` task +- Properly configure integration with the `'maven'` plugin when added. When adding `'maven'` the `'uploadShadow'` task will now properly configure the POM dependencies by removing the `'compile'` and `'runtime'` configurations from the POM and adding the `'shadow'` configuration as a `RUNTIME` scope in the POM. This behavior matches the behavior when using the `'maven-publish'` plugin. -* [Matt Hurne](https://github.com/mhurne) - Allow `ServiceFileTransformer` to specify include/exclude patterns for +- [Matt Hurne](https://github.com/mhurne) - Allow `ServiceFileTransformer` to specify include/exclude patterns for files within the configured path to merge. -* [Matt Hurne](https://github.com/mhurne) - Added `GroovyExtensionModuleTransformer` for merging Groovy Extension module +- [Matt Hurne](https://github.com/mhurne) - Added `GroovyExtensionModuleTransformer` for merging Groovy Extension module descriptor files. The existing `ServiceFileTransformer` now excludes Groovy Extension Module descriptors by default. -* `distShadowZip` and `distShadowZip` now contain the shadow library and run scripts instead of the default from the +- `distShadowZip` and `distShadowZip` now contain the shadow library and run scripts instead of the default from the `'application'` plugin, [#89](https://github.com/johnrengelman/shadow/issues/89) ## v1.0.3 (2014-07-29) -* Make service files root path configurable for `ServiceFileTransformer`, [#72](https://github.com/johnrengelman/shadow/issues/72) -* [Andres Almiray](https://github.com/aalmiray - Added PropertiesFileTransformer, [#73](https://github.com/johnrengelman/shadow/issues/73) -* [Brandon Kearby](https://github.com/brandonkearby) - Fixed StackOverflow when a cycle occurs in the resolved dependency grap, [#69](https://github.com/johnrengelman/shadow/pull/69) -* Apply Transformers to project resources, [#70](https://github.com/johnrengelman/shadow/issues/70), [#71](https://github.com/johnrengelman/shadow/issues/71) -* [Minecrell](https://github.com/Minecrell) - Do not drop non-class files from dependencies when relocation is enabled, [#61](https://github.com/johnrengelman/shadow/issues/61) -* Remove support for applying individual sub-plugins by Id (easier maintenance and cleaner presentation in Gradle Portal) +- Make service files root path configurable for `ServiceFileTransformer`, [#72](https://github.com/johnrengelman/shadow/issues/72) +- [Andres Almiray](https://github.com/aalmiray - Added PropertiesFileTransformer, [#73](https://github.com/johnrengelman/shadow/issues/73) +- [Brandon Kearby](https://github.com/brandonkearby) - Fixed StackOverflow when a cycle occurs in the resolved dependency grap, [#69](https://github.com/johnrengelman/shadow/pull/69) +- Apply Transformers to project resources, [#70](https://github.com/johnrengelman/shadow/issues/70), [#71](https://github.com/johnrengelman/shadow/issues/71) +- [Minecrell](https://github.com/Minecrell) - Do not drop non-class files from dependencies when relocation is enabled, [#61](https://github.com/johnrengelman/shadow/issues/61) +- Remove support for applying individual sub-plugins by Id (easier maintenance and cleaner presentation in Gradle Portal) ## v1.0.2 (2014-07-07) -* Do not add an empty Class-Path attribute to the manifest when the `shadow` configuration contains no dependencies. -* `runShadow` now registers `shadowJar` as an input. Previously, `runShadow` did not execute `shadowJar` and an error occurred. -* Support Gradle 2.0, [#66](https://github.com/johnrengelman/shadow/issues/66) -* Do not override existing 'Class-Path' Manifest attribute settings from Jar configuration. Instead combine, [#65](https://github.com/johnrengelman/shadow/issues/65) +- Do not add an empty Class-Path attribute to the manifest when the `shadow` configuration contains no dependencies. +- `runShadow` now registers `shadowJar` as an input. Previously, `runShadow` did not execute `shadowJar` and an error occurred. +- Support Gradle 2.0, [#66](https://github.com/johnrengelman/shadow/issues/66) +- Do not override existing 'Class-Path' Manifest attribute settings from Jar configuration. Instead combine, [#65](https://github.com/johnrengelman/shadow/issues/65) ## v1.0.1 (2014-06-28) -* Fix issue where non-class files are dropped when using relocation, [#58](https://github.com/johnrengelman/shadow/issues/58) -* Do not create a `/` directory inside the output jar. -* Fix `runShadow` task to evaluate the `shadowJar.archiveFile` property at execution time, [#60](https://github.com/johnrengelman/shadow/issues/60) +- Fix issue where non-class files are dropped when using relocation, [#58](https://github.com/johnrengelman/shadow/issues/58) +- Do not create a `/` directory inside the output jar. +- Fix `runShadow` task to evaluate the `shadowJar.archiveFile` property at execution time, [#60](https://github.com/johnrengelman/shadow/issues/60) ## v1.0.0 (2014-06-27) -* Previously known as v0.9.0 -* All changes from 0.9.0-M1 to 0.9.0-M5 -* Properly configure the ShadowJar task inputs to observe the include/excludes from the `dependencies` block. This +- Previously known as v0.9.0 +- All changes from 0.9.0-M1 to 0.9.0-M5 +- Properly configure the ShadowJar task inputs to observe the include/excludes from the `dependencies` block. This allows UP-TO-DATE checking to work properly when changing the `dependencies` rulea, [#54](https://github.com/johnrengelman/shadow/issues/54) -* Apply relocation remappings to classes and imports in source project, [#55](https://github.com/johnrengelman/shadow/issues/55) -* Do not create directories in jar for source of remapped class, created directories in jar for destination of remapped classes, [#53](https://github.com/johnrengelman/shadow/issues/53) +- Apply relocation remappings to classes and imports in source project, [#55](https://github.com/johnrengelman/shadow/issues/55) +- Do not create directories in jar for source of remapped class, created directories in jar for destination of remapped classes, [#53](https://github.com/johnrengelman/shadow/issues/53) ## v0.9.0-M5 -* Add commons-io to compile classpath -* Update asm library to 4.1 +- Add commons-io to compile classpath +- Update asm library to 4.1 ## v0.9.0-M4 -* Break plugin into multiple sub-plugins. `ShadowBasePlugin` is always applied. +- Break plugin into multiple sub-plugins. `ShadowBasePlugin` is always applied. `ShadowJavaPlugin` and `ShadowApplicationPlugin` are applied in reaction to applying the `java` and `application` plugins respectively. -* Shadow does not applied `java` plugin automatically. `java` or `groovy` must be applied in conjunction with `shadow`. -* Moved artifact filtering to `dependencies {}` block underneath `shadowJar`. This allows better include/exclude control +- Shadow does not applied `java` plugin automatically. `java` or `groovy` must be applied in conjunction with `shadow`. +- Moved artifact filtering to `dependencies {}` block underneath `shadowJar`. This allows better include/exclude control for dependencies. -* Dependencies added to the `shadow` configuration are automatically added to the `Class-Path` attribute in the manifest +- Dependencies added to the `shadow` configuration are automatically added to the `Class-Path` attribute in the manifest for `shadowJar` -* Applying `application` plugin and settings `mainClassName` automatically configures the `Main-Class` attribute in +- Applying `application` plugin and settings `mainClassName` automatically configures the `Main-Class` attribute in the manifest for `shadowJar` -* `runShadow` now utilizes the output of the `shadowJar` and executes using `java -jar ` -* Start Scripts for shadow distribution now utilize `java -jar` to execute instead of placing all files on classpath +- `runShadow` now utilizes the output of the `shadowJar` and executes using `java -jar ` +- Start Scripts for shadow distribution now utilize `java -jar` to execute instead of placing all files on classpath and executing main class. -* Excluding/Including dependencies no longer includes transitive dependencies. All dependencies for inclusion/exclusion +- Excluding/Including dependencies no longer includes transitive dependencies. All dependencies for inclusion/exclusion must be explicitly configured via a spec. ## v0.9.0-M3 -* Use commons.io FilenameUtils to determine name of resolved jars for including/excluding +- Use commons.io FilenameUtils to determine name of resolved jars for including/excluding ## v0.9.0-M2 -* Added integration with `application` plugin to replace old `OutputSignedJars` task -* Fixed bug that resulted in duplicate file entries in the resulting Jar -* Changed plugin id to 'com.github.johnrengelman.shadow' to support Gradle 2.x plugin infrastructure. +- Added integration with `application` plugin to replace old `OutputSignedJars` task +- Fixed bug that resulted in duplicate file entries in the resulting Jar +- Changed plugin id to 'com.github.johnrengelman.shadow' to support Gradle 2.x plugin infrastructure. ## v0.9.0-M1 -* Rewrite based on Gradle Jar Task -* `ShadowJar` now extends `Jar` -* Removed `signedCompile` and `signedRuntime` configurations in favor of `shadow` configuration -* Removed `OutputSignedJars` task +- Rewrite based on Gradle Jar Task +- `ShadowJar` now extends `Jar` +- Removed `signedCompile` and `signedRuntime` configurations in favor of `shadow` configuration +- Removed `OutputSignedJars` task diff --git a/src/docs/configuration/minimizing/README.md b/src/docs/configuration/minimizing/README.md index 0636d1bee..450a3ca0f 100644 --- a/src/docs/configuration/minimizing/README.md +++ b/src/docs/configuration/minimizing/README.md @@ -3,7 +3,7 @@ Shadow can automatically remove all classes of dependencies that are not used by the project, thereby minimizing the resulting shadowed JAR. ```groovy -// Minimizing an shadow JAR +// Minimizing a shadow JAR shadowJar { minimize() } @@ -36,4 +36,4 @@ shadowJar { ``` > When excluding a `project`, all dependencies of the excluded `project` are automatically - excluded as well. \ No newline at end of file + excluded as well. diff --git a/src/docs/configuration/relocation/README.md b/src/docs/configuration/relocation/README.md index 0bce9ae22..f4835602c 100644 --- a/src/docs/configuration/relocation/README.md +++ b/src/docs/configuration/relocation/README.md @@ -72,15 +72,12 @@ dependency so the tasks execute in the correct order. ```groovy // Configure Auto Relocation -import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation - -task relocateShadowJar(type: ConfigureShadowRelocation) { - target = tasks.shadowJar - prefix = "myapp" // Default value is "shadow" +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +tasks.named('shadowJar', ShadowJar) { + enableRelocation true + relocationPrefix "myapp" } - -tasks.shadowJar.dependsOn tasks.relocateShadowJar ``` > Configuring package auto relocation can add significant time to the shadow process as it will process all dependencies diff --git a/src/docs/plugins/README.md b/src/docs/plugins/README.md index 42120c463..4f3ca3fcb 100644 --- a/src/docs/plugins/README.md +++ b/src/docs/plugins/README.md @@ -19,7 +19,7 @@ A simple Gradle plugin can use this feature by applying the `shadow` plugin and to execute before the `shadowJar` tasks: ```groovy no-plugins -import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id 'com.github.johnrengelman.shadow' version '@version@' @@ -38,11 +38,9 @@ dependencies { implementation 'org.codehaus.plexus:plexus-utils:2.0.6' } -task relocateShadowJar(type: ConfigureShadowRelocation) { - target = tasks.shadowJar +tasks.named('shadowJar', ShadowJar) { + enableRelocation true } - -tasks.shadowJar.dependsOn tasks.relocateShadowJar ``` Note that the `localGroovy()` and `gradleApi()` dependencies are added to the `shadow` configuration instead of the diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/PluginShadowPlugin.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/PluginShadowPlugin.groovy deleted file mode 100644 index 4ccef51d7..000000000 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/PluginShadowPlugin.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow - -import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import org.gradle.api.Plugin -import org.gradle.api.Project - -class PluginShadowPlugin implements Plugin { - - @Override - void apply(Project project) { - project.plugins.apply(ShadowPlugin) - - project.tasks.withType(ShadowJar).configureEach { ShadowJar task -> - if (task.name == ShadowJavaPlugin.SHADOW_JAR_TASK_NAME) { - project.tasks.register(ConfigureShadowRelocation.taskName(task), ConfigureShadowRelocation) { relocate -> - relocate.target = (ShadowJar) task - - task.dependsOn relocate - } - } - } - } -} diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy index ef83ff3b5..cc60e8649 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy @@ -9,7 +9,6 @@ import org.gradle.api.distribution.Distribution import org.gradle.api.distribution.DistributionContainer import org.gradle.api.file.CopySpec import org.gradle.api.plugins.ApplicationPlugin -import org.gradle.api.plugins.ApplicationPluginConvention import org.gradle.api.plugins.JavaApplication import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.provider.Provider @@ -26,14 +25,14 @@ class ShadowApplicationPlugin implements Plugin { public static final String SHADOW_INSTALL_TASK_NAME = 'installShadowDist' private Project project - private ApplicationPluginConvention pluginConvention + private JavaApplication javaApplication @Override void apply(Project project) { this.project = project - this.pluginConvention = (ApplicationPluginConvention) project.convention.plugins.application + this.javaApplication = project.extensions.getByType(JavaApplication) - DistributionContainer distributions = project.extensions.getByName("distributions") + DistributionContainer distributions = project.extensions.getByName("distributions") as DistributionContainer Distribution distribution = distributions.create("shadow") addRunTask(project) @@ -46,7 +45,7 @@ class ShadowApplicationPlugin implements Plugin { } protected void configureJarMainClass(Project project) { - def classNameProvider = project.provider { getMainClassName() } + def classNameProvider = javaApplication.mainClass jar.configure { jar -> jar.inputs.property('mainClassName', classNameProvider) jar.doFirst { @@ -55,18 +54,7 @@ class ShadowApplicationPlugin implements Plugin { } } - private Object getMainClassName() { - def mainClassName = project.convention.plugins.application.mainClassName - if (Objects.nonNull(mainClassName)) { - return mainClassName - } - - return project.extensions.getByType(JavaApplication.class).mainClass.get() - } - protected void addRunTask(Project project) { - ApplicationPluginConvention pluginConvention = ( - ApplicationPluginConvention) project.convention.plugins.application project.tasks.register(SHADOW_RUN_TASK_NAME, JavaJarExec) { run -> def install = project.tasks.named(SHADOW_INSTALL_TASK_NAME, Sync) @@ -74,9 +62,9 @@ class ShadowApplicationPlugin implements Plugin { run.mainClass.set('-jar') run.description = 'Runs this project as a JVM application using the shadow jar' run.group = ApplicationPlugin.APPLICATION_GROUP - run.conventionMapping.jvmArgs = { pluginConvention.applicationDefaultJvmArgs } + run.conventionMapping.jvmArgs = { javaApplication.applicationDefaultJvmArgs } run.conventionMapping.jarFile = { - project.file("${install.get().destinationDir.path}/lib/${jar.get().archivePath.name}") + project.file("${install.get().destinationDir.path}/lib/${jar.get().archiveFile.get().asFile.name}") } configureJavaLauncher(run) } @@ -90,32 +78,26 @@ class ShadowApplicationPlugin implements Plugin { } protected void addCreateScriptsTask(Project project) { - ApplicationPluginConvention pluginConvention = - (ApplicationPluginConvention) project.convention.plugins.application - project.tasks.register(SHADOW_SCRIPTS_TASK_NAME, CreateStartScripts) { startScripts -> startScripts.unixStartScriptGenerator.template = project.resources.text.fromString(this.class.getResource("internal/unixStartScript.txt").text) startScripts.windowsStartScriptGenerator.template = project.resources.text.fromString(this.class.getResource("internal/windowsStartScript.txt").text) startScripts.description = 'Creates OS specific scripts to run the project as a JVM application using the shadow jar' startScripts.group = ApplicationPlugin.APPLICATION_GROUP startScripts.classpath = project.files(jar) - startScripts.conventionMapping.mainClassName = { pluginConvention.mainClassName } - startScripts.conventionMapping.applicationName = { pluginConvention.applicationName } + startScripts.conventionMapping.mainClassName = { javaApplication.mainClass.get() } + startScripts.conventionMapping.applicationName = { javaApplication.applicationName } startScripts.conventionMapping.outputDir = { new File(project.buildDir, 'scriptsShadow') } - startScripts.conventionMapping.defaultJvmOpts = { pluginConvention.applicationDefaultJvmArgs } + startScripts.conventionMapping.defaultJvmOpts = { javaApplication.applicationDefaultJvmArgs } startScripts.inputs.files project.objects.fileCollection().from { -> jar } } } protected void configureInstallTask(Project project) { - ApplicationPluginConvention pluginConvention = - (ApplicationPluginConvention) project.convention.plugins.application - project.tasks.named(SHADOW_INSTALL_TASK_NAME).configure { installTask -> installTask.doFirst { Sync task -> if (task.destinationDir.directory) { if (task.destinationDir.listFiles().size() != 0 && (!new File(task.destinationDir, 'lib').directory || !new File(task.destinationDir, 'bin').directory)) { - throw new GradleException("The specified installation directory '${task.destinationDir}' is neither empty nor does it contain an installation for '${pluginConvention.applicationName}'.\n" + + throw new GradleException("The specified installation directory '${task.destinationDir}' is neither empty nor does it contain an installation for '${javaApplication.applicationName}'.\n" + "If you really want to install to this directory, delete it and run the install task again.\n" + "Alternatively, choose a different installation directory." ) @@ -123,7 +105,7 @@ class ShadowApplicationPlugin implements Plugin { } } installTask.doLast { Sync task -> - project.ant.chmod(file: "${task.destinationDir.absolutePath}/bin/${pluginConvention.applicationName}", perm: 'ugo+x') + project.ant.chmod(file: "${task.destinationDir.absolutePath}/bin/${javaApplication.applicationName}", perm: 'ugo+x') } } } diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowBasePlugin.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowBasePlugin.groovy index 795afbee5..1f7a3a7d4 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowBasePlugin.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowBasePlugin.groovy @@ -13,8 +13,8 @@ class ShadowBasePlugin implements Plugin { @Override void apply(Project project) { - if (GradleVersion.current() < GradleVersion.version("7.0")) { - throw new GradleException("This version of Shadow supports Gradle 7.0+ only. Please upgrade.") + if (GradleVersion.current() < GradleVersion.version("8.0")) { + throw new GradleException("This version of Shadow supports Gradle 8.0+ only. Please upgrade.") } project.extensions.create(EXTENSION_NAME, ShadowExtension, project) createShadowConfiguration(project) @@ -25,7 +25,7 @@ class ShadowBasePlugin implements Plugin { } } - private void createShadowConfiguration(Project project) { + private static void createShadowConfiguration(Project project) { project.configurations.create(CONFIGURATION_NAME) } } diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy index 22ff62f80..743e566a8 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy @@ -28,8 +28,7 @@ class ShadowExtension { publication.pom { MavenPom pom -> pom.withXml { xml -> - def dependenciesNode = xml.asNode().get('dependencies')?.get(0) ?: xml.asNode().appendNode('dependencies') - dependenciesNode.value = "" + def dependenciesNode = xml.asNode().get('dependencies') ?: xml.asNode().appendNode('dependencies') project.configurations.shadow.allDependencies.each { if ((it instanceof ProjectDependency) || ! (it instanceof SelfResolvingDependency)) { def dependencyNode = dependenciesNode.appendNode('dependency') diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy index 3123bca5e..22f791066 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy @@ -7,7 +7,7 @@ import org.gradle.api.attributes.Bundling import org.gradle.api.attributes.Category import org.gradle.api.attributes.LibraryElements import org.gradle.api.attributes.Usage -import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.SourceSetContainer import org.gradle.configuration.project.ProjectConfigurationActionContainer import org.gradle.util.GradleVersion @@ -18,7 +18,7 @@ class ShadowJavaPlugin implements Plugin { public static final String SHADOW_JAR_TASK_NAME = 'shadowJar' public static final String SHADOW_GROUP = 'Shadow' - private final ProjectConfigurationActionContainer configurationActionContainer; + private final ProjectConfigurationActionContainer configurationActionContainer @Inject ShadowJavaPlugin(ProjectConfigurationActionContainer configurationActionContainer) { @@ -54,8 +54,8 @@ class ShadowJavaPlugin implements Plugin { } } - protected void configureShadowTask(Project project) { - JavaPluginConvention convention = project.convention.getPlugin(JavaPluginConvention) + protected static void configureShadowTask(Project project) { + SourceSetContainer sourceSets = project.extensions.getByType(SourceSetContainer) project.tasks.register(SHADOW_JAR_TASK_NAME, ShadowJar) { shadow -> shadow.group = SHADOW_GROUP shadow.description = 'Create a combined JAR of project and runtime dependencies' @@ -80,7 +80,7 @@ class ShadowJavaPlugin implements Plugin { manifest.attributes 'Class-Path': libs.findAll { it }.join(' ') } } - shadow.from(convention.sourceSets.main.output) + shadow.from(sourceSets.main.output) shadow.configurations = [project.configurations.findByName('runtimeClasspath') ? project.configurations.runtimeClasspath : project.configurations.runtime] shadow.exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'module-info.class') diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowStats.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowStats.groovy index 4cfdb23c5..2e7815d82 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowStats.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowStats.groovy @@ -22,7 +22,7 @@ class ShadowStats { relocations.collect { k, v -> "${k} ${separator(k, maxLength)} ${v}"}.sort().join("\n") } - String separator(String key, int max) { + static String separator(String key, int max) { return "→" } diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/CleanProperties.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/CleanProperties.groovy new file mode 100644 index 000000000..5bed7a56d --- /dev/null +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/CleanProperties.groovy @@ -0,0 +1,32 @@ +/* + * Source https://stackoverflow.com/a/39043903/519333 + */ +package com.github.jengelman.gradle.plugins.shadow.internal + +class CleanProperties extends Properties { + private static class StripFirstLineStream extends FilterOutputStream { + + private boolean firstLineSeen = false + + StripFirstLineStream(final OutputStream out) { + super(out) + } + + @Override + void write(final int b) throws IOException { + if (firstLineSeen) { + super.write(b) + } else if (b == '\n') { + super.write(b) + + firstLineSeen = true + } + } + + } + + @Override + void store(final OutputStream out, final String comments) throws IOException { + super.store(new StripFirstLineStream(out), null) + } +} diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/GradleVersionUtil.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/GradleVersionUtil.groovy index 4e54a32cd..91606a31d 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/GradleVersionUtil.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/GradleVersionUtil.groovy @@ -9,17 +9,11 @@ import org.gradle.util.GradleVersion class GradleVersionUtil { - private final GradleVersion version - - GradleVersionUtil(String version) { - this.version = GradleVersion.version(version) - } - - PatternSet getRootPatternSet(CopySpecInternal mainSpec) { + static PatternSet getRootPatternSet(CopySpecInternal mainSpec) { return mainSpec.buildRootResolver().getPatternSet() } - ZipCompressor getInternalCompressor(ZipEntryCompression entryCompression, Jar jar) { + static ZipCompressor getInternalCompressor(ZipEntryCompression entryCompression, Jar jar) { switch (entryCompression) { case ZipEntryCompression.DEFLATED: return new DefaultZipCompressor(jar.zip64, ZipOutputStream.DEFLATED) diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/JavaJarExec.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/JavaJarExec.groovy index 890b3fb82..2affa9fbe 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/JavaJarExec.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/JavaJarExec.groovy @@ -11,7 +11,7 @@ class JavaJarExec extends JavaExec { @Override @TaskAction - public void exec() { + void exec() { List allArgs = [getJarFile().path] + getArgs() setArgs(allArgs) super.exec() diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/MinimizeDependencyFilter.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/MinimizeDependencyFilter.groovy index 762005ffc..4853c3a77 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/MinimizeDependencyFilter.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/MinimizeDependencyFilter.groovy @@ -23,7 +23,7 @@ class MinimizeDependencyFilter extends AbstractDependencyFilter { } } - private boolean isParentExcluded(Set excludedDependencies, ResolvedDependency dependency) { + private static boolean isParentExcluded(Set excludedDependencies, ResolvedDependency dependency) { excludedDependencies.any { dependency.parents.contains(it) } } } \ No newline at end of file diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/RelocationUtil.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/RelocationUtil.groovy new file mode 100644 index 000000000..f94ab89ed --- /dev/null +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/RelocationUtil.groovy @@ -0,0 +1,25 @@ +package com.github.jengelman.gradle.plugins.shadow.internal + +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import java.util.jar.JarFile + +class RelocationUtil { + + static void configureRelocation(ShadowJar target, String prefix) { + def packages = [] as Set + target.configurations.each { configuration -> + configuration.files.each { jar -> + JarFile jf = new JarFile(jar) + jf.entries().each { entry -> + if (entry.name.endsWith(".class") && entry.name != "module-info.class") { + packages << entry.name[0..entry.name.lastIndexOf('/') - 1].replaceAll('/', '.') + } + } + jf.close() + } + } + packages.each { + target.relocate(it, "${prefix}.${it}") + } + } +} diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/ZipCompressor.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/ZipCompressor.groovy index 5bd6a5055..b93be9ff3 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/ZipCompressor.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/ZipCompressor.groovy @@ -18,7 +18,7 @@ package com.github.jengelman.gradle.plugins.shadow.internal import org.apache.tools.zip.ZipOutputStream import org.gradle.api.internal.file.archive.compression.ArchiveOutputStreamFactory -public interface ZipCompressor extends ArchiveOutputStreamFactory { +interface ZipCompressor extends ArchiveOutputStreamFactory { ZipOutputStream createArchiveOutputStream(File destination) diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ConfigureShadowRelocation.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ConfigureShadowRelocation.groovy deleted file mode 100644 index 674cd9954..000000000 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ConfigureShadowRelocation.groovy +++ /dev/null @@ -1,51 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.Task -import org.gradle.api.artifacts.Configuration -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.TaskAction - -import java.util.jar.JarFile - - -class ConfigureShadowRelocation extends DefaultTask { - - @Input - ShadowJar target - - @Input - String prefix = "shadow" - - @InputFiles @Optional - List getConfigurations() { - return target.configurations - } - - @TaskAction - void configureRelocation() { - def packages = [] as Set - configurations.each { configuration -> - configuration.files.each { jar -> - JarFile jf = new JarFile(jar) - jf.entries().each { entry -> - if (entry.name.endsWith(".class") && entry.name != "module-info.class") { - packages << entry.name[0..entry.name.lastIndexOf('/')-1].replaceAll('/', '.') - } - } - jf.close() - } - } - packages.each { - target.relocate(it, "${prefix}.${it}") - } - - } - - static String taskName(Task task) { - return "configureRelocation${task.name.capitalize()}" - } - -} diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/DefaultInheritManifest.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/DefaultInheritManifest.groovy index 59aab7207..a215d49fa 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/DefaultInheritManifest.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/DefaultInheritManifest.groovy @@ -59,7 +59,7 @@ class DefaultInheritManifest implements InheritManifest { } @Override - public DefaultManifest getEffectiveManifest() { + DefaultManifest getEffectiveManifest() { DefaultManifest base = new DefaultManifest(fileResolver) inheritMergeSpecs.each { base = it.merge(base, fileResolver) diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.groovy index 3b7747085..69f8f129d 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.groovy @@ -53,14 +53,13 @@ class ShadowCopyAction implements CopyAction { private final PatternSet patternSet private final ShadowStats stats private final String encoding - private final GradleVersionUtil versionUtil private final boolean preserveFileTimestamps private final boolean minimizeJar private final UnusedTracker unusedTracker ShadowCopyAction(File zipFile, ZipCompressor compressor, DocumentationRegistry documentationRegistry, String encoding, List transformers, List relocators, - PatternSet patternSet, ShadowStats stats, GradleVersionUtil util, + PatternSet patternSet, ShadowStats stats, boolean preserveFileTimestamps, boolean minimizeJar, UnusedTracker unusedTracker) { this.zipFile = zipFile @@ -71,7 +70,6 @@ class ShadowCopyAction implements CopyAction { this.patternSet = patternSet this.stats = stats this.encoding = encoding - this.versionUtil = util this.preserveFileTimestamps = preserveFileTimestamps this.minimizeJar = minimizeJar this.unusedTracker = unusedTracker @@ -154,7 +152,7 @@ class ShadowCopyAction implements CopyAction { } catch(Throwable t) { try { resource.close() - } catch (IOException e) { + } catch (IOException ignored) { // Ignored } throw UncheckedException.throwAsUncheckedException(t) @@ -373,7 +371,7 @@ class ShadowCopyAction implements CopyAction { zipOutStr.putNextEntry(archiveEntry) IOUtils.copyLarge(bis, zipOutStr) zipOutStr.closeEntry() - } catch (ZipException e) { + } catch (ZipException ignored) { log.warn("We have a duplicate " + mappedName + " in source project") } finally { bis.close() diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.java b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.java index 1b42c6b94..9dc21742d 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.java +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.java @@ -7,18 +7,16 @@ import com.github.jengelman.gradle.plugins.shadow.relocation.SimpleRelocator; import com.github.jengelman.gradle.plugins.shadow.transformers.*; import org.gradle.api.Action; -import org.gradle.api.Task; -import org.gradle.api.artifacts.Configuration; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.DuplicatesStrategy; import org.gradle.api.file.FileCollection; import org.gradle.api.internal.DocumentationRegistry; import org.gradle.api.internal.file.FileResolver; import org.gradle.api.internal.file.copy.CopyAction; -import org.gradle.api.specs.Spec; import org.gradle.api.tasks.*; import org.gradle.api.tasks.bundling.Jar; import org.gradle.api.tasks.util.PatternSet; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.lang.reflect.InvocationTargetException; @@ -33,20 +31,20 @@ public class ShadowJar extends Jar implements ShadowSpec { private List relocators; private List configurations; private transient DependencyFilter dependencyFilter; - + private boolean enableRelocation; + private String relocationPrefix = "shadow"; private boolean minimizeJar; - private transient DependencyFilter dependencyFilterForMinimize; + private final transient DependencyFilter dependencyFilterForMinimize; private FileCollection toMinimize; private FileCollection apiJars; private FileCollection sourceSetsClassesDirs; private final ShadowStats shadowStats = new ShadowStats(); - private final GradleVersionUtil versionUtil; private final ConfigurableFileCollection includedDependencies = getProject().files(new Callable() { @Override - public FileCollection call() throws Exception { + public FileCollection call() { return dependencyFilter.resolve(configurations); } }); @@ -54,7 +52,6 @@ public FileCollection call() throws Exception { public ShadowJar() { super(); setDuplicatesStrategy(DuplicatesStrategy.INCLUDE); //shadow filters out files later. This was the default behavior in Gradle < 6.x - versionUtil = new GradleVersionUtil(getProject().getGradle().getGradleVersion()); dependencyFilter = new DefaultDependencyFilter(getProject()); dependencyFilterForMinimize = new MinimizeDependencyFilter(getProject()); setManifest(new DefaultInheritManifest(getServices().get(FileResolver.class))); @@ -62,27 +59,19 @@ public ShadowJar() { relocators = new ArrayList<>(); configurations = new ArrayList<>(); - this.getInputs().property("minimize", new Callable() { - @Override - public Boolean call() throws Exception { - return minimizeJar; - } - }); - this.getOutputs().doNotCacheIf("Has one or more transforms or relocators that are not cacheable", new Spec() { - @Override - public boolean isSatisfiedBy(Task task) { - for (Transformer transformer : transformers) { - if (!isCacheableTransform(transformer.getClass())) { - return true; - } + this.getInputs().property("minimize", (Callable) () -> minimizeJar); + this.getOutputs().doNotCacheIf("Has one or more transforms or relocators that are not cacheable", task -> { + for (Transformer transformer : transformers) { + if (!isCacheableTransform(transformer.getClass())) { + return true; } - for (Relocator relocator : relocators) { - if (!isCacheableRelocator(relocator.getClass())) { - return true; - } + } + for (Relocator relocator : relocators) { + if (!isCacheableRelocator(relocator.getClass())) { + return true; } - return false; } + return false; }); } @@ -111,12 +100,13 @@ public InheritManifest getManifest() { } @Override + @NotNull protected CopyAction createCopyAction() { DocumentationRegistry documentationRegistry = getServices().get(DocumentationRegistry.class); final UnusedTracker unusedTracker = minimizeJar ? UnusedTracker.forProject(getApiJars(), getSourceSetsClassesDirs().getFiles(), getToMinimize()) : null; return new ShadowCopyAction(getArchiveFile().get().getAsFile(), getInternalCompressor(), documentationRegistry, this.getMetadataCharset(), transformers, relocators, getRootPatternSet(), shadowStats, - versionUtil, isPreserveFileTimestamps(), minimizeJar, unusedTracker); + isPreserveFileTimestamps(), minimizeJar, unusedTracker); } @Classpath @@ -152,23 +142,21 @@ FileCollection getSourceSetsClassesDirs() { allClassesDirs.from(classesDirs); } } - sourceSetsClassesDirs = allClassesDirs.filter(new Spec() { - @Override - public boolean isSatisfiedBy(File file) { - return file.isDirectory(); - } - }); + sourceSetsClassesDirs = allClassesDirs.filter(File::isDirectory); } return sourceSetsClassesDirs; } @Internal protected ZipCompressor getInternalCompressor() { - return versionUtil.getInternalCompressor(getEntryCompression(), this); + return GradleVersionUtil.getInternalCompressor(getEntryCompression(), this); } @TaskAction protected void copy() { + if (enableRelocation) { + RelocationUtil.configureRelocation(this, relocationPrefix); + } from(getIncludedDependencies()); super.copy(); getLogger().info(shadowStats.toString()); @@ -186,7 +174,7 @@ public FileCollection getIncludedDependencies() { */ @Internal protected PatternSet getRootPatternSet() { - return versionUtil.getRootPatternSet(getMainSpec()); + return GradleVersionUtil.getRootPatternSet(getMainSpec()); } /** @@ -256,10 +244,8 @@ private void addTransform(T transformer, Action c) { public ShadowJar mergeServiceFiles() { try { transform(ServiceFileTransformer.class); - } catch (IllegalAccessException e) { - } catch (InstantiationException e) { - } catch (NoSuchMethodException e) { - } catch (InvocationTargetException e) { + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | + InstantiationException ignored) { } return this; } @@ -271,17 +257,9 @@ public ShadowJar mergeServiceFiles() { */ public ShadowJar mergeServiceFiles(final String rootPath) { try { - transform(ServiceFileTransformer.class, new Action() { - - @Override - public void execute(ServiceFileTransformer serviceFileTransformer) { - serviceFileTransformer.setPath(rootPath); - } - }); - } catch (IllegalAccessException e) { - } catch (InstantiationException e) { - } catch (NoSuchMethodException e) { - } catch (InvocationTargetException e) { + transform(ServiceFileTransformer.class, serviceFileTransformer -> serviceFileTransformer.setPath(rootPath)); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | + InstantiationException ignored) { } return this; } @@ -294,10 +272,8 @@ public void execute(ServiceFileTransformer serviceFileTransformer) { public ShadowJar mergeServiceFiles(Action configureClosure) { try { transform(ServiceFileTransformer.class, configureClosure); - } catch (IllegalAccessException e) { - } catch (InstantiationException e) { - } catch (NoSuchMethodException e) { - } catch (InvocationTargetException e) { + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | + InstantiationException ignored) { } return this; } @@ -310,10 +286,8 @@ public ShadowJar mergeServiceFiles(Action configureClosu public ShadowJar mergeGroovyExtensionModules() { try { transform(GroovyExtensionModuleTransformer.class); - } catch (IllegalAccessException e) { - } catch (InstantiationException e) { - } catch (NoSuchMethodException e) { - } catch (InvocationTargetException e) { + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | + InstantiationException ignored) { } return this; } @@ -325,16 +299,9 @@ public ShadowJar mergeGroovyExtensionModules() { */ public ShadowJar append(final String resourcePath) { try { - transform(AppendingTransformer.class, new Action() { - @Override - public void execute(AppendingTransformer transformer) { - transformer.setResource(resourcePath); - } - }); - } catch (IllegalAccessException e) { - } catch (InstantiationException e) { - } catch (NoSuchMethodException e) { - } catch (InvocationTargetException e) { + transform(AppendingTransformer.class, transformer -> transformer.setResource(resourcePath)); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | + InstantiationException ignored) { } return this; } @@ -359,7 +326,7 @@ public ShadowJar relocate(String pattern, String destination) { * @return this */ public ShadowJar relocate(String pattern, String destination, Action configure) { - SimpleRelocator relocator = new SimpleRelocator(pattern, destination, new ArrayList(), new ArrayList()); + SimpleRelocator relocator = new SimpleRelocator(pattern, destination, new ArrayList<>(), new ArrayList<>()); addRelocator(relocator, configure); return this; } @@ -445,4 +412,22 @@ public DependencyFilter getDependencyFilter() { public void setDependencyFilter(DependencyFilter filter) { this.dependencyFilter = filter; } + + @Input + public boolean isEnableRelocation() { + return enableRelocation; + } + + public void setEnableRelocation(boolean enableRelocation) { + this.enableRelocation = enableRelocation; + } + + @Input + public String getRelocationPrefix() { + return relocationPrefix; + } + + public void setRelocationPrefix(String relocationPrefix) { + this.relocationPrefix = relocationPrefix; + } } diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformer.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformer.groovy index 1db0f3fd1..0daf571a2 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformer.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformer.groovy @@ -94,7 +94,7 @@ class ApacheNoticeResourceTransformer implements Transformer { void transform(TransformerContext context) { if (entries.isEmpty()) { String year = new SimpleDateFormat("yyyy").format(new Date()) - if (!inceptionYear.equals(year)) { + if (inceptionYear != year) { year = inceptionYear + "-" + year } @@ -190,7 +190,7 @@ class ApacheNoticeResourceTransformer implements Transformer { int count = 0 for (String line : entries) { ++count - if (line.equals(copyright) && count != 2) { + if (line == copyright && count != 2) { continue } diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.groovy index 0c91e8fb9..788d0530b 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.groovy @@ -46,7 +46,7 @@ class ComponentsXmlResourceTransformer implements Transformer { boolean canTransformResource(FileTreeElement element) { def path = element.relativePath.pathString - return COMPONENTS_XML_PATH.equals(path) + return COMPONENTS_XML_PATH == path } void transform(TransformerContext context) { diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/IncludeResourceTransformer.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/IncludeResourceTransformer.groovy index 14dabee7b..3980ee1f5 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/IncludeResourceTransformer.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/IncludeResourceTransformer.groovy @@ -36,7 +36,7 @@ import org.gradle.api.tasks.PathSensitivity * * @author John Engelman */ -public class IncludeResourceTransformer implements Transformer { +class IncludeResourceTransformer implements Transformer { @InputFile @PathSensitive(PathSensitivity.NONE) @@ -45,19 +45,19 @@ public class IncludeResourceTransformer implements Transformer { @Input String resource - public boolean canTransformResource(FileTreeElement element) { + boolean canTransformResource(FileTreeElement element) { return false } - public void transform(TransformerContext context) { + void transform(TransformerContext context) { // no op } - public boolean hasTransformedResource() { + boolean hasTransformedResource() { return file != null ? file.exists() : false } - public void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) { + void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) { ZipEntry entry = new ZipEntry(resource) entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time) os.putNextEntry(entry) diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.groovy index 7f90dff1b..69bf20d2f 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.groovy @@ -30,7 +30,7 @@ import org.apache.tools.zip.ZipEntry import org.apache.tools.zip.ZipOutputStream import org.gradle.api.file.FileTreeElement -import static org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor.PLUGIN_CACHE_FILE; +import static org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor.PLUGIN_CACHE_FILE /** * Modified from the maven equivalent to work with gradle diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.groovy index 31e1a5452..2d113ac2f 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.groovy @@ -19,6 +19,7 @@ package com.github.jengelman.gradle.plugins.shadow.transformers +import com.github.jengelman.gradle.plugins.shadow.internal.CleanProperties import org.apache.tools.zip.ZipEntry import org.apache.tools.zip.ZipOutputStream import org.codehaus.plexus.util.IOUtil @@ -117,7 +118,7 @@ import static groovy.lang.Closure.IDENTITY class PropertiesFileTransformer implements Transformer { private static final String PROPERTIES_SUFFIX = '.properties' - private Map propertiesEntries = [:] + private Map propertiesEntries = [:] @Input List paths = [] @@ -179,15 +180,17 @@ class PropertiesFileTransformer implements Transformer { } private Properties loadAndTransformKeys(InputStream is) { - Properties props = new Properties() - props.load(is) + Properties props = new CleanProperties() + if (is != null) { + props.load(is) + } return transformKeys(props) } private Properties transformKeys(Properties properties) { if (keyTransformer == IDENTITY) return properties - def result = new Properties() + def result = new CleanProperties() properties.each { key, value -> result.put(keyTransformer.call(key), value) } diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformer.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformer.groovy index 37a1a4450..b2153a3f9 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformer.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformer.groovy @@ -102,11 +102,11 @@ class ServiceFileTransformer implements Transformer, PatternFilterable { static class ServiceStream extends ByteArrayOutputStream { - public ServiceStream(){ + ServiceStream(){ super( 1024 ) } - public void append( InputStream is ) throws IOException { + void append(InputStream is ) throws IOException { if ( super.count > 0 && super.buf[super.count - 1] != '\n' && super.buf[super.count - 1] != '\r' ) { byte[] newline = '\n'.bytes write(newline, 0, newline.length) @@ -114,7 +114,7 @@ class ServiceFileTransformer implements Transformer, PatternFilterable { IOUtil.copy(is, this) } - public InputStream toInputStream() { + InputStream toInputStream() { return new ByteArrayInputStream( super.buf, 0, super.count ) } } diff --git a/src/main/resources/META-INF/gradle-plugins/com.github.johnrengelman.shadow.properties b/src/main/resources/META-INF/gradle-plugins/com.github.johnrengelman.shadow.properties deleted file mode 100644 index e77803a7e..000000000 --- a/src/main/resources/META-INF/gradle-plugins/com.github.johnrengelman.shadow.properties +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright 2011 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# 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. -# -implementation-class=com.github.jengelman.gradle.plugins.shadow.ShadowPlugin diff --git a/src/main/resources/shadow-version.txt b/src/main/resources/shadow-version.txt index 1996c5044..ae9a76b92 100644 --- a/src/main/resources/shadow-version.txt +++ b/src/main/resources/shadow-version.txt @@ -1 +1 @@ -7.1.3 +8.0.0 diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy index 4ec08237a..b972c2e28 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy @@ -98,7 +98,7 @@ class ApplicationSpec extends PluginSpecification { java { toolchain { - languageVersion = JavaLanguageVersion.of(16) + languageVersion = JavaLanguageVersion.of(17) } } @@ -110,13 +110,20 @@ class ApplicationSpec extends PluginSpecification { } """.stripIndent() - settingsFile << "rootProject.name = 'myapp'" + settingsFile.write """ + plugins { + // https://docs.gradle.org/8.0.1/userguide/toolchains.html#sub:download_repositories + id("org.gradle.toolchains.foojay-resolver-convention") version("0.4.0") + } + + rootProject.name = 'myapp' + """.stripIndent() when: BuildResult result = run('runShadow', '--stacktrace') then: 'tests that runShadow executed and exited' - assert result.output.contains('Running application with JDK 16') + assert result.output.contains('Running application with JDK 17') assert result.output.contains('TestApp: Hello World! (foo)') and: 'Check that the proper jar file was installed' diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ConfigureShadowRelocationSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ConfigureShadowRelocationSpec.groovy index 2768ac347..bcb1a6981 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ConfigureShadowRelocationSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ConfigureShadowRelocationSpec.groovy @@ -8,13 +8,10 @@ class ConfigureShadowRelocationSpec extends PluginSpecification { def "auto relocate plugin dependencies"() { given: buildFile << """ - - task relocateShadowJar(type: com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation) { - target = tasks.shadowJar + tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { + enableRelocation true } - tasks.shadowJar.dependsOn tasks.relocateShadowJar - dependencies { implementation 'junit:junit:3.8.2' } @@ -23,7 +20,6 @@ class ConfigureShadowRelocationSpec extends PluginSpecification { when: run('shadowJar', '-s') - then: then: contains(output, [ 'META-INF/MANIFEST.MF', diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy index 65e150537..ab9ab0c7b 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy @@ -40,16 +40,16 @@ class ShadowPluginSpec extends PluginSpecification { then: ShadowJar shadow = project.tasks.findByName('shadowJar') assert shadow - assert shadow.baseName == projectName - assert shadow.destinationDir == new File(project.buildDir, 'libs') - assert shadow.version == version - assert shadow.classifier == 'all' - assert shadow.extension == 'jar' + assert shadow.archiveBaseName.get() == projectName + assert shadow.destinationDirectory.get().asFile == new File(project.buildDir, 'libs') + assert shadow.archiveVersion.get() == version + assert shadow.archiveClassifier.get() == 'all' + assert shadow.archiveExtension.get() == 'jar' and: Configuration shadowConfig = project.configurations.findByName('shadow') assert shadowConfig - shadowConfig.artifacts.file.contains(shadow.archivePath) + shadowConfig.artifacts.file.contains(shadow.archiveFile.get().asFile) } @@ -86,13 +86,13 @@ class ShadowPluginSpec extends PluginSpecification { assert output.exists() where: - version << ['7.0'] + version << ['8.0'] } - def 'Error in Gradle versions < 7.0'() { + def 'Error in Gradle versions < 8.0'() { given: GradleRunner versionRunner = GradleRunner.create() - .withGradleVersion('6.9') + .withGradleVersion('7.0') .withArguments('--stacktrace') .withProjectDir(dir.root) .forwardOutput() diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/executer/GradleBuildExecuter.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/executer/GradleBuildExecuter.groovy index 493794264..f8ce6e65a 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/executer/GradleBuildExecuter.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/executer/GradleBuildExecuter.groovy @@ -65,7 +65,7 @@ include 'api', 'main' } - private void addSubProject(File dir) { + private static void addSubProject(File dir) { File api = new File(dir, "api") api.mkdirs() File build = new File(api, "build.gradle") diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/DefaultCodeSnippetTests.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/DefaultCodeSnippetTests.groovy index ec613c8e4..45cde6580 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/DefaultCodeSnippetTests.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/DefaultCodeSnippetTests.groovy @@ -1,6 +1,6 @@ package com.github.jengelman.gradle.plugins.shadow.docs.internal.snippets -import com.github.jengelman.gradle.plugins.shadow.docs.internal.snippets.junit.SnippetRunner; +import com.github.jengelman.gradle.plugins.shadow.docs.internal.snippets.junit.SnippetRunner import org.junit.runner.Runner class DefaultCodeSnippetTests implements CodeSnippetTests { diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/fixture/GroovyScriptFixture.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/fixture/GroovyScriptFixture.groovy index 2bd9dd765..deff8e9f0 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/fixture/GroovyScriptFixture.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/docs/internal/snippets/fixture/GroovyScriptFixture.groovy @@ -1,4 +1,4 @@ -package com.github.jengelman.gradle.plugins.shadow.docs.internal.snippets.fixture; +package com.github.jengelman.gradle.plugins.shadow.docs.internal.snippets.fixture class GroovyScriptFixture extends SnippetFixture { diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorParameterTest.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorParameterTest.groovy index 7cd0eec4c..730e351d8 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorParameterTest.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorParameterTest.groovy @@ -42,11 +42,11 @@ class SimpleRelocatorParameterTest extends TestCase { constructThenFailOnNullPointerException("", null) } - private void constructThenFailOnNullPointerException(String pattern, String shadedPattern) { + private static void constructThenFailOnNullPointerException(String pattern, String shadedPattern) { try { new SimpleRelocator(pattern, shadedPattern, Collections. emptyList(), Collections. emptyList()) } - catch (NullPointerException e) { + catch (NullPointerException ignored) { fail("Constructor should not throw null pointer exceptions") } } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerParameterTests.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerParameterTests.groovy index 055ed8503..df38dc5cf 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerParameterTests.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerParameterTests.groovy @@ -74,7 +74,7 @@ class ApacheNoticeResourceTransformerParameterTests extends TestCase { final List emptyList = Collections.emptyList() subject.transform(TransformerContext.builder().path(NOTICE_RESOURCE).is(noticeInputStream).relocators(emptyList).stats(stats).build()) } - catch (NullPointerException e) { + catch (NullPointerException ignored) { fail("Null pointer should not be thrown when no parameters are set.") } } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerTest.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerTest.groovy new file mode 100644 index 000000000..ff23aed96 --- /dev/null +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerTest.groovy @@ -0,0 +1,76 @@ +package com.github.jengelman.gradle.plugins.shadow.transformers + +import com.github.jengelman.gradle.plugins.shadow.ShadowStats +import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator +import org.apache.tools.zip.ZipOutputStream +import org.junit.Before +import org.junit.Test + +import java.util.zip.ZipFile + +import static java.util.Arrays.asList +import static org.junit.Assert.* + +/** + * Test for {@link PropertiesFileTransformer}. + */ +final class PropertiesFileTransformerTest extends TransformerTestSupport { + static final String MANIFEST_NAME = "META-INF/MANIFEST.MF" + + private PropertiesFileTransformer transformer + + @Before + void setUp() { + transformer = new PropertiesFileTransformer() + } + + @Test + void testHasTransformedResource() { + transformer.transform(new TransformerContext(MANIFEST_NAME)) + + assertTrue(transformer.hasTransformedResource()) + } + + @Test + void testHasNotTransformedResource() { + assertFalse(transformer.hasTransformedResource()) + } + + @Test + void testTransformation() { + transformer.transform(new TransformerContext(MANIFEST_NAME, getResourceStream(MANIFEST_NAME), Collections.emptyList(), new ShadowStats())) + + def testableZipFile = File.createTempFile("testable-zip-file-", ".jar") + def fileOutputStream = new FileOutputStream(testableZipFile) + def bufferedOutputStream = new BufferedOutputStream(fileOutputStream) + def zipOutputStream = new ZipOutputStream(bufferedOutputStream) + + try { + transformer.modifyOutputStream(zipOutputStream, false) + } finally { + zipOutputStream.close() + } + def targetLines = readFrom(testableZipFile, MANIFEST_NAME) + + assertFalse(targetLines.isEmpty()) + + assertTrue(targetLines.contains("Manifest-Version=1.0")) + } + + static List readFrom(File jarFile, String resourceName) { + def zip = new ZipFile(jarFile) + try { + def entry = zip.getEntry(resourceName) + if (!entry) { + return Collections.emptyList() + } + return zip.getInputStream(entry).readLines() + } finally { + zip.close() + } + } + + InputStream getResourceStream(String resource) { + this.class.classLoader.getResourceAsStream(resource) + } +} diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy index 7d6040058..0a4414128 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy @@ -48,7 +48,7 @@ class AppendableMavenFileModule extends MavenFileModule { return artifactFile } - void writeJar(OutputStream os, Map contents) { + static void writeJar(OutputStream os, Map contents) { if (contents) { JarBuilder builder = new JarBuilder(os) contents.each { path, content -> diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashUtil.java b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashUtil.java new file mode 100644 index 000000000..c3c41596d --- /dev/null +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashUtil.java @@ -0,0 +1,92 @@ +package com.github.jengelman.gradle.plugins.shadow.util; + +import org.gradle.api.UncheckedIOException; +import org.gradle.internal.UncheckedException; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class HashUtil { + public static HashValue createHash(File file, String algorithm) { + try { + return createHash(new FileInputStream(file), algorithm); + } catch (UncheckedIOException e) { + // Catch any unchecked io exceptions and add the file path for troubleshooting + throw new UncheckedIOException(String.format("Failed to create %s hash for file %s.", algorithm, file.getAbsolutePath()), e.getCause()); + } catch (FileNotFoundException e) { + throw new UncheckedIOException(e); + } + } + + private static HashValue createHash(InputStream instr, String algorithm) { + MessageDigest messageDigest; + try { + messageDigest = createMessageDigest(algorithm); + byte[] buffer = new byte[4096]; + try { + while (true) { + int nread = instr.read(buffer); + if (nread < 0) { + break; + } + messageDigest.update(buffer, 0, nread); + } + } finally { + instr.close(); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return new HashValue(messageDigest.digest()); + } + + private static MessageDigest createMessageDigest(String algorithm) { + try { + return MessageDigest.getInstance(algorithm); + } catch (NoSuchAlgorithmException e) { + throw UncheckedException.throwAsUncheckedException(e); + } + } + + public static HashValue sha1(byte[] bytes) { + return createHash(new ByteArrayInputStream(bytes), "SHA1"); + } + + public static HashValue sha1(InputStream inputStream) { + return createHash(inputStream, "SHA1"); + } + + public static HashValue md5(File file) { + return createHash(file, "MD5"); + } + + public static HashValue sha1(File file) { + return createHash(file, "SHA1"); + } + + public static HashValue sha256(byte[] bytes) { + return createHash(new ByteArrayInputStream(bytes), "SHA-256"); + } + + public static HashValue sha256(InputStream inputStream) { + return createHash(inputStream, "SHA-256"); + } + + public static HashValue sha256(File file) { + return createHash(file, "SHA-256"); + } + + public static HashValue sha512(InputStream inputStream) { + return createHash(inputStream, "SHA-512"); + } + + public static HashValue sha512(File file) { + return createHash(file, "SHA-512"); + } +} + diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashValue.java b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashValue.java new file mode 100644 index 000000000..0812eeb1a --- /dev/null +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashValue.java @@ -0,0 +1,75 @@ +package com.github.jengelman.gradle.plugins.shadow.util; + +import java.math.BigInteger; + +public class HashValue { + private final BigInteger digest; + + public HashValue(byte[] digest) { + this.digest = new BigInteger(1, digest); + } + + public HashValue(String hexString) { + this.digest = new BigInteger(hexString, 16); + } + + public static HashValue parse(String inputString) { + if (inputString == null || inputString.length() == 0) { + return null; + } + return new HashValue(parseInput(inputString)); + } + + private static String parseInput(String inputString) { + if (inputString == null) { + return null; + } + String cleaned = inputString.trim().toLowerCase(); + int spaceIndex = cleaned.indexOf(' '); + if (spaceIndex != -1) { + String firstPart = cleaned.substring(0, spaceIndex); + if (firstPart.startsWith("md") || firstPart.startsWith("sha")) { + cleaned = cleaned.substring(cleaned.lastIndexOf(' ') + 1); + } else if (firstPart.endsWith(":")) { + cleaned = cleaned.substring(spaceIndex + 1).replace(" ", ""); + } else { + cleaned = cleaned.substring(0, spaceIndex); + } + } + return cleaned; + } + + public String asCompactString() { + return digest.toString(36); + } + + public String asHexString() { + return digest.toString(16); + } + + public byte[] asByteArray() { + return digest.toByteArray(); + } + + public BigInteger asBigInteger() { + return digest; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof HashValue)) { + return false; + } + + HashValue otherHashValue = (HashValue) other; + return digest.equals(otherHashValue.digest); + } + + @Override + public int hashCode() { + return digest.hashCode(); + } +} diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestDirectoryProvider.java b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestDirectoryProvider.java index 179781612..9aacdbd8a 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestDirectoryProvider.java +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestDirectoryProvider.java @@ -2,7 +2,7 @@ /** * Implementations provide a working space to be used in tests. - * + *

* The client is not responsible for removing any files. */ public interface TestDirectoryProvider { diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java index b6d395d90..5e1254b38 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java @@ -106,7 +106,7 @@ public TestFile file(Object... path) { } public List files(Object... paths) { - List files = new ArrayList(); + List files = new ArrayList<>(); for (Object path : paths) { files.add(file(path)); } @@ -163,16 +163,13 @@ public Map getProperties() { assertIsFile(); Properties properties = new Properties(); try { - FileInputStream inStream = new FileInputStream(this); - try { + try (FileInputStream inStream = new FileInputStream(this)) { properties.load(inStream); - } finally { - inStream.close(); } } catch (IOException e) { throw new RuntimeException(e); } - Map map = new HashMap(); + Map map = new HashMap<>(); for (Object key : properties.keySet()) { map.put(key.toString(), properties.getProperty(key.toString())); } @@ -182,11 +179,8 @@ public Map getProperties() { public Manifest getManifest() { assertIsFile(); try { - JarFile jarFile = new JarFile(this); - try { + try (JarFile jarFile = new JarFile(this)) { return jarFile.getManifest(); - } finally { - jarFile.close(); } } catch (IOException e) { throw new RuntimeException(e); @@ -195,9 +189,8 @@ public Manifest getManifest() { public List linesThat(Matcher matcher) { try { - BufferedReader reader = new BufferedReader(new FileReader(this)); - try { - List lines = new ArrayList(); + try (BufferedReader reader = new BufferedReader(new FileReader(this))) { + List lines = new ArrayList<>(); String line; while ((line = reader.readLine()) != null) { if (matcher.matches(line)) { @@ -205,8 +198,6 @@ public List linesThat(Matcher matcher) { } } return lines; - } finally { - reader.close(); } } catch (IOException e) { throw new RuntimeException(e); @@ -383,14 +374,14 @@ public int getMode() { * Asserts that this file contains exactly the given set of descendants. */ public TestFile assertHasDescendants(String... descendants) { - Set actual = new TreeSet(); + Set actual = new TreeSet<>(); assertIsDir(); visit(actual, "", this); - Set expected = new TreeSet(Arrays.asList(descendants)); + Set expected = new TreeSet<>(Arrays.asList(descendants)); - Set extras = new TreeSet(actual); + Set extras = new TreeSet<>(actual); extras.removeAll(expected); - Set missing = new TreeSet(expected); + Set missing = new TreeSet<>(expected); missing.removeAll(actual); assertEquals(String.format("For dir: %s, extra files: %s, missing files: %s, expected: %s", this, extras, missing, expected), expected, actual); @@ -544,11 +535,8 @@ public void writeProperties(Map properties) { Properties props = new Properties(); props.putAll(properties); try { - FileOutputStream stream = new FileOutputStream(this); - try { + try (FileOutputStream stream = new FileOutputStream(this)) { props.store(stream, "comment"); - } finally { - stream.close(); } } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFileHelper.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFileHelper.groovy index c1515095f..03dc96c9f 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFileHelper.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFileHelper.groovy @@ -1,4 +1,4 @@ -package com.github.jengelman.gradle.plugins.shadow.util.file; +package com.github.jengelman.gradle.plugins.shadow.util.file import org.apache.commons.io.FileUtils import org.apache.commons.lang3.StringUtils @@ -81,7 +81,7 @@ class TestFileHelper { untar.execute() } - private boolean isUnix() { + private static boolean isUnix() { return !System.getProperty('os.name').toLowerCase().contains('windows') } @@ -119,7 +119,7 @@ class TestFileHelper { } } - private int toMode(String permissions) { + private static int toMode(String permissions) { int m = [6, 3, 0].inject(0) { mode, pos -> mode |= permissions[9 - pos - 3] == 'r' ? 4 << pos : 0 mode |= permissions[9 - pos - 2] == 'w' ? 2 << pos : 0 @@ -142,7 +142,7 @@ class TestFileHelper { throw new RuntimeException("Could not delete '$file': $error") } } else { - FileUtils.deleteQuietly(file); + FileUtils.deleteQuietly(file) } } @@ -170,32 +170,32 @@ class TestFileHelper { return new ExecOutput(output, error) } - public void zipTo(TestFile zipFile, boolean nativeTools) { + void zipTo(TestFile zipFile, boolean nativeTools) { if (nativeTools && isUnix()) { def process = ['zip', zipFile.absolutePath, "-r", file.name].execute(null, zipFile.parentFile) process.consumeProcessOutput(System.out, System.err) assert process.waitFor() == 0 } else { - Zip zip = new Zip(); - zip.setBasedir(file); - zip.setDestFile(zipFile); - zip.setProject(new Project()); + Zip zip = new Zip() + zip.setBasedir(file) + zip.setDestFile(zipFile) + zip.setProject(new Project()) def whenEmpty = new Zip.WhenEmpty() whenEmpty.setValue("create") - zip.setWhenempty(whenEmpty); - zip.execute(); + zip.setWhenempty(whenEmpty) + zip.execute() } } - public void tarTo(TestFile tarFile, boolean nativeTools) { + void tarTo(TestFile tarFile, boolean nativeTools) { if (nativeTools && isUnix()) { def process = ['tar', "-cf", tarFile.absolutePath, file.name].execute(null, tarFile.parentFile) process.consumeProcessOutput(System.out, System.err) assert process.waitFor() == 0 } else { - Tar tar = new Tar(); - tar.setBasedir(file); - tar.setDestFile(tarFile); + Tar tar = new Tar() + tar.setBasedir(file) + tar.setDestFile(tarFile) tar.setProject(new Project()) tar.execute() } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestNameTestDirectoryProvider.java b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestNameTestDirectoryProvider.java index 59f9642a8..8af8fd1ec 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestNameTestDirectoryProvider.java +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestNameTestDirectoryProvider.java @@ -2,6 +2,7 @@ import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; import org.junit.rules.MethodRule; import org.junit.rules.TestRule; import org.junit.runner.Description; @@ -17,8 +18,8 @@ public class TestNameTestDirectoryProvider implements MethodRule, TestRule, TestDirectoryProvider { private TestFile dir; private String prefix; - private static TestFile root; - private static AtomicInteger testCounter = new AtomicInteger(1); + private static final TestFile root; + private static final AtomicInteger testCounter = new AtomicInteger(1); static { // NOTE: the space in the directory name is intentional @@ -47,7 +48,7 @@ public void evaluate() throws Throwable { }; } - public Statement apply(final Statement base, Description description) { + public Statement apply(final @NotNull Statement base, Description description) { init(description.getMethodName(), description.getTestClass().getSimpleName()); return new Statement() { @Override @@ -101,14 +102,14 @@ public TestFile getTestDirectory() { } public TestFile file(Object... path) { - return getTestDirectory().file((Object[]) path); + return getTestDirectory().file(path); } public TestFile createFile(Object... path) { - return file((Object[]) path).createFile(); + return file(path).createFile(); } public TestFile createDir(Object... path) { - return file((Object[]) path).createDir(); + return file(path).createDir(); } } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestWorkspaceBuilder.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestWorkspaceBuilder.groovy index ef54d933a..34ca1ff23 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestWorkspaceBuilder.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestWorkspaceBuilder.groovy @@ -6,9 +6,9 @@ package com.github.jengelman.gradle.plugins.shadow.util.file * Should be inner class of TestFile, but can't because Groovy has issues with inner classes as delegates. */ class TestWorkspaceBuilder { - def TestFile baseDir + TestFile baseDir - def TestWorkspaceBuilder(TestFile baseDir) { + TestWorkspaceBuilder(TestFile baseDir) { this.baseDir = baseDir } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy index 4b9be7c67..ea5504ec7 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy @@ -1,8 +1,7 @@ package com.github.jengelman.gradle.plugins.shadow.util.repo +import com.github.jengelman.gradle.plugins.shadow.util.HashUtil import com.github.jengelman.gradle.plugins.shadow.util.file.TestFile -import org.gradle.internal.hash.HashUtil - abstract class AbstractModule { /** @@ -48,34 +47,34 @@ abstract class AbstractModule { protected abstract onPublish(TestFile file) - TestFile getSha1File(TestFile file) { + static TestFile getSha1File(TestFile file) { getHashFile(file, "sha1") } - TestFile sha1File(TestFile file) { + static TestFile sha1File(TestFile file) { hashFile(file, "sha1", 40) } - TestFile getMd5File(TestFile file) { + static TestFile getMd5File(TestFile file) { getHashFile(file, "md5") } - TestFile md5File(TestFile file) { + static TestFile md5File(TestFile file) { hashFile(file, "md5", 32) } - private TestFile hashFile(TestFile file, String algorithm, int len) { + private static TestFile hashFile(TestFile file, String algorithm, int len) { def hashFile = getHashFile(file, algorithm) def hash = getHash(file, algorithm) hashFile.text = String.format("%0${len}x", hash) return hashFile } - private TestFile getHashFile(TestFile file, String algorithm) { + private static TestFile getHashFile(TestFile file, String algorithm) { file.parentFile.file("${file.name}.${algorithm}") } - protected BigInteger getHash(TestFile file, String algorithm) { + private static BigInteger getHash(TestFile file, String algorithm) { HashUtil.createHash(file, algorithm.toUpperCase()).asBigInteger() } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/AbstractMavenModule.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/AbstractMavenModule.groovy index 837755074..6d0ff135a 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/AbstractMavenModule.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/AbstractMavenModule.groovy @@ -228,7 +228,7 @@ abstract class AbstractMavenModule extends AbstractModule implements MavenModule } publish(pomFile) { Writer writer -> - def pomPackaging = packaging ?: type; + def pomPackaging = packaging ?: type writer << """ @@ -271,7 +271,7 @@ abstract class AbstractMavenModule extends AbstractModule implements MavenModule private void updateRootMavenMetaData(TestFile rootMavenMetaData) { def allVersions = rootMavenMetaData.exists() ? new XmlParser().parseText(rootMavenMetaData.text).versioning.versions.version*.value().flatten() : [] - allVersions << version; + allVersions << version publish(rootMavenMetaData) { Writer writer -> def builder = new MarkupBuilder(writer) builder.metadata { diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenDependency.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenDependency.groovy index 789251310..56db25320 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenDependency.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenDependency.groovy @@ -13,7 +13,7 @@ class MavenDependency { } @Override - public String toString() { + String toString() { return String.format("MavenDependency %s:%s:%s:%s@%s", groupId, artifactId, version, classifier, type) } } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenFileModule.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenFileModule.groovy index 7696ee177..064e53a7f 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenFileModule.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenFileModule.groovy @@ -3,7 +3,7 @@ package com.github.jengelman.gradle.plugins.shadow.util.repo.maven import com.github.jengelman.gradle.plugins.shadow.util.file.TestFile class MavenFileModule extends AbstractMavenModule { - private boolean uniqueSnapshots = true; + private boolean uniqueSnapshots = true MavenFileModule(TestFile moduleDir, String groupId, String artifactId, String version) { super(moduleDir, groupId, artifactId, version) @@ -14,8 +14,8 @@ class MavenFileModule extends AbstractMavenModule { } MavenModule withNonUniqueSnapshots() { - uniqueSnapshots = false; - return this; + uniqueSnapshots = false + return this } @Override diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenMetaData.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenMetaData.groovy index bdceb46f6..0a3b49b11 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenMetaData.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/maven/MavenMetaData.groovy @@ -1,6 +1,6 @@ package com.github.jengelman.gradle.plugins.shadow.util.repo.maven -public interface MavenMetaData { +interface MavenMetaData { List getVersions(); }