Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions api/shadow.api
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,25 @@ public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/Dependenc
public fun resolve (Lorg/gradle/api/artifacts/Configuration;)Lorg/gradle/api/file/FileCollection;
}

public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/FindResourceInClasspath : org/gradle/api/DefaultTask, org/gradle/api/tasks/util/PatternFilterable {
public fun <init> ()V
public fun <init> (Lorg/gradle/api/tasks/util/PatternSet;)V
public synthetic fun <init> (Lorg/gradle/api/tasks/util/PatternSet;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun exclude (Lgroovy/lang/Closure;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun exclude (Ljava/lang/Iterable;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun exclude (Lorg/gradle/api/specs/Spec;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun exclude ([Ljava/lang/String;)Lorg/gradle/api/tasks/util/PatternFilterable;
public abstract fun getClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
public fun getExcludes ()Ljava/util/Set;
public fun getIncludes ()Ljava/util/Set;
public fun include (Lgroovy/lang/Closure;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun include (Ljava/lang/Iterable;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun include (Lorg/gradle/api/specs/Spec;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun include ([Ljava/lang/String;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun setExcludes (Ljava/lang/Iterable;)Lorg/gradle/api/tasks/util/PatternFilterable;
public fun setIncludes (Ljava/lang/Iterable;)Lorg/gradle/api/tasks/util/PatternFilterable;
}

public abstract interface class com/github/jengelman/gradle/plugins/shadow/tasks/InheritManifest : org/gradle/api/java/archives/Manifest {
public fun inheritFrom ([Ljava/lang/Object;)V
public abstract fun inheritFrom ([Ljava/lang/Object;Lorg/gradle/api/Action;)V
Expand Down Expand Up @@ -308,6 +327,14 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsX
public final class com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer$Companion {
}

public class com/github/jengelman/gradle/plugins/shadow/transformers/DeduplicatingResourceTransformer : com/github/jengelman/gradle/plugins/shadow/transformers/PatternFilterableResourceTransformer {
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Lorg/gradle/api/tasks/util/PatternSet;)V
public fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
public final fun getObjectFactory ()Lorg/gradle/api/model/ObjectFactory;
public fun hasTransformedResource ()Z
public fun modifyOutputStream (Lorg/apache/tools/zip/ZipOutputStream;Z)V
}

public class com/github/jengelman/gradle/plugins/shadow/transformers/DontIncludeResourceTransformer : com/github/jengelman/gradle/plugins/shadow/transformers/ResourceTransformer {
public fun <init> (Lorg/gradle/api/model/ObjectFactory;)V
public fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
Expand Down Expand Up @@ -382,6 +409,21 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ManifestRes
public fun transform (Lcom/github/jengelman/gradle/plugins/shadow/transformers/TransformerContext;)V
}

public class com/github/jengelman/gradle/plugins/shadow/transformers/MergeLicenseResourceTransformer : com/github/jengelman/gradle/plugins/shadow/transformers/PatternFilterableResourceTransformer {
public fun <init> (Lorg/gradle/api/model/ObjectFactory;)V
public fun <init> (Lorg/gradle/api/model/ObjectFactory;Lorg/gradle/api/tasks/util/PatternSet;)V
public final fun getArtifactLicense ()Lorg/gradle/api/file/RegularFileProperty;
public final fun getArtifactLicenseSpdxId ()Lorg/gradle/api/provider/Property;
public fun getExcludes ()Ljava/util/Set;
public final fun getFirstSeparator ()Lorg/gradle/api/provider/Property;
public fun getIncludes ()Ljava/util/Set;
public final fun getOutputPath ()Lorg/gradle/api/provider/Property;
public final fun getSeparator ()Lorg/gradle/api/provider/Property;
public fun hasTransformedResource ()Z
public fun modifyOutputStream (Lorg/apache/tools/zip/ZipOutputStream;Z)V
public fun transform (Lcom/github/jengelman/gradle/plugins/shadow/transformers/TransformerContext;)V
}

public abstract class com/github/jengelman/gradle/plugins/shadow/transformers/PatternFilterableResourceTransformer : com/github/jengelman/gradle/plugins/shadow/transformers/ResourceTransformer, org/gradle/api/tasks/util/PatternFilterable {
public fun <init> (Lorg/gradle/api/tasks/util/PatternSet;)V
public fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
Expand Down Expand Up @@ -419,6 +461,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesF
public fun <init> (Lorg/gradle/api/model/ObjectFactory;)V
public fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
public fun getCharsetName ()Lorg/gradle/api/provider/Property;
public fun getEscapeUnicode ()Lorg/gradle/api/provider/Property;
public fun getKeyTransformer ()Lkotlin/jvm/functions/Function1;
public fun getMappings ()Lorg/gradle/api/provider/MapProperty;
public fun getMergeSeparator ()Lorg/gradle/api/provider/Property;
Expand All @@ -434,6 +477,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesF
public final class com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer$MergeStrategy : java/lang/Enum {
public static final field Append Lcom/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer$MergeStrategy;
public static final field Companion Lcom/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer$MergeStrategy$Companion;
public static final field Fail Lcom/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer$MergeStrategy;
public static final field First Lcom/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer$MergeStrategy;
public static final field Latest Lcom/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer$MergeStrategy;
public static final fun from (Ljava/lang/String;)Lcom/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer$MergeStrategy;
Expand Down
1 change: 1 addition & 0 deletions docs/changes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Expose `patternSet` of `ApacheNoticeResourceTransformer` as `public`. ([#1850](https://github.com/GradleUp/shadow/pull/1850))
- Expose `patternSet` of `PreserveFirstFoundResourceTransformer` as `public`. ([#1855](https://github.com/GradleUp/shadow/pull/1855))
- Support overriding output path of `ApacheNoticeResourceTransformer`. ([#1851](https://github.com/GradleUp/shadow/pull/1851))
- Add new merge strategy 'fail' to `PropertiesFileTransformer`. ([#1856](https://github.com/GradleUp/shadow/pull/1856))

### Changed

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import assertk.assertThat
import assertk.assertions.any
import assertk.assertions.containsExactlyInAnyOrder
import assertk.assertions.containsSubList
import assertk.assertions.endsWith
import assertk.assertions.isEqualTo
import assertk.assertions.isSameInstanceAs
import com.github.jengelman.gradle.plugins.shadow.testkit.containsExactlyInAnyOrder
import com.github.jengelman.gradle.plugins.shadow.testkit.containsOnly
import com.github.jengelman.gradle.plugins.shadow.testkit.getContent
import com.github.jengelman.gradle.plugins.shadow.testkit.getContents
import kotlin.booleanArrayOf
import kotlin.io.path.appendText
import org.gradle.testkit.runner.TaskOutcome
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource

class DeduplicatingResourceTransformerTest : BaseTransformerTest() {
@ParameterizedTest
@ValueSource(booleans = [false, true])
fun conflictExclusion(excludeAll: Boolean) {
val one = buildJarOne {
insert("multiple-contents", "content")
insert("single-source", "content")
insert("same-content-twice", "content")
insert("differing-content-2", "content")
}
val two = buildJarTwo {
insert("multiple-contents", "content-is-different")
insert("same-content-twice", "content")
insert("differing-content-2", "content-is-different")
}

projectScript.appendText(
transform<DeduplicatingResourceTransformer>(
dependenciesBlock = implementationFiles(one, two),
transformerBlock = """
exclude("multiple-contents")
${if (excludeAll) "exclude(\"differing-content-2\")" else ""}
""".trimIndent(),
),
)

if (excludeAll) {
runWithSuccess(shadowJarPath)
assertThat(outputShadowedJar).useAll {
containsExactlyInAnyOrder(
// twice:
"multiple-contents",
"multiple-contents",
"single-source",
"same-content-twice",
// twice:
"differing-content-2",
"differing-content-2",
"META-INF/",
"META-INF/MANIFEST.MF",
)
getContents("multiple-contents").containsExactlyInAnyOrder("content", "content-is-different")
getContent("single-source").isEqualTo("content")
getContent("same-content-twice").isEqualTo("content")
getContents("differing-content-2").containsExactlyInAnyOrder("content", "content-is-different")
}
} else {
val buildResult = runWithFailure(shadowJarPath)
assertThat(buildResult.task(":shadowJar")!!.outcome).isSameInstanceAs(TaskOutcome.FAILED)
val outputLines = buildResult.output.lines()
assertThat(outputLines).containsSubList(
listOf(
// Keep this list approach for Unix/Windows test compatibility.
"Execution failed for task ':shadowJar'.",
"> Found 1 path duplicate(s) with different content in the shadow JAR:",
" * differing-content-2",
),
)
assertThat(outputLines).any {
it.endsWith("/differing-content-2 (Hash: -1337566116240053116)")
}
assertThat(outputLines).any {
it.endsWith("/differing-content-2 (Hash: -6159701213549668473)")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.containsExactly
import assertk.assertions.isEqualTo
import com.github.jengelman.gradle.plugins.shadow.testkit.containsExactlyInAnyOrder
import com.github.jengelman.gradle.plugins.shadow.testkit.getContent
import kotlin.io.path.appendText
import kotlin.io.path.writeText
import kotlin.text.lines
import org.junit.jupiter.api.Test

class MergeLicenseResourceTransformerTest : BaseTransformerTest() {

@Test
fun twoLicenses() {
val one = buildJarOne {
insert("META-INF/LICENSE", "license one")
}
val two = buildJarTwo {
insert("META-INF/LICENSE", "license two")
}

val artifactLicense = projectRoot.resolve("my-license")
artifactLicense.writeText("artifact license text")

projectScript.appendText(
transform<MergeLicenseResourceTransformer>(
dependenciesBlock = implementationFiles(one, two),
transformerBlock = """
outputPath = 'MY_LICENSE'
artifactLicense = file('my-license')
firstSeparator = '####'
separator = '----'
""".trimIndent(),
),
)

runWithSuccess(shadowJarPath)

assertThat(outputShadowedJar).useAll {
containsExactlyInAnyOrder(
"MY_LICENSE",
"META-INF/",
"META-INF/MANIFEST.MF",
)
getContent("MY_LICENSE").given {
assertThat(it.lines()).isEqualTo(
listOf(
"artifact license text",
"####",
"license one",
"----",
"license two",
),
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import assertk.assertThat
import assertk.assertions.isEqualTo
import com.github.jengelman.gradle.plugins.shadow.testkit.containsOnly
import com.github.jengelman.gradle.plugins.shadow.testkit.getContent
import kotlin.io.path.appendText
import org.junit.jupiter.api.Test

class PreserveFirstFoundResourceTransformerTest : BaseTransformerTest() {
@Test
fun smokeTest() {
val one = buildJarOne {
insert("dup", "content")
insert("foo", "content-foo")
}
val two = buildJarTwo {
insert("dup", "content-different")
insert("bar", "content-bar")
}

projectScript.appendText(
transform<PreserveFirstFoundResourceTransformer>(
dependenciesBlock = implementationFiles(one, two),
transformerBlock = """
exclude("multiple-contents")
""".trimIndent(),
),
)

runWithSuccess(shadowJarPath)

assertThat(outputShadowedJar).useAll {
containsOnly("dup", "foo", "bar", "META-INF/", "META-INF/MANIFEST.MF")
getContent("dup").isEqualTo("content")
getContent("foo").isEqualTo("content-foo")
getContent("bar").isEqualTo("content-bar")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package com.github.jengelman.gradle.plugins.shadow.transformers

import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.containsSubList
import assertk.assertions.isEqualTo
import assertk.assertions.isSameInstanceAs
import com.github.jengelman.gradle.plugins.shadow.testkit.getContent
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer.MergeStrategy
import com.github.jengelman.gradle.plugins.shadow.util.Issue
import kotlin.io.path.appendText
import org.gradle.testkit.runner.TaskOutcome
import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.EnumSource
Expand All @@ -33,15 +37,31 @@ class PropertiesFileTransformerTest : BaseTransformerTest() {
),
)

runWithSuccess(shadowJarPath)

val expected = when (strategy) {
MergeStrategy.First -> arrayOf("key1=one", "key2=one", "key3=two")
MergeStrategy.Latest -> arrayOf("key1=one", "key2=two", "key3=two")
MergeStrategy.Append -> arrayOf("key1=one", "key2=one;two", "key3=two")
if (strategy == MergeStrategy.Fail) {
val run = runWithFailure(shadowJarPath)
val taskOutcome = run.task(":shadowJar")!!
assertThat(taskOutcome.outcome).isSameInstanceAs(TaskOutcome.FAILED)
assertThat(run.output.lines()).containsSubList(
listOf(
// Keep this list approach for Unix/Windows test compatibility.
"Execution failed for task ':shadowJar'.",
"> The following properties files have conflicting property values and cannot be merged:",
" * META-INF/test.properties",
" * Property key2 is duplicated 2 times with different values",
),
)
} else {
runWithSuccess(shadowJarPath)

val expected = when (strategy) {
MergeStrategy.First -> arrayOf("key1=one", "key2=one", "key3=two")
MergeStrategy.Latest -> arrayOf("key1=one", "key2=two", "key3=two")
MergeStrategy.Append -> arrayOf("key1=one", "key2=one;two", "key3=two")
else -> fail("Unexpected strategy: $strategy")
}
val content = outputShadowedJar.use { it.getContent("META-INF/test.properties") }
assertThat(content).contains(*expected)
}
val content = outputShadowedJar.use { it.getContent("META-INF/test.properties") }
assertThat(content).contains(*expected)
}

@Test
Expand Down Expand Up @@ -151,8 +171,6 @@ class PropertiesFileTransformerTest : BaseTransformerTest() {
val content = outputShadowedJar.use { it.getContent("META-INF/test.properties") }
assertThat(content.trimIndent()).isEqualTo(
"""
#

foo=one,two
""".trimIndent(),
)
Expand Down

This file was deleted.

Loading
Loading