For example in this forum post or there at stackoverflow …
Ah, sorry, forgot that <root project>/.gradle is called “project cache dir” or I might have understood what you mean.
But still, speaking of a “project cache” is not really appropriate.
At this point I don’t get the difference between incremental build and cache or let’s say
Incremental build means that a task can be up-to-date.
up-to-date means, that the inputs are the same since last executing the specific task and outputs were not changed since the task last finished.
what “fingerprints” go into the cache
The inputs of a task (including runtime classpath of the task and so on) are fingerprinted and build together the cache key.
Under the cache key, the task output is stored in an archive so that it can be reused for the same inputs in the future.
why is a task cachable or not
A task is cacheable if it declares to be cacheable, as not for all task types it makes sense to use the cache as it could even slow down the build due to the overhead and it might be faster to just execute the task.
But … but … for any reason, guess that’s the caching mechanism, when building with
--build-cachethen purging thebuild/directory does not affect thegeneratePrototask
Yes, it does affect the task.
If you wouldn’t have cleared the build folder, the generateProto task could have been up-to-date.
As you removed the outputs of the task, but it is cacheable and you already executed the task for the same inputs before, the outputs were taken from the cache which is not located in build.
The cache is not bound to one worktree.
If you have two work-trees, build in one, then in the other run the same task with the same inputs, the outputs can also be taken from the cache there.
Or if you switch between branch A and B in one work-tree and in both branches you have different inputs for the task, then it can go like this - given no cache entry is there yet for the task:
- switch to A
- run task => task is executed, result is cached
- switch to B
- run task => task is executed, result is cached
- switch to A
- run task => result is taken from cache
- switch to B
- run task => result is taken from cache
You can even have CI/CD that writes to a remote cache instance,
and then if you locally run the same task with the same inputs,
the result can be downloaded from the remote cache and reused on your local machine even though you never executed the task locally before.
Although the source files as well as the generated java files based on the proto-files are gone, everything is gone … these information are stored in the cache?
The source files were not gone.
Not from the view of the generateProto task.
The fetchProtoFiles task was run before, so the files are there again.
And as the files are the same as before, the task result for generateProto could be taken from cache.
So, if caching successfully prevents
generateProtofrom runing again - which is awesome - then I guess it simply would make sense to also prevent thefetchProtoFilestask from running again, sincegenerateProto, which depends on it, doesn’t need it - no?
No, Gradle could not guess what fetchProtoFiles does.
The outputs of fetchProtoFiles are the inputs for generateProto.
So to evaluate whether generateProto can be taken from cache, fetchProtoFiles output files have to be present, so it cannot be skipped.
If fetchProtoFiles would be a cacheable task its result could have been taken from cache.
But just with the up-to-dateness, it doesn’t really make sense as the inputs are remote files that you clone, so you could never know whether the inputs are the same and so you could never cleanly take the outcome from cache.
Can we somehow manually add
fetchProtoFilesto the cache?
You can of course make it cacheable yes.
It just does not make sense, as you cannot cleanly define its inputs.
Just like it also does not make sense to ever have it up-to-date as you never know how the state of the remote files is.