Add test tasks to the Gradle model built for MPP

Add `testTasks` to KotlinTarget model class, build them
based on task names until proper test runs API is available.
This commit is contained in:
Sergey Igushkin
2019-07-09 18:12:14 +03:00
parent 9b32670738
commit f6679f27f4
3 changed files with 50 additions and 5 deletions
@@ -140,6 +140,7 @@ interface KotlinTarget : Serializable {
val disambiguationClassifier: String?
val platform: KotlinPlatform
val compilations: Collection<KotlinCompilation>
val testTasks: Collection<KotlinTestTask>
val jar: KotlinTargetJar?
companion object {
@@ -147,6 +148,10 @@ interface KotlinTarget : Serializable {
}
}
interface KotlinTestTask : Serializable {
val taskName: String
}
interface ExtraFeatures : Serializable {
val coroutinesState: String?
val isHMPPEnabled: Boolean
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.Named
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.*
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
@@ -249,7 +246,8 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
buildCompilation(it, disambiguationClassifier, sourceSetMap, dependencyResolver, project, dependencyMapper)
}
val jar = buildTargetJar(gradleTarget, project)
val target = KotlinTargetImpl(gradleTarget.name, targetPresetName, disambiguationClassifier, platform, compilations, jar)
val testTasks = buildTestTasks(project, gradleTarget)
val target = KotlinTargetImpl(gradleTarget.name, targetPresetName, disambiguationClassifier, platform, compilations, testTasks, jar)
compilations.forEach {
it.disambiguationClassifier = target.disambiguationClassifier
it.platform = target.platform
@@ -257,6 +255,38 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
return target
}
private fun buildTestTasks(project: Project, gradleTarget: Named): Collection<KotlinTestTask> {
// TODO: use the test runs API to extract the test tasks once it is available
// Otherwise, find the Kotlin test task with names matching the target name. This is a workaround that makes assumptions about
// the tasks naming logic and is therefore an unstable and temporary solution until test runs API is implemented:
@Suppress("UNCHECKED_CAST")
val kotlinTestTaskClass = try {
gradleTarget.javaClass.classLoader.loadClass("org.jetbrains.kotlin.gradle.tasks.KotlinTest") as Class<out Task>
} catch (_: ClassNotFoundException) {
return emptyList()
}
val targetDisambiguationClassifier = run {
val getDisambiguationClassifier = gradleTarget.javaClass.getMethodOrNull("getDisambiguationClassifier")
?: return emptyList()
getDisambiguationClassifier(gradleTarget) as String?
}
// The 'targetName' of a test task matches the target disambiguation classifier, potentially with suffix, e.g. jsBrowser
val getTargetName = kotlinTestTaskClass.getDeclaredMethodOrNull("getTargetName") ?: return emptyList()
return project.tasks.filter { kotlinTestTaskClass.isInstance(it) }.mapNotNull { task ->
val testTaskDisambiguationClassifier = getTargetName(task) as String?
task.name.takeIf {
targetDisambiguationClassifier.isNullOrEmpty() ||
testTaskDisambiguationClassifier != null &&
testTaskDisambiguationClassifier.startsWith(targetDisambiguationClassifier.orEmpty())
}
}.map(::KotlinTestTaskImpl)
}
private fun buildTargetJar(gradleTarget: Named, project: Project): KotlinTargetJar? {
val targetClass = gradleTarget.javaClass
val getArtifactsTaskName = targetClass.getMethodOrNull("getArtifactsTaskName") ?: return null
@@ -132,6 +132,7 @@ data class KotlinTargetImpl(
override val disambiguationClassifier: String?,
override val platform: KotlinPlatform,
override val compilations: Collection<KotlinCompilation>,
override val testTasks: Collection<KotlinTestTask>,
override val jar: KotlinTargetJar?
) : KotlinTarget {
override fun toString() = name
@@ -146,10 +147,19 @@ data class KotlinTargetImpl(
cloningCache[initialCompilation] = it
}
}.toList(),
target.testTasks.map { initialTestTask ->
(cloningCache[initialTestTask] as? KotlinTestTask) ?: KotlinTestTaskImpl(initialTestTask.taskName).also {
cloningCache[initialTestTask] = it
}
},
KotlinTargetJarImpl(target.jar?.archiveFile)
)
}
data class KotlinTestTaskImpl(
override val taskName: String
) : KotlinTestTask
data class ExtraFeaturesImpl(
override val coroutinesState: String?,
override val isHMPPEnabled: Boolean