[Kotlin] Add multi-module test for tooling metadata

^KT-49704
This commit is contained in:
Anton Lakotka
2022-03-21 15:18:04 +01:00
parent 7af5a93767
commit 2e327f1367
11 changed files with 131 additions and 34 deletions
@@ -8,10 +8,12 @@ package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
import org.jetbrains.kotlin.gradle.tooling.BuildKotlinToolingMetadataTask
import org.jetbrains.kotlin.gradle.tooling.BuildKotlinToolingMetadataTask.Companion.taskNameForKotlinModule
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.tooling.KotlinToolingMetadata
import org.jetbrains.kotlin.tooling.parseJsonOrThrow
import org.junit.Assume.assumeFalse
import org.junit.AssumptionViolatedException
import org.junit.Test
import kotlin.test.assertEquals
@@ -27,14 +29,13 @@ class KotlinToolingMetadataMppIT : BaseGradleIT() {
private val buildKotlinToolingMetadataTaskName get() =
if (isKpmModelMappingEnabled) {
BuildKotlinToolingMetadataTask.taskNameForKotlinModule(KotlinGradleModule.MAIN_MODULE_NAME)
taskNameForKotlinModule(KotlinGradleModule.MAIN_MODULE_NAME)
} else {
BuildKotlinToolingMetadataTask.defaultTaskName
}
@Test
fun `new-mpp-published`() = with(transformProjectWithPluginsDsl("new-mpp-published")) {
projectDir.resolve("gradle.properties").appendText("\nkotlin.mpp.enableKotlinToolingMetadataArtifact=true")
build("publish") {
assertSuccessful()
@@ -106,7 +107,6 @@ class KotlinToolingMetadataMppIT : BaseGradleIT() {
@Test
fun `kotlin-js-browser-project`() = with(transformProjectWithPluginsDsl("kotlin-js-browser-project")) {
assumeFalse("KPM model mapping is not yet supported in single-platform projects", isKpmModelMappingEnabled)
projectDir.resolve("gradle.properties").appendText("\nkotlin.mpp.enableKotlinToolingMetadataArtifact=true")
build(BuildKotlinToolingMetadataTask.defaultTaskName) {
assertSuccessful()
assertTasksExecuted(":app:$buildKotlinToolingMetadataTaskName")
@@ -114,4 +114,39 @@ class KotlinToolingMetadataMppIT : BaseGradleIT() {
assertTasksExecuted(":lib:$buildKotlinToolingMetadataTaskName")
}
}
@Test
fun `kpm multiple modules`() {
// TODO: Move it to Integration Tests Container for pure KPM projects
if (isKpmModelMappingEnabled) throw AssumptionViolatedException("Pure KPM tests don't need KPM model mapping flag")
with(transformProjectWithPluginsDsl("kpm-multi-module-published")) {
val expectedMetadataByModule = mapOf<String, KotlinToolingMetadata.() -> Unit>(
KotlinGradleModule.MAIN_MODULE_NAME to {
val nativeTarget = projectTargets.single { it.platformType == KotlinPlatformType.native.name }
assertEquals(KonanTarget.LINUX_X64.name, nativeTarget.extras.native?.konanTarget)
},
"secondaryModule" to {
val nativeTarget = projectTargets.single { it.platformType == KotlinPlatformType.native.name }
assertEquals(KonanTarget.LINUX_ARM64.name, nativeTarget.extras.native?.konanTarget)
},
)
// FIXME: Use `publish` task for Integration Tests.
// However Publishing of multiple modules fails currently and need proper design & implementation KT-49704
build(BuildKotlinToolingMetadataTask.defaultTaskName) {
assertSuccessful()
expectedMetadataByModule.forEach { (moduleName, assertExpected) ->
assertTasksExecuted(":${taskNameForKotlinModule(moduleName)}")
val pathToMetadata = "build/kotlinToolingMetadata/$moduleName/kotlin-tooling-metadata.json"
assertFileExists(pathToMetadata)
val metadataJson = projectDir.resolve(pathToMetadata).readText()
val metadata = KotlinToolingMetadata.parseJsonOrThrow(metadataJson)
metadata.assertExpected()
}
}
}
}
}
@@ -0,0 +1,45 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
plugins {
kotlin("multiplatform.pm20").version("<pluginMarkerVersion>")
`maven-publish`
}
repositories {
mavenLocal()
mavenCentral()
}
group = "com.example.bar"
version = "1.0"
kotlin {
// feel free to add more modules, variants and fragments
mainAndTest {
jvm
val linuxX64 by fragments.creating(KotlinLinuxX64Variant::class)
}
val secondaryModule by modules.creating {
jvm
val linuxArm64 by fragments.creating(KotlinLinuxArm64Variant::class)
makePublic()
}
test {
dependencies { implementation(kotlin("test")) }
jvm.dependencies { implementation(kotlin("test-junit")) }
}
val integrationTest by modules.creating {
jvm
val linuxX64 by fragments.creating(KotlinLinuxX64Variant::class)
}
}
publishing {
repositories {
maven("../repo")
}
}
@@ -0,0 +1,10 @@
package com.example.bar
import kotlin.test.Test
class BarTest {
@Test
fun testBar() {
}
}
@@ -0,0 +1,10 @@
package com.example.bar
import kotlin.test.Test
class JvmBarTest {
@Test
fun testBar() {
}
}
@@ -34,10 +34,8 @@ import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.tooling.KotlinToolingMetadata
import org.jetbrains.kotlin.tooling.toJsonString
import java.io.File
import javax.inject.Inject
/**
* Register
*/
internal fun Project.registerBuildKotlinToolingMetadataTask() {
if (!project.kotlinPropertiesProvider.enableKotlinToolingMetadataArtifact) return
@@ -80,29 +78,26 @@ internal val KotlinGradleModule.buildKotlinToolingMetadataTask: TaskProvider<Bui
if (!project.kotlinPropertiesProvider.enableKotlinToolingMetadataArtifact) return null
val taskName = BuildKotlinToolingMetadataTask.taskNameForKotlinModule(name)
return project.locateOrRegisterTask<BuildKotlinToolingMetadataTask.FromKpmModule>(taskName) { task ->
task.module.set(this)
task.group = "build"
task.description = "Build metadata json file containing information about the used Kotlin tooling in module $name"
}.also { task ->
project.buildKotlinToolingMetadataForAllKpmModulesTask.dependsOn(task)
}
return project.locateOrRegisterTask(
name = taskName,
args = listOf(this),
invokeWhenRegistered = { project.buildKotlinToolingMetadataForAllKpmModulesTask.dependsOn(this) },
configureTask = {
group = "build"
description = "Build metadata json file containing information about the used Kotlin tooling in module $name"
}
)
}
abstract class BuildKotlinToolingMetadataTask : DefaultTask() {
abstract class FromKpmModule : BuildKotlinToolingMetadataTask() {
@get:Internal
abstract val module: Property<KotlinGradleModule>
abstract class FromKpmModule
@Inject constructor (@get:Internal val module: KotlinGradleModule) : BuildKotlinToolingMetadataTask() {
override val outputDirectory: File
get() = project.buildDir.resolve("kotlinToolingMetadata").resolve(module.get().name)
get() = project.buildDir.resolve("kotlinToolingMetadata").resolve(module.name)
override fun buildKotlinToolingMetadata() = module.get().getKotlinToolingMetadata()
override fun buildKotlinToolingMetadata() = module.getKotlinToolingMetadata()
}
abstract class FromKotlinExtension : BuildKotlinToolingMetadataTask() {
@@ -181,10 +181,6 @@ class DeserializeStringTest {
"konanAbiVersion": "1.4.2"
}
}
},
{
"target": "org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget",
"platformType": "common"
}
]
}
@@ -199,7 +195,7 @@ class DeserializeStringTest {
assertFalse(metadata.projectSettings.isHmppEnabled)
assertTrue(metadata.projectSettings.isCompatibilityMetadataVariantEnabled)
assertTrue(metadata.projectSettings.isKPMEnabled)
assertEquals(5, metadata.projectTargets.size, "Expected exactly 4 targets")
assertEquals(4, metadata.projectTargets.size, "Expected exactly 4 targets")
val androidJvmTarget = metadata.projectTargets.single { it.platformType == "androidJvm" }
assertEquals("org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget", androidJvmTarget.target)
@@ -234,13 +230,6 @@ class DeserializeStringTest {
assertNull(nativeTarget.extras.android)
assertNull(nativeTarget.extras.jvm)
assertNull(nativeTarget.extras.js)
val commonTarget = metadata.projectTargets.single { it.platformType == "common" }
assertEquals("org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget", commonTarget.target)
assertNull(commonTarget.extras.android)
assertNull(commonTarget.extras.jvm)
assertNull(commonTarget.extras.js)
assertNull(commonTarget.extras.native)
}
}