Skip to content

Commit 798b972

Browse files
authored
Fixed enqueue for Android projects
Co-authored-by: Leonid Startsev <[email protected]> PR #617
1 parent 90228e7 commit 798b972

File tree

16 files changed

+265
-19
lines changed

16 files changed

+265
-19
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package kotlinx.kover.gradle.plugin.test.functional.cases
2+
3+
import kotlinx.kover.gradle.plugin.test.functional.framework.checker.CheckerContext
4+
import kotlinx.kover.gradle.plugin.test.functional.framework.starter.TemplateTest
5+
6+
internal class FinalizingEnqueueTests {
7+
@TemplateTest("android-subproject-apply", [":app:koverHtmlReportDebug"])
8+
fun CheckerContext.testPluginsOrder() {
9+
// 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
10+
// see https://github.com/Kotlin/kotlinx-kover/issues/610
11+
}
12+
}

kover-gradle-plugin/src/functionalTest/templates/builds/android-common-verify/app/build.gradle.kts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@ dependencies {
4848
* Kover configs
4949
*/
5050

51-
koverReport {
52-
verify {
53-
rule {
54-
// always fails
55-
minBound(100)
56-
maxBound(0)
51+
kover {
52+
reports {
53+
verify {
54+
rule {
55+
// always fails
56+
minBound(100)
57+
maxBound(0)
58+
}
5759
}
5860
}
5961
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
plugins {
2+
id ("org.jetbrains.kotlin.android")
3+
id ("com.android.application")
4+
}
5+
6+
android {
7+
namespace = "kotlinx.kover.test.android"
8+
compileSdk = 32
9+
10+
defaultConfig {
11+
applicationId = "kotlinx.kover.test.android"
12+
minSdk = 21
13+
targetSdk = 31
14+
versionCode = 1
15+
versionName = "1.0"
16+
17+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
18+
}
19+
20+
buildTypes {
21+
release {
22+
isMinifyEnabled = true
23+
}
24+
}
25+
compileOptions {
26+
sourceCompatibility = JavaVersion.VERSION_1_8
27+
targetCompatibility = JavaVersion.VERSION_1_8
28+
}
29+
kotlinOptions {
30+
jvmTarget = "1.8"
31+
}
32+
buildFeatures {
33+
viewBinding = true
34+
}
35+
}
36+
37+
dependencies {
38+
implementation("androidx.core:core-ktx:1.8.0")
39+
implementation("androidx.appcompat:appcompat:1.5.0")
40+
implementation("com.google.android.material:material:1.6.1")
41+
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
42+
testImplementation("junit:junit:4.13.2")
43+
}
44+
45+
46+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<application android:label="@string/app_name">
5+
<uses-library android:name="com.google.android.things" android:required="false" />
6+
7+
<activity android:name=".MainActivity"
8+
android:exported="true">
9+
<intent-filter>
10+
<action android:name="android.intent.action.MAIN" />
11+
12+
<category android:name="android.intent.category.LAUNCHER" />
13+
</intent-filter>
14+
<!-- Make this the first activity that is displayed when the device boots. -->
15+
<intent-filter>
16+
<action android:name="android.intent.action.MAIN" />
17+
18+
<category android:name="android.intent.category.HOME" />
19+
<category android:name="android.intent.category.DEFAULT" />
20+
</intent-filter>
21+
</activity>
22+
</application>
23+
24+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package kotlinx.kover.test.android
2+
3+
object DebugUtil {
4+
fun log(message: String) {
5+
println("DEBUG: $message")
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package kotlinx.kover.test.android
2+
3+
import android.os.Bundle
4+
import android.app.Activity
5+
6+
class MainActivity : Activity() {
7+
8+
override fun onCreate(savedInstanceState: Bundle?) {
9+
super.onCreate(savedInstanceState)
10+
setContentView(R.layout.activity_main)
11+
}
12+
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package kotlinx.kover.test.android
2+
3+
object Maths {
4+
fun sum(a: Int, b: Int): Int {
5+
DebugUtil.log("invoked sum")
6+
return a + b
7+
}
8+
9+
fun sub(a: Int, b: Int): Int {
10+
DebugUtil.log("invoked sub")
11+
return a - b
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
tools:context=".MainActivity">
8+
9+
<TextView
10+
android:id="@+id/main_label"
11+
android:layout_width="wrap_content"
12+
android:layout_height="wrap_content"
13+
android:layout_marginStart="104dp"
14+
android:layout_marginTop="28dp"
15+
android:text="SERIALIZATION TEST"
16+
android:textSize="20sp"
17+
android:textStyle="bold"
18+
app:layout_constraintStart_toStartOf="parent"
19+
app:layout_constraintTop_toTopOf="parent" />
20+
21+
<EditText
22+
android:id="@+id/encoded_text"
23+
android:layout_width="373dp"
24+
android:layout_height="411dp"
25+
android:layout_marginStart="16dp"
26+
android:layout_marginTop="16dp"
27+
android:editable="false"
28+
android:ems="10"
29+
android:gravity="start|top"
30+
android:inputType="textMultiLine"
31+
android:textAlignment="viewStart"
32+
android:textSize="12sp"
33+
app:layout_constraintStart_toStartOf="parent"
34+
app:layout_constraintTop_toBottomOf="@+id/main_label" />
35+
36+
</androidx.constraintlayout.widget.ConstraintLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<color name="purple_200">#FFBB86FC</color>
4+
<color name="purple_500">#FF6200EE</color>
5+
<color name="purple_700">#FF3700B3</color>
6+
<color name="teal_200">#FF03DAC5</color>
7+
<color name="teal_700">#FF018786</color>
8+
<color name="black">#FF000000</color>
9+
<color name="white">#FFFFFFFF</color>
10+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<string name="app_name">Android Test</string>
3+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<resources>
2+
3+
<style name="Theme.App" parent="android:Theme.Material.Light.DarkActionBar" />
4+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package kotlinx.kover.test.android
2+
3+
import org.junit.Test
4+
5+
import org.junit.Assert.*
6+
7+
8+
class LocalTests {
9+
@Test
10+
fun testDebugUtils() {
11+
assertEquals(3, Maths.sum(1, 2))
12+
}
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
plugins {
2+
id("com.android.application") version "7.4.0" apply false
3+
id("com.android.library") version "7.4.0" apply false
4+
id("org.jetbrains.kotlin.android") version "1.8.20" apply false
5+
id("org.jetbrains.kotlinx.kover") version "0.7.1"
6+
}
7+
8+
/*
9+
* Kover configs
10+
*/
11+
12+
subprojects {
13+
apply(plugin = "org.jetbrains.kotlinx.kover")
14+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Project-wide Gradle settings.
2+
# IDE (e.g. Android Studio) users:
3+
# Gradle settings configured through the IDE *will override*
4+
# any settings specified in this file.
5+
# For more details on how to configure your build environment visit
6+
# http://www.gradle.org/docs/current/userguide/build_environment.html
7+
# Specifies the JVM arguments used for the daemon process.
8+
# The setting is particularly useful for tweaking memory settings.
9+
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10+
# When configured, Gradle will run in incubating parallel mode.
11+
# This option should only be used with decoupled projects. More details, visit
12+
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13+
# org.gradle.parallel=true
14+
# AndroidX package structure to make it clearer which packages are bundled with the
15+
# Android operating system, and which are packaged with your app's APK
16+
# https://developer.android.com/topic/libraries/support-library/androidx-rn
17+
android.useAndroidX=true
18+
# Kotlin code style for this project: "official" or "obsolete":
19+
kotlin.code.style=official
20+
# Enables namespacing of each library's R class so that its R class includes only the
21+
# resources declared in the library itself and none from the library's dependencies,
22+
# thereby reducing the size of the R class for that library
23+
android.nonTransitiveRClass=true
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pluginManagement {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
gradlePluginPortal()
6+
}
7+
}
8+
9+
dependencyResolutionManagement {
10+
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
11+
repositories {
12+
google()
13+
mavenCentral()
14+
gradlePluginPortal()
15+
}
16+
}
17+
18+
rootProject.name = "android_kts"
19+
include(":app")

kover-gradle-plugin/src/main/kotlin/kotlinx/kover/gradle/plugin/locators/ProvidedVariantsLocator.kt

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,45 +18,50 @@ internal class ProvidedVariantsLocator(
1818
private var finilized: Boolean = false
1919

2020
init {
21-
enqueue("no-plugin")
21+
simpleEnqueue("no-plugin")
2222

2323
project.pluginManager.withPlugin(KOTLIN_JVM_PLUGIN_ID) {
24-
enqueue(KOTLIN_JVM_PLUGIN_ID)
24+
simpleEnqueue(KOTLIN_JVM_PLUGIN_ID)
2525
}
2626
project.pluginManager.withPlugin(KOTLIN_MULTIPLATFORM_PLUGIN_ID) {
27-
enqueue(KOTLIN_MULTIPLATFORM_PLUGIN_ID)
27+
simpleEnqueue(KOTLIN_MULTIPLATFORM_PLUGIN_ID)
2828
}
2929
project.pluginManager.withPlugin(KOTLIN_ANDROID_PLUGIN_ID) {
30-
enqueue(KOTLIN_ANDROID_PLUGIN_ID)
30+
simpleEnqueue(KOTLIN_ANDROID_PLUGIN_ID)
3131
}
3232
project.pluginManager.withPlugin(ANDROID_APP_PLUGIN_ID) {
33-
enqueueAndroid(ANDROID_APP_PLUGIN_ID)
33+
androidEnqueue(ANDROID_APP_PLUGIN_ID)
3434
}
3535
project.pluginManager.withPlugin(ANDROID_LIB_PLUGIN_ID) {
36-
enqueueAndroid(ANDROID_LIB_PLUGIN_ID)
36+
androidEnqueue(ANDROID_LIB_PLUGIN_ID)
3737
}
3838
project.pluginManager.withPlugin(ANDROID_DYNAMIC_PLUGIN_ID) {
39-
enqueueAndroid(ANDROID_DYNAMIC_PLUGIN_ID)
39+
androidEnqueue(ANDROID_DYNAMIC_PLUGIN_ID)
4040
}
4141
}
4242

43-
private fun enqueueAndroid(reason: String) {
44-
val androidComponents = project.extensions.findByName("androidComponents")?.bean()
43+
private fun simpleEnqueue(reason: String) {
44+
enqueue(reason)
45+
scheduleDequeue(reason)
46+
}
4547

46-
val callback = Action<Any> {
47-
enqueue(reason)
48+
private fun androidEnqueue(reason: String) {
49+
enqueue(reason)
50+
val dequeueAction = Action<Any> {
51+
scheduleDequeue(reason)
4852
}
4953

54+
val androidComponents = project.extensions.findByName("androidComponents")?.bean()
5055
if (androidComponents != null && androidComponents.hasFunction("finalizeDsl", callback)) {
5156
/*
5257
Assumption: `finalizeDsl` is called in the `afterEvaluate` action, in which build variants are created.
5358
Therefore, if an action is added to the queue inside it, it will be executed only after variants are created
5459
*/
55-
androidComponents("finalizeDsl", callback)
60+
androidComponents("finalizeDsl", dequeueAction)
5661
} else {
5762
// for old versions < 7.0 an action is added to the AAA queue.
5863
// 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
59-
enqueue(reason)
64+
dequeueAction.execute(Unit)
6065
}
6166
}
6267

@@ -65,7 +70,9 @@ internal class ProvidedVariantsLocator(
6570
throw KoverCriticalException("Attempt to queue after finalizing.")
6671
}
6772
reasons += reason
73+
}
6874

75+
private fun scheduleDequeue(reason: String) {
6976
project.afterEvaluate {
7077
if (reasons.isEmpty()) {
7178
throw KoverCriticalException("Error when searching for finalizing configuration variant.")

0 commit comments

Comments
 (0)