I’m looking for help in creating a custom cacheable task. I’d like to use a recommended best practice if possible, so if my approach seems wrong then I’m happy to adapt, but I’ve started down a route already.
So I’m trying to cache an expensive test run written in JavaScript. It doesn’t create any output – it just validates that the code is correct. It’s important for me to know that the tests have been run for the given inputs, and avoid running them if the input hasn’t changed.
The build cache seems like the obvious solution, but gradle builds with no outputs are always considered out of date. It seems that in order to create a cacheable task, I need to declare at least one output file, whose contents varies based on the input.
To that end I’m considering writing out a small token file, whose contents reflect the inputs, as the sole output. That way, gradle will consider the task cacheable, and I can avoid unnecessary test runs.
If that’s not true, and I can declare a task cacheable which only has inputs, that’d be great. Or if I can declare a non-file output, or derive/create an output automatically, that’d be great.
Assuming I have to write the file myself, the question is what should go into that file. Initially I thought of creating an MD5 hash of all the input files and writing that out, but that sounds an awful lot like recreating the gradle build cache key, but badly. Ideally I’d write that key out but it seems from Gradle build cache key that it’s not possible.
Pseudocode for my current approach;
// terrible pseudocode to show the point
task test() {
inputs.dir("src").withPathSensitivity(PathSensitivity.RELATIVE)
outputs.file(".tested.update-tracker")
outputs.cacheIf { true }
doLast {
exec <something to run the tests>
new File(".tested.update-tracker").text = task.buildCacheKey
}
}
Is there some way I can either;
- calculate the build cache key
- mark the task as cacheable despite it having no output
- read more about how other people have solved this problem?