Skip to content

Commit

Permalink
Implemented Kover Gradle Plugin DSL v4
Browse files Browse the repository at this point in the history
- blocks kover and koverReports are merged
- added possibility of lazy configuration of Kover extensions
- removed the concept of default reports
- added the ability to create custom report variants
- Created interfaces for Kover tasks

Resolves #461
Resolves #410
Resolves #462
Resolves #463
Resolves #338
  • Loading branch information
shanshin committed Feb 19, 2024
1 parent 0575a68 commit b5903d3
Show file tree
Hide file tree
Showing 125 changed files with 5,518 additions and 5,173 deletions.
373 changes: 136 additions & 237 deletions kover-gradle-plugin/api/kover-gradle-plugin.api

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions kover-gradle-plugin/docs/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ koverReport {
onCheck = false

// XML report title (the location depends on the library)
title.set("Custom XML report title")
title = "Custom XML report title"

// XML report file
setReportFile(layout.buildDirectory.file("my-project-report/result.xml"))
xmlFile = layout.buildDirectory.file("my-project-report/result.xml")

// overriding filters only for the XML report
filters {
Expand Down Expand Up @@ -134,7 +134,7 @@ koverReport {
onCheck = false

// directory for HTML report
setReportDir(layout.buildDirectory.dir("my-project-report/html-result"))
htmlDir = layout.buildDirectory.dir("my-project-report/html-result")

// overriding filters only for the HTML report
filters {
Expand Down Expand Up @@ -326,7 +326,7 @@ koverReport {
onCheck = false

// directory for HTML report
setReportDir(layout.buildDirectory.dir("my-project-report/html-result"))
htmlDir = layout.buildDirectory.dir("my-project-report/html-result")

// overriding filters only for the HTML report
filters {
Expand Down
2 changes: 1 addition & 1 deletion kover-gradle-plugin/docs/migrations/migration-to-0.7.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ koverReport {
onCheck = false
// directory for HTML report
setReportDir(layout.buildDirectory.dir("my-project-report/html-result"))
htmlDir = layout.buildDirectory.dir("my-project-report/html-result")
// overriding filters only for the HTML report
filters {
Expand Down
228 changes: 228 additions & 0 deletions kover-gradle-plugin/docs/migrations/migration-to-0.8.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
# Kover migration guide from 0.7.x to 0.8.0

## Conceptual changes
### Single kover project extension
The `0.7.x` version used two project extensions named `kover` and `koverReports`.
This was confusing and made it difficult to search through documentation or examples.

Since `0.8.0`, there is only one `kover` extension left.
All the settings that used to be in `koverReports` are now located in
```kotlin
kover {
reports {
// setting from old koverReports extension
}
}
```
The settings from the old `kover` are now either left as is, or moved to `kover { variants { ... } }` block.

Following configuration
```kotlin
kover {
// exclude classes compiled by Java compiler from all reports
excludeJavaCode()

excludeTests {
// exclude Gradle test tasks
tasks(testTasks)
}
excludeInstrumentation {
// exclude classes from instrumentation
classes(unistrumentedClasses)
}
excludeSourceSets {
// exclude source classes of specified source sets from all reports
names(excludedSourceSet)
}
}
```

Since `0.8.0` looks like:
```kotlin
kover {
variants {
testTasks {
/* exclude Gradle test tasks */
excluded.addAll(testTasks)
}

instrumentation {
// exclude classes from instrumentation
excludedClasses.addAll(unistrumentedClasses)
}

sources {
// exclude classes compiled by Java compiler from all reports
excludeJava = true

// exclude source classes of specified source sets from all reports
excludedSourceSets.addAll(excludedSourceSet)
}
}
}
```

### The concept of default reports has been removed
In the `0.7.x` version, there were tasks named `koverHtmlReport`, `koverXmlReport`, `koverVerify`, `koverLog`, `koverBinaryReport`,
which included only classes and tests for JVM target, and it was also possible to add tests from classes of specified Android build variant using
```kotlin
koverReport {
defaults {
mergeWith("buildVariant")
}
}
```

Starting with the `0.8.0` version, these features have been removed.
However, to implement similar capabilities, the concepts of _Total reports_ and _Custom reports_ were introduced.

### Total reports
Since `0.8.0` tasks `koverHtmlReport`, `koverXmlReport`, `koverVerify`, `koverLog`, `koverBinaryReport` are designed
to generate reports on all classes and tests of the project.
For JVM projects, nothing changes compared to the `0.7.x` version, however, for Android projects,
running one of these tasks will result running tests for all build variants present in the project.

### Custom reports variants
In the `0.7.x` version, it was allowed to merge a report for several Android build variants only into default reports,
it was not possible to create several combinations with the arbitrary inclusion of different build variants.

Since `0.8.0` in order to merge several Android build variants, you need to create a custom reports variant.

The newly created variant is initially empty, in order for classes to appear in the report and tests to be executed
when generating it, need to add existing variants provided from Kotlin targets to it: it can be a `jvm` variant, or any of an Android build variant.
```kotlin
kover {
variants {
create("custom") {
add("jvm")
add("release")
}
}
}
```

Creating a variant with a name `custom` will add tasks named `koverHtmlReportCustom`, `koverXmlReportCustom`, `koverVerifyCustom`, `koverLogCustom`, `koverBinaryReportCustom`.

### More about the reports variant
A reports variant is a set of information used to generate a report, namely:
project classes, a list of Gradle test tasks, classes that need to be excluded from instrumentation.

There are several types of report variants:
- total variant (have no special name), always created
- variant for classes in JVM target (named `jvm`), created by Kover Gradle Plugin if JVM target is present
- variants for the Android build variant (the name matches the name of the build variant), created by Kover Gradle Plugin if there are Android build variants in the project
- custom variants (the name is specified when creating), declared in the build script configuration

For each variant, a set of tasks is created in the project to generate reports on the information contained in it.

The names are generated according to the following rule:
`koverHtmlReport<VariantName>`, `koverXmlReport<VariantName>`, `koverVerify<VariantName>`, `koverLog<VariantName>`, `koverBinaryReport<VariantName>`


The reports variant can be used in another project to create a merged reports.
To do this, in another project, which we will call the merging project, we will specify a dependency on the project from which we want to import classes and Gradle test tasks.
```kotlin
dependencies {
kover(project(":lib"))
}
```
As a result, if you run the `:koverHtmlReport` task, it will run all the tests from merging project and `:lib` project
and generate a report for all classes from merging project and `:lib` project.

However, if you call a task for a named variant, for example `:koverHtmlReportRelease`, then it will run tests for `release` variant from merging project and `:lib` project
and generate a report for classes of `release` variant from merging project and `:lib` project.

At the same time, it is recommended that variant `release` is also present in the `:lib` project, however,
for technical reasons, such a check may not be implemented in `0.8.0` and subsequent versions.

### The format-specific reports filters has been removed
Previously, it was acceptable to override filters for each report format (XML, HTML, etc.), like
```kotlin
koverReport {
filters {
// top-level filters
}
defaults {
filters {
// filters for all default reports
}

html {
filters {
// filters for HTML default report
}
}
}
}
```

This is very confusing, because there are 3 levels in which you can write `filters { }` also it is difficult for users to understand exactly where to write filters - which leads to the fact of copy-paste the same filters are specified for all types of reports (inside xml, html, verify blocks).

Since `0.8.0`, specifying filters for specific type of report (HTML or XML) is deprecated. It is now possible to create custom variants of reports, if it is necessary to generate a report with a different set of filters.
In this case, it is better to create a new custom variant and override the filters in it:
```kotlin
kover {
variants {
create("customJvm") {
add("jvm")
}
}

reports {
variant("customJvm") {
filters {
// filters only for customJvm report set
}
}
}
}

```


### Added the ability of lazy configuration
In some cases, the values are not known at the time of configuration, for example, when using convention plugins and extensions in them.

To do this, overloads have been added that allow to work with the value providers (Gradle `Provider<T>` type).

```kotlin
kover {
reports {
filters {
exludes {
classes(classProvider)
}
}

verify {
rule {
bound {
min = minValueProvider
}
// or
minBound(minValueProvider)
}
}
}
}

```


### Added public interfaces for Kover tasks

Now all Kover report tasks implement interface `kotlinx.kover.gradle.plugin.dsl.tasks.KoverReport`.

Also, a separate interface has been created for each report type:
- `kotlinx.kover.gradle.plugin.dsl.tasks.KoverXmlReport`
- `kotlinx.kover.gradle.plugin.dsl.tasks.KoverHtmlReport`
- `kotlinx.kover.gradle.plugin.dsl.tasks.KoverLogReport`
- `kotlinx.kover.gradle.plugin.dsl.tasks.KoverVerifyReport`
- `kotlinx.kover.gradle.plugin.dsl.tasks.KoverBinaryReport`

Adding public interfaces will allow to filter Kover tasks, for example, to specify them in dependencies
```kotlin
tasks.check {
dependsOn(tasks.matching { it is KoverHtmlReport })
}
```
46 changes: 18 additions & 28 deletions kover-gradle-plugin/examples/android/dynamic/dyn/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,39 +40,29 @@ dependencies {
kover(project(":app"))
}


koverReport {
// filters for all report types of all build variants
filters {
excludes {
classes(
"*Fragment",
"*Fragment\$*",
"*Activity",
"*Activity\$*",
"*.databinding.*",
"*.BuildConfig"
)
}
}

androidReports("release") {
// filters for all report types only of 'release' build type
kover {
reports {
// filters for all report types of all build variants
filters {
excludes {
classes(
"*Fragment",
"*Fragment\$*",
"*Activity",
"*Activity\$*",
"*.databinding.*",
"*.BuildConfig",
androidGeneratedClasses()
}
}

// excludes debug classes
"*.DebugUtil"
)
variant("release") {
// filters for all report types only of 'release' build type
filters {
excludes {
androidGeneratedClasses()

classes(
// excludes debug classes
"*.DebugUtil"
)
}
}
}
}

}

58 changes: 25 additions & 33 deletions kover-gradle-plugin/examples/android/flavors/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -98,44 +98,36 @@ dependencies {
}


koverReport {
// filters for all report types of all build variants
filters {
excludes {
classes(
"*Fragment",
"*Fragment\$*",
"*Activity",
"*Activity\$*",
"*.databinding.*",
"*.BuildConfig"
)
kover {
variants {
create("custom") {
/**
* Tests, sources, classes, and compilation tasks of the 'app1AppDebug' build variant will be included in the report variant `custom`.
* Thus, information from the 'app1AppDebug' variant will be included in the 'custom' report for this project and any project that specifies this project as a dependency.
*/
addWithDependencies("app1AppDebug")
}
}

defaults {
/**
* Tests, sources, classes, and compilation tasks of the 'debug' build variant will be included in the default report.
* Thus, information from the 'app1AppDebug' variant will be included in the default report for this project and any project that specifies this project as a dependency.
*/
mergeWith("app1AppDebug")
}

androidReports("app1AppRelease") {
// filters for all report types only of 'app1AppRelease' build variant
reports {
// filters for all report types of all build variants
filters {
excludes {
classes(
"*Fragment",
"*Fragment\$*",
"*Activity",
"*Activity\$*",
"*.databinding.*",
"*.BuildConfig",

// excludes debug classes
"*.DebugUtil"
)
androidGeneratedClasses()
}
}

variant("app1AppRelease") {
// filters for all report types only of 'app1AppRelease' build variant
filters {
excludes {
androidGeneratedClasses()

classes(
// excludes debug classes
"*.DebugUtil"
)
}
}
}
}
Expand Down

0 comments on commit b5903d3

Please sign in to comment.