I am learning to use task configuration avoidance and am having difficulty connecting the outputs of a task to the inputs and avoiding the use of the get() method. I have tried several different methods including using a model that uses properties. Entities of the model are associated using the map() function of a Provider. However, I have not had much luck with this approach. Is there guidance on how to connect the properties of tasks?
The Property class accepts other Property(s) when being set. This can be shown here
I have a plugin that uses the new lazy api heavily and am happy to help but i don’t understand the problem you are experiencing. Could you clarify?
In short if you have two task types, one that has an output property and one that has an input property, and an instance of each, you can set one to the other. The Groovy syntax just looks different from Kotlin since the groovy syntax has operator overloading for the assignment(=) operator which i believe calls the set method on the property.
Pseudo Groovy Script:
// input is a Property type with a get/set api
taskConsumer.input =
taskProducer.output //(output is a Property type, with a get/set api)
Pseudo KotlinScript:
taskConsumer.input.set(taskProducer.output)
Psuedo class examples
class Producer extends DefaultTask {
@Output
val output: Property<String> = project.objects.property(String::class)
@TaskAction
fun execute() { output.set("foo") }
}
class Consumer extends DefaultTask {
@Input
val input: Property<String> = project.objects.property(String::class)
@TaskAction
fun execute() { println(input.get()) }
}
Glad to help more if you can provide what you are trying to do.
Thanks for getting back to me! I have used lazy configuration independently of the task configuration avoidance functionality and have found the “autowiring” of task dependencies to be a nice feature. I was hoping there might be an idiom for using them together.
When registering a task it provides a TaskProvider. However, in order to use the underlying task within the provider you would need to call get(). Gradle will then configure the task and as most tasks will be configured similarly one will loose the advantages within the task configuration avoidance functionality.
In order to solve this problem, I created a companion model that used similar properties to those needed by a task such as RegularFileProperty, DirectoryProperty, and Property. As I couldn’t anticipate the settings of the properties within the companion model I needed a way to dynamically configure the companion model. This was accomplished through the service-provider loading facility of the JDK (java.util.ServiceLoader). A provider would configure the properties of the task using the extension model and the providers for other tasks in order to set its values. For those considering this approach, there is one trick that is required as Gradle uses a custom class loader and this prevents ServiceLoader from finding the providers. The relevant code is (where ProjectProperties is the enclosing class)
I realize that this description may be a little difficult to understand and if there is interest I would be willing to spend some time to create an example of how this allowed me to use the task avoidance configuration functionality. I couldn’t figure out how to use the lazy configuration and the task “autowiring” so I used the “traditional” method of dependsOn to specify task dependencies.
Yes and no … The examples you provided show how to specify dependencies between tasks, but I was unsure if there was an idiomatic method for “linking” the output of one task to the input of another task. The reply to your first post suggests a method for accomplishing that and adheres to the principles of task avoidance. While I don’t know for certain, I have a feeling that the Gradle team is working on providing a Gradle-specific way of linking the outputs of a task to the inputs of another …