diff --git a/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/FinalizingEnqueueTests.kt b/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/FinalizingEnqueueTests.kt
new file mode 100644
index 00000000..97475fd3
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/kotlin/kotlinx/kover/gradle/plugin/test/functional/cases/FinalizingEnqueueTests.kt
@@ -0,0 +1,12 @@
+package kotlinx.kover.gradle.plugin.test.functional.cases
+
+import kotlinx.kover.gradle.plugin.test.functional.framework.checker.CheckerContext
+import kotlinx.kover.gradle.plugin.test.functional.framework.starter.TemplateTest
+
+internal class FinalizingEnqueueTests {
+ @TemplateTest("android-subproject-apply", [":app:koverHtmlReportDebug"])
+ fun CheckerContext.testPluginsOrder() {
+ // if Kotlin Gradle Plugin is applied before any Android Gradle Plugin and Kover is applied from `subprojects` block, `Attempt to queue after finalizing` error should not occur
+ // see https://github.com/Kotlin/kotlinx-kover/issues/610
+ }
+}
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-common-verify/app/build.gradle.kts b/kover-gradle-plugin/src/functionalTest/templates/builds/android-common-verify/app/build.gradle.kts
index 942d20d0..62c72eaa 100644
--- a/kover-gradle-plugin/src/functionalTest/templates/builds/android-common-verify/app/build.gradle.kts
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-common-verify/app/build.gradle.kts
@@ -48,12 +48,14 @@ dependencies {
* Kover configs
*/
-koverReport {
- verify {
- rule {
- // always fails
- minBound(100)
- maxBound(0)
+kover {
+ reports {
+ verify {
+ rule {
+ // always fails
+ minBound(100)
+ maxBound(0)
+ }
}
}
}
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/build.gradle.kts b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/build.gradle.kts
new file mode 100644
index 00000000..92d09d44
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/build.gradle.kts
@@ -0,0 +1,46 @@
+plugins {
+ id ("org.jetbrains.kotlin.android")
+ id ("com.android.application")
+}
+
+android {
+ namespace = "kotlinx.kover.test.android"
+ compileSdk = 32
+
+ defaultConfig {
+ applicationId = "kotlinx.kover.test.android"
+ minSdk = 21
+ targetSdk = 31
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = true
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+ buildFeatures {
+ viewBinding = true
+ }
+}
+
+dependencies {
+ implementation("androidx.core:core-ktx:1.8.0")
+ implementation("androidx.appcompat:appcompat:1.5.0")
+ implementation("com.google.android.material:material:1.6.1")
+ implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+ testImplementation("junit:junit:4.13.2")
+}
+
+
+
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/AndroidManifest.xml b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..358fac25
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/DebugUtil.kt b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/DebugUtil.kt
new file mode 100644
index 00000000..efe82040
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/DebugUtil.kt
@@ -0,0 +1,7 @@
+package kotlinx.kover.test.android
+
+object DebugUtil {
+ fun log(message: String) {
+ println("DEBUG: $message")
+ }
+}
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/MainActivity.kt b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/MainActivity.kt
new file mode 100644
index 00000000..1caaf5b6
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/MainActivity.kt
@@ -0,0 +1,13 @@
+package kotlinx.kover.test.android
+
+import android.os.Bundle
+import android.app.Activity
+
+class MainActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ }
+
+}
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/Maths.kt b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/Maths.kt
new file mode 100644
index 00000000..03edc099
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/java/kotlinx/kover/test/android/Maths.kt
@@ -0,0 +1,13 @@
+package kotlinx.kover.test.android
+
+object Maths {
+ fun sum(a: Int, b: Int): Int {
+ DebugUtil.log("invoked sum")
+ return a + b
+ }
+
+ fun sub(a: Int, b: Int): Int {
+ DebugUtil.log("invoked sub")
+ return a - b
+ }
+}
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/layout/activity_main.xml b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..ee57d166
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/colors.xml b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..f8c6127d
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/strings.xml b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..fa43411e
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Android Test
+
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/themes.xml b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/themes.xml
new file mode 100644
index 00000000..0b4cfc4c
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/main/res/values/themes.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/test/java/kotlinx/kover/test/android/LocalTests.kt b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/test/java/kotlinx/kover/test/android/LocalTests.kt
new file mode 100644
index 00000000..c6453c26
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/app/src/test/java/kotlinx/kover/test/android/LocalTests.kt
@@ -0,0 +1,13 @@
+package kotlinx.kover.test.android
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+
+class LocalTests {
+ @Test
+ fun testDebugUtils() {
+ assertEquals(3, Maths.sum(1, 2))
+ }
+}
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/build.gradle.kts b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/build.gradle.kts
new file mode 100644
index 00000000..2de83d85
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/build.gradle.kts
@@ -0,0 +1,14 @@
+plugins {
+ id("com.android.application") version "7.4.0" apply false
+ id("com.android.library") version "7.4.0" apply false
+ id("org.jetbrains.kotlin.android") version "1.8.20" apply false
+ id("org.jetbrains.kotlinx.kover") version "0.7.1"
+}
+
+/*
+ * Kover configs
+ */
+
+subprojects {
+ apply(plugin = "org.jetbrains.kotlinx.kover")
+}
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/gradle.properties b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/gradle.properties
new file mode 100644
index 00000000..3c5031eb
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/settings.gradle.kts b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/settings.gradle.kts
new file mode 100644
index 00000000..406a4374
--- /dev/null
+++ b/kover-gradle-plugin/src/functionalTest/templates/builds/android-subproject-apply/settings.gradle.kts
@@ -0,0 +1,19 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+rootProject.name = "android_kts"
+include(":app")
diff --git a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/locators/ProvidedVariantsLocator.kt b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/locators/ProvidedVariantsLocator.kt
index 6054a0ef..a004a942 100644
--- a/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/locators/ProvidedVariantsLocator.kt
+++ b/kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/locators/ProvidedVariantsLocator.kt
@@ -18,45 +18,50 @@ internal class ProvidedVariantsLocator(
private var finilized: Boolean = false
init {
- enqueue("no-plugin")
+ simpleEnqueue("no-plugin")
project.pluginManager.withPlugin(KOTLIN_JVM_PLUGIN_ID) {
- enqueue(KOTLIN_JVM_PLUGIN_ID)
+ simpleEnqueue(KOTLIN_JVM_PLUGIN_ID)
}
project.pluginManager.withPlugin(KOTLIN_MULTIPLATFORM_PLUGIN_ID) {
- enqueue(KOTLIN_MULTIPLATFORM_PLUGIN_ID)
+ simpleEnqueue(KOTLIN_MULTIPLATFORM_PLUGIN_ID)
}
project.pluginManager.withPlugin(KOTLIN_ANDROID_PLUGIN_ID) {
- enqueue(KOTLIN_ANDROID_PLUGIN_ID)
+ simpleEnqueue(KOTLIN_ANDROID_PLUGIN_ID)
}
project.pluginManager.withPlugin(ANDROID_APP_PLUGIN_ID) {
- enqueueAndroid(ANDROID_APP_PLUGIN_ID)
+ androidEnqueue(ANDROID_APP_PLUGIN_ID)
}
project.pluginManager.withPlugin(ANDROID_LIB_PLUGIN_ID) {
- enqueueAndroid(ANDROID_LIB_PLUGIN_ID)
+ androidEnqueue(ANDROID_LIB_PLUGIN_ID)
}
project.pluginManager.withPlugin(ANDROID_DYNAMIC_PLUGIN_ID) {
- enqueueAndroid(ANDROID_DYNAMIC_PLUGIN_ID)
+ androidEnqueue(ANDROID_DYNAMIC_PLUGIN_ID)
}
}
- private fun enqueueAndroid(reason: String) {
- val androidComponents = project.extensions.findByName("androidComponents")?.bean()
+ private fun simpleEnqueue(reason: String) {
+ enqueue(reason)
+ scheduleDequeue(reason)
+ }
- val callback = Action {
- enqueue(reason)
+ private fun androidEnqueue(reason: String) {
+ enqueue(reason)
+ val dequeueAction = Action {
+ scheduleDequeue(reason)
}
+ val androidComponents = project.extensions.findByName("androidComponents")?.bean()
if (androidComponents != null && androidComponents.hasFunction("finalizeDsl", callback)) {
/*
Assumption: `finalizeDsl` is called in the `afterEvaluate` action, in which build variants are created.
Therefore, if an action is added to the queue inside it, it will be executed only after variants are created
*/
- androidComponents("finalizeDsl", callback)
+ androidComponents("finalizeDsl", dequeueAction)
} else {
// for old versions < 7.0 an action is added to the AAA queue.
// Since this code is executed after the applying of AGP, there is a high probability that the action will fall into the `afterEvaluate` queue after the actions of the AGP
- enqueue(reason)
+ dequeueAction.execute(Unit)
}
}
@@ -65,7 +70,9 @@ internal class ProvidedVariantsLocator(
throw KoverCriticalException("Attempt to queue after finalizing.")
}
reasons += reason
+ }
+ private fun scheduleDequeue(reason: String) {
project.afterEvaluate {
if (reasons.isEmpty()) {
throw KoverCriticalException("Error when searching for finalizing configuration variant.")