Skip to content
Merged
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
9 changes: 9 additions & 0 deletions api/shadow.api
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,13 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ApacheLicen
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 canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
}

public class com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformer : 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 fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
public fun getAddHeader ()Lorg/gradle/api/provider/Property;
public fun getCharsetName ()Lorg/gradle/api/provider/Property;
public fun getCopyright ()Lorg/gradle/api/provider/Property;
Expand Down Expand Up @@ -323,6 +325,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsX
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 canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
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
Expand Down Expand Up @@ -364,6 +367,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExten
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 canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
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
Expand All @@ -388,6 +392,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2Plugi
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 canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
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
Expand All @@ -397,6 +402,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ManifestApp
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 fun append (Ljava/lang/String;Ljava/lang/Comparable;)V
public fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
public fun getAttributes ()Lorg/gradle/api/provider/SetProperty;
public final fun getObjectFactory ()Lorg/gradle/api/model/ObjectFactory;
public fun hasTransformedResource ()Z
Expand All @@ -408,6 +414,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ManifestRes
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 fun attributes (Ljava/util/Map;)V
public fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
public fun getMainClass ()Lorg/gradle/api/provider/Property;
public fun getManifestEntries ()Lorg/gradle/api/provider/MapProperty;
public final fun getObjectFactory ()Lorg/gradle/api/model/ObjectFactory;
Expand All @@ -419,6 +426,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ManifestRes
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 fun canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
public fun getArtifactLicense ()Lorg/gradle/api/file/RegularFileProperty;
public fun getArtifactLicenseSpdxId ()Lorg/gradle/api/provider/Property;
public fun getFirstSeparator ()Lorg/gradle/api/provider/Property;
Expand Down Expand Up @@ -518,6 +526,7 @@ public class com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFile
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 canTransformResource (Lorg/gradle/api/file/FileTreeElement;)Z
public fun getPath ()Ljava/lang/String;
public fun hasTransformedResource ()Z
public fun modifyOutputStream (Lorg/apache/tools/zip/ZipOutputStream;Z)V
Expand Down
2 changes: 2 additions & 0 deletions docs/changes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

### Added

- Check `DuplicatesStrategy` for merging transformers. ([#2026](https://github.com/GradleUp/shadow/pull/2026))
This will log warnings when an incompatible `DuplicatesStrategy` (e.g., `EXCLUDE`) is applied in Gradle configuration for built-in `ResourceTransformer`s.
- Expose `patternSet` of `ComponentsXmlResourceTransformer` as `public`. ([#2028](https://github.com/GradleUp/shadow/pull/2028))
- Expose `patternSet` of `GroovyExtensionModuleTransformer` as `public`. ([#2028](https://github.com/GradleUp/shadow/pull/2028))
- Expose `patternSet` of `Log4j2PluginsCacheFileTransformer` as `public`. ([#2028](https://github.com/GradleUp/shadow/pull/2028))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.containsMatch
import assertk.assertions.isEqualTo
import com.github.jengelman.gradle.plugins.shadow.testkit.getContent
Expand Down Expand Up @@ -221,7 +222,15 @@ class ServiceFileTransformerTest : BaseTransformerTest() {
) {
writeDuplicatesStrategy(strategy)

runWithSuccess(shadowJarPath)
val result = runWithSuccess(shadowJarPath)

if (strategy == EXCLUDE) {
assertThat(result.output)
.contains(
"'META-INF/services/com.acme.Foo' is matched by com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer but its DuplicatesStrategy is EXCLUDE — duplicates may be silently dropped before the transformer processes them.",
"'META-INF/services/org.apache.maven.Shade' is matched by com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer but its DuplicatesStrategy is EXCLUDE — duplicates may be silently dropped before the transformer processes them.",
)
Comment thread
Goooler marked this conversation as resolved.
}

assertThat(outputShadowedJar).useAll {
getContent(ENTRY_SERVICES_SHADE).isEqualTo(firstValue)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.jengelman.gradle.plugins.shadow.internal

import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.file.FileTreeElement
import org.gradle.api.logging.Logging
import org.jetbrains.annotations.VisibleForTesting

@VisibleForTesting internal var onCheckDupStrategyInvoked: (() -> Unit)? = null

internal fun ResourceTransformer.checkDupStrategy(
matched: Boolean,
element: FileTreeElement,
) {
onCheckDupStrategyInvoked?.invoke()
when {
!matched -> return
element !is FileCopyDetails -> return
element.duplicatesStrategy == DuplicatesStrategy.EXCLUDE -> {
val logger = Logging.getLogger(this::class.java)
logger.warn(
"""
'${element.path}' is matched by ${this::class.qualifiedName} but its DuplicatesStrategy is ${element.duplicatesStrategy} — duplicates may be silently dropped before the transformer processes them.
Set it to INCLUDE or WARN to ensure all duplicates are processed by the transformer.
See https://gradleup.com/shadow/configuration/merging/#handling-duplicates-strategy for more details.
"""
.trimIndent()
Comment thread
Goooler marked this conversation as resolved.
)
}
else -> Unit
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import org.gradle.api.file.FileTreeElement
import org.gradle.api.tasks.util.PatternSet

/**
Expand All @@ -19,6 +21,10 @@ constructor(
.apply { isCaseSensitive = false }
.include(LICENSE_PATH, LICENSE_TXT_PATH, LICENSE_MD_PATH)
) : PatternFilterableResourceTransformer(patternSet = patternSet) {
override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

private companion object {
private const val LICENSE_PATH = "META-INF/LICENSE"
private const val LICENSE_TXT_PATH = "META-INF/LICENSE.txt"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.property
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import java.nio.charset.Charset
Expand All @@ -9,6 +10,7 @@ import java.util.Locale
import java.util.TreeSet
import javax.inject.Inject
import org.apache.tools.zip.ZipOutputStream
import org.gradle.api.file.FileTreeElement
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
Expand Down Expand Up @@ -94,6 +96,10 @@ public open class ApacheNoticeResourceTransformer(
.include(NOTICE_PATH, NOTICE_TXT_PATH, NOTICE_MD_PATH),
)

override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

override fun transform(context: TransformerContext) {
val projectName = projectName.get()
val addHeader = addHeader.get()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.property
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import java.io.ByteArrayOutputStream
Expand Down Expand Up @@ -32,7 +33,9 @@ constructor(final override val objectFactory: ObjectFactory) : ResourceTransform
@get:Input public open val separator: Property<String> = objectFactory.property(DEFAULT_SEPARATOR)

override fun canTransformResource(element: FileTreeElement): Boolean {
return resource.get().equals(element.path, ignoreCase = true)
return resource.get().equals(element.path, ignoreCase = true).also { flag ->
checkDupStrategy(flag, element)
}
}

override fun transform(context: TransformerContext) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import com.github.jengelman.gradle.plugins.shadow.relocation.relocateClass
import java.io.BufferedInputStream
Expand All @@ -11,6 +12,7 @@ import org.codehaus.plexus.util.xml.XmlStreamWriter
import org.codehaus.plexus.util.xml.Xpp3Dom
import org.codehaus.plexus.util.xml.Xpp3DomBuilder
import org.codehaus.plexus.util.xml.Xpp3DomWriter
import org.gradle.api.file.FileTreeElement
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.util.PatternSet

Expand Down Expand Up @@ -45,6 +47,10 @@ constructor(patternSet: PatternSet = PatternSet().include(COMPONENTS_XML_PATH))
return os.toByteArray()
}

override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

override fun transform(context: TransformerContext) {
val newDom =
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.tasks.FindResourceInClasspath
import java.io.File
import javax.inject.Inject
Expand Down Expand Up @@ -66,8 +67,10 @@ public open class DeduplicatingResourceTransformer(
val file = element.file
val hash = file.sha256Hex()

val pathInfos =
sources.computeIfAbsent(element.path) { PathInfos(patternSpec.isSatisfiedBy(element)) }
val flag = patternSpec.isSatisfiedBy(element)
checkDupStrategy(flag, element)

val pathInfos = sources.computeIfAbsent(element.path) { PathInfos(flag) }
val retainInOutput = pathInfos.addFile(hash, file)

return !retainInOutput
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.inputStream
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import com.github.jengelman.gradle.plugins.shadow.relocation.relocateClass
import java.util.Properties
import org.apache.tools.zip.ZipOutputStream
import org.gradle.api.file.FileTreeElement
import org.gradle.api.tasks.util.PatternSet

/**
Expand Down Expand Up @@ -39,6 +41,10 @@ constructor(
) : PatternFilterableResourceTransformer(patternSet) {
private val module = Properties()

override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

override fun transform(context: TransformerContext) {
val props = Properties()
props.load(context.inputStream)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
import com.github.jengelman.gradle.plugins.shadow.relocation.relocateClass
Expand All @@ -14,6 +15,7 @@ import org.apache.commons.io.output.CloseShieldOutputStream
import org.apache.logging.log4j.core.config.plugins.processor.PluginCache
import org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor.PLUGIN_CACHE_FILE
import org.apache.tools.zip.ZipOutputStream
import org.gradle.api.file.FileTreeElement
import org.gradle.api.tasks.util.PatternSet

/**
Expand All @@ -34,6 +36,10 @@ constructor(patternSet: PatternSet = PatternSet().include(PLUGIN_CACHE_FILE)) :
/** [Relocator] instances to share across the transformation stages. */
private val tempRelocators = mutableListOf<Relocator>()

override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

override fun transform(context: TransformerContext) {
val temporaryFile = createTempFile("Log4j2Plugins", ".dat")
tempFiles.add(temporaryFile)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.setProperty
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.util.jar.JarFile.MANIFEST_NAME
import javax.inject.Inject
import org.apache.tools.zip.ZipOutputStream
import org.gradle.api.file.FileTreeElement
import org.gradle.api.logging.Logging
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.SetProperty
Expand Down Expand Up @@ -40,6 +42,10 @@ public open class ManifestAppenderTransformer(
patternSet = PatternSet().apply { isCaseSensitive = false }.include(MANIFEST_NAME),
)

override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

override fun transform(context: TransformerContext) {
if (manifestContents.isEmpty()) {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.mainClassAttributeKey
import com.github.jengelman.gradle.plugins.shadow.internal.mapProperty
import com.github.jengelman.gradle.plugins.shadow.internal.property
Expand All @@ -10,6 +11,7 @@ import java.util.jar.JarFile
import java.util.jar.Manifest
import javax.inject.Inject
import org.apache.tools.zip.ZipOutputStream
import org.gradle.api.file.FileTreeElement
import org.gradle.api.logging.Logging
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.MapProperty
Expand Down Expand Up @@ -49,6 +51,10 @@ public open class ManifestResourceTransformer(
patternSet = PatternSet().apply { isCaseSensitive = false }.include(JarFile.MANIFEST_NAME),
)

override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

override fun transform(context: TransformerContext) {
// We just want to take the first manifest we come across as that's our project's manifest. This
// is the behavior
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.property
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import java.nio.charset.StandardCharsets.UTF_8
import java.util.LinkedHashSet
import javax.inject.Inject
import org.apache.tools.zip.ZipOutputStream
import org.gradle.api.file.FileTreeElement
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
Expand Down Expand Up @@ -100,6 +102,10 @@ public open class MergeLicenseResourceTransformer(
},
)

override fun canTransformResource(element: FileTreeElement): Boolean {
return super.canTransformResource(element).also { flag -> checkDupStrategy(flag, element) }
}

override fun transform(context: TransformerContext) {
transformInternal(context.inputStream.readAllBytes())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.setProperty
import com.github.jengelman.gradle.plugins.shadow.internal.unsafeLazy
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
Expand Down Expand Up @@ -48,6 +49,8 @@ public open class PreserveFirstFoundResourceTransformer(
override fun canTransformResource(element: FileTreeElement): Boolean {
// Init once before patternSpec is accessed.
includeResources
return patternSpec.isSatisfiedBy(element) && !found.add(element.path)
val flag = patternSpec.isSatisfiedBy(element)
checkDupStrategy(flag, element)
return flag && !found.add(element.path)
}
}
Loading