Kotlin / kotlinx-kover

Apache License 2.0
1.37k stars 53 forks source link

koverCachedVerify failure due to incorrect paths in the .artifact file #633

Closed remcomokveld closed 5 months ago

remcomokveld commented 5 months ago

Describe the bug

Sporadically, in a medium-to-large project which has a couple of included builds, the koverCachedVerify of some android modules will fail due to having inputs from tasks that it didn't declare.

The error below is the result, of the bug, but I think the bug is further upstream in the Gradle plugin.

When I look at the files in included-build/project-a/build/kover/.artifact, included-build/project-a/build/kover/debug.artifact and included-build/project-a/build/kover/release.artifact they all contain the following

:project-b
project-b/src/debug/kotlin
project-b/src/debug/java
project-b/src/main/kotlin
project-b/src/main/java

project-b/build/tmp/kotlin-classes/debug
project-b/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes

project-b/build/kover/bin-reports/testDebugUnitTest.ic

Errors

I guess as a result of the .artifact files having the wrong paths in them, the following gradle error appears.

* What went wrong:
A problem was found with the configuration of task ':included-build:project-a:koverCachedVerify' (type 'KoverDoVerifyTask').
  - Gradle detected a problem with the following location: '/Users/me/Projects/included-build/project-b/build/kover/bin-reports/testDebugUnitTest.ic'.

    Reason: Task ':included-build:project-a:koverCachedVerify' uses this output of task ':included-build:project-b:testDebugUnitTest' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.

    Possible solutions:
      1. Declare task ':included-build:project-b:testDebugUnitTest' as an input of ':included-build:project-a:koverCachedVerify'.
      2. Declare an explicit dependency on ':included-build:project-b:testDebugUnitTest' from ':included-build:project-a:koverCachedVerify' using Task#dependsOn.
      3. Declare an explicit dependency on ':included-build:project-b:testDebugUnitTest' from ':included-build:project-a:koverCachedVerify' using Task#mustRunAfter.

    For more information, please refer to https://docs.gradle.org/8.7/userguide/validation_problems.html#implicit_dependency in the Gradle documentation.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Expected behavior The paths in the .artifact files of project-a to point to directories in project-a rather than directories in project-b

Reproducer

I have attached a project which is able to reproduce this issue 100% for me.

When I run ./gradlew check in the root directory

kover-repro-project.zip

It might be worth noting that I have org.gradle.caching=true set in ~/.gradle/gradle.properties so gradle build cache caching is enabled for this build

Reports If applicable, report files or screenshots.

Environment

shanshin commented 5 months ago

Hi, could you please specify the exact version of Kover Gradle Plugin? I assume that 2.0.0 is Kotlin version.

Unfortunately, it's hard to say anything without seeing the full Kover configuration for all projects. Do you use composite builds?

remcomokveld commented 5 months ago

Actually I don't know why the repro project wasn't working earlier. I updated OP with a repro project, it seems to happen all the time from a clean build on that project.

remcomokveld commented 5 months ago

I think I found the root cause. The cacheKey of the kotlinx.kover.gradle.plugin.tasks.services.KoverArtifactGenerationTask is computed based on its inputs. If there are no inputs, which is the case in both the original project and the repro project, the cache key ends up being the same, resulting in the cache entry of :included-build:project-b:koverGenerateArtifact to be the pulled from cache for that :included-build:project-a:koverGenerateArtifact, or vice versa, depending on which one writes to cache first.

I've got a buildScan to prove that theory here

You can see the cacheKey for :included-build:project-a:koverGenerateArtifact is 3dcbd960c9a87344fddf0288f721b449

And the cacheKey of :included-build:project-b:koverGenerateArtifact is also 3dcbd960c9a87344fddf0288f721b449

I tried adding @get:Input to the projectPath property of KoverArtifactGenerationTask and then the issue goes away. (See buildscan here with different cacheKeys for each task). https://github.com/Kotlin/kotlinx-kover/blob/f8d3b5e87ecc05e67ae8088d1271be570aeacd53/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/tasks/services/KoverArtifactGenerationTask.kt#L45

shanshin commented 5 months ago

Fixed in 0.8.2