How can we get the output directory defined with the annotation @OutputDirectory
or outputs.dir(<dir>)
in another task?
This doesnt work
task A {
outputs.dir("/home/build")
}
task B {
println A.outputs.dir
}
How can we get the output directory defined with the annotation @OutputDirectory
or outputs.dir(<dir>)
in another task?
This doesnt work
task A {
outputs.dir("/home/build")
}
task B {
println A.outputs.dir
}
Since you’ll probably also want task B to depend on task A, I recommend you use “lazy properties” to help avoid issues related to missing task dependencies.
Here’s some examples of using both task classes and the groovy DSL. In both cases the output properties of the producer tasks carry a reference to their respective tasks. When those properties are used as inputs to another task, Gradle is smart enough to infer the task dependencies. For example, running gradlew consumer consumerDsl
will execute all 4 tasks in the correct order (producer tasks before the corresponding consumer task).
abstract class MyProducerTask extends DefaultTask {
@OutputDirectory
abstract DirectoryProperty getOutDir()
MyProducerTask() {
// avoid up-to-date status for demo purposes
outputs.upToDateWhen { false }
}
@TaskAction
void doWork() {
logger.lifecycle("Doing work into {}", outDir.get())
}
}
abstract class MyConsumerTask extends DefaultTask {
@InputDirectory
abstract DirectoryProperty getInDir()
@TaskAction
void doWork() {
logger.lifecycle("Doing work from {}", inDir.get())
}
}
task producer(type: MyProducerTask) {
outDir = layout.buildDirectory.dir("myOutDir")
}
task consumer(type: MyConsumerTask) {
inDir = tasks.producer.outDir
}
task producerDsl {
// avoid up-to-date status for demo purposes
outputs.upToDateWhen { false }
ext {
outDir = objects.directoryProperty()
}
outDir.set(layout.buildDirectory.dir("myOutDir"))
outputs.dir(outDir)
doLast {
logger.lifecycle("Doing DSL work into {}", outDir.get())
}
}
task consumerDsl {
ext {
inDir = objects.directoryProperty()
}
inDir.set(tasks.producerDsl.outDir)
inputs.dir(inDir)
doLast {
logger.lifecycle("Doing DSL work from {}", inDir.get())
}
}
To more directly answer your question; you can generically get a task’s output files via <task>.outputs.files
, which will return a FileCollection
(a task could have more than one output directory or file).
task consumerDsl2 {
dependsOn tasks.producerDsl
doLast {
logger.lifecycle("Doing DSL2 work from:\n\t{}", tasks.producerDsl.outputs.files.join('\n\t'))
}
}
Thanks for answer. From your example you save the output directory of that task in A.ext.var
and used that to read it back in task B. For my example it will be
task A {
ext.outDir = file("/home/build")
}
task B {
println A.outDir
}
And as you said, there can be more than one output directory I have to retrieve via <task>.outputs.files
So does it mean that from
uses output.files
when used in copy
like this?
copy {
from A
into "/another/folder"
}
Correct, when a task is given to CopySpec.from
it is converted to the task’s output files.
However, in your example of:
task A {
ext.outDir = file("/home/build")
}
copy {
from A
into "/another/folder"
}
the copy
would not copy anything from /home/build
because task A
has no declared outputs (ie outputs.dir(outDir)
.