Slackbot
02/02/2022, 1:02 AMVampire
02/02/2022, 1:41 AMAutocloseable so that it's close() method is called before it is disposed
• implement OperationCompletionListener so that you can use it as build event listener
• register it as build event listener using BuildEventsListenerRegistry so that it receives events about executed tasks and thus is required until the last task is executed
This way somewhere between the last task being finished and the build being finished the close method will be called which roughly is at the end of the build.John Bellini
02/03/2022, 12:19 AMproject.gradle.sharedServices.registerIfAbsent("myBuildService", MyTask::class.java) {}
The docs talk about injecting the BuildEventsListenerRegistry but I haven't figured out how to do that yet.Vampire
02/03/2022, 12:26 AMBuildEventsListenerRegistry and use that to register the build service as listener.
How to do it depends on where you do it, but you basically inject it like any other built-in service you inject.Vampire
02/03/2022, 12:30 AMinterface BuildEventsListenerRegistryProvider {
@get:Inject
val buildEventsListenerRegistry: BuildEventsListenerRegistry
}
objects.newInstance<BuildEventsListenerRegistryProvider>().buildEventsListenerRegistry...Vampire
02/03/2022, 12:31 AMJohn Bellini
02/03/2022, 5:56 PMVampire
02/03/2022, 6:31 PMProperty interface, but about a normal Kotlin class propertyVampire
02/03/2022, 6:33 PMabstract class FooPlugin {
@get:Inject
abstract val buildEventsListenerRegistry: BuildEventsListenerRegistry
override fun apply(target: Project) {
buildEventsListenerRegistry...
}
}Vampire
02/03/2022, 6:33 PMJohn Bellini
02/03/2022, 6:39 PM@Inject
protected abstract fun getObjectFactory(): ObjectFactory?
So after I inject the buildEventsListenerRegistry,
override fun apply(project: Project) {
val task = project.tasks.create(PLUGIN_TASK_NAME, MyTask::class.java)
buildEventsListenerRegistry.onTaskCompletion(task)
}
That results in this error:
Type mismatch.
Required:
Provider<out OperationCompletionListener!>!
Found:
MyTask
where MyTask is define like so:
abstract class MyTask : DefaultTask(), AutoCloseable, OperationCompletionListener, BuildService<BuildServiceParameters.None> {John Bellini
02/03/2022, 6:46 PMoverride fun apply(project: Project) {
val task = project.tasks.create(PLUGIN_TASK_NAME, MyTask::class.java)
val provider = project.gradle.sharedServices.registerIfAbsent("myBuildService", MyTask::class.java) {}
buildEventsListenerRegistry.onTaskCompletion(provider)
}
}John Bellini
02/03/2022, 7:00 PMorg.gradle.api.tasks.TaskInstantiationException: Task of type 'com.ea.gradle.plugin.coverage.CoverageTask$Inject' has been instantiated directly which is not supported. Tasks can only be created using the Gradle API or DSL.
Seems like I might need to split the Task from the Service and Listener? So another class that is a BuildService and OperationCompletionListener and the task uses that new class? 🤔Vampire
02/04/2022, 2:57 PMThanks. Interesting that I have to have @get:Inject rather than just @Inject. Some objects you can just do @Inject for example
```@Inject
protected abstract fun getObjectFactory(): ObjectFactory?```Because that is a getter, not a property. You can write it like
@Inject
protected abstract fun getObjectFactory(): ObjectFactory?
or imho nicer and more idiomatic as
@get:Inject
abstract val objectFactory : ObjectFactory
Nicer especially because you can then use it directly and do not have to call the getter explicitly when using it.
But still the annotations needs to be effective on the getter, hence the get: which will put the annotation on the generated getter in the class file.
Seems like I might need to split the Task from the Service and Listener?Might be, never tried to combine it like that, as that is not very OO. It is cleaner to separate concerns and it could well be that such a combination is not supported, but I don't know.
So another class that is a BuildService and OperationCompletionListener and the task uses that new class?Yes, that's the usual process. While in your case the task does not use the build service. Or at least you didn't say that, you just said you want some "build finished" behaviour.
John Bellini
02/07/2022, 5:09 PMVampire
02/07/2022, 6:40 PMproject for?
Using project in tasks at runtime is also bad, especially with the upcoming configuration cache in mind where it is illegal to do so.John Bellini
02/07/2022, 7:22 PMVampire
02/07/2022, 11:15 PMProject instance at runtimeVampire
02/07/2022, 11:17 PMproject is usually accessed for.