-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GenerateProtoTask should support incremental build and more thorough clean #33
Comments
We should probably add |
WRT deleted or moved source files, currently protoc doesn't provide any information on what files it will generate, and I don't foresee this will happen easily. We cannot precisely delete the corresponding output files, and we can only delete the whole output directory. This leads to my concern about the safety of deleting the whole directory (#24). @ejona86 what's your take on this? |
Gradle does provide information like this. We already use it in the J2ObjC Gradle Plugin: My suggestion is that you start with a system where you just do a clean build if there's been a significant enough change. Most proto changes are within a file or a new file, which should be fine. It's removing a file that'll likely cause issues. Bruno |
Several ways can give us the knowledge. The easiest way would be providing a patch to protoc to give it to us. I don't see any verbose flag, could it be something the guys at protoc would be willing to add or accept a pull request for? If that is out of the question, we can always use hooking in the process to figure out the output. However this is hard to deal with the various OS. We could also output the files into a known to be clean folder and move them to the target folder. If we build each file individually (invoking the compiler for each file) then we could figure out what are the output for each input files. Solution 1 would be ideal and optimal. Solution 3 is a quick and easy hack. I would try to avoid solution 2 as it contains too much support burden. Let me know what you guys think. |
I was a little surprised that the output isn't that predictable. Can each My concern is that getting any information from the protoc could be flaky. On Thu, Aug 20, 2015 at 7:39 PM Daniel Lacasse notifications@github.com
|
A verbose flag from protoc could help us to piece together what happen to each input file. This can be flaky as we depend on purely informational output from the compiler. The clean folder output will work best with least work and wouldn't affect the up to date information as we don't tag the clean temporary folder with Gradle as output. We only tag the target folder or the target file (final destination) as output and the move occurs as the task action instead of a seperate task. Gradle execute the @TaskAction then snapshot the output. The intermediate destination would be invisible to Gradle. However, this method do introduce more IO corresponding to the move. Although, as long as we do an actual move as opposed to writing a new file and deleting the old one, the performance impact should be very minimal as the file system will optimize the IO operations. Without depending on a modification to protoc, the clean folder technique would fix the problem. I would probably put the associating knowledge base file in the target output folder as it shield against someone manually deleting the build directory when the output dir is not in that directory. So the clean and incremental compilation will keep on working. Don't hesitate to ask any questions. |
Just confirmed with protobuf team. Adding the "verbose flag" to protoc is not a trivial change, as it requires changes to all code generators and plugins. However, I think this could work: When build:
When clean:
@brunobowden I am not sure I get it. Is my proposal affected by the issue you described? |
Your proposition is very good and quite easy to implement. I would suggest to put the manifest in the target directory instead. This way if someone deletes the build directory manually (without going through gradle), no generated files will be leak as the next time gradle runs, it will be able to figure out which file were not deleted by the manual cleanup. The plugin will then be able to recover and remove dangling files. Typical scenario would be: This way the plugin will never fall into a unknown state where it could be difficult for a new user to debug to the expense of creating an extra metadata file in the target folder. I think it's a fair trade for stability. |
Sorry for the belated follow up on this. Firstly, this system would work easily without a manifest file, if everything was isolated to the build directory. Is that possible? That way, it's much easier to manage state. We do this with the J2ObjC Gradle Plugin for example. The idea is that the proto files are the only thing checked in the repository and then everything else is generated from that. Here's a few things to help:
IncrementalTaskInputs will certainly improve the performance but doesn't solve the wider issue. |
That last link is where I've asked a question publicly about this issue: |
There's now an answer to the post that I agree with: The plugin will work best if all output is done to the build directory, as specified by the For the protobuf plugin, if you get IncrementalTaskInputs and nothing has been deleted (i.e. only edit and new protos), can you be efficient and recalculate only those outputs? I'm wondering if just an edit can delete a generated file, which is a hassle. If you get an incremental delete... or no incremental information, then you have to delete everything and regenerate. It should be a requirement that the target folder contains nothing except for the output. Though this can be configured to be outside the build folder, I think that should get a warning and encouragement to change it. |
- Generate to a temp directory - Recursively copy files whose contents have changed This was the suggestion here, to get around the difficulty of figuring out dependencies of a protobuf, and its target output files, as described here: google/protobuf-gradle-plugin#33
- Generate to a temp directory - Recursively copy files whose contents have changed This was the suggestion here, to get around the difficulty of figuring out dependencies of a protobuf, and its target output files, as described here: google/protobuf-gradle-plugin#33
You don't even have to do incremental to fix the primary issue: don't get ratholed on it. Just making it specify its output files, and have stable generation will mean that even if protoc reruns, gradle will see that the output files haven't changed and won't recompile them unnecessarily. Right now, a global clean and recompile of the protoc files would be better than the current situation - this is the only gradle plugin in a VERY LARGE project which can't elegantly update its outputs based on a change of inputs, at any cost. |
Somewhat related to #180 - correcting the gradle annotations will fix (most of) both. |
Possible workaround, although highly non-ideal in a Gradle world:
|
with the latest Gradle 6.4.1 I get the following error if I try and use the workaround:
|
This worked for me:
|
Fixes google#33 for users not changing generatedFilesBaseDir. Stop documenting generatedFilesBaseDir since it produces poor results, but keep it functional with its existing Copy semantics. Fixes google#332
Fixes #33 for users not changing generatedFilesBaseDir. Stop documenting generatedFilesBaseDir since it produces poor results, but keep it functional with its existing Copy semantics. Fixes #332 This deprecates the setter, but I don't know how to make this trigger a warning, for either Groovy and Kotlin. Both seem to ignore it. Turn off UnnecessaryObjectReferences because it isn't providing value.
The current implementation of GenerateProtoTask will not support scenario where a proto file is renamed or even deleted. In that scenario, the old generated file will be left behind and may cause unwanted build success or failure (by duplication). The task should take an IncrementalTaskInputs parameters to remove stalled output. It will also be able to build only the proto file that as changed - very useful in big proto source set.
The text was updated successfully, but these errors were encountered: