[Gradle] Migrate warning about missing Android-target to new infra
This commit is contained in:
-31
@@ -38,37 +38,6 @@ internal fun Project.runMissingKotlinTargetsProjectConfigurationHealthCheck() =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Project.runMissingAndroidTargetProjectConfigurationHealthCheck(
|
|
||||||
warningLogger: (warningMessage: String) -> Unit = project.logger::warn
|
|
||||||
) = project.runProjectConfigurationHealthCheck check@{
|
|
||||||
if (project.kotlinPropertiesProvider.ignoreAbsentAndroidMultiplatformTarget) {
|
|
||||||
return@check
|
|
||||||
}
|
|
||||||
|
|
||||||
val androidPluginId = findAppliedAndroidPluginIdOrNull() ?: return@check
|
|
||||||
|
|
||||||
if (findAndroidTarget() != null) return@check
|
|
||||||
|
|
||||||
warningLogger(
|
|
||||||
"""
|
|
||||||
Missing 'androidTarget()' Kotlin target in multiplatform project ${project.name} (${project.path})'.
|
|
||||||
The Android Gradle plugin was applied without creating a corresponding 'androidTarget()' Kotlin Target:
|
|
||||||
|
|
||||||
```
|
|
||||||
plugins {
|
|
||||||
id("$androidPluginId")
|
|
||||||
kotlin("multiplatform")
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
androidTarget() // <-- please register this Android target
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun Project.runDisabledCInteropCommonizationOnHmppProjectConfigurationHealthCheck(
|
internal fun Project.runDisabledCInteropCommonizationOnHmppProjectConfigurationHealthCheck(
|
||||||
warningLogger: (warningMessage: String) -> Unit = project.logger::warn
|
warningLogger: (warningMessage: String) -> Unit = project.logger::warn
|
||||||
) {
|
) {
|
||||||
|
|||||||
-1
@@ -387,7 +387,6 @@ abstract class AbstractKotlinMultiplatformPluginWrapper : KotlinBasePluginWrappe
|
|||||||
get() = KotlinMultiplatformExtension::class
|
get() = KotlinMultiplatformExtension::class
|
||||||
|
|
||||||
override fun whenBuildEvaluated(project: Project) {
|
override fun whenBuildEvaluated(project: Project) {
|
||||||
project.runMissingAndroidTargetProjectConfigurationHealthCheck()
|
|
||||||
project.runMissingKotlinTargetsProjectConfigurationHealthCheck()
|
project.runMissingKotlinTargetsProjectConfigurationHealthCheck()
|
||||||
project.runDisabledCInteropCommonizationOnHmppProjectConfigurationHealthCheck()
|
project.runDisabledCInteropCommonizationOnHmppProjectConfigurationHealthCheck()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -99,7 +99,8 @@ internal interface KotlinGradleProjectChecker {
|
|||||||
MissingNativeStdlibChecker,
|
MissingNativeStdlibChecker,
|
||||||
UnusedSourceSetsChecker,
|
UnusedSourceSetsChecker,
|
||||||
AndroidSourceSetLayoutV1SourceSetsNotFoundChecker,
|
AndroidSourceSetLayoutV1SourceSetsNotFoundChecker,
|
||||||
TargetsWithAmbiguousConsumableConfigurationsChecker
|
TargetsWithAmbiguousConsumableConfigurationsChecker,
|
||||||
|
AndroidPluginWithoutAndroidTargetChecker
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -220,4 +220,24 @@ object KotlinToolingDiagnostics {
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object AndroidTargetIsMissing : ToolingDiagnosticFactory(WARNING) {
|
||||||
|
operator fun invoke(projectName: String, projectPath: String, androidPluginId: String) = build(
|
||||||
|
"""
|
||||||
|
Missing 'androidTarget()' Kotlin target in multiplatform project '$projectName ($projectPath)'.
|
||||||
|
The Android Gradle plugin was applied without creating a corresponding 'android()' Kotlin Target:
|
||||||
|
|
||||||
|
```
|
||||||
|
plugins {
|
||||||
|
id("$androidPluginId")
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
androidTarget() // <-- please register this Android target
|
||||||
|
}
|
||||||
|
```
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.configurationResult
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.android.findAndroidTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.findAppliedAndroidPluginIdOrNull
|
||||||
|
|
||||||
|
internal object AndroidPluginWithoutAndroidTargetChecker : KotlinGradleProjectChecker {
|
||||||
|
override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) {
|
||||||
|
project.configurationResult.await()
|
||||||
|
if (multiplatformExtension == null || kotlinPropertiesProvider.ignoreAbsentAndroidMultiplatformTarget) return
|
||||||
|
|
||||||
|
val androidPluginId = project.findAppliedAndroidPluginIdOrNull() ?: return
|
||||||
|
if (project.findAndroidTarget() != null) return
|
||||||
|
collector.reportOncePerGradleProject(
|
||||||
|
project,
|
||||||
|
KotlinToolingDiagnostics.AndroidTargetIsMissing(project.name, project.path, androidPluginId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
-52
@@ -8,84 +8,79 @@
|
|||||||
package org.jetbrains.kotlin.gradle.regressionTests
|
package org.jetbrains.kotlin.gradle.regressionTests
|
||||||
|
|
||||||
import com.android.build.gradle.LibraryExtension
|
import com.android.build.gradle.LibraryExtension
|
||||||
import org.jetbrains.kotlin.gradle.util.MultiplatformExtensionTest
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||||
import org.jetbrains.kotlin.gradle.plugin.runMissingAndroidTargetProjectConfigurationHealthCheck
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.android.findAndroidTarget
|
import org.jetbrains.kotlin.gradle.targets.android.findAndroidTarget
|
||||||
import org.jetbrains.kotlin.gradle.util.propertiesExtension
|
import org.jetbrains.kotlin.gradle.util.*
|
||||||
|
import org.jetbrains.kotlin.gradle.util.assertNoDiagnostics
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.*
|
import kotlin.test.assertNull
|
||||||
|
import kotlin.test.assertSame
|
||||||
|
|
||||||
class KT41641AbsentAndroidTarget : MultiplatformExtensionTest() {
|
class KT41641AbsentAndroidTarget : MultiplatformExtensionTest() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test android plugin without android target`() {
|
fun `test android plugin without android target`() {
|
||||||
project.plugins.apply("kotlin-multiplatform")
|
defaultSetupWithoutAndroidTarget()
|
||||||
project.plugins.apply("android-library")
|
|
||||||
|
|
||||||
/* Arbitrary minimal Android setup */
|
|
||||||
val android = project.extensions.getByName("android") as LibraryExtension
|
|
||||||
android.compileSdk = 31
|
|
||||||
|
|
||||||
kotlin.jvm()
|
|
||||||
|
|
||||||
/* Previously failed with 'Collection is empty.' */
|
/* Previously failed with 'Collection is empty.' */
|
||||||
assertNull(project.findAndroidTarget())
|
assertNull(project.findAndroidTarget())
|
||||||
assertSame(kotlin.androidTarget(), project.findAndroidTarget())
|
assertSame(kotlin.androidTarget(), project.findAndroidTarget())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test runMissingAndroidTargetProjectConfigurationHealthCheck`() {
|
fun `test runMissingAndroidTargetProjectConfigurationHealthCheck - warning`() {
|
||||||
project.plugins.apply("kotlin-multiplatform")
|
defaultSetupWithoutAndroidTarget()
|
||||||
project.plugins.apply("android-library")
|
|
||||||
|
|
||||||
/* Arbitrary minimal Android setup */
|
|
||||||
val android = project.extensions.getByName("android") as LibraryExtension
|
|
||||||
android.compileSdk = 31
|
|
||||||
|
|
||||||
kotlin.jvm()
|
|
||||||
|
|
||||||
// Missing android target -> expect warning message
|
// Missing android target -> expect warning message
|
||||||
var warningMessage: String? = null
|
project.evaluate()
|
||||||
project.runMissingAndroidTargetProjectConfigurationHealthCheck(warningLogger = { warningMessage = it })
|
project.assertContainsDiagnostic(KotlinToolingDiagnostics.AndroidTargetIsMissing)
|
||||||
assertNotNull(warningMessage, "Expected warning message to be logged")
|
|
||||||
|
|
||||||
// Present android target -> expect no warning message anymore
|
|
||||||
kotlin.androidTarget()
|
|
||||||
project.runMissingAndroidTargetProjectConfigurationHealthCheck(warningLogger = {
|
|
||||||
fail("Expected no warning message to be logged. Received: $it")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test kotlin-mpp-absentAndroidTarget-nowarn flag`() {
|
fun `test runMissingAndroidTargetProjectConfigurationHealthCheck - no warning`() {
|
||||||
|
defaultSetupWithoutAndroidTarget()
|
||||||
|
kotlin.androidTarget()
|
||||||
|
|
||||||
|
// Present android target -> expect no warning message anymore
|
||||||
|
project.evaluate()
|
||||||
|
project.assertNoDiagnostics()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test kotlin-mpp-absentAndroidTarget-nowarn flag set to true`() {
|
||||||
|
defaultSetupWithoutAndroidTarget()
|
||||||
project.propertiesExtension["kotlin.mpp.absentAndroidTarget.nowarn"] = "true"
|
project.propertiesExtension["kotlin.mpp.absentAndroidTarget.nowarn"] = "true"
|
||||||
|
|
||||||
|
project.evaluate()
|
||||||
|
project.assertNoDiagnostics()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test kotlin-mpp-absentAndroidTarget-nowarn flag set to false`() {
|
||||||
|
defaultSetupWithoutAndroidTarget()
|
||||||
|
project.propertiesExtension["kotlin.mpp.absentAndroidTarget.nowarn"] = null
|
||||||
|
|
||||||
|
project.evaluate()
|
||||||
|
project.assertContainsDiagnostic(KotlinToolingDiagnostics.AndroidTargetIsMissing)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test kotlin-mpp-absentAndroidTarget-nowarn flag set to null`() {
|
||||||
|
defaultSetupWithoutAndroidTarget()
|
||||||
|
project.propertiesExtension["kotlin.mpp.absentAndroidTarget.nowarn"] = null
|
||||||
|
|
||||||
|
project.evaluate()
|
||||||
|
project.assertContainsDiagnostic(KotlinToolingDiagnostics.AndroidTargetIsMissing)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun defaultSetupWithoutAndroidTarget() {
|
||||||
project.plugins.apply("kotlin-multiplatform")
|
project.plugins.apply("kotlin-multiplatform")
|
||||||
project.plugins.apply("android-library")
|
project.plugins.apply("android-library")
|
||||||
|
|
||||||
/* Arbitrary minimal Android setup */
|
/* Arbitrary minimal Android setup */
|
||||||
val android = project.extensions.getByName("android") as LibraryExtension
|
val android = project.extensions.getByName("android") as LibraryExtension
|
||||||
android.compileSdk = 31
|
android.compileSdk = 31
|
||||||
|
|
||||||
kotlin.jvm()
|
kotlin.jvm()
|
||||||
|
|
||||||
project.runMissingAndroidTargetProjectConfigurationHealthCheck(warningLogger = {
|
project.setMultiplatformAndroidSourceSetLayoutVersion(2)
|
||||||
fail("Expected no warning message to be logged. Received $it")
|
|
||||||
})
|
|
||||||
|
|
||||||
// Test when nowarn is set to false
|
|
||||||
run {
|
|
||||||
var warningMessage: String? = null
|
|
||||||
project.propertiesExtension["kotlin.mpp.absentAndroidTarget.nowarn"] = "false"
|
|
||||||
project.runMissingAndroidTargetProjectConfigurationHealthCheck(warningLogger = { warningMessage = it })
|
|
||||||
assertNotNull(warningMessage, "Expected warning message to be logged")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test when nowarn is set to null
|
|
||||||
run {
|
|
||||||
var warningMessage: String? = null
|
|
||||||
project.propertiesExtension["kotlin.mpp.absentAndroidTarget.nowarn"] = null
|
|
||||||
project.runMissingAndroidTargetProjectConfigurationHealthCheck(warningLogger = { warningMessage = it })
|
|
||||||
assertNotNull(warningMessage, "Expected warning message to be logged")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-4
@@ -68,15 +68,29 @@ internal fun Project.assertNoDiagnostics() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that diagnostic with [factory.id] is reported. The exact parameters (if any)
|
||||||
|
* are ignored. If you need to compare the parameters, refer to the overload accepting [ToolingDiagnostic]
|
||||||
|
*/
|
||||||
|
internal fun Project.assertContainsDiagnostic(factory: ToolingDiagnosticFactory) {
|
||||||
|
kotlinToolingDiagnosticsCollector.getDiagnosticsForProject(this).assertContainsDiagnostic(factory)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun Project.assertContainsDiagnostic(diagnostic: ToolingDiagnostic) {
|
internal fun Project.assertContainsDiagnostic(diagnostic: ToolingDiagnostic) {
|
||||||
kotlinToolingDiagnosticsCollector.getDiagnosticsForProject(this).assertContainsDiagnostic(diagnostic)
|
kotlinToolingDiagnosticsCollector.getDiagnosticsForProject(this).assertContainsDiagnostic(diagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun Collection<ToolingDiagnostic>.assertContainsDiagnostic(factory: ToolingDiagnosticFactory) {
|
||||||
|
if (!any { it.id == factory.id }) failDiagnosticNotFound("diagnostic with id ${factory.id} ", this)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun Collection<ToolingDiagnostic>.assertContainsDiagnostic(diagnostic: ToolingDiagnostic) {
|
internal fun Collection<ToolingDiagnostic>.assertContainsDiagnostic(diagnostic: ToolingDiagnostic) {
|
||||||
|
if (diagnostic !in this) failDiagnosticNotFound("diagnostic $diagnostic\n", this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun failDiagnosticNotFound(diagnosticDescription: String, notFoundInCollection: Collection<ToolingDiagnostic>) {
|
||||||
fun Any.withIndent() = this.toString().prependIndent(" ")
|
fun Any.withIndent() = this.toString().prependIndent(" ")
|
||||||
if (diagnostic !in this) {
|
fail("Missing ${diagnosticDescription}in:\n${notFoundInCollection.render().withIndent()}")
|
||||||
fail("Missing diagnostic\n${diagnostic.withIndent()} \nin:\n${this.render().withIndent()}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Project.assertNoDiagnostics(id: String) {
|
internal fun Project.assertNoDiagnostics(id: String) {
|
||||||
@@ -100,4 +114,3 @@ private val expectedDiagnosticsRoot: Path
|
|||||||
get() = resourcesRoot.resolve("expectedDiagnostics")
|
get() = resourcesRoot.resolve("expectedDiagnostics")
|
||||||
|
|
||||||
private fun expectedDiagnosticsFile(projectName: String): File = expectedDiagnosticsRoot.resolve("$projectName.txt").toFile()
|
private fun expectedDiagnosticsFile(projectName: String): File = expectedDiagnosticsRoot.resolve("$projectName.txt").toFile()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user