Filtering configurations using configurations?

Hello! I have a bit of a cursed setup on my hands where i’d need to filter the resolved results of a configuration (“includeTransitive”) (to then register those in another configuration, “include” that is provided by another plugin) by checking if a dependency is already in a manual exclude list or another configuration, “shadowBundle”. Here’s the hacky thing that i currently have set up: gist:51e96b6762102e57c772a1f310e6fb26 · GitHub

Using afterEvaluate like this is, from what i’ve heard, very bad practice, so i’m curious to hear what the best approach here would be. Thanks in advance!

afterEvaluate is practically always bad practice and should be avoided at almost any cost.

Resolving configurations at configuration time is also almost always a bad idea, there are even thoughts about technically forbidding this.

Can’t you just make include to extendsFrom the includeTransitive and declare your excludes on include?

Thanks for the reply!
I’ve tried to configure the include configuration to extend from my own; unfortunately it seems like this doesn’t work out as include is non-transitive, while mine is. This is what i have tried:

configurations {
    create("includeTransitive").isTransitive = true
    create("shadowBundle") {
        isCanBeResolved = true
        isCanBeConsumed = false
        isTransitive = false
    }
    include {
        extendsFrom(configurations["includeTransitive"])
        incoming.beforeResolve {
            providedDependencies[project.name]?.forEach { depString ->
                val parts = depString.split(":", limit = 2)
                if (parts.size == 2) {
                    println("Excluding provided ${parts[0]}:${parts[1]} from ${project.name}")
                    exclude(mapOf("group" to parts[0], "module" to parts[1]))
                } else {
                    // fallback: treat whole string as group
                    println("Excluding provided group $depString from ${project.name}")
                    exclude(mapOf("group" to depString))
                }
            }

            configurations["shadowBundle"].dependencies.forEach { dependency ->
                println("Excluding provided ${dependency.group}:${dependency.name} from ${project.name}")
                exclude(mapOf("group" to dependency.group, "module" to dependency.name))
            }
        }
    }
}

Since shadowBundle is non-transitive, i’m assuming it’s fine to query the dependencies like this?

unfortunately it seems like this doesn’t work out as include is non-transitive

Ah, well, yeah, the resolved configuration decides whether to resolve stuff transitively or non-transitively.
No idea how to do it halfway cleanly then.

The beforeResolve might indeed be the way to go as it is the last possible place before resolution to add further dependencies. :man_shrugging:

Since shadowBundle is non-transitive, i’m assuming it’s fine to query the dependencies like this?

I have no idea, well, you anyway do not resolve it there but just list the declared dependencies, that does not necessarily have much to do with what it would resolve to, transitively or not.