Add external APIs to publish multiplatform resources in a target
^KT-65540
This commit is contained in:
committed by
Space Team
parent
4e10dcd808
commit
3dd33e5aa7
@@ -910,6 +910,8 @@ public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotli
|
|||||||
public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication {
|
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 Companion Lorg/jetbrains/kotlin/gradle/plugin/mpp/resources/KotlinTargetResourcesPublication$Companion;
|
||||||
public static final field EXTENSION_NAME Ljava/lang/String;
|
public static final field EXTENSION_NAME Ljava/lang/String;
|
||||||
|
public abstract fun canPublishResources (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTarget;)Z
|
||||||
|
public abstract fun publishResourcesAsKotlinComponent (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTarget;Lkotlin/jvm/functions/Function1;Lorg/gradle/api/provider/Provider;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier {
|
public abstract class org/jetbrains/kotlin/gradle/plugin/mpp/targetHierarchy/SourceSetTreeClassifier {
|
||||||
|
|||||||
+10
@@ -776,6 +776,16 @@ object KotlinToolingDiagnostics {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object ResourceMayNotBePublishedForTarget : ToolingDiagnosticFactory(ERROR) {
|
||||||
|
operator fun invoke(targetName: String) = build(
|
||||||
|
"""
|
||||||
|
Resources publication for target $targetName is not supported yet.
|
||||||
|
|
||||||
|
$resourcesBugReportRequest
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
object DependencyDoesNotPhysicallyExist : ToolingDiagnosticFactory(WARNING) {
|
object DependencyDoesNotPhysicallyExist : ToolingDiagnosticFactory(WARNING) {
|
||||||
operator fun invoke(dependency: File) = build(
|
operator fun invoke(dependency: File) = build(
|
||||||
"""
|
"""
|
||||||
|
|||||||
+8
@@ -21,6 +21,14 @@ interface KotlinTargetResourcesPublication {
|
|||||||
val excludes: List<String>,
|
val excludes: List<String>,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun canPublishResources(target: KotlinTarget): Boolean
|
||||||
|
|
||||||
|
fun publishResourcesAsKotlinComponent(
|
||||||
|
target: KotlinTarget,
|
||||||
|
resourcePathForSourceSet: (KotlinSourceSet) -> (ResourceRoot),
|
||||||
|
relativeResourcePlacement: Provider<File>,
|
||||||
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTENSION_NAME = "multiplatformResourcesPublication"
|
const val EXTENSION_NAME = "multiplatformResourcesPublication"
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-2
@@ -11,6 +11,8 @@ import org.gradle.api.provider.Provider
|
|||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.reportDiagnostic
|
||||||
import org.jetbrains.kotlin.gradle.plugin.launchInStage
|
import org.jetbrains.kotlin.gradle.plugin.launchInStage
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||||
@@ -32,8 +34,11 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
|||||||
val relativeResourcePlacement: Provider<File>,
|
val relativeResourcePlacement: Provider<File>,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val targetToResourcesMap: MutableMap<KotlinTarget, TargetResources> = mutableMapOf()
|
private val targetsThatSupportPublication = listOf(
|
||||||
|
KotlinJvmTarget::class,
|
||||||
|
)
|
||||||
|
|
||||||
|
private val targetToResourcesMap: MutableMap<KotlinTarget, TargetResources> = mutableMapOf()
|
||||||
private val targetResourcesSubscribers: MutableMap<KotlinTarget, MutableList<(TargetResources) -> (Unit)>> = mutableMapOf()
|
private val targetResourcesSubscribers: MutableMap<KotlinTarget, MutableList<(TargetResources) -> (Unit)>> = mutableMapOf()
|
||||||
|
|
||||||
internal fun subscribeOnPublishResources(
|
internal fun subscribeOnPublishResources(
|
||||||
@@ -45,8 +50,36 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun canPublishResources(target: KotlinTarget): Boolean {
|
||||||
|
if (targetsThatSupportPublication.none { it.isInstance(target) }) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun publishResourcesAsKotlinComponent(
|
||||||
|
target: KotlinTarget,
|
||||||
|
resourcePathForSourceSet: (KotlinSourceSet) -> (KotlinTargetResourcesPublication.ResourceRoot),
|
||||||
|
relativeResourcePlacement: Provider<File>,
|
||||||
|
) {
|
||||||
|
if (!canPublishResources(target)) {
|
||||||
|
target.project.reportDiagnostic(KotlinToolingDiagnostics.ResourceMayNotBePublishedForTarget(target.name))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (targetToResourcesMap[target] != null) {
|
||||||
|
target.project.reportDiagnostic(KotlinToolingDiagnostics.ResourcePublishedMoreThanOncePerTarget(target.name))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val resources = TargetResources(
|
||||||
|
resourcePathForSourceSet = resourcePathForSourceSet,
|
||||||
|
relativeResourcePlacement = relativeResourcePlacement,
|
||||||
|
)
|
||||||
|
targetToResourcesMap[target] = resources
|
||||||
|
targetResourcesSubscribers[target].orEmpty().forEach { notify ->
|
||||||
|
notify(resources)
|
||||||
|
}
|
||||||
|
}
|
||||||
internal companion object {
|
internal companion object {
|
||||||
const val MULTIPLATFORM_RESOURCES_DIRECTORY = "kotlin-multiplatform-resources"
|
const val MULTIPLATFORM_RESOURCES_DIRECTORY = "kotlin-multiplatform-resources"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* 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.gradle.api.Project
|
||||||
|
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.mpp.resources.KotlinTargetResourcesPublication
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.util.assertContainsDiagnostic
|
||||||
|
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||||
|
import org.jetbrains.kotlin.gradle.util.kotlin
|
||||||
|
import org.junit.Test
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class KotlinTargetResourcesPublicationImplTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test publication callback - after resources publication`() {
|
||||||
|
val project = buildProjectWithMPP {
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val target = project.multiplatformExtension.jvm()
|
||||||
|
|
||||||
|
var callbacks = 0
|
||||||
|
project.publishFakeResources(target)
|
||||||
|
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnPublishResources(
|
||||||
|
target
|
||||||
|
) {
|
||||||
|
callbacks += 1
|
||||||
|
}
|
||||||
|
assertEquals(callbacks, 1)
|
||||||
|
|
||||||
|
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnPublishResources(
|
||||||
|
target
|
||||||
|
) {
|
||||||
|
callbacks += 1
|
||||||
|
}
|
||||||
|
assertEquals(callbacks, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test publication callback - before and after resources publication`() {
|
||||||
|
val project = buildProjectWithMPP {
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val target = project.multiplatformExtension.jvm()
|
||||||
|
|
||||||
|
var callbacks = 0
|
||||||
|
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnPublishResources(
|
||||||
|
target
|
||||||
|
) {
|
||||||
|
callbacks += 1
|
||||||
|
}
|
||||||
|
project.publishFakeResources(target)
|
||||||
|
assertEquals(callbacks, 1)
|
||||||
|
|
||||||
|
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnPublishResources(
|
||||||
|
target
|
||||||
|
) {
|
||||||
|
callbacks += 1
|
||||||
|
}
|
||||||
|
assertEquals(callbacks, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test publication - reports a diagnostic when publishing multiple times per target`() {
|
||||||
|
val project = buildProjectWithMPP {
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val target = project.multiplatformExtension.jvm()
|
||||||
|
|
||||||
|
project.publishFakeResources(target)
|
||||||
|
project.publishFakeResources(target)
|
||||||
|
|
||||||
|
project.assertContainsDiagnostic(KotlinToolingDiagnostics.ResourcePublishedMoreThanOncePerTarget)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.publishFakeResources(target: KotlinTarget) {
|
||||||
|
project.multiplatformExtension.resourcesPublicationExtension?.publishResourcesAsKotlinComponent(
|
||||||
|
target,
|
||||||
|
resourcePathForSourceSet = {
|
||||||
|
KotlinTargetResourcesPublication.ResourceRoot(
|
||||||
|
project.provider { File(it.name) },
|
||||||
|
emptyList(),
|
||||||
|
emptyList(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
relativeResourcePlacement = project.provider { File("test") },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user