diff-coverage-gradle icon indicating copy to clipboard operation
diff-coverage-gradle copied to clipboard

'diffCoverageReport.jacocoExecFiles' file collection is empty

Open adityameesho opened this issue 1 year ago • 3 comments

Describe the bug FAILURE: Build failed with an exception.

  • What went wrong: Could not determine the dependencies of task ':diffCoverage'.

'diffCoverageReport.jacocoExecFiles' file collection is empty.

Desktop (please complete the following information):

  • OS: Linux, Mac
  • Gradle version: 7.5.1
  • Diff Coverage plugin version 0.9.5

To Reproduce ./gradlew clean diffCoverage

Expected behavior The build fails, it would be great to add an option to fail silently. The use-case is in CI builds the diff might not have any test coverage and can lead to this failure.

Logs FAILURE: Build failed with an exception.

  • What went wrong: Could not determine the dependencies of task ':diffCoverage'.

'diffCoverageReport.jacocoExecFiles' file collection is empty.

  • Try:

Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output Additional context Add any other context about the problem here.

adityameesho avatar Sep 14 '23 10:09 adityameesho

This is my actual task and it's configuration

tasks.register("jacocoDiffReport", JacocoReport) {
        diffCoverageReport {
            diffSource.git.compareWith 'refs/remotes/origin/develop'
            reports {
                html = true
                baseReportDir = file(project.jacocoPrReportLocation)
            }
            def jacocoProjects = subprojects.findAll {
                it.getTasksByName("jacocoAndroidTestReport", false)
            }

            srcDirs = files(jacocoProjects.jacocoAndroidTestReport.sourceDirectories)
            classesDirs = files(jacocoProjects.jacocoAndroidTestReport.classDirectories)
            jacocoExecFiles = files(jacocoProjects.jacocoAndroidTestReport.executionData)
        }
        group = project.jacocoGroupName
        dependsOn diffCoverage
    }

adityameesho avatar Sep 14 '23 10:09 adityameesho

Hi @adityameesho

It's not clear for me why you configure diff coverage plugin inside custom JacocoReport.

diffCoverageReport - is function itself that configures extension with further usage in DiffCoverageTask.


First of all just move the diff coverage plugin configuration outside of the custom JacocoReportTask


tasks.register("jacocoDiffReport", JacocoReport) {
        group = project.jacocoGroupName
        dependsOn diffCoverage
}

diffCoverageReport {
            diffSource.git.compareWith 'refs/remotes/origin/develop'
            reports {
                html = true
                baseReportDir = file(project.jacocoPrReportLocation)
            }
            def jacocoProjects = subprojects.findAll {
                it.getTasksByName("jacocoAndroidTestReport", false)
            }

            srcDirs = files(jacocoProjects.jacocoAndroidTestReport.sourceDirectories)
            classesDirs = files(jacocoProjects.jacocoAndroidTestReport.classDirectories)
            jacocoExecFiles = files(jacocoProjects.jacocoAndroidTestReport.executionData)
}

Then remove jacocoDiffReport task. Maybe you want to have custom JacocReport with custom name or custom configuration, but remember that it doesn't impact the diff coverage plugin.


How to deal with

'diffCoverageReport.jacocoExecFiles' file collection is empty.

Ok, it means, that the plugin wasn't able to find .exec files.

You should add some debug messages:

  1. run the plugin's task with debug option ./gradlew diffCoverage -d and investigate diff coverage plugin's log messages.
  2. OR add custom print:

diffCoverageReport {

            // other configuration part is omitted

            srcDirs = files(jacocoProjects.jacocoAndroidTestReport.sourceDirectories)
            classesDirs = files(jacocoProjects.jacocoAndroidTestReport.classDirectories)
            jacocoExecFiles = files(jacocoProjects.jacocoAndroidTestReport.executionData)

           println('SRC files:')
           srcDirs.filter {
               println "\tFile $it: ${it.exists()}"
               it.exists()
           }.each {
              println "\tFound: $it"
           }
           println('-------------')

           println('CLASS files:')
           classesDirs.filter {
               println "\tFile $it: ${it.exists()}"
               it.exists()
           }.each {
              println "\tFound: $it"
           }
           println('-------------')

           println('EXEC files:')
           jacocoExecFiles.filter {
               println "\tFile $it: ${it.exists()}"
               it.exists()
           }.each {
              println "\tFound: $it"
           }
           println('-------------')
}

Then just execute and inestigate printed messages:

./gradlew tasks -m

I think it will help you to find issue in your configuration.

SurpSG avatar Sep 15 '23 17:09 SurpSG

It's not clear for me why you configure diff coverage plugin inside custom JacocoReport.

This is done to avoid configuration time, the project is very large and we cannot afford any configuration time.

Ok, it means, that the plugin wasn't able to find .exec files.

yes, there are valid use-cases where an .exec file may not be generated, for e.g a PR which has a diff from jacoco ignored files. In out current CI workflow, we run the tests first followed by diffCoverageReport. And there are valid cases when an .exec file may not be available.

would it be possible to add an option in the plugin to fail gracefully when this sort of edge case happens?

I'm open to other possible ways to solve this edge-case.

adityameesho avatar Sep 18 '23 06:09 adityameesho