I have two Gradle plugins which use the Gradle incremental API, but have to do wonky workarounds. Perhaps these use-cases aren’t worth supporting, but I just wanted to throw them out as possibly helpful testcases in case you revisit the API.
A task that may modify its input
It’s generally a bad idea for a task to modify any of its inputs, but one notable counter-example is a code formatting task. Example:
- Change
MyClass.java
, and its formatting is now bad. - Run
spotlessApply
, which uses Gradle’s incremental to run a formatter on only that one changed file. - If the user immediately runs
spotlessApply
again it ought to be up-to-date (in an ideal world), but it’s not because the file was changed byspotlessApply
. - The third run of
spotlessApply
will now be up-to-date.
Ideally, there would be something like IncrementalTaskInputs::setUpToDate(File, boolean)
or InputFileDetails::setUpToDate(boolean)
that we could call after modifying a file so that the task would be up-to-date in step 3 instead of step 4.
That minor performance hit is not a huge deal, but there’s actually a bug that I missed for a long time hiding there:
- Change
MyClass.java
, and its formatting is now bad. - Run
spotlessApply
, which uses Gradle’s incremental to run a formatter on only that file. - The user manually changes
MyClass.java
back to its pre-formatted content. - Run
spotlessApply
, which ought to run in an ideal world becauseMyClass.java
has bad formatting. But becausestep 2
was successful, and the content ofMyClass.java
is exactly the same as it was at the beginning ofstep 2
, the task is marked as up-to-date, and the badly formatted file lives on.
We handle this by creating a synthetic extra file in the build directory which we treat as an incremental input. Into this file we store a timestamp and the file names that were changed in the previous round. That way we are able to detect and handle the obscure use-case above. This would be unnecessary if we had something like InputFileDetails::setUpToDate(boolean)
.
A task where a file’s output files might depend on its content
There are some cases where, for each input file, the name and number of its output files might depend on its content. But with the current API, when a file is removed or changed, there is no way to get information on its previous content.
We handle this by storing this information ourselves in a special file in the build directory.
Ideally, there would be something like InputFileDetails::setMetadata(Object serializableMetadata)
which would be available in future runs for changed and removed files
as InputFileDetails::getMetadata()
.
code example, test case where this is useful
Probs not your top priority
Right now, the incremental API assumes:
- None of the inputs will change (probably a pretty good assumption)
- Responding to a changed or removed file will not require any information about the previous content (an okay assumption for most Java, not great for other kinds of tasks)
If you’re looking for simple but useful tasks which don’t meet these two assumptions, see the links above.
Thanks again for Gradle! Can’t believe the consistent improvement, release after release.