[Gradle, MPP] Print warning on absent 'android' targets

^KT-41641 Verification Pending
This commit is contained in:
sebastian.sellmair
2021-11-11 15:48:41 +01:00
committed by Space
parent db21bfe13b
commit bf04f821d6
3 changed files with 89 additions and 16 deletions
@@ -8,12 +8,13 @@
package org.jetbrains.kotlin.gradle
import com.android.build.gradle.LibraryExtension
import org.jetbrains.kotlin.gradle.plugin.runMissingAndroidTargetProjectConfigurationHealthCheck
import org.jetbrains.kotlin.gradle.targets.android.findAndroidTarget
import org.junit.Test
import kotlin.test.assertNull
import kotlin.test.assertSame
import kotlin.test.*
class KT41641AbsentAndroidTarget : MultiplatformExtensionTest() {
@Test
fun `test android plugin without android target`() {
project.plugins.apply("kotlin-multiplatform")
@@ -29,4 +30,27 @@ class KT41641AbsentAndroidTarget : MultiplatformExtensionTest() {
assertNull(project.findAndroidTarget())
assertSame(kotlin.android(), project.findAndroidTarget())
}
@Test
fun `test runMissingAndroidTargetProjectConfigurationHealthCheck`() {
project.plugins.apply("kotlin-multiplatform")
project.plugins.apply("android-library")
/* Arbitrary minimal Android setup */
val android = project.extensions.getByName("android") as LibraryExtension
android.compileSdkVersion(30)
kotlin.jvm()
// Missing android target -> expect warning message
var warningMessage: String? = null
project.runMissingAndroidTargetProjectConfigurationHealthCheck(warningLogger = { warningMessage = it })
assertNotNull(warningMessage, "Expected warning message to be logged")
// Present android target -> expect no warning message anymore
kotlin.android()
project.runMissingAndroidTargetProjectConfigurationHealthCheck(warningLogger = {
fail("Expected no warning message to be logged. Received: $it")
})
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
import org.jetbrains.kotlin.gradle.targets.android.findAndroidTarget
import org.jetbrains.kotlin.gradle.utils.androidPluginIds
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheck
private class KotlinMultiplatformProjectConfigurationException(message: String) : Exception(message)
internal fun Project.runMissingKotlinTargetsProjectConfigurationHealthCheck() = project.runProjectConfigurationHealthCheck {
val isNoTargetsInitialized = (project.kotlinExtension as KotlinMultiplatformExtension)
.targets
.none { it !is KotlinMetadataTarget }
if (isNoTargetsInitialized) {
throw KotlinMultiplatformProjectConfigurationException(
"""
Please initialize at least one Kotlin target in '${project.name} (${project.path})'.
Read more https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets
""".trimIndent()
)
}
}
internal fun Project.runMissingAndroidTargetProjectConfigurationHealthCheck(
warningLogger: (warningMessage: String) -> Unit = project.logger::warn
) = project.runProjectConfigurationHealthCheck check@{
val androidPluginId = androidPluginIds
.firstOrNull { androidPluginId -> plugins.findPlugin(androidPluginId) != null } ?: return@check
if (findAndroidTarget() != null) return@check
warningLogger(
"""
Missing 'android()' Kotlin target in ${project.name} (${project.path})'.
The Android Gradle plugin was applied without creating a corresponding 'android()' Kotlin Target:
```
plugins {
id("$androidPluginId")
kotlin("multiplatform")
}
kotlin {
android() // <-- please register this Android target
}
```
""".trimIndent()
)
}
@@ -50,7 +50,7 @@ import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import javax.inject.Inject
import kotlin.reflect.KClass
abstract class KotlinBasePluginWrapper: Plugin<Project> {
abstract class KotlinBasePluginWrapper : Plugin<Project> {
private val log = Logging.getLogger(this.javaClass)
@@ -232,19 +232,9 @@ open class KotlinMultiplatformPluginWrapper : KotlinBasePluginWrapper() {
override val projectExtensionClass: KClass<out KotlinMultiplatformExtension>
get() = KotlinMultiplatformExtension::class
override fun whenBuildEvaluated(project: Project) = project.runProjectConfigurationHealthCheck {
val isNoTargetsInitialized = (project.kotlinExtension as KotlinMultiplatformExtension)
.targets
.none { it !is KotlinMetadataTarget }
if (isNoTargetsInitialized) {
throw GradleException(
"""
Please initialize at least one Kotlin target in '${project.name} (${project.path})'.
Read more https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets
""".trimIndent()
)
}
override fun whenBuildEvaluated(project: Project) {
project.runMissingAndroidTargetProjectConfigurationHealthCheck()
project.runMissingKotlinTargetsProjectConfigurationHealthCheck()
}
}