Skip to content
Draft
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
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 if the wrong `DuplicatesStrategy` values are applied in the Gradle configurations 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,29 @@
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

internal fun ResourceTransformer.checkDupStrategy(
canTransformResource: Boolean,
element: FileTreeElement,
) {
when {
!canTransformResource -> 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,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.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,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.unsafeLazy
import org.gradle.api.file.FileTreeElement
import org.gradle.api.specs.Spec
Expand All @@ -24,7 +25,7 @@ public abstract class PatternFilterableResourceTransformer(
}

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

@Input // Trigger task executions after includes changed.
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)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.jengelman.gradle.plugins.shadow.transformers

import com.github.jengelman.gradle.plugins.shadow.internal.ReproducibleProperties
import com.github.jengelman.gradle.plugins.shadow.internal.checkDupStrategy
import com.github.jengelman.gradle.plugins.shadow.internal.mapProperty
import com.github.jengelman.gradle.plugins.shadow.internal.property
import com.github.jengelman.gradle.plugins.shadow.internal.setProperty
Expand Down Expand Up @@ -137,7 +138,7 @@ constructor(final override val objectFactory: ObjectFactory) : ResourceTransform
path in paths -> true
paths.any { it.toRegex().containsMatchIn(path) } -> true
else -> mappings.isEmpty() && paths.isEmpty() && path.endsWith(PROPERTIES_SUFFIX)
}
}.also { checkDupStrategy(it, 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.property
import com.github.jengelman.gradle.plugins.shadow.internal.zipEntry
import java.io.IOException
Expand Down Expand Up @@ -38,7 +39,9 @@ constructor(final override val objectFactory: ObjectFactory) : ResourceTransform
@get:Input public open val resource: Property<String> = objectFactory.property("")

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