buf-gradle-plugin icon indicating copy to clipboard operation
buf-gradle-plugin copied to clipboard

Make build depend on `bufGenerate`

Open remoun opened this issue 3 years ago • 7 comments

We use buf generate for generating code from protobufs. I've been integrating this step in build scripts with:

// Add a task dependency for compilation
tasks.named("compileJava").configure { dependsOn("bufGenerate") }
tasks.named("compileKotlin").configure { dependsOn("bufGenerate") }

It would be great if the buf plugin did this automatically, perhaps with a config flag? e.g. buf { generateInBuild = true }

remoun avatar Sep 16 '22 01:09 remoun

Just thinking out loud for a moment: the way to do this is probably via implicit dependencies on task output. It looks like that's how the protobuf-gradle-plugin does it. This would work nicely as part of a larger effort to use proper Gradle task APIs instead of doFirst all over the place.

andrewparmet avatar Sep 16 '22 03:09 andrewparmet

The first step - using custom task classes - is complete: https://github.com/andrewparmet/buf-gradle-plugin/pull/94.

andrewparmet avatar Sep 26 '22 14:09 andrewparmet

Another problem is that there's no great way to know from the buf.gen.yaml which generators are being used and their target directories, and therefore which tasks ought to depend on buf generate and where the output should be for the compile task's new source directory.

Support for this might require a proper config DSL that generates a YAML itself, which I was hoping to avoid.

andrewparmet avatar Oct 12 '22 21:10 andrewparmet

Why not add it to the CompileJava and CompileKotlin tasks/types, e.g.

tasks.withType(JavaCompile) { dependsOn("bufGenerate") }
tasks.withType(KotlinCompile) { dependsOn("bufGenerate") }

remoun avatar Oct 12 '22 23:10 remoun

I don't think that's the right path forward since it only addresses half the issue. I think a more elegant solution may be to introduce a function on the extension like addGeneratedSource<KotlinCompile>("path-to-generated-code") that adds the task dependency and the source set location in one shot. I'm not sure if it's possible to easily determine the SourceSet based on the task type though.

andrewparmet avatar Oct 16 '22 23:10 andrewparmet

I'm not sure if it's possible to easily determine the SourceSet based on the task type though.

FWIW the protobuf plugin configures its extension for all SourceSets, although it switches paths based on whether the project is an Android project.

Generally, I think making all {Java,Kotlin}Compile tasks depend on bufGenerate is a reasonable default, and we could add an escape hatch (e.g. config flag) for folks who want to customize that behaviour.

remoun avatar Oct 18 '22 00:10 remoun

One thing I noticed recently that after adding

tasks.withType<KotlinJvmCompile>().configureEach {
    dependsOn("bufGenerate")
}

to my build file, buf is invoked on any compilation-related command and it will contact the BSR - even if no input files changed. I only noticed when I ran into rate limiting issues. Now I don't want to waste anyones resources but I also feel like this should be possible to automate so one cannot forget to compile .proto files in case they actually do change.

As someone who practices TDD a lot, having buf run a full compile step including remote services for every change (even in non-buf-related files) is quite an overhead. Unfortunately I also couldn't find anything that would allow me to tune this behaviour. Gradle build cache is already enabled.

milgner avatar Sep 13 '24 07:09 milgner