Browse Source
We had two build services: 1) to check unsupported compose compiler plugins were applied 2) to check a native cache kind configuration Both of them are outdated and we may get rid of them. Fixes https://github.com/JetBrains/compose-multiplatform/issues/4815 ## Release Notes ### Fixes - Gradle Plugin - Delete outdated build servicespull/4963/head
Konstantin
5 months ago
committed by
GitHub
10 changed files with 6 additions and 588 deletions
@ -1,127 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.experimental.internal |
|
||||||
|
|
||||||
import org.gradle.api.Project |
|
||||||
import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID |
|
||||||
import org.jetbrains.compose.internal.mppExt |
|
||||||
import org.jetbrains.compose.internal.utils.KGPPropertyProvider |
|
||||||
import org.jetbrains.compose.internal.utils.configureEachWithType |
|
||||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion |
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget |
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget |
|
||||||
import org.jetbrains.kotlin.konan.target.presetName |
|
||||||
|
|
||||||
private const val PROJECT_CACHE_KIND_PROPERTY_NAME = "kotlin.native.cacheKind" |
|
||||||
private const val COMPOSE_NATIVE_MANAGE_CACHE_KIND = "compose.kotlin.native.manageCacheKind" |
|
||||||
private const val NONE_VALUE = "none" |
|
||||||
|
|
||||||
// Compose runtime supports these k/native targets: |
|
||||||
// https://github.com/JetBrains/compose-multiplatform-core/blob/jb-main/compose/runtime/runtime/build.gradle#L75 |
|
||||||
private val SUPPORTED_NATIVE_TARGETS = setOf( |
|
||||||
// ios |
|
||||||
KonanTarget.IOS_X64, |
|
||||||
KonanTarget.IOS_ARM64, |
|
||||||
KonanTarget.IOS_SIMULATOR_ARM64, |
|
||||||
// macos |
|
||||||
KonanTarget.MACOS_X64, |
|
||||||
KonanTarget.MACOS_ARM64, |
|
||||||
// tvos |
|
||||||
KonanTarget.TVOS_X64, |
|
||||||
KonanTarget.TVOS_ARM64, |
|
||||||
KonanTarget.TVOS_SIMULATOR_ARM64, |
|
||||||
// watchOS |
|
||||||
KonanTarget.WATCHOS_ARM64, |
|
||||||
KonanTarget.WATCHOS_ARM32, |
|
||||||
KonanTarget.WATCHOS_X64, |
|
||||||
KonanTarget.WATCHOS_SIMULATOR_ARM64, |
|
||||||
// mingw |
|
||||||
KonanTarget.MINGW_X64, |
|
||||||
// linux |
|
||||||
KonanTarget.LINUX_X64, |
|
||||||
) |
|
||||||
|
|
||||||
internal val SUPPORTED_NATIVE_CACHE_KIND_PROPERTIES = |
|
||||||
SUPPORTED_NATIVE_TARGETS.map { it.targetCacheKindPropertyName } + |
|
||||||
PROJECT_CACHE_KIND_PROPERTY_NAME |
|
||||||
|
|
||||||
internal fun Project.configureNativeCompilerCaching() { |
|
||||||
if (findProperty(COMPOSE_NATIVE_MANAGE_CACHE_KIND) == "false") return |
|
||||||
|
|
||||||
plugins.withId(KOTLIN_MPP_PLUGIN_ID) { |
|
||||||
val kotlinPluginVersion = kotlinVersionNumbers(project.getKotlinPluginVersion()) |
|
||||||
mppExt.targets.configureEachWithType<KotlinNativeTarget> { |
|
||||||
if (konanTarget in SUPPORTED_NATIVE_TARGETS) { |
|
||||||
checkExplicitCacheKind() |
|
||||||
if (kotlinPluginVersion < KotlinVersion(1, 9, 20)) { |
|
||||||
// Pre-1.9.20 Kotlin compiler caches have known compatibility issues |
|
||||||
// See KT-57329, KT-61270 |
|
||||||
disableKotlinNativeCache() |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private fun KotlinNativeTarget.checkExplicitCacheKind() { |
|
||||||
// To determine cache kind KGP checks kotlin.native.cacheKind.<PRESET_NAME> first, then kotlin.native.cacheKind |
|
||||||
// For each property it tries to read Project.property, then checks local.properties |
|
||||||
// See https://github.com/JetBrains/kotlin/blob/d4d30dcfcf1afb083f09279c6f1ba05031efeabb/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt#L416 |
|
||||||
val cacheKindProperties = listOf(targetCacheKindPropertyName, PROJECT_CACHE_KIND_PROPERTY_NAME) |
|
||||||
val propertyProviders = listOf( |
|
||||||
KGPPropertyProvider.GradleProperties(project), |
|
||||||
KGPPropertyProvider.LocalProperties(project) |
|
||||||
) |
|
||||||
|
|
||||||
for (cacheKindProperty in cacheKindProperties) { |
|
||||||
for (provider in propertyProviders) { |
|
||||||
val value = provider.valueOrNull(cacheKindProperty) |
|
||||||
if (value != null) { |
|
||||||
error(explicitCacheKindErrorMessage(cacheKindProperty, value, provider)) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private fun explicitCacheKindErrorMessage( |
|
||||||
cacheKindProperty: String, |
|
||||||
value: String, |
|
||||||
provider: KGPPropertyProvider |
|
||||||
) = """ |
|
||||||
|Error: '$cacheKindProperty' is explicitly set to '$value'. |
|
||||||
|This option significantly slows the Kotlin/Native compiler. |
|
||||||
|Compose Multiplatform Gradle plugin manages this property automatically based on a Kotlin compiler version being used. |
|
||||||
| * Recommended action: remove explicit '$cacheKindProperty=$value' from ${provider.location}. |
|
||||||
| * Alternative action: disable cache kind management by adding '$COMPOSE_NATIVE_MANAGE_CACHE_KIND=false' to your 'gradle.properties'. |
|
||||||
""".trimMargin() |
|
||||||
|
|
||||||
|
|
||||||
private val KotlinNativeTarget.targetCacheKindPropertyName: String |
|
||||||
get() = konanTarget.targetCacheKindPropertyName |
|
||||||
|
|
||||||
private val KonanTarget.targetCacheKindPropertyName: String |
|
||||||
get() = "$PROJECT_CACHE_KIND_PROPERTY_NAME.${presetName}" |
|
||||||
|
|
||||||
private fun KotlinNativeTarget.disableKotlinNativeCache() { |
|
||||||
val existingValue = project.findProperty(targetCacheKindPropertyName)?.toString() |
|
||||||
if (NONE_VALUE.equals(existingValue, ignoreCase = true)) return |
|
||||||
|
|
||||||
if (targetCacheKindPropertyName in project.properties) { |
|
||||||
project.setProperty(targetCacheKindPropertyName, NONE_VALUE) |
|
||||||
} else { |
|
||||||
project.extensions.extraProperties.set(targetCacheKindPropertyName, NONE_VALUE) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal fun kotlinVersionNumbers(version: String): KotlinVersion { |
|
||||||
val m = Regex("(\\d+)\\.(\\d+)\\.(\\d+)").find(version) ?: error("Kotlin version has unexpected format: '$version'") |
|
||||||
val (_, majorPart, minorPart, patchPart) = m.groupValues |
|
||||||
return KotlinVersion( |
|
||||||
major = majorPart.toIntOrNull() ?: error("Could not parse major part '$majorPart' of Kotlin plugin version: '$version'"), |
|
||||||
minor = minorPart.toIntOrNull() ?: error("Could not parse minor part '$minorPart' of Kotlin plugin version: '$version'"), |
|
||||||
patch = patchPart.toIntOrNull() ?: error("Could not parse patch part '$patchPart' of Kotlin plugin version: '$version'"), |
|
||||||
) |
|
||||||
} |
|
@ -1,81 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.internal.service |
|
||||||
|
|
||||||
import org.gradle.api.Project |
|
||||||
import org.gradle.api.services.BuildService |
|
||||||
import org.gradle.api.services.BuildServiceParameters |
|
||||||
import org.gradle.api.services.BuildServiceRegistration |
|
||||||
import org.gradle.tooling.events.FinishEvent |
|
||||||
import org.gradle.tooling.events.OperationCompletionListener |
|
||||||
|
|
||||||
// The service implements OperationCompletionListener just so Gradle would materialize the service even if the service is not used by any task or transformation |
|
||||||
abstract class AbstractComposeMultiplatformBuildService<P : BuildServiceParameters> : BuildService<P> , OperationCompletionListener, AutoCloseable { |
|
||||||
override fun onFinish(event: FinishEvent) {} |
|
||||||
override fun close() {} |
|
||||||
} |
|
||||||
|
|
||||||
internal inline fun <reified Service : BuildService<*>> serviceName(instance: Service? = null): String = |
|
||||||
fqName(instance) |
|
||||||
|
|
||||||
internal inline fun <reified Service : AbstractComposeMultiplatformBuildService<Params>, reified Params : BuildServiceParameters> registerServiceIfAbsent( |
|
||||||
project: Project, |
|
||||||
crossinline initParams: Params.() -> Unit = {} |
|
||||||
): BuildServiceRegistration<Service, Params> { |
|
||||||
if (findRegistration<Service, Params>(project) == null) { |
|
||||||
val newService = project.gradle.sharedServices.registerIfAbsent(fqName<Service>(), Service::class.java) { |
|
||||||
it.parameters.initParams() |
|
||||||
} |
|
||||||
// Workaround to materialize a service even if it is not bound to a task |
|
||||||
BuildEventsListenerRegistryProvider.getInstance(project).onTaskCompletion(newService) |
|
||||||
} |
|
||||||
|
|
||||||
return getExistingServiceRegistration(project) |
|
||||||
} |
|
||||||
|
|
||||||
internal inline fun <reified Service : BuildService<Params>, reified Params : BuildServiceParameters> getExistingServiceRegistration( |
|
||||||
project: Project |
|
||||||
): BuildServiceRegistration<Service, Params> { |
|
||||||
val registration = findRegistration<Service, Params>(project) |
|
||||||
?: error("Service '${serviceName<Service>()}' was not initialized") |
|
||||||
return registration.verified(project) |
|
||||||
} |
|
||||||
|
|
||||||
private inline fun <reified Service : BuildService<Params>, reified Params : BuildServiceParameters> BuildServiceRegistration<*, *>.verified( |
|
||||||
project: Project |
|
||||||
): BuildServiceRegistration<Service, Params> { |
|
||||||
val parameters = parameters |
|
||||||
// We are checking the type of parameters instead of the type of service |
|
||||||
// to avoid materializing the service. |
|
||||||
// After a service instance is created all changes made to its parameters won't be visible to |
|
||||||
// that particular service instance. |
|
||||||
// This is undesirable in some cases. For example, when reporting configuration problems, |
|
||||||
// we want to collect all configuration issues from all projects first, then report issues all at once |
|
||||||
// in execution phase. |
|
||||||
if (parameters !is Params) { |
|
||||||
// Compose Gradle plugin was probably loaded more than once |
|
||||||
// See https://github.com/JetBrains/compose-multiplatform/issues/3459 |
|
||||||
if (fqName(parameters) == fqName<Params>()) { |
|
||||||
val rootScript = project.rootProject.buildFile |
|
||||||
error(""" |
|
||||||
Compose Multiplatform Gradle plugin has been loaded in multiple classloaders. |
|
||||||
To avoid classloading issues, declare Compose Gradle Plugin in root build file $rootScript. |
|
||||||
""".trimIndent()) |
|
||||||
} else { |
|
||||||
error("Shared build service '${serviceName<Service>()}' parameters have unexpected type: ${fqName(parameters)}") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST") |
|
||||||
return this as BuildServiceRegistration<Service, Params> |
|
||||||
} |
|
||||||
|
|
||||||
private inline fun <reified S : BuildService<P>, reified P : BuildServiceParameters> findRegistration( |
|
||||||
project: Project |
|
||||||
): BuildServiceRegistration<*, *>? = |
|
||||||
project.gradle.sharedServices.registrations.findByName(fqName<S>()) |
|
||||||
|
|
||||||
private inline fun <reified T : Any> fqName(instance: T? = null) = T::class.java.canonicalName |
|
@ -1,19 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.internal.service |
|
||||||
|
|
||||||
import org.gradle.api.Project |
|
||||||
import org.gradle.build.event.BuildEventsListenerRegistry |
|
||||||
import javax.inject.Inject |
|
||||||
|
|
||||||
// a hack to get BuildEventsListenerRegistry conveniently, which can only be injected by Gradle |
|
||||||
@Suppress("UnstableApiUsage") |
|
||||||
internal abstract class BuildEventsListenerRegistryProvider @Inject constructor(val registry: BuildEventsListenerRegistry) { |
|
||||||
companion object { |
|
||||||
fun getInstance(project: Project): BuildEventsListenerRegistry = |
|
||||||
project.objects.newInstance(BuildEventsListenerRegistryProvider::class.java).registry |
|
||||||
} |
|
||||||
} |
|
@ -1,69 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.internal.service |
|
||||||
|
|
||||||
import org.gradle.api.Project |
|
||||||
import org.gradle.api.logging.Logging |
|
||||||
import org.gradle.api.provider.ListProperty |
|
||||||
import org.gradle.api.provider.Provider |
|
||||||
import org.gradle.api.provider.SetProperty |
|
||||||
import org.gradle.api.services.BuildServiceParameters |
|
||||||
import org.jetbrains.compose.createWarningAboutNonCompatibleCompiler |
|
||||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact |
|
||||||
|
|
||||||
abstract class ConfigurationProblemReporterService : AbstractComposeMultiplatformBuildService<ConfigurationProblemReporterService.Parameters>() { |
|
||||||
interface Parameters : BuildServiceParameters { |
|
||||||
val unsupportedPluginWarningProviders: ListProperty<Provider<String?>> |
|
||||||
val warnings: SetProperty<String> |
|
||||||
} |
|
||||||
|
|
||||||
private val log = Logging.getLogger(this.javaClass) |
|
||||||
|
|
||||||
override fun close() { |
|
||||||
warnAboutUnsupportedCompilerPlugin() |
|
||||||
logWarnings() |
|
||||||
} |
|
||||||
|
|
||||||
private fun warnAboutUnsupportedCompilerPlugin() { |
|
||||||
for (warningProvider in parameters.unsupportedPluginWarningProviders.get()) { |
|
||||||
val warning = warningProvider.orNull |
|
||||||
if (warning != null) { |
|
||||||
log.warn(warning) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private fun logWarnings() { |
|
||||||
for (warning in parameters.warnings.get()) { |
|
||||||
log.warn(warning) |
|
||||||
} |
|
||||||
} |
|
||||||
companion object { |
|
||||||
fun init(project: Project) { |
|
||||||
registerServiceIfAbsent<ConfigurationProblemReporterService, Parameters>(project) { |
|
||||||
// WORKAROUND! Call getter at least once, because of Issue: https://github.com/gradle/gradle/issues/27099 |
|
||||||
warnings |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private inline fun configureParameters(project: Project, fn: Parameters.() -> Unit) { |
|
||||||
getExistingServiceRegistration<ConfigurationProblemReporterService, Parameters>(project) |
|
||||||
.parameters.fn() |
|
||||||
} |
|
||||||
|
|
||||||
fun reportWarning(project: Project, message: String) { |
|
||||||
configureParameters(project) { warnings.add(message) } |
|
||||||
} |
|
||||||
|
|
||||||
fun registerUnsupportedPluginProvider(project: Project, unsupportedPlugin: Provider<SubpluginArtifact?>) { |
|
||||||
configureParameters(project) { |
|
||||||
unsupportedPluginWarningProviders.add(unsupportedPlugin.map { unsupportedCompiler -> |
|
||||||
unsupportedCompiler?.groupId?.let { createWarningAboutNonCompatibleCompiler(it) } |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.internal.service |
|
||||||
|
|
||||||
import org.gradle.api.Project |
|
||||||
import org.gradle.api.provider.MapProperty |
|
||||||
import org.gradle.api.services.BuildServiceParameters |
|
||||||
import org.jetbrains.compose.experimental.internal.SUPPORTED_NATIVE_CACHE_KIND_PROPERTIES |
|
||||||
import org.jetbrains.compose.internal.utils.loadProperties |
|
||||||
import org.jetbrains.compose.internal.utils.localPropertiesFile |
|
||||||
|
|
||||||
internal abstract class GradlePropertySnapshotService : AbstractComposeMultiplatformBuildService<GradlePropertySnapshotService.Parameters>() { |
|
||||||
interface Parameters : BuildServiceParameters { |
|
||||||
val gradlePropertiesCacheKindSnapshot: MapProperty<String, String> |
|
||||||
val localPropertiesCacheKindSnapshot: MapProperty<String, String> |
|
||||||
} |
|
||||||
|
|
||||||
internal val gradleProperties: Map<String, String> = parameters.gradlePropertiesCacheKindSnapshot.get() |
|
||||||
internal val localProperties: Map<String, String> = parameters.localPropertiesCacheKindSnapshot.get() |
|
||||||
|
|
||||||
companion object { |
|
||||||
fun init(project: Project) { |
|
||||||
registerServiceIfAbsent<GradlePropertySnapshotService, Parameters>(project) { |
|
||||||
// WORKAROUND! Call getter at least once, because of Issue: https://github.com/gradle/gradle/issues/27099 |
|
||||||
gradlePropertiesCacheKindSnapshot |
|
||||||
localPropertiesCacheKindSnapshot |
|
||||||
initParams(project) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun getInstance(project: Project): GradlePropertySnapshotService = |
|
||||||
getExistingServiceRegistration<GradlePropertySnapshotService, Parameters>(project).service.get() |
|
||||||
|
|
||||||
private fun Parameters.initParams(project: Project) { |
|
||||||
// we want to record original properties (explicitly set by a user) |
|
||||||
// before we possibly change them in configureNativeCompilerCaching.kt |
|
||||||
val rootProject = project.rootProject |
|
||||||
val localProperties = loadProperties(rootProject.localPropertiesFile) |
|
||||||
for (cacheKindProperty in SUPPORTED_NATIVE_CACHE_KIND_PROPERTIES) { |
|
||||||
rootProject.findProperty(cacheKindProperty)?.toString()?.let { value -> |
|
||||||
gradlePropertiesCacheKindSnapshot.put(cacheKindProperty, value) |
|
||||||
} |
|
||||||
localProperties[cacheKindProperty]?.toString()?.let { value -> |
|
||||||
localPropertiesCacheKindSnapshot.put(cacheKindProperty, value) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,36 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2023 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.internal.utils |
|
||||||
|
|
||||||
import org.gradle.api.Project |
|
||||||
import org.jetbrains.compose.internal.service.GradlePropertySnapshotService |
|
||||||
|
|
||||||
/** |
|
||||||
* Reads Kotlin Gradle plugin properties. |
|
||||||
* |
|
||||||
* Kotlin Gradle plugin supports reading property from two sources: |
|
||||||
* 1. Gradle properties. Normally located in gradle.properties file, |
|
||||||
* but can also be provided via command-line, <GRADLE_HOME>/gradle.properties |
|
||||||
* or can be set via Gradle API. |
|
||||||
* 2. local.properties file. local.properties file is not supported by Gradle out-of-the-box. |
|
||||||
* Nevertheless, it became a widespread convention. |
|
||||||
*/ |
|
||||||
internal abstract class KGPPropertyProvider { |
|
||||||
abstract fun valueOrNull(propertyName: String): String? |
|
||||||
abstract val location: String |
|
||||||
|
|
||||||
class GradleProperties(private val project: Project) : KGPPropertyProvider() { |
|
||||||
override fun valueOrNull(propertyName: String): String? = |
|
||||||
GradlePropertySnapshotService.getInstance(project).gradleProperties[propertyName] |
|
||||||
override val location: String = "gradle.properties" |
|
||||||
} |
|
||||||
|
|
||||||
class LocalProperties(private val project: Project) : KGPPropertyProvider() { |
|
||||||
override fun valueOrNull(propertyName: String): String? = |
|
||||||
GradlePropertySnapshotService.getInstance(project).localProperties[propertyName] |
|
||||||
override val location: String = "local.properties" |
|
||||||
} |
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
package org.jetbrains.compose.test.tests.integration |
|
||||||
|
|
||||||
import org.jetbrains.compose.createWarningAboutNonCompatibleCompiler |
|
||||||
import org.jetbrains.compose.test.utils.GradlePluginTestBase |
|
||||||
import org.jetbrains.compose.test.utils.TestProjects |
|
||||||
import org.jetbrains.compose.test.utils.checks |
|
||||||
import org.junit.jupiter.api.Test |
|
||||||
|
|
||||||
class UnsupportedCompilerPluginWarningTest : GradlePluginTestBase() { |
|
||||||
|
|
||||||
private val androidxComposeCompilerGroupId = "androidx.compose.compiler" |
|
||||||
private val androidxComposeCompilerPlugin = "$androidxComposeCompilerGroupId:compiler:1.4.8" |
|
||||||
|
|
||||||
private fun testCustomCompilerUnsupportedPlatformsWarning( |
|
||||||
platforms: String, |
|
||||||
warningIsExpected: Boolean |
|
||||||
) { |
|
||||||
testProject( |
|
||||||
TestProjects.customCompilerUnsupportedPlatformsWarning, defaultTestEnvironment.copy( |
|
||||||
kotlinVersion = "1.8.22", |
|
||||||
composeCompilerPlugin = "\"$androidxComposeCompilerPlugin\"", |
|
||||||
) |
|
||||||
).apply { |
|
||||||
// repeat twice to check that configuration cache hit does not affect the result |
|
||||||
repeat(2) { |
|
||||||
gradle("-Pplatforms=$platforms").checks { |
|
||||||
val warning = createWarningAboutNonCompatibleCompiler(androidxComposeCompilerGroupId) |
|
||||||
if (warningIsExpected) { |
|
||||||
check.logContainsOnce(warning) |
|
||||||
} else { |
|
||||||
check.logDoesntContain(warning) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
fun testJs() { |
|
||||||
testCustomCompilerUnsupportedPlatformsWarning("js", warningIsExpected = true) |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
fun testIos() { |
|
||||||
testCustomCompilerUnsupportedPlatformsWarning("ios", warningIsExpected = true) |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
fun testJvm() { |
|
||||||
testCustomCompilerUnsupportedPlatformsWarning("jvm", warningIsExpected = false) |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue