From 74628c03947d90839487081ba666da6237069422 Mon Sep 17 00:00:00 2001 From: Timofey Solonin Date: Wed, 14 Feb 2024 15:10:38 +0100 Subject: [PATCH] Register multiplatform publication extension ^KT-65540 --- .../api/kotlin-gradle-plugin-annotations.api | 3 ++ .../gradle/ComposeKotlinGradlePluginApi.kt | 12 +++++ .../build.gradle.kts | 1 + .../api/kotlin-gradle-plugin.api | 5 ++ .../kotlin-gradle-plugin/build.gradle.kts | 2 + .../KotlinTargetResourcesPublication.kt | 28 ++++++++++ .../KotlinTargetResourcesPublicationImpl.kt | 52 +++++++++++++++++++ .../resourcesPublicationExtension.kt | 25 +++++++++ .../plugin/registerKotlinPluginExtensions.kt | 2 + ...esourcesPublicationExtensionActionTests.kt | 41 +++++++++++++++ .../kotlin/gradle/util/buildProject.kt | 4 ++ 11 files changed, 175 insertions(+) create mode 100644 libraries/tools/kotlin-gradle-plugin-annotations/src/main/kotlin/org/jetbrains/kotlin/gradle/ComposeKotlinGradlePluginApi.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublicationImpl.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/resourcesPublicationExtension.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/RegisterMultiplatformResourcesPublicationExtensionActionTests.kt diff --git a/libraries/tools/kotlin-gradle-plugin-annotations/api/kotlin-gradle-plugin-annotations.api b/libraries/tools/kotlin-gradle-plugin-annotations/api/kotlin-gradle-plugin-annotations.api index f06ca422ba2..9fbebdba9b1 100644 --- a/libraries/tools/kotlin-gradle-plugin-annotations/api/kotlin-gradle-plugin-annotations.api +++ b/libraries/tools/kotlin-gradle-plugin-annotations/api/kotlin-gradle-plugin-annotations.api @@ -1,3 +1,6 @@ +public abstract interface annotation class org/jetbrains/kotlin/gradle/ComposeKotlinGradlePluginApi : java/lang/annotation/Annotation { +} + public final class org/jetbrains/kotlin/gradle/DeprecatedTargetPresetApiKt { public static final field PRESETS_API_IS_DEPRECATED_MESSAGE Ljava/lang/String; public static final field PRESETS_DEPRECATION_MESSAGE_SUFFIX Ljava/lang/String; diff --git a/libraries/tools/kotlin-gradle-plugin-annotations/src/main/kotlin/org/jetbrains/kotlin/gradle/ComposeKotlinGradlePluginApi.kt b/libraries/tools/kotlin-gradle-plugin-annotations/src/main/kotlin/org/jetbrains/kotlin/gradle/ComposeKotlinGradlePluginApi.kt new file mode 100644 index 00000000000..c0d2c386ed8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-annotations/src/main/kotlin/org/jetbrains/kotlin/gradle/ComposeKotlinGradlePluginApi.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2010-2022 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 + +@RequiresOptIn( + message = "This API is not intended to be used outside of the Kotlin Gradle Plugin and Compose Multiplatform Plugin integration", + level = RequiresOptIn.Level.ERROR +) +annotation class ComposeKotlinGradlePluginApi diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts index faa18e88fa5..235c200909e 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts @@ -13,6 +13,7 @@ testsJar() kotlin.sourceSets.all { languageSettings.optIn("org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi") + languageSettings.optIn("org.jetbrains.kotlin.gradle.ComposeKotlinGradlePluginApi") } val kotlinGradlePluginTest = project(":kotlin-gradle-plugin").sourceSets.named("test").map { it.output } diff --git a/libraries/tools/kotlin-gradle-plugin/api/kotlin-gradle-plugin.api b/libraries/tools/kotlin-gradle-plugin/api/kotlin-gradle-plugin.api index 8cc707cf532..f0c953046da 100644 --- a/libraries/tools/kotlin-gradle-plugin/api/kotlin-gradle-plugin.api +++ b/libraries/tools/kotlin-gradle-plugin/api/kotlin-gradle-plugin.api @@ -907,6 +907,11 @@ public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotli public static final fun sourcesJarTask (Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget;Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinCompilation;)Lorg/gradle/api/tasks/TaskProvider; } +public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication { + public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication$Companion; + public static final field EXTENSION_NAME Ljava/lang/String; +} + public abstract class org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier { } diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts index ac7d8b2493c..d3867e8d9a3 100644 --- a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts @@ -23,6 +23,7 @@ kotlin { "org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi", "org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi", "org.jetbrains.kotlin.buildtools.api.ExperimentalBuildToolsApi", + "org.jetbrains.kotlin.gradle.ComposeKotlinGradlePluginApi", ) ) } @@ -30,6 +31,7 @@ kotlin { apiValidation { publicMarkers.add("org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi") + publicMarkers.add("org.jetbrains.kotlin.gradle.ComposeKotlinGradlePluginApi") publicMarkers.add("org.jetbrains.kotlin.gradle.dsl.KotlinGradlePluginPublicDsl") nonPublicMarkers.add("org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi") additionalSourceSets.add("common") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication.kt new file mode 100644 index 00000000000..eb98edce6bd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication.kt @@ -0,0 +1,28 @@ +/* + * 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.provider.Provider +import org.jetbrains.kotlin.gradle.ComposeKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget +import java.io.File + +@ComposeKotlinGradlePluginApi +interface KotlinTargetResourcesPublication { + + data class ResourceRoot( + val resourcesBaseDirectory: Provider, + val includes: List, + val excludes: List, + ) + + companion object { + const val EXTENSION_NAME = "multiplatformResourcesPublication" + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublicationImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublicationImpl.kt new file mode 100644 index 00000000000..09da9452fd2 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublicationImpl.kt @@ -0,0 +1,52 @@ +/* + * 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.api.artifacts.Configuration +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.TaskProvider +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle +import org.jetbrains.kotlin.gradle.plugin.launchInStage +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName +import org.jetbrains.kotlin.gradle.plugin.mpp.internal +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget +import org.jetbrains.kotlin.gradle.tasks.locateTask +import org.jetbrains.kotlin.gradle.tasks.registerTask +import java.io.File +import javax.inject.Inject + +internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor( + val project: Project +) : KotlinTargetResourcesPublication { + + internal data class TargetResources( + val resourcePathForSourceSet: (KotlinSourceSet) -> (KotlinTargetResourcesPublication.ResourceRoot), + val relativeResourcePlacement: Provider, + ) + + private val targetToResourcesMap: MutableMap = mutableMapOf() + + private val targetResourcesSubscribers: MutableMap (Unit)>> = mutableMapOf() + + internal fun subscribeOnPublishResources( + target: KotlinTarget, + notify: (TargetResources) -> (Unit), + ) { + targetToResourcesMap[target]?.let(notify) + targetResourcesSubscribers.getOrPut(target, { mutableListOf() }).add(notify) + } + + + internal companion object { + const val MULTIPLATFORM_RESOURCES_DIRECTORY = "kotlin-multiplatform-resources" + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/resourcesPublicationExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/resourcesPublicationExtension.kt new file mode 100644 index 00000000000..230cd18e9fd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/resources/resourcesPublicationExtension.kt @@ -0,0 +1,25 @@ +/* + * 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.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupAction +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider +import org.jetbrains.kotlin.gradle.plugin.extraProperties +import org.jetbrains.kotlin.gradle.utils.getOrPut + +internal val KotlinMultiplatformExtension.resourcesPublicationExtension: KotlinTargetResourcesPublicationImpl? + get() { + if (!project.kotlinPropertiesProvider.mppResourcesPublication) return null + return project.extraProperties.getOrPut(KotlinTargetResourcesPublication.EXTENSION_NAME) { + project.objects.newInstance(KotlinTargetResourcesPublicationImpl::class.java, project) + } + } + +internal val RegisterMultiplatformResourcesPublicationExtensionAction = KotlinProjectSetupAction { + multiplatformExtension.resourcesPublicationExtension +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt index fb1a638e6fa..8261880bcd8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.apple.AddBuildListenerForXCodeSetupAction import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.* import org.jetbrains.kotlin.gradle.plugin.mpp.internal.DeprecatedMppGradlePropertiesMigrationSetupAction +import org.jetbrains.kotlin.gradle.plugin.mpp.resources.RegisterMultiplatformResourcesPublicationExtensionAction import org.jetbrains.kotlin.gradle.plugin.sources.KotlinMultiplatformSourceSetSetupAction import org.jetbrains.kotlin.gradle.plugin.sources.LanguageSettingsSetupAction import org.jetbrains.kotlin.gradle.plugin.statistics.MultiplatformBuildStatsReportSetupAction @@ -78,6 +79,7 @@ internal fun Project.registerKotlinPluginExtensions() { register(project, KotlinLLDBScriptSetupAction) register(project, ExcludeDefaultPlatformDependenciesFromKotlinNativeCompileTasks) register(project, SetupConsistentMetadataDependenciesResolution) + register(project, RegisterMultiplatformResourcesPublicationExtensionAction) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/RegisterMultiplatformResourcesPublicationExtensionActionTests.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/RegisterMultiplatformResourcesPublicationExtensionActionTests.kt new file mode 100644 index 00000000000..1545b1a4ce8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/RegisterMultiplatformResourcesPublicationExtensionActionTests.kt @@ -0,0 +1,41 @@ +/* + * 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.unitTests + +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.mpp.resources.KotlinTargetResourcesPublication +import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension +import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP +import org.jetbrains.kotlin.gradle.util.enableMppResourcesPublication +import org.jetbrains.kotlin.gradle.util.kotlin +import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest +import org.junit.Test +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +class RegisterMultiplatformResourcesPublicationExtensionActionTests { + + @Test + fun `test mppResourcesPublication toggle - prevents extension creation`() { + assertNull( + buildProjectWithMPP { + kotlin { jvm() } + enableMppResourcesPublication(false) + }.evaluate().multiplatformExtension.resourcesPublicationExtension + ) + } + + @Test + fun `test mppResourcesPublication toggle - enables extension creation`() { + assertNotNull( + buildProjectWithMPP { + kotlin { jvm() } + enableMppResourcesPublication(true) + }.evaluate().multiplatformExtension.resourcesPublicationExtension + ) + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt index 652e53b389e..8a44d709eb4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/util/buildProject.kt @@ -113,6 +113,10 @@ fun Project.enableCInteropCommonization(enabled: Boolean = true) { propertiesExtension.set(PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION, enabled.toString()) } +fun Project.enableMppResourcesPublication(enabled: Boolean = true) { + propertiesExtension.set(PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_RESOURCES_PUBLICATION, enabled.toString()) +} + fun Project.enableIntransitiveMetadataConfiguration(enabled: Boolean = true) { propertiesExtension.set(KOTLIN_MPP_ENABLE_INTRANSITIVE_METADATA_CONFIGURATION, enabled.toString()) }