Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create tasks for custom Gradle tasks to generate reports from binary reports #588

Open
shanshin opened this issue Mar 28, 2024 · 5 comments
Assignees
Labels
Feature Feature request issue type S: untriaged Status: issue reported but unprocessed

Comments

@shanshin
Copy link
Collaborator

shanshin commented Mar 28, 2024

What is your use-case and why do you need this feature?
If the testing does not take place in one build run, but is distributed over several builds, for example, at different CI steps.

In this case, it is necessary to generate a binary report in each shard, and later generate a report from them: XML, HTML or verification.

Now user may use:

  • Kover CLI
  • KoverFeatures dependency

However, this is inconvenient for use in Gradle, because it does not into the concept of runnable Gradle tasks.

In this case, users need to write their own tasks, set up input and output properties in them, which takes some time and is not very obvious to a person who is not familiar with Gradle.

Describe the solution you'd like
Create a set of users tasks to generate report from evaluated earlier binary reports.

public abstract class KoverUserHtmlReport {
    filters(config: Action<KoverReportFiltersConfig>)

    val binaryReports: ListProperty<RegularFile>
    val charset: Property<String>
    val title: Property<String>
    val sourceRoots: ListProperty<Directory>

    val htmlDir: DirectoryProperty
}

public abstract class KoverUserXmlReport {
    filters(config: Action<KoverReportFiltersConfig>)

    val binaryReports: ListProperty<RegularFile>
    val title: Property<String>

    val xmlFile: RegularFileProperty
}

public abstract class KoverUserVerifyReport {
    filters(config: Action<KoverReportFiltersConfig>)
    verify(config: Action<KoverVerificationRulesConfig>)

    val binaryReports: ListProperty<RegularFile>
}

*Manually specifying the root directories with source files is inconvenient, but in the first iteration we can leave it like this, because it is not very clear how to do it better: users need to include all source files, including all Android build variants, or how

@shanshin shanshin added Feature Feature request issue type S: untriaged Status: issue reported but unprocessed labels Mar 28, 2024
@shanshin shanshin self-assigned this Mar 28, 2024
@mgroth0
Copy link

mgroth0 commented Mar 29, 2024

I think this is related to #443

In my workaround for that, I am currently configuring the koverHtmlReport in a somewhat hack way:

    tasks.withType<KoverHtmlReport>().configureEach {
        val reportDir = layout.buildDirectory.asFile.get().resolve("reports").resolve("kover")
        val htmlReportDir =
            reportDir.resolve(
                when (name) {
                    "koverHtmlReport" -> "html"
                    "koverHtmlReportJvm" -> "htmlJvm"
                    "koverHtmlReportDebug" -> "htmlDebug"
                    "koverHtmlReportRelease" -> "htmlRelease"
                    else -> error("What is the kover html report name for $name?")
                }
            )
        val cssDir = htmlReportDir.resolve("css")
        val coverageCss = cssDir.resolve("coverage.css")
        val ideaMinCss = cssDir.resolve("idea.min.css")
        doLast {
            // here I make rough edits to the CSS files to invert some of the colors
        }
    }

This workaround is sufficient for me to be able to look at the HTML reports without my eyes hurting.

The reason I wanted to bring this up here is to suggest that exposing the report directory for each kover report task could be a nice feature.

Then I could completely eliminate this part:

   tasks.withType<KoverHtmlReport>().configureEach {
        val reportDir = layout.buildDirectory.asFile.get().resolve("reports").resolve("kover")
        val htmlReportDir =
            reportDir.resolve(
                when (name) {
                    "koverHtmlReport" -> "html"
                    "koverHtmlReportJvm" -> "htmlJvm"
                    "koverHtmlReportDebug" -> "htmlDebug"
                    "koverHtmlReportRelease" -> "htmlRelease"
                    else -> error("What is the kover html report name for $name?")
                }
            )

Of course, I could also possibly just simplify my workaround like:

val htmlReportDir = reportDir.resolve("html" + name.substringAfter("koverHtmlReport"))

But in any case, this still requires me as the user to implement some logic related to the variant names.

Also, of course #587 would also help with this. But then, still, I need to know to look inside the "reports/kover" directory and I need to know the prefix is "html".

I hope this provides some more context into how users might want to modify reports. For my use case, perhaps the main takeaways are:

  1. In this case, I didn't want to create my own report from the binary data. I just wanted to take the default HTML report and modify it directly. I imagine others also might prefer this over creating their own report for simple cases
  2. The way the kover gradle plugin could help the most would be to expose the report directories and maybe even the specific files (the CSS files for me)

@mgroth0
Copy link

mgroth0 commented Mar 29, 2024

Worth noting that for my specific use case, I technically don't even need the report dir to be exposed as long as the CSS files are. But that's probably too specific of a consideration for my use case since I only needed to edit the CSS

@shanshin
Copy link
Collaborator Author

@mgroth0, it seems that your use-case and #443 is not quite related to the current task.

Your problem is that you need to read the directory for the each HTML report task, this is solved by simply exposing property

interface KoverHtmlReprt {
    val reportDir: Provider<Directory>
}

Then you can write something like this

tasks.withType<KoverHtmlReport>().configureEach {
    doLast {
        val dir = reportDir.get().asFile
        // do some changes in dir
    }
}

@mgroth0
Copy link

mgroth0 commented Mar 29, 2024

You're right, it is different. And you are right that exposing reportDir would be a good solution for my use case.

Still, I added my comment here because I thought maybe it would be useful to consider as this API is being designed. Looking at the big picture, I think you would be supporting users in two different ways to make their own reports:

  1. To create their own report from binary data (this task)
  2. To modify default reports (exposing reportDir)

@shanshin
Copy link
Collaborator Author

Relates #590

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Feature request issue type S: untriaged Status: issue reported but unprocessed
Projects
None yet
Development

No branches or pull requests

2 participants