Custom plugin task dependency problem

Hello dear Gradle users,

on a project I am working on which uses SonarQube / JaCoCo im am asked to write a custom plugin to handle the configuration of SonarQube.
Basically it reads the configuration from a file and applies it to the SonarQubeExtension properties. After that it modifies every SonarQubeTask of the project the plugin is applied on, to only work if gradle runs on the build server (using the OnlyIf statement, which is a variable given to the plugin through an extension and does not change over time) and to depend on the “jacocoTestReport” gradle task (using dependsOn, also given through extension, does not change).
The problem is, that it also uses an OnlyIf statement to check if the “tasks.jacocoTesReport.get().didWork” variable is true (this was given and shall stay this way) which worked before, when the modification to the SonarQubeTask was handled outside the plugin.

The rough source code to this plugin looks like this (Kotlin, directly inside the build.gradle.kts):

open class ConfigureSonarQubePluginExtension {
var buildServer : Boolean = true
var dependencyTask : String = “jacocoTestReport”
}

open class ConfigureSonarQubePlugin : Plugin<Project> {
override fun apply(target : Project) {
target.apply(plugin = “org.sonarqube”)
val extension = target.extensions.create<ConfigureSonarQubePluginExtension>(“configuresonarqubeplugin”)
[… stuff happening …]
afterEvaluate {
target.tasks.withType(SonarQubeTask::class.java) {
OnlyIf {extension.buildServer}
dependsOn(extension.dependencyTask)
OnlyIf {target.tasks.jacocoTestReport.get().didWork}
}
}
}
}

[… build.gradle.kts stuff …]

configure(subprojects.filter {…}) {
[… stuff happening …]
apply<ConfigureSonarQubePlugin>()
configure<ConfigureSonarQubePluginExtension> {
buildServer = isBuildSever
dependencyTask = “jacocoTestReport”
}
}

Problem now is, if the gradle task “jacocoTestReport” is done (no UP-TO-DATE or the other possibilities there) the “sonarqube” task won’t run. I debugged it and it looked like, the “target.tasks.jacocoTestReport.get().didWork” is allways false because it is read when the plugin is applied. But when I transfer everything from the afterEvaluate outside the plugin and paste it behind the apply statement, it magically works.

I tested multiple different options I was addressed by co workers including:

  • not using tasks.withType but tasks.withType(…).configureEach
  • not using tasks.withType at all and only using tasks.named
  • adressing the “jacocoTestReport” task seperatly for every OnlyIf and dependsOn statement
  • using the configure for the plugin extension in different ways (adressing the members directly) or not using a configure statement at all
  • using another extension member called “didWork” and setting it in the lower configure<…> statement to “tasks.jacocoTestReport.get().didWork” directly
  • disabled the “sonarqube” task inside the plugin only to conditionally enable it using “tasks.jacocoTestReport { val dw = this.didWork ; doLast { tasks.withType(SonarQubeTask::class.java) { enabled = dw } } }”

So i do not know how to make it work. On the other hand someone suggestet (and i read it online only with no one supporting or denying it) that the use of “target.tasks.jacocoTestReport.get().didWork” does not work inside a plugin because it is changed at runtime and the plugin is loaded (apply is run) at what i call compile time (I do not get the gradle system when what is running yet).
This also makes sense because when I use this variable outside the plugin (as mentioned above) it works but not inside the plugin.

Hope somebody can help me as non of my coworkers can, the documentation is also not very helpfull :frowning:
And I am sorry if the source code is not well formatted (I dont get this forum software) and there is not much other information. I can not publish the full build.gradle.kts file -.-

Also what i forgot to mention:
when the output is sth. like this:
… project:jacocoTestReport SKIPPED / UP-TO-DATE / FROM-CACHE
… project:sonarqube SKIPPED

is valid but
… project:jacocoTestReport
… project:sonarqube SKIPPED

is invalid! This is why the “didWork” is used and without using it it would not work, ive testet it.

During your testing, are you sure that extension.buildServer is true?