Kotlin / kotlinx-kover

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to run XML generator after upgrading to 0.7.2 (or later) from 0.7.1.

jhperezd opened this issue · comments

Describe the bug
We are unable to generate XML reports (or HTML reports for that matter) after upgrading to 0.7.2 from 0.7.1. Are there any recommended "migration" steps needed to be done after this upgrade, or any known issues why a configuration that works with 0.7.1 may not work with 0.7.2?

Note that note all of our subprojects produce the error above, but it is not obvious as to why we do see this error in some cases and only after upgrading from 0.7.1 to 0.7.2.

Errors

663: Task failed with an exception.
-----------
* What went wrong:
Some problems were found with the configuration of task ':libraries:path:to:subproject:koverXmlReport' (type 'KoverXmlTask').
  - In plugin 'org.jetbrains.kotlinx.kover' type 'kotlinx.kover.gradle.plugin.tasks.reports.KoverXmlTask' property 'filters' doesn't have a configured value.
    Reason: This property isn't marked as optional and no value has been configured.
    Possible solutions:
      1. Assign a value to 'filters'.
      2. Mark property 'filters' as optional.
    For more information, please refer to https://docs.gradle.org/8.4/userguide/validation_problems.html#value_not_set
 in the Gradle documentation.
  - In plugin 'org.jetbrains.kotlinx.kover' type 'kotlinx.kover.gradle.plugin.tasks.reports.KoverXmlTask' property 'reportFile$kover_gradle_plugin' doesn't have a configured value.
    Reason: This property isn't marked as optional and no value has been configured.
    Possible solutions:
      1. Assign a value to 'reportFile$kover_gradle_plugin'.
      2. Mark property 'reportFile$kover_gradle_plugin' as optional.
    For more information, please refer to https://docs.gradle.org/8.4/userguide/validation_problems.html#value_not_set
 in the Gradle documentation.

Reproducer
We don't have a sample project to share, our main project is close source but here is a description of our setup:
Our project has a large number of subproject, and it is setup with the following configuration in our top-level build.gradle.kts, notice that the configuration does have a "filters" section and a call to "setReportFile()". This configuration propagates down to all of our subprojects.

  // Configuring the kover (code coverage) plugin
  pluginManager.withPlugin("org.jetbrains.kotlinx.kover") {
    val codeCoverageIncludes: List<String> = listOf("<some files>")
    val codeCoverageExcludes: List<String> = listOf("<some files>")

    // Common report configuration
    val config =
      Action<KoverReportsConfig> {
        // configure html report Kover task
        html {
          // change report directory
          setReportDir(layout.buildDirectory.dir("code-coverage/html-report"))
        }

        // configure xml report Kover task
        xml {
          // change report directory & report file name
          setReportFile(
            layout.buildDirectory.file("code-coverage/xml-report/code-coverage-result.xml")
          )
        }
      }

    extensions.configure(KoverReportExtension::class) {
      // Common filters
      filters {
        excludes {
          classes(codeCoverageExcludes)
          packages("<some packages>")
          annotatedBy("<some string>")
        }
        includes { classes(codeCoverageIncludes) }
      }

      // Use the same variant as ciUnitTest if it's an android project
      val androidTestVariant =
        if (plugins.hasPlugin("com.android.base")) {
          SlackProperties(project).ciUnitTestVariant
        } else {
          null
        }

      // Default reports (JVM, Multiplatform)
      defaults {
        androidTestVariant?.let(::mergeWith)
        config.execute(this)
      }

      androidTestVariant?.let {
        // Android reports
        androidReports(variant = it, config = config)
      }
    }
  }

Environment

  • Kover Gradle Plugin version: 0.7.2
  • Gradle version: AGP 8.1.2
  • Kotlin project type: Kotlin/Android

Hi,
could you please clarify a few questions:

  1. have you tried version 0.7.3 or 0.7.4?

pluginManager.withPlugin("org.jetbrains.kotlinx.kover") {
is this script used only in the root project?
If yes, then it is enough to write after using the Kover plugin in the plugins block

koverReport {
    // Common filters
    filters {
      // ...
    }

      // Default reports (JVM, Multiplatform)
    defaults {
        // ...
      }
}
  1. how do you apply Kover plugin in project (and subprojects)?
  2. are build variants created dynamically in your projects?
  3. Which command do you run Kover tasks with?
    Using androidReports(variant = it, config = config) looks superfluous, because the same settings are applied to reports by default and koverXmlReport can be runned always

Also, for flexibility, it is always better to use a lazy Gradle DSL.
Instead of

if (plugins.hasPlugin("com.android.base")) {

it is better to use

pluginManager.withPlugin("com.android.base") {
    koverReport {
        defaults {
            mergeWith(SlackProperties(project).ciUnitTestVariant)
            
            // config file names
        }
        
        // no `androidReports` config if always executes only `koverXmlReport` command
    }
}

Hello, thanks for looking into the problem. We'll try out some of the changes you mention, it is possible we are configuring something incorrectly that only became apparent with 0.7.2.
In the meantime, I'll attempt to answer your questions:

  1. Yes. We first jump straight up to 0.7.4, that's where we first saw the issue. We then went back down the different releases to see where the issues started and kept seeing the same issues with anything higher than 0.7.1.

  2. our gradle file has a "subprojects" section where we list all the plugins/configurations that are propagated down to the subproject:

subprojects {
  pluginManager.withPlugin("<plugin>") {
  }
  pluginManager.withPlugin("org.jetbrains.kotlinx.kover") {
  }
...
}
  1. I am not sure I understand what you need to know here 😅

  2. yes! We have a few variants that we generate for different usages.

  3. That's probably because of the different variants we have, since our tests only run on one (or two) of the variants. The command we use is: ./gradlew koverXmlReport , we pass a couple of extra parameters for gradle here such as --no-configuration-cache and --exclude-task <task>, so some subprojects may not need to generate a report.

commented

Hello,
It seems like I have a similar — if not the same — issue.

Reproducer: https://github.com/armatys/KoverTest/tree/kover_074_gradle_81 (note: it's on a branch called kover_074_gradle_81)

Basically, I'm applying the kover plugin in afterEvaluate. Then, run any of the commands: ./gradlew koverVerify, ./gradlew koverHtmlReport or ./gradlew koverXmlReport and it will fail.

In 0.7.1. it worked fine, but it fails in 0.7.2, 0.7.3 and 0.7.4.


I'm applying the kover plugin in after evaluate, because I'm using a custom convention plugin with a custom extension object, so I need to wait until afterEvaluate to get the proper configuration values.

I could move the application of kover plugin outside of afterEvaluate block, but then, the lib project is not configured properly (see classes(ext.excludeClasses.get()) in CustomPlugin). The class "com.example.lib.MyClass" is not excluded from the report if the plugin is applied immediately.

I guess it could be solved with #410 ?

@armatys

I guess it could be solved with #410 ?

Yes, the implementing of #410 should simplify the use of convention plugins and it should solve your problem.

Closed as duplicate of #410.

Feel free to open new issue if the problem persists after the release of #410.