I have a configuration that contains some dependencies. I want a task that extracts all resolved artifacts into a directory, but I’m getting stuck with Gradle’s Lifecycle I think…
Here’s what I want:
configurations {
api
}
dependencies {
api ( group: 'somegroup', name: 'someArtifact', version: 'someVersion' )
}
task extractApi(type: Copy) {
configurations.api.asFileTree.each {
from( zipTree(it) )
}
into file("${project.buildDir}/api/")
}
But I’m getting: > * What went wrong: > A problem occurred evaluating project ‘:myproject’. > > You can’t change a configuration which is not in unresolved state!
… which makes sense: I’m trying to configure a copy task (gradle configuration phase) with configuration dependencies, which would have to be resolved first, but they may not even be readily configured, so they can’t…
… the problem here is, that gradle tells me the task is up-to-date, which, again, seems plausible since no input has been configured during its configuration phase.
The following SEEMS to work, but seems very wrong :S
task extractApi(type: Copy) {
dependsOn configurations.api
from {
configurations.api.asFileTree.each {
from( zipTree(it) )
}
// Don't include the actual archives themselves
null
}
into file("${project.buildDir}/api/")
}
Just for the record: The specified solution needs a
dependsOn configurations.api
Because if it’s not present and if the configuration depends on another project in a multi-project build, that project doesn’t get build - resulting in missing dependency artifacts in the copy operation.
Your code works for me but it only extracts one file at a time. If I have 7 native jars from dependecy archives that I would like to extract to their own directories. Do you know how to that in a loop?
A side affect of this code, is that Gradle will resolve and download dependencies even if the task is not in the taskgraph. Is there a way to move the dependency resolution to task execution step?
Works fine for me, both with 1.9 and 1.11. The configuration only gets resolved if Gradle decides that ‘extractApi’ will get executed. In that case, ‘from’ (and therefore also resolution of the configuration) gets triggered when the task execution graph is built, i.e. between configuration and execution phase.
configurations {
api
}
dependencies {
api 'somegroup:someArtifact:someVersion'
}
task extractApi(type: Sync) {
dependsOn configurations.api
from { // use of closure defers evaluation until execution time
configurations.api.collect { zipTree(it) }
}
into "$buildDir/api/"
}