Add an API for KotlinAndroidTarget to publish assets
^KT-65540
This commit is contained in:
committed by
Space Team
parent
bf6a82fdc1
commit
43a4fd5ddf
@@ -911,6 +911,7 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/resources
|
||||
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 fun canPublishResources (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTarget;)Z
|
||||
public abstract fun publishInAndroidAssets (Lorg/jetbrains/kotlin/gradle/plugin/mpp/KotlinAndroidTarget;Lkotlin/jvm/functions/Function1;Lorg/gradle/api/provider/Provider;)V
|
||||
public abstract fun publishResourcesAsKotlinComponent (Lorg/jetbrains/kotlin/gradle/plugin/KotlinTarget;Lkotlin/jvm/functions/Function1;Lorg/gradle/api/provider/Provider;)V
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -776,6 +776,16 @@ object KotlinToolingDiagnostics {
|
||||
)
|
||||
}
|
||||
|
||||
object AssetsPublishedMoreThanOncePerTarget : ToolingDiagnosticFactory(ERROR) {
|
||||
operator fun invoke() = build(
|
||||
"""
|
||||
Only one assets publication per android target is allowed.
|
||||
|
||||
$resourcesBugReportRequest
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
object ResourceMayNotBePublishedForTarget : ToolingDiagnosticFactory(ERROR) {
|
||||
operator fun invoke(targetName: String) = build(
|
||||
"""
|
||||
|
||||
+6
@@ -29,6 +29,12 @@ interface KotlinTargetResourcesPublication {
|
||||
relativeResourcePlacement: Provider<File>,
|
||||
)
|
||||
|
||||
fun publishInAndroidAssets(
|
||||
target: KotlinAndroidTarget,
|
||||
resourcePathForSourceSet: (KotlinSourceSet) -> (ResourceRoot),
|
||||
relativeResourcePlacement: Provider<File>,
|
||||
)
|
||||
|
||||
companion object {
|
||||
const val EXTENSION_NAME = "multiplatformResourcesPublication"
|
||||
}
|
||||
|
||||
+34
@@ -18,6 +18,7 @@ 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.plugin.mpp.resources.publication.KotlinAndroidTargetResourcesPublication
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
@@ -36,10 +37,14 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
||||
|
||||
private val targetsThatSupportPublication = listOf(
|
||||
KotlinJvmTarget::class,
|
||||
KotlinAndroidTarget::class,
|
||||
)
|
||||
|
||||
private val targetToResourcesMap: MutableMap<KotlinTarget, TargetResources> = mutableMapOf()
|
||||
private val androidTargetAssetsMap: MutableMap<KotlinAndroidTarget, TargetResources> = mutableMapOf()
|
||||
|
||||
private val targetResourcesSubscribers: MutableMap<KotlinTarget, MutableList<(TargetResources) -> (Unit)>> = mutableMapOf()
|
||||
private val androidTargetAssetsSubscribers: MutableMap<KotlinAndroidTarget, MutableList<(TargetResources) -> (Unit)>> = mutableMapOf()
|
||||
|
||||
internal fun subscribeOnPublishResources(
|
||||
target: KotlinTarget,
|
||||
@@ -49,9 +54,19 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
||||
targetResourcesSubscribers.getOrPut(target, { mutableListOf() }).add(notify)
|
||||
}
|
||||
|
||||
internal fun subscribeOnAndroidPublishAssets(
|
||||
target: KotlinAndroidTarget,
|
||||
notify: (TargetResources) -> (Unit),
|
||||
) {
|
||||
androidTargetAssetsMap[target]?.let(notify)
|
||||
androidTargetAssetsSubscribers.getOrPut(target, { mutableListOf() }).add(notify)
|
||||
}
|
||||
|
||||
override fun canPublishResources(target: KotlinTarget): Boolean {
|
||||
if (targetsThatSupportPublication.none { it.isInstance(target) }) return false
|
||||
if (target is KotlinAndroidTarget) {
|
||||
return AndroidGradlePluginVersion.current >= KotlinAndroidTargetResourcesPublication.MIN_AGP_VERSION
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -78,6 +93,25 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
||||
notify(resources)
|
||||
}
|
||||
}
|
||||
|
||||
override fun publishInAndroidAssets(
|
||||
target: KotlinAndroidTarget,
|
||||
resourcePathForSourceSet: (KotlinSourceSet) -> (KotlinTargetResourcesPublication.ResourceRoot),
|
||||
relativeResourcePlacement: Provider<File>,
|
||||
) {
|
||||
if (androidTargetAssetsMap[target] != null) {
|
||||
target.project.reportDiagnostic(KotlinToolingDiagnostics.AssetsPublishedMoreThanOncePerTarget())
|
||||
}
|
||||
val resources = TargetResources(
|
||||
resourcePathForSourceSet = resourcePathForSourceSet,
|
||||
relativeResourcePlacement = relativeResourcePlacement,
|
||||
)
|
||||
androidTargetAssetsMap[target] = resources
|
||||
androidTargetAssetsSubscribers[target].orEmpty().forEach { notify ->
|
||||
notify(resources)
|
||||
}
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
const val MULTIPLATFORM_RESOURCES_DIRECTORY = "kotlin-multiplatform-resources"
|
||||
}
|
||||
|
||||
+68
@@ -5,12 +5,14 @@
|
||||
|
||||
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.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.resourcesPublicationExtension
|
||||
import org.jetbrains.kotlin.gradle.util.assertContainsDiagnostic
|
||||
@@ -42,6 +44,21 @@ class KotlinTargetResourcesPublicationImplTests {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test assets callback - after resources publication`() {
|
||||
val project = mppProjectWithAndroidTarget()
|
||||
val target = project.multiplatformExtension.androidTarget()
|
||||
|
||||
testCallbacksAfterApiCall(
|
||||
callback = { back ->
|
||||
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnAndroidPublishAssets(target) {
|
||||
back(Unit)
|
||||
}
|
||||
},
|
||||
apiCall = { project.publishFakeAssets(target) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test publication callback - before and after resources publication`() {
|
||||
val project = buildProjectWithMPP {
|
||||
@@ -61,6 +78,21 @@ class KotlinTargetResourcesPublicationImplTests {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test assets callback - before and after resources publication`() {
|
||||
val project = mppProjectWithAndroidTarget()
|
||||
val target = project.multiplatformExtension.androidTarget()
|
||||
|
||||
testCallbacksBeforeAndAfterApiCall(
|
||||
callback = { back ->
|
||||
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnAndroidPublishAssets(target) {
|
||||
back(Unit)
|
||||
}
|
||||
},
|
||||
apiCall = { project.publishFakeAssets(target) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test publication - reports a diagnostic when publishing multiple times per target`() {
|
||||
val project = buildProjectWithMPP {
|
||||
@@ -76,6 +108,17 @@ class KotlinTargetResourcesPublicationImplTests {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test assets - reports a diagnostic when publishing multiple times per target`() {
|
||||
val project = mppProjectWithAndroidTarget()
|
||||
val target = project.multiplatformExtension.androidTarget()
|
||||
|
||||
project.testMultipleApiCallsEmitDiagnostic(
|
||||
apiCall = { project.publishFakeAssets(target) },
|
||||
diagnostic = KotlinToolingDiagnostics.AssetsPublishedMoreThanOncePerTarget,
|
||||
)
|
||||
}
|
||||
|
||||
private fun testCallbacksAfterApiCall(
|
||||
callback: ((Unit) -> Unit) -> Unit,
|
||||
apiCall: (Unit) -> Unit,
|
||||
@@ -125,6 +168,17 @@ class KotlinTargetResourcesPublicationImplTests {
|
||||
assertContainsDiagnostic(diagnostic)
|
||||
}
|
||||
|
||||
private fun mppProjectWithAndroidTarget(): ProjectInternal {
|
||||
val project = buildProjectWithMPP {
|
||||
plugins.apply("com.android.library")
|
||||
kotlin {
|
||||
androidTarget()
|
||||
}
|
||||
}
|
||||
(project.extensions.getByName("android") as LibraryExtension).compileSdk = 30
|
||||
return project
|
||||
}
|
||||
|
||||
private fun Project.publishFakeResources(target: KotlinTarget) {
|
||||
project.multiplatformExtension.resourcesPublicationExtension?.publishResourcesAsKotlinComponent(
|
||||
target,
|
||||
@@ -139,4 +193,18 @@ class KotlinTargetResourcesPublicationImplTests {
|
||||
)
|
||||
}
|
||||
|
||||
private fun Project.publishFakeAssets(target: KotlinAndroidTarget) {
|
||||
project.multiplatformExtension.resourcesPublicationExtension?.publishInAndroidAssets(
|
||||
target,
|
||||
resourcePathForSourceSet = {
|
||||
KotlinTargetResourcesPublication.ResourceRoot(
|
||||
project.provider { File(it.name) },
|
||||
emptyList(),
|
||||
emptyList(),
|
||||
)
|
||||
},
|
||||
relativeResourcePlacement = project.provider { File("test") },
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user