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 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 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
|
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) {
|
object ResourceMayNotBePublishedForTarget : ToolingDiagnosticFactory(ERROR) {
|
||||||
operator fun invoke(targetName: String) = build(
|
operator fun invoke(targetName: String) = build(
|
||||||
"""
|
"""
|
||||||
|
|||||||
+6
@@ -29,6 +29,12 @@ interface KotlinTargetResourcesPublication {
|
|||||||
relativeResourcePlacement: Provider<File>,
|
relativeResourcePlacement: Provider<File>,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun publishInAndroidAssets(
|
||||||
|
target: KotlinAndroidTarget,
|
||||||
|
resourcePathForSourceSet: (KotlinSourceSet) -> (ResourceRoot),
|
||||||
|
relativeResourcePlacement: Provider<File>,
|
||||||
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTENSION_NAME = "multiplatformResourcesPublication"
|
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.KotlinNativeTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
|
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
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.js.ir.KotlinJsIrTarget
|
||||||
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||||
@@ -36,10 +37,14 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
|||||||
|
|
||||||
private val targetsThatSupportPublication = listOf(
|
private val targetsThatSupportPublication = listOf(
|
||||||
KotlinJvmTarget::class,
|
KotlinJvmTarget::class,
|
||||||
|
KotlinAndroidTarget::class,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val targetToResourcesMap: MutableMap<KotlinTarget, TargetResources> = mutableMapOf()
|
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 targetResourcesSubscribers: MutableMap<KotlinTarget, MutableList<(TargetResources) -> (Unit)>> = mutableMapOf()
|
||||||
|
private val androidTargetAssetsSubscribers: MutableMap<KotlinAndroidTarget, MutableList<(TargetResources) -> (Unit)>> = mutableMapOf()
|
||||||
|
|
||||||
internal fun subscribeOnPublishResources(
|
internal fun subscribeOnPublishResources(
|
||||||
target: KotlinTarget,
|
target: KotlinTarget,
|
||||||
@@ -49,9 +54,19 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
|||||||
targetResourcesSubscribers.getOrPut(target, { mutableListOf() }).add(notify)
|
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 {
|
override fun canPublishResources(target: KotlinTarget): Boolean {
|
||||||
if (targetsThatSupportPublication.none { it.isInstance(target) }) return false
|
if (targetsThatSupportPublication.none { it.isInstance(target) }) return false
|
||||||
|
if (target is KotlinAndroidTarget) {
|
||||||
|
return AndroidGradlePluginVersion.current >= KotlinAndroidTargetResourcesPublication.MIN_AGP_VERSION
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +93,25 @@ internal abstract class KotlinTargetResourcesPublicationImpl @Inject constructor
|
|||||||
notify(resources)
|
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 {
|
internal companion object {
|
||||||
const val MULTIPLATFORM_RESOURCES_DIRECTORY = "kotlin-multiplatform-resources"
|
const val MULTIPLATFORM_RESOURCES_DIRECTORY = "kotlin-multiplatform-resources"
|
||||||
}
|
}
|
||||||
|
|||||||
+68
@@ -5,12 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.unitTests
|
package org.jetbrains.kotlin.gradle.unitTests
|
||||||
|
|
||||||
|
import com.android.build.gradle.LibraryExtension
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.internal.project.ProjectInternal
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
|
||||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.ToolingDiagnosticFactory
|
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.KotlinTargetResourcesPublication
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension
|
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension
|
||||||
import org.jetbrains.kotlin.gradle.util.assertContainsDiagnostic
|
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
|
@Test
|
||||||
fun `test publication callback - before and after resources publication`() {
|
fun `test publication callback - before and after resources publication`() {
|
||||||
val project = buildProjectWithMPP {
|
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
|
@Test
|
||||||
fun `test publication - reports a diagnostic when publishing multiple times per target`() {
|
fun `test publication - reports a diagnostic when publishing multiple times per target`() {
|
||||||
val project = buildProjectWithMPP {
|
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(
|
private fun testCallbacksAfterApiCall(
|
||||||
callback: ((Unit) -> Unit) -> Unit,
|
callback: ((Unit) -> Unit) -> Unit,
|
||||||
apiCall: (Unit) -> Unit,
|
apiCall: (Unit) -> Unit,
|
||||||
@@ -125,6 +168,17 @@ class KotlinTargetResourcesPublicationImplTests {
|
|||||||
assertContainsDiagnostic(diagnostic)
|
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) {
|
private fun Project.publishFakeResources(target: KotlinTarget) {
|
||||||
project.multiplatformExtension.resourcesPublicationExtension?.publishResourcesAsKotlinComponent(
|
project.multiplatformExtension.resourcesPublicationExtension?.publishResourcesAsKotlinComponent(
|
||||||
target,
|
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