diff --git a/README.md b/README.md index bf17a430..3a91fdbb 100644 --- a/README.md +++ b/README.md @@ -304,6 +304,7 @@ kover { jacocoEngineVersion.set("0.8.7") // change version of JaCoCo agent and reporter generateReportOnCheck.set(true) // false to do not execute `koverReport` task before `check` task disabledModules = setOf() // setOf("module-name") to disable coverage for module with name `module-name` + instrumentAndroidPackage = false // true to instrument packages `android.*` and `com.android.*` } ``` @@ -319,6 +320,7 @@ kover { jacocoEngineVersion.set('0.8.7') // change version of JaCoCo agent and reporter generateReportOnCheck.set(true) // false to do not execute `koverReport` task before `check` task disabledModules = [] // ["module-name"] to disable coverage for module with name `module-name` + instrumentAndroidPackage = false // true to instrument packages `android.*` and `com.android.*` } ``` diff --git a/src/main/kotlin/kotlinx/kover/KoverPlugin.kt b/src/main/kotlin/kotlinx/kover/KoverPlugin.kt index 9ff9f066..8da69a67 100644 --- a/src/main/kotlin/kotlinx/kover/KoverPlugin.kt +++ b/src/main/kotlin/kotlinx/kover/KoverPlugin.kt @@ -4,6 +4,7 @@ package kotlinx.kover +import kotlinx.kover.adapters.* import kotlinx.kover.api.* import kotlinx.kover.api.KoverPaths.HTML_AGG_REPORT_DEFAULT_PATH import kotlinx.kover.api.KoverNames.CHECK_TASK_NAME @@ -264,7 +265,18 @@ class KoverPlugin : Plugin { else null }) - jvmArgumentProviders.add(CoverageArgumentProvider(this, agents, providers.koverExtension)) + + val excludeAndroidPackages = + project.provider { project.androidPluginIsApplied && !providers.koverExtension.get().instrumentAndroidPackage } + + jvmArgumentProviders.add( + CoverageArgumentProvider( + this, + agents, + providers.koverExtension, + excludeAndroidPackages + ) + ) doLast(IntellijErrorLogChecker(taskExtension)) } @@ -293,8 +305,8 @@ private class IntellijErrorLogChecker(private val taskExtension: KoverTaskExtens private class CoverageArgumentProvider( private val task: Task, private val agents: Map, - @get:Nested - val koverExtension: Provider + @get:Nested val koverExtension: Provider, + @get:Input val excludeAndroidPackage: Provider ) : CommandLineArgumentProvider, Named { @get:Nested @@ -318,6 +330,19 @@ private class CoverageArgumentProvider( return mutableListOf() } + if (excludeAndroidPackage.get()) { + /* + The instrumentation of android classes often causes errors when using third-party + frameworks (see https://github.com/Kotlin/kotlinx-kover/issues/89). + + Because android classes are not part of the project, in any case they do not get into the report, + and they can be excluded from instrumentation. + + FIXME Remove this code if the IntelliJ Agent stops changing project classes during instrumentation + */ + taskExtensionValue.excludes = taskExtensionValue.excludes + "android.*" + "com.android.*" + } + return agents.getFor(koverExtensionValue.coverageEngine.get()).buildCommandLineArgs(task, taskExtensionValue) } } diff --git a/src/main/kotlin/kotlinx/kover/adapters/PluginAdaptersFactory.kt b/src/main/kotlin/kotlinx/kover/adapters/PluginAdaptersFactory.kt index 30f6ccbd..f9d2e05d 100644 --- a/src/main/kotlin/kotlinx/kover/adapters/PluginAdaptersFactory.kt +++ b/src/main/kotlin/kotlinx/kover/adapters/PluginAdaptersFactory.kt @@ -17,3 +17,8 @@ internal fun createAdapters(): List { KotlinAndroidPluginAdapter() ) } + +val Project.androidPluginIsApplied: Boolean + get() { + return plugins.findPlugin("android") != null || plugins.findPlugin("kotlin-android") != null + } diff --git a/src/main/kotlin/kotlinx/kover/api/KoverExtension.kt b/src/main/kotlin/kotlinx/kover/api/KoverExtension.kt index a8ee0ad3..37a30848 100644 --- a/src/main/kotlin/kotlinx/kover/api/KoverExtension.kt +++ b/src/main/kotlin/kotlinx/kover/api/KoverExtension.kt @@ -45,6 +45,12 @@ open class KoverExtension(objects: ObjectFactory) { */ @get:Input var disabledModules: Set = emptySet() + + /** + * Specifies whether the classes from 'android' and 'com.android' packages should be included if Android plugin is applied. + */ + @get:Input + public var instrumentAndroidPackage: Boolean = false } public enum class CoverageEngine {