Gradle InputChanges example is wrong

Hi Gradle Team,

The new gradle release 5.4 includes a New API for Incremental Tasks

https://docs.gradle.org/current/javadoc/org/gradle/work/InputChanges.html

https://docs.gradle.org/current/dsl/org.gradle.work.InputChanges.html

The example provided in the above links doesnt work as expected

abstract class IncrementalReverseTask extends DefaultTask {
    @Incremental
    @InputDirectory
    abstract DirectoryProperty getInputDir()

    @OutputDirectory
    abstract DirectoryProperty getOutputDir()

    @TaskAction
    void execute(InputChanges inputChanges) {
        inputChanges.getFileChanges(inputDir).each { change ->
           **// This is wrong once this code is executed further changes are not notified to this method**
               // Example: when there is no history of previous execution (during first time run)
              // All the files in the input directory along with the input directory should be notified to this method as ChangeType.ADDED
              // However once the input directory is received as a change
             // after the execution of return statement
            // further file changes of the input directory are not reported back to this method
            if (change.fileType == FileType.DIRECTORY) return      

            def targetFile = outputDir.file(change.normalizedPath).get().asFile
            if (change.changeType == ChangeType.REMOVED) {
                targetFile.delete()
            } else {
                targetFile.text = change.file.text.reverse()
            }
        }
    }
}

The right code that is working for me is

abstract class IncrementalReverseTask extends DefaultTask {
    @Incremental
    @InputDirectory
    abstract DirectoryProperty getInputDir()

    @OutputDirectory
    abstract DirectoryProperty getOutputDir()

    @TaskAction
    void execute(InputChanges inputChanges) {
        inputChanges.getFileChanges(inputDir).each { change ->
            if (change.fileType == FileType.FILE) { 
                    def targetFile = outputDir.file(change.normalizedPath).get().asFile
                    if (change.changeType == ChangeType.REMOVED) {
                        targetFile.delete()
                    } else {
                       targetFile.text = change.file.text.reverse()
                   }
            }
        }
    }
}

Please check and update accordingly

Or Please Let me know if I misunderstood the concept.

Hi,

if I understand correctly, the return will only return within the each block for Groovy, so the remaining files will still be processed. We have the same sample in the user manual, and that seems to work. Are you using exactly the code you posted?

Note that in Kotlin, the behaviour of return is slightly different, and needs to be qualified with e.g. return@forEach.

Please report back if you still see the wrong behaviour.

Cheers,
Stefan

@Stefan_Wolf

Thank you for clarifying yes it works fine for groovy and I was using kotlin.

When I used return@forEach it worked perfectly fine.

Totally my mistake as I copy pasted the example and edited :frowning:

Thanks a lot once again for clarifying