Slackbot
06/16/2022, 2:51 PMAndrew Grosner
06/16/2022, 3:19 PMval provider = target.gradle.sharedServices.registerIfAbsent("TimingsService", TimingsService::class) {
val apkBuildDir = File(target.projectDir, "app/build/outputs/apk")
this.parameters.apkDirExists.set(apkBuildDir.exists())
this.parameters.projectName.set(target.name)
this.parameters.taskNameList.set(target.gradle.startParameter.taskNames)
}
if (registry is BuildEventListenerRegistryInternal) {
registry.onOperationCompletion(provider)
}
abstract class TimingsService :
BuildService<TimingsService.Params>,
BuildOperationListener,
Closeable {
overridding:
override fun finished(buildOperation: BuildOperationDescriptor, finishEvent: OperationFinishEvent) {
val result = finishEvent.result
val details = buildOperation.details
if (result is ExecuteTaskBuildOperationType.Result && details is ExecuteTaskBuildOperationDetails) {
val name = details.task.project.name
val duration = finishEvent.endTime - finishEvent.startTime
if (result.skipMessage == null) {
val total = moduleTimings[name]
if (total != null) {
moduleTimings[name] = total + duration
} else {
moduleTimings[name] = duration
}
} else {
moduleCached[name] = result.skipMessage == TaskExecutionOutcome.FROM_CACHE.message
}
}
Andrew Grosner
06/16/2022, 3:20 PMinterface Params : BuildServiceParameters {
val apkDirExists: Property<Boolean>
val projectName: Property<String>
val taskNameList: ListProperty<String>
}
Andrew Grosner
06/16/2022, 3:20 PMKen Yee
06/16/2022, 3:22 PMAndrew Grosner
06/16/2022, 3:22 PMAndrew Grosner
06/16/2022, 3:23 PMKen Yee
06/16/2022, 3:24 PMAndrew Grosner
06/16/2022, 3:38 PMVampire
06/16/2022, 3:58 PMBuilOperationListener
or an internal class. Here the proper way is documented: https://docs.gradle.org/current/userguide/build_services.html#operation_listener
Make the build service implement OperationCompletionListener
and register it with BuildEventsListenerRegistry
. And if you need a hook for build finish, make the service also implement AutoCloseable
. Those are the supported CC compatible ways.Andrew Grosner
06/16/2022, 4:05 PMOperationCompletedListener
only gives you start and end time, not which module task ranAndrew Grosner
06/16/2022, 4:06 PMAndrew Grosner
06/16/2022, 4:06 PMVampire
06/16/2022, 4:40 PMevent.displayName
=> "Task :foo:compileJava SUCCESS"
event.descriptor.displayName
=> "Task :foo:compileJava"
event.descriptor.name
=> ":foo:compileJava"
Andrew Grosner
06/16/2022, 5:12 PMAndrew Grosner
06/16/2022, 5:13 PMAndrew Grosner
06/16/2022, 5:13 PMVampire
06/16/2022, 5:16 PMAutoCloseable
too, it will be triggered somewhen between the last task finished and the build finished.
So you could record the start time of the first finished task and remember the task finish time of the last finished task and when the close
is triggered, you know the last task happened, or you just take the time in the close
method.
You could also take the time when the listener is instaniated, but I'm not fully sure whether this will be after the first task finished or before it is started.
By taking the task start time of the first task finished event you are on the safe side, especially if you want to record task execution time.