Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ maven-embedder = "3.9.8"
maven-api = "3.0"
maven-resolver = "1.9.21"
maven-slf4j = "1.7.36"
jacoco = "0.8.12"
jacoco = "0.8.14"

[libraries]

Expand Down
1 change: 1 addition & 0 deletions kover-gradle-plugin/api/kover-gradle-plugin.api
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ public abstract interface class kotlinx/kover/gradle/plugin/dsl/KoverVerifyTaskC
public final class kotlinx/kover/gradle/plugin/dsl/KoverVersions {
public static final field INSTANCE Lkotlinx/kover/gradle/plugin/dsl/KoverVersions;
public static final field JACOCO_TOOL_DEFAULT_VERSION Ljava/lang/String;
public static final field JACOCO_TOOL_MINIMAL_VERSION Ljava/lang/String;
public static final field MINIMUM_GRADLE_VERSION Ljava/lang/String;
public final fun getVersion ()Ljava/lang/String;
}
Expand Down
6 changes: 5 additions & 1 deletion kover-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ dependencies {
// exclude transitive dependency on stdlib, the Gradle version should be used
compileOnly(kotlin("stdlib"))
compileOnly(libs.gradlePlugin.kotlin)
compileOnly(libs.jacoco.reporter)

compileOnly(libs.jacoco.reporter) {
// use ASM from JaCoCo for compilation
isTransitive = true
}

functionalTestImplementation(kotlin("test"))
functionalTestImplementation(libs.junit.jupiter)
Expand Down
2 changes: 1 addition & 1 deletion kover-gradle-plugin/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,7 @@ kover {
for the custom version
```kotlin
kover {
useJacoco("0.8.10")
useJacoco("0.8.14")
}
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2017-2025 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.kover.gradle.plugin.test.functional.cases

import kotlinx.kover.gradle.plugin.test.functional.framework.configurator.BuildConfigurator
import kotlinx.kover.gradle.plugin.test.functional.framework.starter.SlicedGeneratedTest

internal class InlineTests {
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testFilteringInline() {
addProjectWithKover {
sourcesFrom("inlines")
kover {
reports.filters.excludes.classes("*.TestingClass")
}
}

run("koverXmlReport") {
xmlReport {
methodCounter("org.jetbrains.ClassWithInline", "main", type = "LINE").assertFullyCovered()
classCounter("org.jetbrains.TestingClass").assertAbsent()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2017-2025 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.kover.gradle.plugin.test.functional.cases

import kotlinx.kover.gradle.plugin.commons.CoverageToolVendor
import kotlinx.kover.gradle.plugin.dsl.AggregationType
import kotlinx.kover.gradle.plugin.test.functional.framework.configurator.BuildConfigurator
import kotlinx.kover.gradle.plugin.test.functional.framework.starter.GeneratedTest

internal class JacocoTests {
@GeneratedTest(tool = CoverageToolVendor.JACOCO)
fun BuildConfigurator.testMinimalVersion() {
addProjectWithKover {
sourcesFrom("simple")
kover {
useJacoco("0.8.7")
}

kover {
reports {
filters {
excludes {
classes("org.jetbrains.*Exa?ple*")
}
}
verify {
rule {
// without ExampleClass covered lines count = 2, but 4 with it
maxBound(2, aggregationForGroup = AggregationType.COVERED_COUNT)
}
}
}
}
}
run("koverXmlReport", "koverVerify") {
xmlReport {
classCounter("org.jetbrains.ExampleClass").assertAbsent()
classCounter("org.jetbrains.SecondClass").assertCovered()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import kotlinx.kover.gradle.plugin.dsl.*
import kotlinx.kover.gradle.plugin.dsl.CoverageUnit.LINE
import kotlinx.kover.gradle.plugin.test.functional.framework.configurator.*
import kotlinx.kover.gradle.plugin.test.functional.framework.starter.*
import java.io.Closeable


internal class ReportAnnotationFilterTests {

@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testExclusions() {
addProjectWithKover {
sourcesFrom("annotations-main")
Expand All @@ -40,7 +38,7 @@ internal class ReportAnnotationFilterTests {
}
}

@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testInclusions() {
addProjectWithKover {
sourcesFrom("annotations-mix")
Expand Down Expand Up @@ -74,7 +72,7 @@ internal class ReportAnnotationFilterTests {
}
}

@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testOverride() {
addProjectWithKover {
sourcesFrom("annotations-main")
Expand All @@ -91,7 +89,7 @@ internal class ReportAnnotationFilterTests {
coverageUnits.set(LINE)
aggregationForGroup.set(AggregationType.COVERED_COUNT)
minValue.set(15)
maxValue.set(15)
maxValue.set(16)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
package kotlinx.kover.gradle.plugin.test.functional.cases

import kotlinx.kover.gradle.plugin.test.functional.framework.configurator.BuildConfigurator
import kotlinx.kover.gradle.plugin.test.functional.framework.starter.GeneratedTest
import kotlinx.kover.gradle.plugin.test.functional.framework.starter.SlicedGeneratedTest

internal class ReportInheritedFromFilterTests {
@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testExclusions() {
addProjectWithKover {
sourcesFrom("inherited-main")
Expand Down Expand Up @@ -40,7 +40,7 @@ internal class ReportInheritedFromFilterTests {
}
}

@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testInclusions() {
addProjectWithKover {
sourcesFrom("inherited-main")
Expand Down Expand Up @@ -72,7 +72,7 @@ internal class ReportInheritedFromFilterTests {
}
}

@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testIncludeAndExclude() {
addProjectWithKover {
sourcesFrom("inherited-main")
Expand Down Expand Up @@ -108,7 +108,7 @@ internal class ReportInheritedFromFilterTests {
}
}

@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testDifferentIncludeFilters() {
addProjectWithKover {
sourcesFrom("inherited-main")
Expand All @@ -119,6 +119,7 @@ internal class ReportInheritedFromFilterTests {
// for includes 'AND' rule should work
inheritedFrom("org.jetbrains.A")
classes("*.*Child")
annotatedBy("*.MyAnnotation")
}
}
}
Expand All @@ -129,13 +130,13 @@ internal class ReportInheritedFromFilterTests {
xmlReport {
classCounter("org.jetbrains.A").assertAbsent()
classCounter("org.jetbrains.B").assertAbsent()
classCounter("org.jetbrains.AChild").assertAbsent()

classCounter("org.jetbrains.BChild").assertFullyMissed()
classCounter("org.jetbrains.AChild").assertFullyMissed()
}
}
}
@GeneratedTest
@SlicedGeneratedTest(allTools = true)
fun BuildConfigurator.testDifferentExcludeFilters() {
addProjectWithKover {
sourcesFrom("inherited-main")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class AChild: A() {
}
}

@MyAnnotation
// indirect inheritance of project class
class BChild: B() {
fun functionBB() {
Expand Down Expand Up @@ -79,3 +80,5 @@ class CloseableClass : Closeable {
println("foo")
}
}

annotation class MyAnnotation
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.jetbrains

class ClassWithInline {
inline fun main(block: () -> Unit) {
block()
println("first")
println("second")
}
}

class TestingClass {
fun test() {
ClassWithInline().main { println("") }
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.jetbrains

import kotlin.test.Test

class TestClass {
@Test
fun simpleTest() {
TestingClass().test()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,16 @@ internal data class ReportFilters(
val excludeInheritedFrom: Set<String> = emptySet(),
@get:Input
val excludeProjects: Set<String> = emptySet()
): Serializable
) : Serializable {
@get:Internal
val isEmpty: Boolean
get() = excludesClasses.isEmpty()
&& excludesAnnotations.isEmpty()
&& excludeInheritedFrom.isEmpty()
&& includesClasses.isEmpty()
&& includesAnnotations.isEmpty()
&& includeInheritedFrom.isEmpty()
}

internal open class VerificationRule @Inject constructor(
@get:Input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -729,8 +729,6 @@ public interface KoverReportFilter {
* It is acceptable to use `*` and `?` wildcards,
* `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character.
*
* **_Does not work for JaCoCo_**
*
* Example:
* ```
* annotatedBy("*Generated*", "com.example.KoverExclude")
Expand All @@ -750,8 +748,6 @@ public interface KoverReportFilter {
* It is acceptable to use `*` and `?` wildcards,
* `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character.
*
* **_Does not work for JaCoCo_**
*
* Example:
* ```
* val annotation: Provider<String> = ...
Expand All @@ -770,8 +766,6 @@ public interface KoverReportFilter {
* It is acceptable to use `*` and `?` wildcards,
* `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character.
*
* **_Does not work for JaCoCo_**
*
* Example:
* ```
* annotatedBy.addAll("*Generated*", "com.example.KoverExclude")
Expand Down Expand Up @@ -809,8 +803,6 @@ public interface KoverReportFilter {
* It is acceptable to use `*` and `?` wildcards,
* `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character.
*
* **_Does not work for JaCoCo_**
*
* Example:
* ```
* inheritedFrom("*Repository")
Expand All @@ -837,8 +829,6 @@ public interface KoverReportFilter {
* It is acceptable to use `*` and `?` wildcards,
* `*` means any number of arbitrary characters (including no chars), `?` means one arbitrary character.
*
* **_Does not work for JaCoCo_**
*
* Example:
* ```
* inheritedFrom("*Repository")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ public object KoverVersions {
/**
* JaCoCo coverage tool version used by default.
*/
public const val JACOCO_TOOL_DEFAULT_VERSION = "0.8.12"
public const val JACOCO_TOOL_DEFAULT_VERSION = "0.8.14"

/**
* JaCoCo coverage tool minimal supported version.
*/
public const val JACOCO_TOOL_MINIMAL_VERSION = "0.8.7"

/**
* Current version of Kover Gradle Plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

package kotlinx.kover.gradle.plugin.dsl.internal

import kotlinx.kover.gradle.plugin.commons.KoverIllegalConfigException
import kotlinx.kover.gradle.plugin.dsl.KoverCurrentProjectVariantsConfig
import kotlinx.kover.gradle.plugin.dsl.KoverMergingConfig
import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension
import kotlinx.kover.gradle.plugin.dsl.KoverReportsConfig
import kotlinx.kover.gradle.plugin.dsl.KoverVersions.JACOCO_TOOL_DEFAULT_VERSION
import kotlinx.kover.gradle.plugin.dsl.KoverVersions.JACOCO_TOOL_MINIMAL_VERSION
import kotlinx.kover.gradle.plugin.util.SemVer
import org.gradle.api.Action
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
Expand Down Expand Up @@ -47,6 +50,11 @@ internal abstract class KoverProjectExtensionImpl @Inject constructor(
}

override fun useJacoco(version: String) {
SemVer.ofThreePartOrNull(version)?.also { semver ->
if (semver < SemVer.ofThreePartOrNull(JACOCO_TOOL_MINIMAL_VERSION)!!) {
throw KoverIllegalConfigException("Jacoco version $version is not supported. The minimum supported version is '$JACOCO_TOOL_MINIMAL_VERSION'")
}
}
useJacoco.set(true)
jacocoVersion.set(version)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
package kotlinx.kover.gradle.plugin.tools

import kotlinx.kover.features.jvm.KoverFeatures
import kotlinx.kover.features.jvm.RuleViolations
import kotlinx.kover.gradle.plugin.commons.*
import kotlinx.kover.gradle.plugin.commons.VerificationRule
import kotlinx.kover.gradle.plugin.dsl.*
import kotlinx.kover.gradle.plugin.dsl.KoverVersions.JACOCO_TOOL_MINIMAL_VERSION
import kotlinx.kover.gradle.plugin.dsl.internal.KoverProjectExtensionImpl
import kotlinx.kover.gradle.plugin.tools.jacoco.JacocoTool
import kotlinx.kover.gradle.plugin.tools.kover.KoverTool
import kotlinx.kover.gradle.plugin.util.SemVer
import org.gradle.api.file.*
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
Expand Down Expand Up @@ -134,7 +135,13 @@ internal object CoverageToolFactory {
fun get(projectExtension: KoverProjectExtensionImpl): Provider<CoverageTool> {
return projectExtension.useJacoco.map {
if (it) {
JacocoTool(JacocoToolVariant(projectExtension.jacocoVersion.get()))
val version = projectExtension.jacocoVersion.get()
SemVer.ofThreePartOrNull(version)?.also { semver ->
if (semver < SemVer.ofThreePartOrNull(JACOCO_TOOL_MINIMAL_VERSION)!!) {
throw KoverIllegalConfigException("Jacoco version $version is not supported. The minimum supported version is '$JACOCO_TOOL_MINIMAL_VERSION'")
}
}
JacocoTool(JacocoToolVariant(version))
} else {
KoverTool(KoverToolBuiltin)
}
Expand Down
Loading