This message was deleted.
# dependency-management
s
This message was deleted.
v
Yes and no. You cannot declare one dependency and get all its variants. But if you have 3 variants you can declare three dependencies for the same configuration. If the variants are selected by capability, dependency requests the according capability. If the variants are selected by attributes, the attributes can also be declared on the dependency instead of on the configuration iirc. Another option if the selection is by attributes is by having only the dependency on the configuration once and then using different artifact views with variant reselection to get the different variants. In any way you probably want to use a lenient artifact view which will then care for the dependencies not matching the attribute set by ignoring them
a
you could try using
artifactView {}
, but it's pretty flaky. Example:
Copy code
/** Some specific type of a 'Foo' configuration */
interface FooArtifactTypeAttribute : Named

val fooArtifactTypeAttribute = Attribute.of(FooArtifactTypeAttribute::class.java)

val fooConfigurationResolver by configurations.registering {
    description = "fetches 'Foo' files which have a 'Foo' attribute (should include all 'FooArtifactTypes')"
    attributes {
        attribute(Usage.USAGE_ATTRIBUTE, objects.named("foo-artifacts"))
    }
}

val gatherFooFilesWithTypeJar by tasks.registering(Sync::class) {
    val fooJarFiles: Provider<List<File>> =
        fooConfigurationResolver.flatMap { conf ->
            conf.incoming
                .artifactView {
                    attributes {
                        // only find 'jars'
                        attribute(fooArtifactTypeAttribute, objects.named("jars"))
                    }
                }
                .artifacts
                .resolvedArtifacts
                .map { it.map(ResolvedArtifactResult::getFile) }
        }
    from(fooJarFiles)

    into(temporaryDir)
}
But there are a tonne of hidden problems, because Gradle randomly doesn't consider attributes or will decide it doesn't need to do variant re-selection and so you end up with files from Configurations that have completely the wrong attributes. What I've been experimenting with recently is manually filtering the discovered artifacts, because if you use
resolvedArtifacts
then you can view the variant that provided each file, and then filter based on the available attributes.
Copy code
val gatherFooFilesWithTypeJar by tasks.registering(Sync::class) {
    val fooJarFiles: Provider<List<File>> =
        fooConfigurationResolver.flatMap { conf ->
            conf.incoming
//                .artifactView {
//                    attributes {
//                        attribute(fooArtifactTypeAttribute, objects.named("jars"))
//                    }
//                }
                .artifacts
                .resolvedArtifacts
                .map { artifacts ->
                    artifacts
                        .filter { artifact -> 
                          // only find 'jars'
                            artifact.variant.attributes.getAttribute(fooArtifactTypeAttribute) == objects.named("jars")
                        }
                        .map { it.file }
                }
        }
    from(fooJarFiles)

    into(temporaryDir)
}
I haven't used it in anger yet, so I'm curious whether it might help you :)
v
Artifact views are not flaky and also what Gradle itself uses. You just have to request variant reselection if you need it, like I described.
a
Oh I've tried using that :) But it's really inconsistent whether Gradle decides it wants to consider the attributes or not. Sometimes Gradle just doesn't use them and you end up with random files from another Configuration.
c
Thanks for the ideas, I completely forgot about artifact views. I also thought of adding an
all
variant that includes each of the artifacts. The consumer can then request
all
instead of enumerating the possible variants. New variants can be added without having to update the consumer. This is new stuff and I don't have to deal with any legacy modules that would be missing the
all
variant.
v
Yeah, that would also be an option probably.
@Adam can you share examples where it misbehaves? I'm really curious to see them and know what is or is not working. And / or did you report bugs about the strange behavior you have seen?