This message was deleted.
# dependency-management
s
This message was deleted.
j
I might be wrong, but I think this won’t work conceptually. The resolution is happening unfiltered and produces the ’ResolvedComponentResult’s, which point at the components, but not directly at the artifacts behind them. The artifacts are retrieved in the next step (if needed), where an Artifact View possibly intervenes/filters/transforms. If this is correct, you need to do the filtering inside the task. Which is fine from a performance perspective etc., because the resolution result (which is not the artifacts) is constructed in any case.
t
hmmm ok, thanks for the perspective. I'll give it a try (filtering inside the task action)
I'm having trouble making this work. I'm following the Authoring Tasks guide as well as the sample and I'm getting this error:
Copy code
Caused by: org.gradle.internal.execution.fingerprint.InputFingerprinter$InputFingerprintingException: Cannot fingerprint input property 'artifactIds': value '[junit-4.12.jar (junit:junit:4.12), hamcrest-core-1.3.jar ... 

cannot be serialized.
...
Caused by: java.lang.ClassCastException: class org.gradle.internal.component.local.model.ComponentFileArtifactIdentifier cannot be cast to class org.gradle.internal.component.external.model.ModuleComponentFileArtifactIdentifier (org.gradle.internal.component.local.model.ComponentFileArtifactIdentifier and org.gradle.internal.component.external.model.ModuleComponentFileArtifactIdentifier are in unnamed module of loader org.gradle.initialization.MixInLegacyTypesClassLoader @638ef7ed)
	at org.gradle.api.internal.artifacts.metadata.ModuleComponentFileArtifactIdentifierSerializer.write(ModuleComponentFileArtifactIdentifierSerializer.java:26)
	at org.gradle.internal.snapshot.impl.AbstractValueProcessor.gradleSerialization(AbstractValueProcessor.java:160)
	... 68 more
where my code looks like this:
Copy code
@get:Input
abstract val artifactIds: ListProperty<ComponentArtifactIdentifier>

internal fun configureTask(
  compileClasspath: Configuration,
  runtimeClasspath: Configuration
) {
  val extractor = IdExtractor()
  artifactIds.addAll(compileClasspath.externalArtifactsFor("jar").resolvedArtifacts.map(extractor))
  artifactIds.addAll(runtimeClasspath.externalArtifactsFor("jar").resolvedArtifacts.map(extractor))
}

internal fun Configuration.externalArtifactsFor(attrValue: String): ArtifactCollection = externalArtifactViewFor(attrValue).artifacts

private fun Configuration.externalArtifactViewFor(attrValue: String): ArtifactView = incoming.artifactView {
  attributes.attribute(Attribute.of("artifactType", String::class.java), attrValue)
  lenient(true)
  componentFilter { id -> id is ModuleComponentIdentifier }
}

private class IdExtractor : Transformer<List<ComponentArtifactIdentifier>, Collection<ResolvedArtifactResult>> {
  override fun transform(artifacts: Collection<ResolvedArtifactResult>): List<ComponentArtifactIdentifier> {
    return artifacts.stream().map(ResolvedArtifactResult::getId).collect(Collectors.toList())
  }
}
Note that I must use an
ArtifactView
, because this is an Android project, and I have to tell Gradle which
artifactType
I'm querying for or it cannot resolve the configuration. Not using an artifactView simply leads to a different error.
👀 1
r
@tony do you have a complete failing example? I tried to reproduce with the following build script but I was unable to:
Copy code
plugins {
    `java-library`
}

abstract class PrintIds : DefaultTask() {

    @get:Input
    abstract val artifactIds: ListProperty<ComponentArtifactIdentifier>

    @TaskAction
    fun printIds() {
        artifactIds.orNull?.forEach {
            println(it)
        }
    }

    internal fun configureTask(
        compileClasspath: Configuration,
        runtimeClasspath: Configuration
    ) {
        val extractor = IdExtractor()
        artifactIds.addAll(compileClasspath.externalArtifactsFor("jar").resolvedArtifacts.map(extractor))
        artifactIds.addAll(runtimeClasspath.externalArtifactsFor("jar").resolvedArtifacts.map(extractor))
    }

    internal fun Configuration.externalArtifactsFor(attrValue: String): ArtifactCollection =
        externalArtifactViewFor(attrValue).artifacts

    private fun Configuration.externalArtifactViewFor(attrValue: String): ArtifactView = incoming.artifactView {
        attributes.attribute(Attribute.of("artifactType", String::class.java), attrValue)
        lenient(true)
        componentFilter { id -> id is ModuleComponentIdentifier }
    }

    private class IdExtractor : Transformer<List<ComponentArtifactIdentifier>, Collection<ResolvedArtifactResult>> {
        override fun transform(artifacts: Collection<ResolvedArtifactResult>): List<ComponentArtifactIdentifier> {
            return artifacts.map(ResolvedArtifactResult::getId)
        }
    }
}

dependencies {
    implementation("junit:junit:4.12")
}

repositories {
    mavenCentral()
}


tasks {
    register<PrintIds>("printIds") {
        configureTask(
            configurations.compileClasspath.get(),
            configurations.runtimeClasspath.get()
        )
    }
}
I tried it with Gradle 7.5.1
t
@Rodrigo Oliveira thanks for taking a look. Here's a draft PR with the changes. You can repro the failure with
Copy code
./gradlew :funcTest --tests DuplicateDependencyVersionsSpec
and for good measure, here's a build scan showing the test failure
👀 1
@Rodrigo Oliveira hate to bother you, is there anything else I can provide to help get to the bottom of this?
r
Hey @tony, I was about to give you an update. I was able to reproduce the issue and come up with a fix.
👏 2
I’ll need you to test a nightly once it’s out.
t
thanks! That's exciting 🙂 and no problem
👍 2
r
Hey @tony, CI had some hiccups producing the nightly but it’s available now,
7.6-branch-bamboo_cc_release_ComponentArtifactIdentifier_ListProperty-20220914130118+0000
has the candidate fix.
👀 2
t
@Rodrigo Oliveira I have confirmed that the candidate fixes my test!
🎉 1
r
Great, thanks, @tony!
🤝 1
t
@Rodrigo Oliveira does that mean this change will be in Gradle 7.6? Any eta on that release?
r
The change will be in Gradle 7.6.
We’re targeting September.
t
👍