This message was deleted.
# community-support
s
This message was deleted.
v
You can probably have a look at the implementation of the
dependencies
task.
l
Thanks,
dependencies
task uses
configuration.incoming.resolutionResult
- using that I can get to the imported BOMs of my platform. Potentially I could now recurse into them by using another detached configuration. However, whats stopping me, is that I can't figure how to access the version constraints listed in a BOM itself
v
I don't think you need another detached configuration and I repeat my recommendation. Look at the implementation of the
dependencies
task. If you look at the result, you see that it shows the full tree and shows all the constraints (the lines with
(c)
in the end). And I don't think the task makes several resolutions.
Btw. alternatively you could also publish a version catalog for the end users. Then they can import that version catalog and just use the accessors. Then they don't need to care whether the version catalog contains a version for that dependency or not.
l
I don't quite know if I am looking at this right - but to me it seems the
dependencies
tasks lists only constraints on the actual dependencies of a project. However, I want to list all potential constraints of the platform the project is using. For instance my platform is importing spring-boot-bom, cxf-bom and a few more, that's hundreds of potential dependencies which are version managed. I'll have a look at version catalogs, although judging from https://docs.gradle.org/current/userguide/platforms.html#sub:platforms-vs-catalog a platform is what I really want.
v
You can have both. A platform that controls the dependency versions, also transitively and a version catalog they can use to declare dependencies. That way they don't need to look up which dependencies are version controlled or not, they can simply use the accessors.
Hm, regarding the dependencies task you seem to be right. I thought all are shown, but it indeed seems to only list the used ones. But I'd expect the information to still be there and accessible programmatically. But I might be wrong.
l
Yeah, the info has to be in there somewhere 🙂 For the time being I hacked together a brutish solution which resolves the actual Maven BOMs involved and XML-parses them to extract the information. The user can then do:
Copy code
> gradlew findManaged --query=jakarta
Configuration on demand is an incubating feature.

> Task :findManagedDependency
--> Suche nach Dependency mit: jakarta
jakarta.inject:jakarta.inject-api:1.0.5 -> use: implementation("jakarta.inject:jakarta.inject-api")
jakarta.jws:jakarta.jws-api:2.1.0 -> use: implementation("jakarta.jws:jakarta.jws-api")
org.glassfish:jakarta.el:3.0.4 -> use: implementation("org.glassfish:jakarta.el")
...
regarding version catalogs, I'll look into them, though I am not quite sure how to maintain them for the 1500+ dependencies managed by the platform without going insane.
v
I probaby have used an artifact resolution query and a POM parser for that. Similar to how I search for jdk-activated profiles in Maven POMs that add dependencies to then do the needed fixups in the settings script. I'll probably make a plugin out of it, but if you're interseted or want to adapt for your use-case:
Copy code
val checkForJdkActivatedProfiles by tasks.registering {
        doLast {
            val pomReader = MavenXpp3Reader()
    
            fun collectAncestorPoms(pom: ResolvedArtifactResult, result: MutableList<ResolvedArtifactResult>) {
                val parent = FileReader(pom.file)
                    .use { pomReader.read(it) }
                    .parent
                if (parent != null) {
                    val parentPom = dependencies
                        .createArtifactResolutionQuery()
                        .forModule(parent.groupId, parent.artifactId, parent.version)
                        .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java)
                        .execute()
                        .resolvedComponents
                        .asSequence()
                        .flatMap { it.getArtifacts(MavenPomArtifact::class.java).asSequence() }
                        .filterIsInstance<ResolvedArtifactResult>()
                        .single()
                    result.add(parentPom)
                    collectAncestorPoms(parentPom, result)
                }
            }
    
            dependencies
                .createArtifactResolutionQuery()
                .forComponents(configurations.filter { it.isCanBeResolved }.flatMap { configuration ->
                    configuration.incoming.resolutionResult.allDependencies.mapNotNull {
                        (it as? ResolvedDependencyResult)?.selected?.id
                    }
                }.distinct())
                .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java)
                .execute()
                .resolvedComponents
                .asSequence()
                .flatMap { it.getArtifacts(MavenPomArtifact::class.java).asSequence() }
                .filterIsInstance<ResolvedArtifactResult>()
                .map { pom ->
                    val ancestorPoms = mutableListOf<ResolvedArtifactResult>()
                    collectAncestorPoms(pom, ancestorPoms)
                    Pair(pom, ancestorPoms)
                }
                .forEach { (bottomPom, ancestorPoms) ->
                    sequenceOf(bottomPom, *ancestorPoms.toTypedArray()).forEach { pom ->
                        FileReader(pom.file)
                            .use { pomReader.read(it) }
                            .profiles
                            .forEach { profile ->
                                if ((profile.activation?.jdk != null) && (!profile.dependencies.isNullOrEmpty())) {
                                    println("jdk activated Maven profile with dependencies found in ${pom.id}")
                                    if (pom != bottomPom) {
                                        println("ancestor of dependency ${bottomPom.id}")
                                    }
                                }
                            }
                    }
                }
        }
    }
regarding version catalogs, I'll look into them, though I am not quite sure how to maintain them for the 1500+ dependencies managed by the platform without going insane.
Well, you can generate it from the information you just extracted. 🙂
l
😅 indeed, thanks so far 🙌