autonomousapps / dependency-analysis-gradle-plugin

Gradle plugin for JVM projects written in Java, Kotlin, Groovy, or Scala; and Android projects written in Java or Kotlin. Provides advice for managing dependencies and other applied plugins
Apache License 2.0
1.67k stars 115 forks source link

Fail to configure projects with `tasks.whenTaskAdded` #1116

Closed BraisGabin closed 4 months ago

BraisGabin commented 5 months ago

Build scan link https://scans.gradle.com/s/dxmdvblizkask

Plugin version 1.29.0

Gradle version 8.5

JDK version 17

(Optional) Kotlin and Kotlin Gradle Plugin (KGP) version 1.9.22

(Optional) Android Gradle Plugin (AGP) version 8.2.2

Describe the bug On the projects where I use tasks.whenTaskAdded DAGP fails with this message:

* What went wrong:
A problem occurred configuring project ':app'.
> Could not create task ':app:explodeByteCodeSourceDebug'.
   > Task with name 'compileDebugJavaWithJavac' not found in project ':app'.

Even if I do nothing inside it

To Reproduce Steps to reproduce the behavior:

  1. Clone https://github.com/BraisGabin/dependency-analysis-gradle-plugin-1116
  2. Execute ./gradlew buildHealth and you will see the issue
  3. remove the line tasks.whenTaskAdded {} from app/build.gradle.kts
  4. Re-execute ./gradlew buildHealth and you will see that the issue is gone

Expected behavior It works

Additional context This issue was introduced on 1.29.0. With 1.28.0 everything works as expected.

autonomousapps commented 4 months ago

Could you try this again with the latest snapshot? I wonder if this relates to https://github.com/autonomousapps/dependency-analysis-gradle-plugin/issues/1115, which is fixed now.

autonomousapps commented 4 months ago

Nevermind, I can reproduce this easily in a test.

Although, what is your use-case for using whenTaskAdded? Looking at the javadoc, I'd say it's a bad practice, as it realizes all tasks in a project.

BraisGabin commented 4 months ago
tasks.whenTaskAdded {
    if (name.startsWith("generate") && name.endsWith("Assets")) {
        dependsOn("downloadStrings")
    }
}

Last week I saw on our scans that we were creating a lot of tasks con configuration on the tasks that use that and we are looking for a way to remove them.

The use case is that we want to execute the task downloadStrings before a stand alone app is assembled. The normal tasks.named doesn't work because the task that we are looking for doesn't exist yet.

autonomousapps commented 4 months ago

The use case is that we want to execute the task downloadStrings before a stand alone app is assembled. The normal tasks.named doesn't work because the task that we are looking for doesn't exist yet.

You can use afterEvaluate for this case. That won't eagerly realize all your tasks. Or even better, tasks.withType().matching { /* check name here */ }. If you're on Gradle 8.6, you can use tasks.named { ... } and that is lazy.