Using a dynamic collection of files as a task output?


(Alex Landau) #1

Hello! I’m trying to write some Gradle tasks dealing with npm/yarn-based dependency installation. However, I keep finding that with the way I have my task outputs set up, these keep running more often than necessary.

The short version is that these installations produce directory structures with an enormous number of files in them, but I only need to track a relatively small subset of those files, which makes a big difference performance-wise. The problem is that 1) this requires computing and passing in a custom set of files (vs. a static folder), and 2) I can’t find a way to have this computation reevaluated after the task actually runs, even with the use of closures. The consequence is that after the first time the task runs, the wrong set of output files gets stored, and the task gets run a second time even though nothing needs to change.

I wanted to check here if there’s a known way to get the task to recompute its outputs after running before I open a ticket about this. (If there’s a way to get a filtered subset of a directory’s contents, that could work too, but it also needs to be dynamically recomputed at the right time.)

I have put together an example project with a single task for ease of experimentation: https://github.com/AlexLandau/gradle-dynamic-outputs You’ll see that theTask needs to be run twice after a git clean or after removing a subfolder in generated/.


(uklance) #2

I’ve just had a quick eyeball of the code but I think you can do the following

    outputs.files fileTree('generated').matching {
        include '*/canary/**'
    }

See FileTree.matching(Closure)


(Alex Landau) #3

This construct works as intended. Thank you!