Publish multiplatform resources in for jvm target

^KT-65540
This commit is contained in:
Timofey Solonin
2024-02-14 11:13:30 +01:00
committed by Space Team
parent 3dd33e5aa7
commit 370799b4e3
4 changed files with 195 additions and 33 deletions
@@ -0,0 +1,38 @@
/*
* 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.publication
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupAction
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.assembleHierarchicalResources
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
internal val SetUpMultiplatformJvmResourcesPublicationAction = KotlinProjectSetupAction {
if (!kotlinPropertiesProvider.mppResourcesPublication) return@KotlinProjectSetupAction
multiplatformExtension.targets.all { target ->
if (target is KotlinJvmTarget) {
target.setUpMultiplatformResourcesAndAssets()
}
}
}
private fun KotlinJvmTarget.setUpMultiplatformResourcesAndAssets() {
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnPublishResources(
this
) { resources ->
val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
val copyResourcesTask = mainCompilation.assembleHierarchicalResources(
targetName,
resources,
)
mainCompilation.defaultSourceSet.resources.srcDir(copyResourcesTask)
}
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XcodeVersionSetupAction
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.mpp.resources.publication.SetUpMultiplatformJvmResourcesPublicationAction
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinMultiplatformSourceSetSetupAction
import org.jetbrains.kotlin.gradle.plugin.sources.LanguageSettingsSetupAction
import org.jetbrains.kotlin.gradle.plugin.statistics.MultiplatformBuildStatsReportSetupAction
@@ -82,6 +83,7 @@ internal fun Project.registerKotlinPluginExtensions() {
register(project, ExcludeDefaultPlatformDependenciesFromKotlinNativeCompileTasks)
register(project, SetupConsistentMetadataDependenciesResolution)
register(project, RegisterMultiplatformResourcesPublicationExtensionAction)
register(project, SetUpMultiplatformJvmResourcesPublicationAction)
}
}
@@ -0,0 +1,84 @@
/*
* 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.gradle.api.file.FileCollection
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
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.kotlin
import org.junit.Test
import java.io.File
class KotlinJvmTargetResourcesPublicationTests {
private val Project.expectedResourcePath get() = layout.buildDirectory.dir(
"kotlin-multiplatform-resources/assemble-hierarchically/jvm"
).get().asFile
@Test
fun `test publishing jvm resources - reflects in jvm resource directories`() {
val project = buildProjectWithMPP {
kotlin {
jvm()
}
}
project.evaluate()
project.publishFakeResources(
project.multiplatformExtension.jvm()
)
val actualSourcesDirectories = project.multiplatformExtension.jvm()
.compilations.getByName("main")
.defaultSourceSet.resources.sourceDirectories
assert(
actualSourcesDirectories.contains(project.expectedResourcePath)
) { actualSourcesDirectories.dumpPaths() }
}
@Test
fun `test publishing jvm resources - doesn't show up in resources - when there is no publication`() {
val project = buildProjectWithMPP {
kotlin {
jvm()
}
}
project.evaluate()
val actualSourcesDirectories = project.multiplatformExtension.jvm()
.compilations.getByName("main")
.defaultSourceSet.resources.sourceDirectories
assert(
!actualSourcesDirectories.contains(project.expectedResourcePath)
) { actualSourcesDirectories.dumpPaths() }
}
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") },
)
}
private fun FileCollection.dumpPaths(): String {
return "Actual paths:" + if (isEmpty) " <Empty>" else joinToString("") { "\n${it.path}" }
}
}
@@ -6,12 +6,15 @@
package org.jetbrains.kotlin.gradle.unitTests
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.resources.KotlinTargetResourcesPublication
import org.jetbrains.kotlin.gradle.plugin.mpp.resources.resourcesPublicationExtension
import org.jetbrains.kotlin.gradle.util.assertContainsDiagnostic
import org.jetbrains.kotlin.gradle.util.assertNoDiagnostics
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
import org.jetbrains.kotlin.gradle.util.kotlin
import org.junit.Test
@@ -29,21 +32,14 @@ class KotlinTargetResourcesPublicationImplTests {
}
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)
testCallbacksAfterApiCall(
callback = { back ->
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnPublishResources(target) {
back(Unit)
}
},
apiCall = { project.publishFakeResources(target) }
)
}
@Test
@@ -55,21 +51,14 @@ class KotlinTargetResourcesPublicationImplTests {
}
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)
testCallbacksBeforeAndAfterApiCall(
callback = { back ->
project.multiplatformExtension.resourcesPublicationExtension?.subscribeOnPublishResources(target) {
back(Unit)
}
},
apiCall = { project.publishFakeResources(target) }
)
}
@Test
@@ -81,10 +70,59 @@ class KotlinTargetResourcesPublicationImplTests {
}
val target = project.multiplatformExtension.jvm()
project.publishFakeResources(target)
project.publishFakeResources(target)
project.testMultipleApiCallsEmitDiagnostic(
apiCall = { project.publishFakeResources(target) },
diagnostic = KotlinToolingDiagnostics.ResourcePublishedMoreThanOncePerTarget,
)
}
project.assertContainsDiagnostic(KotlinToolingDiagnostics.ResourcePublishedMoreThanOncePerTarget)
private fun testCallbacksAfterApiCall(
callback: ((Unit) -> Unit) -> Unit,
apiCall: (Unit) -> Unit,
) {
var callbacks = 0
apiCall.invoke(Unit)
callback {
callbacks += 1
}
assertEquals(callbacks, 1)
callback {
callbacks += 1
}
assertEquals(callbacks, 2)
}
private fun testCallbacksBeforeAndAfterApiCall(
callback: ((Unit) -> Unit) -> Unit,
apiCall: (Unit) -> Unit,
) {
var callbacks = 0
callback {
callbacks += 1
}
assertEquals(callbacks, 0)
apiCall.invoke(Unit)
assertEquals(callbacks, 1)
callback {
callbacks += 1
}
assertEquals(callbacks, 2)
}
private fun ProjectInternal.testMultipleApiCallsEmitDiagnostic(
apiCall: (Unit) -> Unit,
diagnostic: ToolingDiagnosticFactory,
) {
assertNoDiagnostics(diagnostic)
apiCall(Unit)
assertNoDiagnostics(diagnostic)
apiCall(Unit)
assertContainsDiagnostic(diagnostic)
}
private fun Project.publishFakeResources(target: KotlinTarget) {