Support Gradle Incremental Annotation Processing
Closed this issue · 9 comments
It would be nice if crumb would support incremental annotation processing released in Gradle 4.7.
Given that crumb uses resources, it doesn't look like that's going to work. See https://docs.gradle.org/4.7/userguide/java_plugin.html#sec:incremental_annotation_processing
A similar project I work on solves a similar problem (with a million times less flexibility). The library TLDR is this:
- The composite equivalent of
CrumbProducer
generates a class with an annotation on it. - The composite equivalent of
CrumbConsumer
looks for the generated classes annotated by the step above
I think an approach similar to this would allow the crumb annotation processors to be incremental.
This would essentially change the implementation details within crumb to use classes (again, that can be proguarded out) instead of resources.
I'd be willing to help/do the work for this if it's a direction that the library maintainers deem appropriate.
Thanks for the issue. The resources limitation seems not to be a technical one and one they plan on supporting in the future (on mobile and don't have a link handy), so I'd rather wait for that. It's unlikely that consumers could ever be incremental, but I recommend making consumer modules smaller where possible. In general I think you'll get a lot more mileage out of modularization than incremental processing.
The annotation idea is interesting, but I don't like the idea of generating code that consumers have to bear the burden of.
Agreed on the consumer side! Small modules for the win!
I think I found the issue you referenced here: gradle/gradle#4702
Yep that's the one! Let's touch base again once that's available
Looks like this support just got merged in! gradle/gradle#8797
Hmm. So the resources bit works, but crumb can be a bit weird in that it should re-run if dependencies change. I think gradle will skip incremental processing in this event anyway, but will check. Alternatively, we can also add the type elements of transitive dependencies picked up too in consumers, but that could make consumers potentially aggregating when they could be isolating
it seems like the resources support is really more oriented toward making emission of side-effect resources not impact incrementalism of a main source-emitting processor, not necessarily about aggregating resources. I think this makes incremental support for this project not really viable beyond maybe making producer extensions incremental-friendly. Consumers would always be non-incremental since they read resources. Does that seem worthwhile/viable?
Should note that the discussion is still ongoing in the original gradle issue. I'm trying to understand how tools that use something like a ServiceLoader wouldn't break in this paradigm or if they're just unsupported in general as a result.
Yeah, the benefit is certainly not as much unless everything is incremental.
I've been digging a bit, and there is a way we can do this, but requires an overhaul of the current core API to not be resources-based. Glide makes this work by basically generating a placeholder type with an annotation containing all the relevant metadata, I guess with the expectation that it would just be removed in release by proguard or something similar. All of these types are put in the same package, so just at the final "app"-level, it loads all the types in that package and looks for any annotated with its Index
annotation, then reads metadata from that.
Then no resources are used at all, at the cost of basically generating boilerplate code. I think this is an ok tradeoff. We can also do our best to obfuscate this class from public API (package private, comment, etc).
At a high level:
- crumb producers: similar to GlideLibraryModules. For every one, generate a holder class with an annotation of the metadata it produces
- crumb consumers: similar to GlideAppModules.