Skip to content

Commit

Permalink
Avoid implicit task dependencies for grpc generated tasks (#2442)
Browse files Browse the repository at this point in the history
Motivation:
The protobuf gradle plugin will generate tasks dynamically, which have
implicit relationships on our dynamically generated quality tasks (pmd, spotbugs, checkstyle).
Gradle build generates warnings and deoptimizes some flows.

```
Execution optimizations have been disabled for task ':servicetalk-grpc-health:pmdMain' to ensure correctness due to the following reasons:
  - Gradle detected a problem with the following location: '/Users/scottmitchell/git/servicetalk/servicetalk-grpc-health/src/generated'. Reason: Task ':servicetalk-grpc-health:pmdMain' uses this output of task ':servicetalk-grpc-health:generateTestProto' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.6-rc-3/userguide/validation_problems.html#implicit_dependency for more details about this problem.
```
  • Loading branch information
Scottmitch authored Nov 23, 2022
1 parent d76b87b commit 07255b0
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.servicetalk.gradle.plugin.internal

import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
Expand Down Expand Up @@ -124,6 +125,23 @@ final class ProjectUtils {
)
}

static void addGeneratedProtoDependsOn(Project project,
/*com.google.protobuf.gradle.GenerateProtoTask*/ DefaultTask task,
boolean projectTestGeneratedOnly) {
if (!projectTestGeneratedOnly) {
if (!task.isTest) {
project.sourcesJar.dependsOn task
}
// generateTestProto tasks also depends upon non-test proto tasks
project.pmdMain.dependsOn task
project.spotbugsMain.dependsOn task
project.checkstyleMain.dependsOn task
}
project.pmdTest.dependsOn task
project.spotbugsTest.dependsOn task
project.checkstyleTest.dependsOn task
}

private static <T extends Task> T createTask(Project project, String name, @DelegatesTo.Target Class<T> type,
@DelegatesTo(strategy = 1, genericTypeIndex = 0) Closure<?> config) {
project.task(name, type: type, config) as T
Expand Down
3 changes: 2 additions & 1 deletion servicetalk-grpc-health/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ protobuf {
}
generateProtoTasks {
all().each { task ->
task.dependsOn unzipGrpcProtos
//// REMOVE if outside of ServiceTalk gradle project
io.servicetalk.gradle.plugin.internal.ProjectUtils.addGeneratedProtoDependsOn(project, task, false)
task.dependsOn unzipGrpcProtos
task.dependsOn(":servicetalk-grpc-protoc:buildExecutable") // use gradle project local grpc-protoc dependency

// you may need to manually add the artifact name as an input
Expand Down
1 change: 1 addition & 0 deletions servicetalk-grpc-netty/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ protobuf {
}
generateProtoTasks {
all().each { task ->
io.servicetalk.gradle.plugin.internal.ProjectUtils.addGeneratedProtoDependsOn(project, task, true)
if (task.isTest) {
task.dependsOn(":servicetalk-grpc-protoc:buildExecutable") // use gradle project local grpc-protoc dependency

Expand Down
1 change: 1 addition & 0 deletions servicetalk-grpc-protoc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ protobuf {
}
generateProtoTasks {
all().each { task ->
io.servicetalk.gradle.plugin.internal.ProjectUtils.addGeneratedProtoDependsOn(project, task, true)
task.generateDescriptorSet = true
task.descriptorSetOptions.includeImports = true
task.inputs
Expand Down

0 comments on commit 07255b0

Please sign in to comment.