diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt index be80e5e49..7859b117d 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt @@ -1,6 +1,8 @@ package com.github.jengelman.gradle.plugins.shadow import assertk.assertThat +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar.Companion.SHADOW_JAR_TASK_NAME +import com.github.jengelman.gradle.plugins.shadow.testkit.containsAtLeast import com.github.jengelman.gradle.plugins.shadow.testkit.containsOnly import com.github.jengelman.gradle.plugins.shadow.util.Issue import kotlin.io.path.appendText @@ -247,6 +249,81 @@ class FilteringTest : BasePluginTest() { } } + @Issue("https://github.com/GradleUp/shadow/issues/882") + @Test + fun shadowJarWithArtifactTransformOnProjectDependency() { + settingsScript.appendText( + """ + include 'lib', 'app' + """ + .trimIndent() + ) + projectScript.writeText("") + + path("lib/src/main/java/lib/Lib.java") + .writeText( + """ + package lib; + public class Lib {} + """ + .trimIndent() + ) + path("lib/build.gradle").writeText(getDefaultProjectBuildScript("java") + lineSeparator) + + path("app/src/main/java/app/App.java") + .writeText( + """ + package app; + public class App {} + """ + .trimIndent() + ) + path("app/build.gradle") + .writeText( + """ + ${getDefaultProjectBuildScript("java")} + + abstract class NoOpTransform implements TransformAction { + @InputArtifact + abstract Provider getInputArtifact() + + void transform(TransformOutputs outputs) { + def input = inputArtifact.get().asFile + def output = outputs.file(input.name) + output.bytes = input.bytes + } + } + + def customAttr = Attribute.of('custom-transformed', Boolean) + + dependencies { + implementation project(':lib') + attributesSchema { + attribute(customAttr) + } + artifactTypes.getByName('jar') { + attributes.attribute(customAttr, false) + } + registerTransform(NoOpTransform) { + from.attribute(customAttr, false) + to.attribute(customAttr, true) + } + } + + configurations.runtimeClasspath { + attributes.attribute(customAttr, true) + } + """ + .trimIndent() + lineSeparator + ) + + runWithSuccess(":app:$SHADOW_JAR_TASK_NAME") + + assertThat(jarPath("app/build/libs/app-1.0-all.jar")).useAll { + containsAtLeast("app/", "app/App.class", *manifestEntries) + } + } + private fun commonAssertions() { assertThat(outputShadowedJar).useAll { containsOnly("c.properties", *entriesInAB, *manifestEntries) diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter.kt index 90d38555b..4a9a668ba 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter.kt @@ -1,6 +1,7 @@ package com.github.jengelman.gradle.plugins.shadow.tasks import java.io.Serializable +import java.util.concurrent.Callable import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency @@ -47,15 +48,22 @@ public interface DependencyFilter : Serializable { ) override fun resolve(configuration: Configuration): FileCollection { - val includes = mutableSetOf() - val excludes = mutableSetOf() - resolve( - dependencies = configuration.resolvedConfiguration.firstLevelModuleDependencies, - includedDependencies = includes, - excludedDependencies = excludes, - ) - return project.files(configuration.files) - - project.files(excludes.flatMap { it.moduleArtifacts.map(ResolvedArtifact::getFile) }) + return project + .files( + Callable { + val includes = mutableSetOf() + val excludes = mutableSetOf() + resolve( + dependencies = configuration.resolvedConfiguration.firstLevelModuleDependencies, + includedDependencies = includes, + excludedDependencies = excludes, + ) + val excludedFiles = + excludes.flatMap { it.moduleArtifacts.map(ResolvedArtifact::getFile) }.toSet() + configuration.files.filter { it !in excludedFiles } + } + ) + .builtBy(configuration) } override fun resolve(configurations: Collection): FileCollection {