[Gradle] Implement AndroidGradlePluginIsMissing diagnostics

^KT-60693 Verification Pending
This commit is contained in:
Sebastian Sellmair
2023-07-26 15:18:35 +02:00
committed by Space Team
parent 951b299268
commit e8004a4034
5 changed files with 82 additions and 16 deletions
@@ -237,6 +237,27 @@ object KotlinToolingDiagnostics {
)
}
object AndroidGradlePluginIsMissing : ToolingDiagnosticFactory(FATAL) {
operator fun invoke(trace: Throwable? = null) = build(
"""
The Android target requires a 'Android Gradle Plugin' to be applied to the project.
plugins {
kotlin("multiplatform")
/* Android Gradle Plugin missing */
id("com.android.library") /* <- Android Gradle Plugin for libraries */
id("com.android.application") <* <- Android Gradle Plugin for applications */
}
kotlin {
androidTarget() /* <- requires Android Gradle Plugin to be applied */
}
""".trimIndent(),
throwable = trace
)
}
object NoKotlinTargetsDeclared : ToolingDiagnosticFactory(ERROR) {
operator fun invoke(projectName: String, projectPath: String) = build(
"""
@@ -9,6 +9,10 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin.Companion.dynamicallyApplyWhenAndroidPluginIsApplied
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.AndroidGradlePluginIsMissing
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic
import org.jetbrains.kotlin.gradle.utils.findAppliedAndroidPluginIdOrNull
import javax.inject.Inject
@@ -19,25 +23,23 @@ abstract class KotlinAndroidTargetPreset @Inject constructor(
override fun getName(): String = PRESET_NAME
override fun createTarget(name: String): KotlinAndroidTarget {
val result = project.objects.newInstance(
KotlinAndroidTarget::class.java,
name,
project
).apply {
/*
Android Gradle Plugin is required:
Creating target will fail with Linkage Error instead
Could not create an instance of type org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget.
> Could not generate a decorated class for type KotlinAndroidTarget.
> com/android/build/gradle/api/BaseVariant
*/
project.findAppliedAndroidPluginIdOrNull() ?: project.reportDiagnostic(AndroidGradlePluginIsMissing(Throwable()))
return project.objects.newInstance(KotlinAndroidTarget::class.java, name, project).apply {
preset = this@KotlinAndroidTargetPreset
targetUnderConstruction = this
project.dynamicallyApplyWhenAndroidPluginIsApplied({ this })
}
project.dynamicallyApplyWhenAndroidPluginIsApplied({ result })
targetUnderConstruction = null
return result
}
/** This is a way to check if there's an Android target being configured now despite it not being added to the `kotlin.targets` yet */
internal var targetUnderConstruction: KotlinAndroidTarget? = null
companion object {
const val PRESET_NAME = "android"
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2023 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.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.unitTests.diagnosticsTests
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.util.*
import kotlin.test.Test
import kotlin.test.assertFails
class AndroidGradlePluginIsMissingTest {
@Test
fun `test - android plugin is not applied`() {
val project = buildProjectWithMPP()
assertFails { project.multiplatformExtension.androidTarget() }
project.checkDiagnostics("AndroidGradlePluginIsMissing")
}
@Test
fun `test - android application plugin is applied`() {
val project = buildProjectWithMPP()
project.androidApplication { compileSdk = 33 }
project.multiplatformExtension.androidTarget()
project.assertNoDiagnostics()
}
}
@@ -18,9 +18,9 @@ class KotlinSourceSetTreeDependsOnMismatchTest {
private fun checkDiagnostics(configure: KotlinMultiplatformExtension.() -> Unit): List<ToolingDiagnostic> {
val project = buildProjectWithMPP {
kotlin {
project.androidApplication { compileSdk = 32 }
applyDefaultHierarchyTemplate()
androidTarget()
project.androidApplication { compileSdk = 32 }
iosX64(); iosArm64(); iosSimulatorArm64()
macosX64(); macosArm64()
@@ -0,0 +1,13 @@
[AndroidGradlePluginIsMissing | FATAL] The Android target requires a 'Android Gradle Plugin' to be applied to the project.
plugins {
kotlin("multiplatform")
/* Android Gradle Plugin missing */
id("com.android.library") /* <- Android Gradle Plugin for libraries */
id("com.android.application") <* <- Android Gradle Plugin for applications */
}
kotlin {
androidTarget() /* <- requires Android Gradle Plugin to be applied */
}