Use directory recursively (with exclusions) as input of Exec task

I want to write an Exec task that processes the contents of a directory and generates another directory. But if I do inputs.dir("input") it seems to only check the modified time of the directory itself, not the contents. That means if I do touch input/abc the task does not re-run.

Also, we have some subdirectories of input that need to be excluded.

Here is the current task definition:

tasks.register('build', Exec) {
    // TODO fix up-to-date checking.
    inputs.dir("$rootDir/input")
    outputs.dir("$rootDir/input/build")

    workingDir "$rootDir/input"
    commandLine "build", "$rootDir/input", "$rootDir/input/build"
}

input/build as well as input/other need to be excluded from the inputs.

Do you mean touch input/abc when abc does not exist previously and thus you create it, or when it already exists?
If it already exists, doing a touch does not modify the input.
Gradle by default does not care about timestamps as they are useless.
If you switch a branch in VCS that changes the file and switch back to the previous branch, the file time will have changed but the contents is still the same.
98.7% of the tasks out there do not care about the file modified date.
Gradle uses as inputs fingerprints consisting of the actual contents of files, and eventually paths, depending on configured path sensitivity for the given file.

To exclude input/build from the inputs, you probably have to use a fileTree and input.files instead, something like inputs.files(fileTree("input").matching { exclude("**/build/**") }) (not tested thoroughly).
But if possible it is most probably better to not have the output directory inside the input directory, but somwehere seperate, for example at layout.buildDirectory.dir("build-output").

OK fileTree is the solution I think, thanks.

1 Like