[Gradle] Implement IosSourceSetConventionUsedWithoutIosTarget diagnostic

... in case when iosMain, iosTest conventions are used
w/o any ios target being applied

^KT-58676 Verification Pending
This commit is contained in:
Sebastian Sellmair
2023-06-23 14:38:50 +02:00
committed by Space Team
parent 6d1e039b77
commit c31c5ea0be
5 changed files with 97 additions and 2 deletions
@@ -8,16 +8,22 @@ package org.jetbrains.kotlin.gradle.dsl
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.NamedDomainObjectProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinSourceSetConvention.isRegisteredByKotlinSourceSetConventionAt
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.AndroidMainSourceSetConventionUsedWithoutAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.IosSourceSetConventionUsedWithoutIosTarget
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.PlatformSourceSetConventionUsedWithCustomTargetName
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics.PlatformSourceSetConventionUsedWithoutCorrespondingTarget
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.konan.target.Family
@KotlinGradlePluginDsl
interface KotlinMultiplatformSourceSetConventions {
@@ -152,3 +158,24 @@ internal object AndroidMainSourceSetConventionsChecker : KotlinGradleProjectChec
}
}
}
internal object IosSourceSetConventionChecker : KotlinGradleProjectChecker {
override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) {
val kotlin = project.multiplatformExtensionOrNull ?: return
val iosSourceSets = listOf("iosMain", "iosTest")
.mapNotNull { sourceSetName -> kotlin.awaitSourceSets().findByName(sourceSetName) }
.filter { it.isRegisteredByKotlinSourceSetConventionAt != null }
val hasIosTarget = kotlin.awaitTargets()
.any { target -> target is KotlinNativeTarget && target.konanTarget.family == Family.IOS }
if (!hasIosTarget) {
iosSourceSets.forEach { sourceSet ->
project.reportDiagnostic(IosSourceSetConventionUsedWithoutIosTarget(sourceSet))
}
}
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.diagnostics
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.AndroidMainSourceSetConventionsChecker
import org.jetbrains.kotlin.gradle.dsl.IosSourceSetConventionChecker
import org.jetbrains.kotlin.gradle.dsl.PlatformSourceSetConventionsChecker
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
@@ -112,6 +113,7 @@ internal interface KotlinGradleProjectChecker {
KotlinSourceSetTreeDependsOnMismatchChecker,
PlatformSourceSetConventionsChecker,
AndroidMainSourceSetConventionsChecker,
IosSourceSetConventionChecker
)
}
}
@@ -425,7 +425,28 @@ object KotlinToolingDiagnostics {
| kotlin {
| androidTarget() /* <- register the androidTarget */
| }
""".trimMargin()
""".trimMargin(),
throwable = sourceSet.isRegisteredByKotlinSourceSetConventionAt
)
}
object IosSourceSetConventionUsedWithoutIosTarget : ToolingDiagnosticFactory(WARNING) {
operator fun invoke(sourceSet: KotlinSourceSet) = build(
"""
|Accessed '$sourceSet' without registering any ios target:
| kotlin {
| /* Register at least one of the following targets */
| iosX64()
| iosArm64()
| iosSimulatorArm64()
|
| /* Use convention
| sourceSets.${sourceSet.name}.dependencies {
|
| }
| }
""".trimMargin(),
throwable = sourceSet.isRegisteredByKotlinSourceSetConventionAt
)
}
@@ -7,6 +7,8 @@
package org.jetbrains.kotlin.gradle.unitTests.diagnosticsTests
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.iosMain
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.iosTest
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.configurationResult
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
@@ -86,4 +88,16 @@ class MppSourceSetConventionsDiagnosticTests {
checkDiagnostics("AndroidMainSourceSetConventionUsedWithoutAndroidTarget")
}
}
@Test
fun `test - iosMain and iosTest - without any ios target`() = buildProjectWithMPP().runLifecycleAwareTest {
multiplatformExtension.linuxX64()
multiplatformExtension.jvm()
multiplatformExtension.sourceSets.iosMain
multiplatformExtension.sourceSets.iosTest
configurationResult.await()
checkDiagnostics("IosSourceSetConventionUsedWithoutIosTarget")
}
}
@@ -0,0 +1,31 @@
[IosSourceSetConventionUsedWithoutIosTarget | WARNING] Accessed 'source set iosMain' without registering any ios target:
kotlin {
/* Register at least one of the following targets */
iosX64()
iosArm64()
iosSimulatorArm64()
/* Use convention
sourceSets.iosMain.dependencies {
}
}
----
[IosSourceSetConventionUsedWithoutIosTarget | WARNING] Accessed 'source set iosTest' without registering any ios target:
kotlin {
/* Register at least one of the following targets */
iosX64()
iosArm64()
iosSimulatorArm64()
/* Use convention
sourceSets.iosTest.dependencies {
}
}
----
[UnusedSourceSetsWarning | WARNING] The following Kotlin source sets were configured but not added to any Kotlin compilation:
* iosMain
* iosTest
You can add a source set to a target's compilation by connecting it with the compilation's default source set using 'dependsOn'.
See https://kotl.in/connecting-source-sets