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
6 changes: 6 additions & 0 deletions api/shadow.api
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,21 @@ public class com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocat
public abstract interface class com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter : java/io/Serializable {
public abstract fun dependency (Ljava/lang/Object;)Lorg/gradle/api/specs/Spec;
public abstract fun exclude (Lorg/gradle/api/specs/Spec;)V
public abstract fun getAddExcludedIntoShadowConfiguration ()Lorg/gradle/api/provider/Property;
public abstract fun include (Lorg/gradle/api/specs/Spec;)V
public abstract fun project (Ljava/lang/Object;)Lorg/gradle/api/specs/Spec;
public abstract fun resolve (Ljava/util/Collection;)Lorg/gradle/api/file/FileCollection;
public abstract fun resolve (Lorg/gradle/api/artifacts/Configuration;)Lorg/gradle/api/file/FileCollection;
public abstract fun resolveExcluded (Ljava/util/Collection;)Lorg/gradle/api/file/FileCollection;
public abstract fun resolveExcluded (Lorg/gradle/api/artifacts/Configuration;)Lorg/gradle/api/file/FileCollection;
}

public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter$AbstractDependencyFilter : com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter {
public fun <init> (Lorg/gradle/api/Project;Ljava/util/List;Ljava/util/List;)V
public synthetic fun <init> (Lorg/gradle/api/Project;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun dependency (Ljava/lang/Object;)Lorg/gradle/api/specs/Spec;
public fun exclude (Lorg/gradle/api/specs/Spec;)V
public fun getAddExcludedIntoShadowConfiguration ()Lorg/gradle/api/provider/Property;
protected final fun getExcludeSpecs ()Ljava/util/List;
protected final fun getIncludeSpecs ()Ljava/util/List;
public fun include (Lorg/gradle/api/specs/Spec;)V
Expand All @@ -175,6 +179,8 @@ public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/Dependenc
public fun resolve (Ljava/util/Collection;)Lorg/gradle/api/file/FileCollection;
protected abstract fun resolve (Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)V
public fun resolve (Lorg/gradle/api/artifacts/Configuration;)Lorg/gradle/api/file/FileCollection;
public fun resolveExcluded (Ljava/util/Collection;)Lorg/gradle/api/file/FileCollection;
public fun resolveExcluded (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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,33 @@ class JavaPluginsTest : BasePluginTest() {
assertThat(value).isEqualTo("junit-3.8.2.jar")
}

@Issue("https://github.com/GradleUp/shadow/issues/265")
@Test
fun addExcludedDependencyIntoShadowConfiguration() {
projectScript.appendText(
"""
dependencies {
shadow 'my:a:1.0'
implementation 'my:b:1.0'
}
$shadowJarTask {
dependencies {
addExcludedIntoShadowConfiguration = true
exclude(dependency('my:b:1.0'))
}
}
"""
.trimIndent()
)

runWithSuccess(shadowJarPath)

assertThat(outputShadowedJar).useAll {
containsOnly(*manifestEntries)
getMainAttr(classPathAttributeKey).isEqualTo("b-1.0.jar a-1.0.jar")
}
}

@Issue("https://github.com/GradleUp/shadow/issues/203")
@ParameterizedTest
@EnumSource(ZipEntryCompression::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ constructor(private val softwareComponentFactory: SoftwareComponentFactory) : Pl
task.configurations.convention(provider { listOf(runtimeConfiguration) })
}
artifacts.add(configurations.shadow.name, taskProvider)

val excludedFiles = taskProvider.map { task ->
val filter = task.dependencyFilter.get()
if (filter.addExcludedIntoShadowConfiguration.get()) {
filter.resolveExcluded(task.configurations.get())
} else {
files()
}
}
dependencies.add(configurations.shadow.name, excludedFiles)
}

protected open fun Project.configureConfigurations() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.jengelman.gradle.plugins.shadow.tasks

import com.github.jengelman.gradle.plugins.shadow.internal.property
import java.io.Serializable
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
Expand All @@ -8,11 +9,22 @@ import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.ResolvedDependency
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.specs.Spec
import org.gradle.api.tasks.Input

// DependencyFilter is used as Gradle Input in ShadowJar, so it must be Serializable.
public interface DependencyFilter : Serializable {
/**
* When `true`, excluded dependencies will be added to the `shadow` configuration. This is useful
* when you want to exclude a dependency from the shadowed JAR, but still want it to be available
* at the `Class-Path` manifest attribute.
*
* Default is `false`.
*/
@get:Input public val addExcludedIntoShadowConfiguration: Property<Boolean>

/** Resolve a [configuration] against the [include]/[exclude] rules in the filter. */
public fun resolve(configuration: Configuration): FileCollection

Expand All @@ -22,6 +34,18 @@ public interface DependencyFilter : Serializable {
*/
public fun resolve(configurations: Collection<Configuration>): FileCollection

/**
* Resolve the excluded files of a [configuration] against the [include]/[exclude] rules in the
* filter.
*/
public fun resolveExcluded(configuration: Configuration): FileCollection

/**
* Resolve the excluded files of all [configurations] against the [include]/[exclude] rules in the
* filter and combine the results.
*/
public fun resolveExcluded(configurations: Collection<Configuration>): FileCollection

/** Exclude dependencies that match the provided [spec]. */
public fun exclude(spec: Spec<ResolvedDependency>)

Expand All @@ -39,6 +63,9 @@ public interface DependencyFilter : Serializable {
@Transient protected val includeSpecs: MutableList<Spec<ResolvedDependency>> = mutableListOf(),
@Transient protected val excludeSpecs: MutableList<Spec<ResolvedDependency>> = mutableListOf(),
) : DependencyFilter {
@Transient
override val addExcludedIntoShadowConfiguration: Property<Boolean> =
project.objects.property(false)

protected abstract fun resolve(
dependencies: Set<ResolvedDependency>,
Expand All @@ -47,19 +74,7 @@ public interface DependencyFilter : Serializable {
)

override fun resolve(configuration: Configuration): FileCollection {
return configuration -
project.files(
project.provider {
val includes = mutableSetOf<ResolvedDependency>()
val excludes = mutableSetOf<ResolvedDependency>()
resolve(
dependencies = configuration.resolvedConfiguration.firstLevelModuleDependencies,
includedDependencies = includes,
excludedDependencies = excludes,
)
excludes.flatMap { it.moduleArtifacts.map(ResolvedArtifact::getFile) }
}
)
return configuration - resolveExcluded(configuration)
}

override fun resolve(configurations: Collection<Configuration>): FileCollection {
Expand All @@ -68,6 +83,27 @@ public interface DependencyFilter : Serializable {
.reduceOrNull { acc, fileCollection -> acc + fileCollection } ?: project.files()
}

override fun resolveExcluded(configuration: Configuration): FileCollection {
return project.files(
project.provider {
val includes = mutableSetOf<ResolvedDependency>()
val excludes = mutableSetOf<ResolvedDependency>()
resolve(
dependencies = configuration.resolvedConfiguration.firstLevelModuleDependencies,
includedDependencies = includes,
excludedDependencies = excludes,
)
excludes.flatMap { it.moduleArtifacts.map(ResolvedArtifact::getFile) }
}
)
}

override fun resolveExcluded(configurations: Collection<Configuration>): FileCollection {
return configurations
.map { resolveExcluded(it) }
.reduceOrNull { acc, fileCollection -> acc + fileCollection } ?: project.files()
}

override fun exclude(spec: Spec<ResolvedDependency>) {
excludeSpecs.add(spec)
}
Expand Down