From 098cfae957275f51e20a6514d2b0295e3efd82f2 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Thu, 9 Mar 2023 12:59:13 +0100 Subject: [PATCH] [Gradle] Implement Android DSL for choosing KotlinTargetHierarchy.ModuleName KT-34662 --- .../applyKotlinTargetHierarchy.kt | 8 ++- .../targets/android/KotlinAndroidTarget.kt | 8 +-- .../KotlinAndroidTargetVariantTypeDsl.kt | 33 +++++++----- ...tlinAndroidTargetVariantTypeDslImplTest.kt | 54 +++++++++++++++++++ .../KotlinAndroidTargetVariantTypeDslTest.kt | 31 ----------- 5 files changed, 83 insertions(+), 51 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslImplTest.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslTest.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt index c2fe490679c..622947fbb0a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/applyKotlinTargetHierarchy.kt @@ -8,6 +8,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy import org.gradle.api.DomainObjectCollection import org.gradle.api.NamedDomainObjectContainer import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginLifecycle.Stage +import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginLifecycle.Stage.Companion.upTo import org.jetbrains.kotlin.gradle.plugin.mpp.internal internal fun applyKotlinTargetHierarchy( @@ -20,8 +22,10 @@ internal fun applyKotlinTargetHierarchy( .all { target -> target.compilations.all forCompilation@{ compilation -> target.project.kotlinMultiplatformPluginLifecycle.launch { - val hierarchy = hierarchyDescriptor.buildKotlinTargetHierarchy(compilation) ?: return@launch - applyKotlinTargetHierarchy(hierarchy, compilation, sourceSets) + withRestrictedStages(upTo(Stage.FinaliseRefinesEdges)) { + val hierarchy = hierarchyDescriptor.buildKotlinTargetHierarchy(compilation) ?: return@withRestrictedStages + applyKotlinTargetHierarchy(hierarchy, compilation, sourceSets) + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt index 803c20af7d5..ad4818d5581 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt @@ -17,8 +17,8 @@ import org.gradle.api.attributes.AttributeContainer import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes -import org.jetbrains.kotlin.gradle.targets.android.InternalKotlinAndroidTargetVariantTypeDsl import org.jetbrains.kotlin.gradle.targets.android.KotlinAndroidTargetVariantTypeDsl +import org.jetbrains.kotlin.gradle.targets.android.KotlinAndroidTargetVariantTypeDslImpl import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.gradle.utils.forAllAndroidVariants import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName @@ -41,13 +41,13 @@ abstract class KotlinAndroidTarget @Inject constructor( project.container(KotlinJvmAndroidCompilation::class.java) @ExperimentalKotlinGradlePluginApi - val main: KotlinAndroidTargetVariantTypeDsl = InternalKotlinAndroidTargetVariantTypeDsl(project) + val main: KotlinAndroidTargetVariantTypeDsl = KotlinAndroidTargetVariantTypeDslImpl(project) @ExperimentalKotlinGradlePluginApi - val unitTest: KotlinAndroidTargetVariantTypeDsl = InternalKotlinAndroidTargetVariantTypeDsl(project) + val unitTest: KotlinAndroidTargetVariantTypeDsl = KotlinAndroidTargetVariantTypeDslImpl(project) @ExperimentalKotlinGradlePluginApi - val instrumentedTest: KotlinAndroidTargetVariantTypeDsl = InternalKotlinAndroidTargetVariantTypeDsl(project) + val instrumentedTest: KotlinAndroidTargetVariantTypeDsl = KotlinAndroidTargetVariantTypeDslImpl(project) /** Names of the Android library variants that should be published from the target's project within the default publications which are * set up if the `maven-publish` Gradle plugin is applied. diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTargetVariantTypeDsl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTargetVariantTypeDsl.kt index f8273b92976..58d93a1e4b6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTargetVariantTypeDsl.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTargetVariantTypeDsl.kt @@ -5,25 +5,30 @@ package org.jetbrains.kotlin.gradle.targets.android +import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.provider.Property -import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginLifecycle.Stage +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginLifecycle.Stage.FinaliseDsl +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetHierarchy import org.jetbrains.kotlin.gradle.plugin.newLifecycleAwareProperty -sealed class KotlinAndroidTargetVariantTypeDsl { - abstract val kotlinModuleName: Property -} - -internal val KotlinAndroidTargetVariantTypeDsl.internal: InternalKotlinAndroidTargetVariantTypeDsl - get() = when (this) { - is InternalKotlinAndroidTargetVariantTypeDsl -> this +@ExperimentalKotlinGradlePluginApi +interface KotlinAndroidTargetVariantTypeDsl { + interface TargetHierarchyDsl { + val module: Property } -internal class InternalKotlinAndroidTargetVariantTypeDsl( - val project: Project, -) : KotlinAndroidTargetVariantTypeDsl() { + val targetHierarchy: TargetHierarchyDsl + fun targetHierarchy(configure: TargetHierarchyDsl.() -> Unit): Unit = targetHierarchy.configure() + fun targetHierarchy(configure: Action<@UnsafeVariance TargetHierarchyDsl>): Unit = configure.execute(targetHierarchy) +} - override val kotlinModuleName: Property by project.newLifecycleAwareProperty( - finaliseIn = Stage.BeforeFinaliseRefinesEdges - ) + +internal class KotlinAndroidTargetVariantTypeDslImpl(private val project: Project) : KotlinAndroidTargetVariantTypeDsl { + internal inner class TargetHierarchyDslImpl : KotlinAndroidTargetVariantTypeDsl.TargetHierarchyDsl { + override val module: Property by project.newLifecycleAwareProperty(FinaliseDsl) + } + + override val targetHierarchy: KotlinAndroidTargetVariantTypeDsl.TargetHierarchyDsl = TargetHierarchyDslImpl() } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslImplTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslImplTest.kt new file mode 100644 index 00000000000..f03b1325492 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslImplTest.kt @@ -0,0 +1,54 @@ +/* + * 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 + +import junit.framework.TestCase.assertNull +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue +import org.jetbrains.kotlin.gradle.plugin.currentMultiplatformPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.kotlinMultiplatformPluginLifecycle +import org.jetbrains.kotlin.gradle.targets.android.KotlinAndroidTargetVariantTypeDslImpl +import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP +import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFails + +class KotlinAndroidTargetVariantTypeDslImplTest { + private val project = buildProjectWithMPP() + private val dsl = KotlinAndroidTargetVariantTypeDslImpl(project) + + + @Test + fun `test - module - not set`() = project.runLifecycleAwareTest { + project.kotlinMultiplatformPluginLifecycle.launch { + assertNull(dsl.targetHierarchy.module.orNull) + assertNull(dsl.targetHierarchy.module.awaitFinalValue()) + } + } + + @Test + fun `test - module - can be set in users afterEvaluate`() = project.runLifecycleAwareTest { + afterEvaluate { dsl.targetHierarchy.module.set(KotlinTargetHierarchy.ModuleName("x")) } + dsl.targetHierarchy.module.set(KotlinTargetHierarchy.ModuleName("-set-before-after-evaluate-")) + assertEquals("x", dsl.targetHierarchy.module.awaitFinalValue()?.name) + assertEquals(KotlinMultiplatformPluginLifecycle.Stage.FinaliseDsl, currentMultiplatformPluginLifecycle().stage) + } + + @Test + fun `test - module - cannot be set after FinaliseDsl`() = project.runLifecycleAwareTest { + launchInStage(KotlinMultiplatformPluginLifecycle.Stage.BeforeFinaliseDsl) { + dsl.targetHierarchy.module.set(KotlinTargetHierarchy.ModuleName("x")) + } + + launchInStage(KotlinMultiplatformPluginLifecycle.Stage.FinaliseDsl) { + assertFails { dsl.targetHierarchy.module.set(KotlinTargetHierarchy.ModuleName("y")) } + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslTest.kt deleted file mode 100644 index fd75d7ff56e..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/KotlinAndroidTargetVariantTypeDslTest.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 - -import junit.framework.TestCase.assertNull -import org.jetbrains.kotlin.gradle.plugin.awaitFinalValue -import org.jetbrains.kotlin.gradle.plugin.kotlinMultiplatformPluginLifecycle -import org.jetbrains.kotlin.gradle.targets.android.InternalKotlinAndroidTargetVariantTypeDsl -import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP -import org.junit.Test - -class KotlinAndroidTargetVariantTypeDslTest { - private val project = buildProjectWithMPP() - - - @Test - fun `test - targetHierarchyModuleName - not set`() { - val dsl = InternalKotlinAndroidTargetVariantTypeDsl(project) - project.kotlinMultiplatformPluginLifecycle.launch { - assertNull(dsl.kotlinModuleName.orNull) - assertNull(dsl.kotlinModuleName.awaitFinalValue()) - } - - project.evaluate() - } -} \ No newline at end of file