How to assign closure to File based Task property?


according to the documentation, it should be possible to define a task property of type File annotated with @InputFile which will be lazily evaluated (using Closure).

I am trying to write such case, I was not successful:

task execBinary(type: MyTask) {
//    binary = file('build.gradle')
    binary { file('build.gradle') }

class MyTask extends DefaultTask {
    @Optional @InputFile
    Object binary

    def exec() {
        println "binary: $binary"

I am getting either casting exceptions or internal Gradle checking errors.

How can I do that using Gradle 4.0?

You’d do that with the new public Provider API. You can find an example in the release notes.

You can also do it the “old way” by having a setter that takes Object and puts that object into the field and a getter that calls project.file() on that field.

The new Provider API makes this more explicit and type safe and should be preferred for new plugins. Gradle 4.1 will bring even more convenience with special types for file and directory providers.