Emit a diagnostic if variant reselection is used pre Gradle 7.6

^KT-66133
This commit is contained in:
Timofey Solonin
2024-03-07 17:40:41 +01:00
committed by Space Team
parent e1180adfbd
commit c34bfcdb1d
5 changed files with 100 additions and 5 deletions
@@ -806,6 +806,17 @@ object KotlinToolingDiagnostics {
)
}
object ResourceMayNotBeResolvedWithGradleVersion : ToolingDiagnosticFactory(ERROR) {
operator fun invoke(
targetName: String, currentGradleVersion: String, minimumRequiredVersion: String) = build(
"""
Resources for target $targetName may not be resolved. Minimum required Gradle version is ${minimumRequiredVersion} but current is ${currentGradleVersion}.
$resourcesBugReportRequest
""".trimIndent()
)
}
object UnknownValueProvidedForResourcesStrategy : ToolingDiagnosticFactory(ERROR) {
operator fun invoke(value: String) = build(
"""
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2024 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.mpp.resources
import org.gradle.api.Project
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.plugin.extraProperties
import org.jetbrains.kotlin.gradle.plugin.getOrNull
private const val OVERRIDE_GRADLE_VERSION_FOR_TESTS = "org.jetbrains.kotlin.internal.overriddenGradleVersionForTests"
internal var Project.overriddenGradleVersionForTests: GradleVersion?
set(value) = extraProperties.set(OVERRIDE_GRADLE_VERSION_FOR_TESTS, value)
get() = extraProperties.getOrNull(OVERRIDE_GRADLE_VERSION_FOR_TESTS) as? GradleVersion
internal val Project.gradleVersion: GradleVersion get() = overriddenGradleVersionForTests ?: GradleVersion.current()
@@ -8,11 +8,13 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.resources
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnosticOncePerBuild
import org.jetbrains.kotlin.gradle.plugin.launchInStage
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
@@ -29,7 +31,7 @@ import java.io.File
import javax.inject.Inject
internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor(
val project: Project
private val project: Project,
) : KotlinTargetResourcesPublication {
internal data class TargetResources(
@@ -126,9 +128,8 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
}
override fun resolveResources(target: KotlinTarget): Provider<File> {
if (!canResolveResources(target)) {
target.project.reportDiagnostic(KotlinToolingDiagnostics.ResourceMayNotBeResolvedForTarget(target.name))
}
validateTargetResourcesAreResolvable(target)
validateGradleVersionIsCompatibleWithResolutionStrategy(target.name)
val aggregateResourcesTaskName = target.disambiguateName("AggregateResources")
project.locateTask<AggregateResourcesTask>(aggregateResourcesTaskName)?.let {
@@ -201,12 +202,34 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
}
}
private fun validateTargetResourcesAreResolvable(target: KotlinTarget) {
if (!canResolveResources(target)) {
target.project.reportDiagnostic(KotlinToolingDiagnostics.ResourceMayNotBeResolvedForTarget(target.name))
}
}
private fun validateGradleVersionIsCompatibleWithResolutionStrategy(targetName: String) {
if (project.kotlinPropertiesProvider.mppResourcesResolutionStrategy == KotlinTargetResourcesResolutionStrategy.VariantReselection) {
if (project.gradleVersion < minimumGradleVersionForVariantReselection) {
project.reportDiagnosticOncePerBuild(
KotlinToolingDiagnostics.ResourceMayNotBeResolvedWithGradleVersion(
targetName,
GradleVersion.current().toString(),
minimumGradleVersionForVariantReselection.toString(),
)
)
}
}
}
internal companion object {
const val MULTIPLATFORM_RESOURCES_DIRECTORY = "kotlin-multiplatform-resources"
const val RESOURCES_CLASSIFIER = "kotlin_resources"
const val RESOURCES_ZIP_EXTENSION = "${RESOURCES_CLASSIFIER}.zip"
const val RESOURCES_PATH = "ResourcesPath"
val minimumGradleVersionForVariantReselection = GradleVersion.version("7.6")
}
}
@@ -16,7 +16,10 @@ internal val KotlinMultiplatformExtension.resourcesPublicationExtension: KotlinT
get() {
if (!project.kotlinPropertiesProvider.mppResourcesPublication) return null
return project.extraProperties.getOrPut(KotlinTargetResourcesPublication.EXTENSION_NAME) {
project.objects.newInstance(KotlinTargetResourcesPublicationImpl::class.java, project)
project.objects.newInstance(
KotlinTargetResourcesPublicationImpl::class.java,
project,
)
}
}
@@ -10,12 +10,15 @@ package org.jetbrains.kotlin.gradle.unitTests
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Project
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnosticFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.KotlinTargetResourcesPublication
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.overriddenGradleVersionForTests
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resolve.KotlinTargetResourcesResolutionStrategy
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.util.*
@@ -164,6 +167,43 @@ class KotlinTargetResourcesPublicationImplTests {
}
}
@Test
fun `test resolution - emits diagnostic in first resolving project with variant reselection - when Gradle version is below 7_6`() {
val rootProject = buildProjectWithMPP(
projectBuilder = { withName("root") },
preApplyCode = {
setMppResourcesResolutionStrategy(KotlinTargetResourcesResolutionStrategy.VariantReselection)
overriddenGradleVersionForTests = GradleVersion.version("7.5.1")
},
) { kotlin { linuxArm64() } }
val childProject = buildProjectWithMPP(
projectBuilder = { withParent(rootProject).withName("child") },
preApplyCode = {
setMppResourcesResolutionStrategy(KotlinTargetResourcesResolutionStrategy.VariantReselection)
overriddenGradleVersionForTests = GradleVersion.version("7.5.1")
},
) { kotlin { linuxArm64() } }
childProject.multiplatformExtension.resourcesPublicationExtension?.resolveResources(childProject.multiplatformExtension.linuxArm64())
rootProject.multiplatformExtension.resourcesPublicationExtension?.resolveResources(rootProject.multiplatformExtension.linuxArm64())
childProject.assertContainsDiagnostic(KotlinToolingDiagnostics.ResourceMayNotBeResolvedWithGradleVersion)
rootProject.assertNoDiagnostics(KotlinToolingDiagnostics.ResourceMayNotBeResolvedWithGradleVersion)
}
@Test
fun `test resolution - doesn't emit diagnostic with variant reselection - when Gradle version is above 7_6`() {
buildProjectWithMPP(
preApplyCode = { overriddenGradleVersionForTests = GradleVersion.version("7.6.1") }
) {
setMppResourcesResolutionStrategy(KotlinTargetResourcesResolutionStrategy.VariantReselection)
kotlin {
linuxArm64()
resourcesPublicationExtension?.resolveResources(linuxArm64())
}
}.assertNoDiagnostics()
}
private fun testCallbacksAfterApiCall(
callback: ((Unit) -> Unit) -> Unit,
apiCall: (Unit) -> Unit,