Introduce execution & test run API, KT-32679
* KotlinExecution * KotlinExecutionSource * KotlinTestRun * Aggregating executions and execution sources * KotlinTargetWithTests * Add a `testableTargets` extension * Make some Kotlin/Native targets testable (this requires having a separate preset type for them) * Implement test runs encapsulating the tests for all existing testable targets by refactoring their TargetConfigurator classes Issue #KT-32679 Fixed
This commit is contained in:
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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
|
||||
|
||||
import org.gradle.api.Named
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinExecution.ExecutionSource
|
||||
|
||||
/**
|
||||
* An execution of Kotlin code. Executions in a single family (e.g. test runs) are distinguished by [Named.getName].
|
||||
* Names may not be unique across different execution families, such as test runs of different targets.
|
||||
*
|
||||
* A particular kind of execution is a [KotlinTestRun] which runs tests.
|
||||
*/
|
||||
interface KotlinExecution<out SourceType : ExecutionSource> : Named {
|
||||
interface ExecutionSource
|
||||
|
||||
/**
|
||||
* The source of the executable code that this execution runs from. It is usually set via members of execution source support
|
||||
* interfaces, such as [CompilationExecutionSourceSupport] or [ClasspathTestRunSourceSupport], or `setExecutionSourceFrom*` functions.
|
||||
*/
|
||||
val executionSource: SourceType
|
||||
}
|
||||
|
||||
interface KotlinTargetExecution<out SourceType : ExecutionSource> : KotlinExecution<SourceType> {
|
||||
val target: KotlinTarget
|
||||
}
|
||||
|
||||
/**
|
||||
* An execution source that is produced by a [compilation].
|
||||
*
|
||||
* See also: [CompilationExecutionSourceSupport].
|
||||
*/
|
||||
interface CompilationExecutionSource<CompilationType : KotlinCompilation<*>> : ExecutionSource {
|
||||
val compilation: CompilationType
|
||||
}
|
||||
|
||||
interface CompilationExecutionSourceSupport<in T : KotlinCompilationToRunnableFiles<*>> {
|
||||
/**
|
||||
* Select a compilation to run the execution from.
|
||||
*
|
||||
* The [compilation]'s [KotlinCompilationToRunnableFiles.runtimeDependencyFiles]
|
||||
* will be treated as runtime dependencies, and its [output] as runnable files.
|
||||
*
|
||||
* This overrides other [KotlinExecution.executionSource] selection options.
|
||||
*/
|
||||
fun setExecutionSourceFrom(compilation: T)
|
||||
}
|
||||
|
||||
interface ExecutionTaskHolder<T : Task> {
|
||||
val executionTask: TaskProvider<T>
|
||||
}
|
||||
+10
@@ -54,4 +54,14 @@ interface KotlinTarget : Named, HasAttributes {
|
||||
val preset: KotlinTargetPreset<out KotlinTarget>?
|
||||
|
||||
override fun getName(): String = targetName
|
||||
}
|
||||
|
||||
interface KotlinTargetWithTests<E : KotlinExecution.ExecutionSource, T : KotlinTargetTestRun<E>> : KotlinTarget {
|
||||
/** The container with the test run executions.
|
||||
* A target may automatically create and configure a test run by the name [DEFAULT_TEST_RUN_NAME]. */
|
||||
val testRuns: NamedDomainObjectContainer<T>
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_TEST_RUN_NAME = "test"
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.testing.TestFilter
|
||||
import org.gradle.util.ConfigureUtil
|
||||
|
||||
interface KotlinTestRun<out SourceType : KotlinExecution.ExecutionSource> : KotlinExecution<SourceType> {
|
||||
fun filter(configureFilter: TestFilter.() -> Unit)
|
||||
|
||||
fun filter(configureFilter: Closure<*>) = filter { ConfigureUtil.configureSelf(configureFilter, this) }
|
||||
}
|
||||
|
||||
interface KotlinTargetTestRun<ExecutionSource : KotlinExecution.ExecutionSource> :
|
||||
KotlinTestRun<ExecutionSource>,
|
||||
KotlinTargetExecution<ExecutionSource>
|
||||
|
||||
interface JvmClasspathTestRunSource : KotlinExecution.ExecutionSource {
|
||||
val testClassesDirs: FileCollection
|
||||
val classpath: FileCollection
|
||||
}
|
||||
|
||||
interface ClasspathTestRunSourceSupport {
|
||||
/**
|
||||
* Select the exact [classpath] to run the tests from.
|
||||
*
|
||||
* Only the classes from [testClasses] will be treated as tests.
|
||||
*
|
||||
* This overrides other [KotlinExecution.executionSource] selection options.
|
||||
*/
|
||||
fun setExecutionSourceFrom(classpath: FileCollection, testClassesDirs: FileCollection)
|
||||
}
|
||||
+19
-2
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.generators.gradle.dsl
|
||||
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.presetName
|
||||
|
||||
internal class KotlinPresetEntry(
|
||||
@@ -21,6 +22,9 @@ internal const val MPP_PACKAGE = "org.jetbrains.kotlin.gradle.plugin.mpp"
|
||||
internal const val KOTLIN_NATIVE_TARGET_PRESET_CLASS_FQNAME = "$MPP_PACKAGE.KotlinNativeTargetPreset"
|
||||
internal const val KOTLIN_NATIVE_TARGET_CLASS_FQNAME = "$MPP_PACKAGE.KotlinNativeTarget"
|
||||
|
||||
internal const val KOTLIN_NATIVE_TARGET_WITH_TESTS_PRESET_CLASS_FQNAME = "$MPP_PACKAGE.KotlinNativeTargetWithTestsPreset"
|
||||
internal const val KOTLIN_NATIVE_TARGET_WITH_TESTS_CLASS_FQNAME = "$MPP_PACKAGE.KotlinNativeTargetWithTests"
|
||||
|
||||
internal val jvmPresetEntry = KotlinPresetEntry(
|
||||
"jvm",
|
||||
typeName("$MPP_PACKAGE.KotlinJvmTargetPreset"),
|
||||
@@ -39,11 +43,24 @@ internal val androidPresetEntry = KotlinPresetEntry(
|
||||
typeName("$MPP_PACKAGE.KotlinAndroidTarget")
|
||||
)
|
||||
|
||||
// Note: modifying this set should also be reflected in the MPP plugin code, see 'setupDefaultPresets'
|
||||
private val testableNativeTargets = setOf(KonanTarget.LINUX_X64, KonanTarget.MACOS_X64, KonanTarget.MINGW_X64)
|
||||
|
||||
internal val nativePresetEntries = HostManager().targets.map { (_, target) ->
|
||||
KotlinPresetEntry(
|
||||
target.presetName,
|
||||
typeName(KOTLIN_NATIVE_TARGET_PRESET_CLASS_FQNAME),
|
||||
typeName(KOTLIN_NATIVE_TARGET_CLASS_FQNAME)
|
||||
typeName(
|
||||
if (target in testableNativeTargets)
|
||||
KOTLIN_NATIVE_TARGET_WITH_TESTS_PRESET_CLASS_FQNAME
|
||||
else
|
||||
KOTLIN_NATIVE_TARGET_PRESET_CLASS_FQNAME
|
||||
),
|
||||
typeName(
|
||||
if (target in testableNativeTargets)
|
||||
KOTLIN_NATIVE_TARGET_WITH_TESTS_CLASS_FQNAME
|
||||
else
|
||||
KOTLIN_NATIVE_TARGET_CLASS_FQNAME
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -9,9 +9,7 @@ import groovy.lang.Closure
|
||||
import org.gradle.api.InvalidUserCodeException
|
||||
import org.gradle.api.NamedDomainObjectCollection
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetsContainerWithPresets
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
|
||||
@@ -22,6 +20,10 @@ open class KotlinMultiplatformExtension : KotlinProjectExtension(), KotlinTarget
|
||||
override lateinit var targets: NamedDomainObjectCollection<KotlinTarget>
|
||||
internal set
|
||||
|
||||
@Suppress("unused") // DSL
|
||||
val testableTargets: NamedDomainObjectCollection<KotlinTargetWithTests<*, *>>
|
||||
get() = targets.withType(KotlinTargetWithTests::class.java)
|
||||
|
||||
internal var isGradleMetadataAvailable: Boolean = false
|
||||
internal var isGradleMetadataExperimental: Boolean = false
|
||||
|
||||
|
||||
+11
-9
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsTargetPreset
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmTargetPreset
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetPreset
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetWithTests
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetWithTestsPreset
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||
|
||||
@@ -258,11 +260,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
|
||||
|
||||
fun linuxX64(
|
||||
name: String = "linuxX64",
|
||||
configure: KotlinNativeTarget.() -> Unit = { }
|
||||
): KotlinNativeTarget =
|
||||
configure: KotlinNativeTargetWithTests.() -> Unit = { }
|
||||
): KotlinNativeTargetWithTests =
|
||||
configureOrCreate(
|
||||
name,
|
||||
presets.getByName("linuxX64") as KotlinNativeTargetPreset,
|
||||
presets.getByName("linuxX64") as KotlinNativeTargetWithTestsPreset,
|
||||
configure
|
||||
)
|
||||
|
||||
@@ -333,11 +335,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
|
||||
|
||||
fun mingwX64(
|
||||
name: String = "mingwX64",
|
||||
configure: KotlinNativeTarget.() -> Unit = { }
|
||||
): KotlinNativeTarget =
|
||||
configure: KotlinNativeTargetWithTests.() -> Unit = { }
|
||||
): KotlinNativeTargetWithTests =
|
||||
configureOrCreate(
|
||||
name,
|
||||
presets.getByName("mingwX64") as KotlinNativeTargetPreset,
|
||||
presets.getByName("mingwX64") as KotlinNativeTargetWithTestsPreset,
|
||||
configure
|
||||
)
|
||||
|
||||
@@ -363,11 +365,11 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
|
||||
|
||||
fun macosX64(
|
||||
name: String = "macosX64",
|
||||
configure: KotlinNativeTarget.() -> Unit = { }
|
||||
): KotlinNativeTarget =
|
||||
configure: KotlinNativeTargetWithTests.() -> Unit = { }
|
||||
): KotlinNativeTargetWithTests =
|
||||
configureOrCreate(
|
||||
name,
|
||||
presets.getByName("macosX64") as KotlinNativeTargetPreset,
|
||||
presets.getByName("macosX64") as KotlinNativeTargetWithTestsPreset,
|
||||
configure
|
||||
)
|
||||
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.execution
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinExecution
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinExecution.ExecutionSource
|
||||
|
||||
/**
|
||||
* An execution source that aggregates other [executionSources].
|
||||
*/
|
||||
interface KotlinAggregateExecutionSource<AggregatedSourceType : ExecutionSource> : ExecutionSource {
|
||||
val executionSources: Iterable<AggregatedSourceType>
|
||||
}
|
||||
|
||||
interface KotlinAggregatingExecution<
|
||||
AggregatedSourceType : ExecutionSource,
|
||||
AggregatingSourceType : KotlinAggregateExecutionSource<AggregatedSourceType>,
|
||||
AggregatedExecutionType : KotlinExecution<AggregatedSourceType>
|
||||
> :
|
||||
KotlinExecution<AggregatingSourceType> {
|
||||
/**
|
||||
* Configures all of the executions aggregated by this execution. If some of the executions are not yet created up to this point,
|
||||
* [configure] will be called on them later, once they are created.
|
||||
*/
|
||||
fun configureAllExecutions(configure: AggregatedExecutionType.() -> Unit): Unit
|
||||
|
||||
/**
|
||||
* Returns the aggregated executions that are already configured up to this moment.
|
||||
* Some test runs may be missing from the results if they are not yet configured.
|
||||
*/
|
||||
fun getConfiguredExecutions(): Iterable<AggregatedExecutionType>
|
||||
|
||||
fun configureAllExecutions(configureClosure: Closure<*>) = configureAllExecutions {
|
||||
ConfigureUtil.configureSelf(
|
||||
configureClosure,
|
||||
this
|
||||
)
|
||||
}
|
||||
}
|
||||
+73
-50
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
@@ -25,30 +26,36 @@ import org.gradle.language.jvm.tasks.ProcessResources
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
|
||||
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import java.util.concurrent.Callable
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>(
|
||||
protected val createDefaultSourceSets: Boolean,
|
||||
protected val createTestCompilation: Boolean
|
||||
) {
|
||||
open fun configureTarget(
|
||||
interface KotlinTargetConfigurator<KotlinTargetType : KotlinTarget> {
|
||||
fun configureTarget(
|
||||
target: KotlinTargetType
|
||||
) {
|
||||
configureCompilationDefaults(target)
|
||||
configureCompilations(target)
|
||||
defineConfigurationsForTarget(target)
|
||||
configureArchivesAndComponent(target)
|
||||
configureTest(target)
|
||||
configureBuild(target)
|
||||
configurePlatformSpecificModel(target)
|
||||
}
|
||||
|
||||
fun configureCompilationDefaults(target: KotlinTargetType)
|
||||
fun configureCompilations(target: KotlinTargetType)
|
||||
fun defineConfigurationsForTarget(target: KotlinTargetType)
|
||||
fun configureArchivesAndComponent(target: KotlinTargetType)
|
||||
fun configureBuild(target: KotlinTargetType)
|
||||
|
||||
protected abstract fun configureArchivesAndComponent(target: KotlinTargetType)
|
||||
protected abstract fun configureTest(target: KotlinTargetType)
|
||||
fun configurePlatformSpecificModel(target: KotlinTargetType) = Unit
|
||||
}
|
||||
|
||||
abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>(
|
||||
protected val createDefaultSourceSets: Boolean,
|
||||
protected val createTestCompilation: Boolean
|
||||
) : KotlinTargetConfigurator<KotlinTargetType> {
|
||||
|
||||
private fun Project.registerOutputsForStaleOutputCleanup(kotlinCompilation: KotlinCompilation<*>) {
|
||||
val cleanTask = tasks.getByName(LifecycleBasePlugin.CLEAN_TASK_NAME) as Delete
|
||||
@@ -62,17 +69,17 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun configureCompilations(platformTarget: KotlinTargetType) {
|
||||
val project = platformTarget.project
|
||||
val main = platformTarget.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||
override fun configureCompilations(target: KotlinTargetType) {
|
||||
val project = target.project
|
||||
val main = target.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||
|
||||
platformTarget.compilations.all {
|
||||
target.compilations.all {
|
||||
project.registerOutputsForStaleOutputCleanup(it)
|
||||
setupCompilationDependencyFiles(project, it)
|
||||
}
|
||||
|
||||
if (createTestCompilation) {
|
||||
platformTarget.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME).apply {
|
||||
target.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME).apply {
|
||||
compileDependencyFiles += main.output.allOutputs
|
||||
|
||||
if (this is KotlinCompilationToRunnableFiles) {
|
||||
@@ -82,7 +89,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
||||
}
|
||||
}
|
||||
|
||||
protected fun configureCompilationDefaults(target: KotlinTargetType) {
|
||||
override fun configureCompilationDefaults(target: KotlinTargetType) {
|
||||
val project = target.project
|
||||
|
||||
target.compilations.all { compilation ->
|
||||
@@ -129,7 +136,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun defineConfigurationsForTarget(target: KotlinTargetType) {
|
||||
override fun defineConfigurationsForTarget(target: KotlinTargetType) {
|
||||
val project = target.project
|
||||
|
||||
val configurations = project.configurations
|
||||
@@ -195,7 +202,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
||||
}
|
||||
}
|
||||
|
||||
protected fun configureBuild(target: KotlinTargetType) {
|
||||
override fun configureBuild(target: KotlinTargetType) {
|
||||
val project = target.project
|
||||
|
||||
val buildNeeded = project.tasks.getByName(JavaBasePlugin.BUILD_NEEDED_TASK_NAME)
|
||||
@@ -305,23 +312,23 @@ internal val KotlinCompilationToRunnableFiles<*>.deprecatedRuntimeConfigurationN
|
||||
internal val KotlinTarget.testTaskName: String
|
||||
get() = lowerCamelCaseName(targetName, AbstractKotlinTargetConfigurator.testTaskNameSuffix)
|
||||
|
||||
abstract class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilation<*>>(
|
||||
abstract class KotlinOnlyTargetConfigurator<KotlinCompilationType : KotlinCompilation<*>, KotlinTargetType : KotlinOnlyTarget<KotlinCompilationType>>(
|
||||
createDefaultSourceSets: Boolean,
|
||||
createTestCompilation: Boolean,
|
||||
val kotlinPluginVersion: String
|
||||
) : AbstractKotlinTargetConfigurator<KotlinOnlyTarget<KotlinCompilationType>>(
|
||||
) : AbstractKotlinTargetConfigurator<KotlinTargetType>(
|
||||
createDefaultSourceSets,
|
||||
createTestCompilation
|
||||
) {
|
||||
internal abstract fun buildCompilationProcessor(compilation: KotlinCompilationType): KotlinSourceSetProcessor<*>
|
||||
|
||||
override fun configureCompilations(platformTarget: KotlinOnlyTarget<KotlinCompilationType>) {
|
||||
super.configureCompilations(platformTarget)
|
||||
override fun configureCompilations(target: KotlinTargetType) {
|
||||
super.configureCompilations(target)
|
||||
|
||||
platformTarget.compilations.all { compilation ->
|
||||
target.compilations.all { compilation ->
|
||||
buildCompilationProcessor(compilation).run()
|
||||
if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) {
|
||||
sourcesJarTask(compilation, platformTarget.targetName, platformTarget.targetName.toLowerCase())
|
||||
sourcesJarTask(compilation, target.targetName, target.targetName.toLowerCase())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,7 +341,7 @@ abstract class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilatio
|
||||
result.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs)
|
||||
}
|
||||
|
||||
override fun configureArchivesAndComponent(target: KotlinOnlyTarget<KotlinCompilationType>) {
|
||||
override fun configureArchivesAndComponent(target: KotlinTargetType) {
|
||||
val project = target.project
|
||||
|
||||
val mainCompilation = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||
@@ -365,30 +372,6 @@ abstract class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilatio
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureTest(target: KotlinOnlyTarget<KotlinCompilationType>) {
|
||||
val testCompilation =
|
||||
target.compilations.findByName(KotlinCompilation.TEST_COMPILATION_NAME) as? KotlinCompilationToRunnableFiles<*>
|
||||
?: return // Otherwise, there is no runtime classpath
|
||||
|
||||
val testTaskName = lowerCamelCaseName(target.disambiguationClassifier, testTaskNameSuffix)
|
||||
val testTask = target.project.createOrRegisterTask<KotlinJvmTest>(testTaskName) { testTask ->
|
||||
testTask.targetName = target.disambiguationClassifier
|
||||
}
|
||||
|
||||
testTask.project.afterEvaluate {
|
||||
// use afterEvaluate to override the JavaPlugin defaults for Test tasks
|
||||
testTask.configure { testTask ->
|
||||
testTask.conventionMapping.map("testClassesDirs") { testCompilation.output.classesDirs }
|
||||
testTask.conventionMapping.map("classpath") { testCompilation.runtimeDependencyFiles }
|
||||
testTask.description = "Runs the unit tests."
|
||||
testTask.group = JavaBasePlugin.VERIFICATION_GROUP
|
||||
testTask.project.tasks.findByName(JavaBasePlugin.CHECK_TASK_NAME)?.dependsOn(testTask)
|
||||
}
|
||||
}
|
||||
|
||||
target.project.kotlinTestRegistry.registerTestTask(testTask)
|
||||
}
|
||||
|
||||
private fun addJar(configuration: Configuration, jarArtifact: PublishArtifact) {
|
||||
val publications = configuration.outgoing
|
||||
|
||||
@@ -398,6 +381,46 @@ abstract class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilatio
|
||||
}
|
||||
}
|
||||
|
||||
internal interface KotlinTargetWithTestsConfigurator<R : KotlinTargetTestRun<*>, T : KotlinTargetWithTests<*, R>>
|
||||
: KotlinTargetConfigurator<T> {
|
||||
|
||||
override fun configureTarget(target: T) {
|
||||
super.configureTarget(target)
|
||||
configureTest(target)
|
||||
}
|
||||
|
||||
val testRunClass: Class<R>
|
||||
|
||||
fun createTestRun(name: String, target: T): R
|
||||
|
||||
fun configureTest(target: T) {
|
||||
initializeTestRuns(target)
|
||||
target.testRuns.create(KotlinTargetWithTests.DEFAULT_TEST_RUN_NAME)
|
||||
}
|
||||
|
||||
private fun initializeTestRuns(target: T) {
|
||||
val project = target.project
|
||||
|
||||
val testRunsPropertyName = KotlinTargetWithTests<*, *>::testRuns.name
|
||||
val mutableProperty =
|
||||
target::class.memberProperties
|
||||
.find { it.name == testRunsPropertyName } as? KMutableProperty1<*, *>
|
||||
?: error(
|
||||
"The ${this::class.qualifiedName} implementation of ${KotlinTargetWithTests::class.qualifiedName} must " +
|
||||
"override the $testRunsPropertyName property with a var."
|
||||
)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(mutableProperty as KMutableProperty1<KotlinTargetWithTests<*, R>, NamedDomainObjectContainer<R>>)
|
||||
.set(
|
||||
target,
|
||||
project.container(testRunClass) { testRunName ->
|
||||
createTestRun(testRunName, target)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Project.usageByName(usageName: String): Usage =
|
||||
project.objects.named(Usage::class.java, usageName)
|
||||
|
||||
|
||||
+12
-2
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.presetName
|
||||
|
||||
class KotlinMultiplatformPlugin(
|
||||
@@ -137,8 +138,17 @@ class KotlinMultiplatformPlugin(
|
||||
add(KotlinJsTargetPreset(project, kotlinPluginVersion))
|
||||
add(KotlinAndroidTargetPreset(project, kotlinPluginVersion))
|
||||
add(KotlinJvmWithJavaTargetPreset(project, kotlinPluginVersion))
|
||||
HostManager().targets.forEach { _, target ->
|
||||
add(KotlinNativeTargetPreset(target.presetName, project, target, kotlinPluginVersion))
|
||||
|
||||
// Note: modifying this set should also be reflected in the DSL code generator, see 'presetEntries.kt'
|
||||
val testableNativeTargets = setOf(KonanTarget.LINUX_X64, KonanTarget.MACOS_X64, KonanTarget.MINGW_X64)
|
||||
|
||||
HostManager().targets.forEach { (_, target) ->
|
||||
add(
|
||||
if (target in testableNativeTargets)
|
||||
KotlinNativeTargetWithTestsPreset(target.presetName, project, target, kotlinPluginVersion)
|
||||
else
|
||||
KotlinNativeTargetPreset(target.presetName, project, target, kotlinPluginVersion)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinOnlyTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
|
||||
|
||||
abstract class KotlinOnlyTargetPreset<R : KotlinOnlyTarget<T>, T : KotlinCompilation<*>>(
|
||||
@@ -16,7 +16,7 @@ abstract class KotlinOnlyTargetPreset<R : KotlinOnlyTarget<T>, T : KotlinCompila
|
||||
protected val kotlinPluginVersion: String
|
||||
) : KotlinTargetPreset<R> {
|
||||
|
||||
protected abstract fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<T>
|
||||
protected abstract fun createKotlinTargetConfigurator(): KotlinOnlyTargetConfigurator<T, R>
|
||||
|
||||
protected open fun provideTargetDisambiguationClassifier(target: KotlinOnlyTarget<T>): String? =
|
||||
target.targetName
|
||||
|
||||
+2
-3
@@ -254,7 +254,7 @@ internal fun javaApiUsageForMavenScoping() =
|
||||
JAVA_API
|
||||
}
|
||||
|
||||
open class KotlinOnlyTarget<T : KotlinCompilation<*>>(
|
||||
abstract class KotlinOnlyTarget<T : KotlinCompilation<*>>(
|
||||
project: Project,
|
||||
override val platformType: KotlinPlatformType
|
||||
) : AbstractKotlinTarget(project) {
|
||||
@@ -267,5 +267,4 @@ open class KotlinOnlyTarget<T : KotlinCompilation<*>>(
|
||||
|
||||
override var disambiguationClassifier: String? = null
|
||||
internal set
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.targets.js
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.testing.TestFilter
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.execution.KotlinAggregateExecutionSource
|
||||
import org.jetbrains.kotlin.gradle.plugin.ExecutionTaskHolder
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinExecution
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinExecution.ExecutionSource
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTestRun
|
||||
import org.jetbrains.kotlin.gradle.testing.KotlinAggregatingTestRun
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestReport
|
||||
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.targets.js
|
||||
|
||||
import org.jetbrains.kotlin.gradle.execution.KotlinAggregateExecutionSource
|
||||
import org.jetbrains.kotlin.gradle.execution.KotlinAggregatingExecution
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilationExecutionSource
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilationExecutionSourceSupport
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetTestRun
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.subtargets.KotlinJsSubTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.testing.KotlinReportAggregatingTestRun
|
||||
import org.jetbrains.kotlin.gradle.testing.KotlinTaskTestRun
|
||||
import org.jetbrains.kotlin.gradle.testing.requireCompilationOfTarget
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
class JsCompilationExecutionSource(override val compilation: KotlinJsCompilation) :
|
||||
CompilationExecutionSource<KotlinJsCompilation>
|
||||
|
||||
open class KotlinJsPlatformTestRun(testRunName: String, subtarget: KotlinJsSubTarget) :
|
||||
KotlinTaskTestRun<JsCompilationExecutionSource, KotlinJsTest>(testRunName, subtarget.target),
|
||||
CompilationExecutionSourceSupport<KotlinJsCompilation> {
|
||||
|
||||
private var _executionSource: JsCompilationExecutionSource by Delegates.notNull()
|
||||
|
||||
final override var executionSource: JsCompilationExecutionSource
|
||||
get() = _executionSource
|
||||
set(value) {
|
||||
executionTask.configure { it.compilation = value.compilation }
|
||||
_executionSource = value
|
||||
}
|
||||
|
||||
override fun setExecutionSourceFrom(compilation: KotlinJsCompilation) {
|
||||
requireCompilationOfTarget(compilation, target)
|
||||
|
||||
executionSource = JsCompilationExecutionSource(compilation)
|
||||
}
|
||||
}
|
||||
|
||||
class JsAggregatingExecutionSource(private val aggregatingTestRun: KotlinJsReportAggregatingTestRun) :
|
||||
KotlinAggregateExecutionSource<JsCompilationExecutionSource> {
|
||||
|
||||
override val executionSources: Iterable<JsCompilationExecutionSource>
|
||||
get() = aggregatingTestRun.getConfiguredExecutions().map { it.executionSource }
|
||||
}
|
||||
|
||||
open class KotlinJsReportAggregatingTestRun(
|
||||
testRunName: String,
|
||||
override val target: KotlinJsTarget
|
||||
) : KotlinReportAggregatingTestRun<JsCompilationExecutionSource, JsAggregatingExecutionSource, KotlinJsPlatformTestRun>(testRunName),
|
||||
KotlinTargetTestRun<JsAggregatingExecutionSource>,
|
||||
CompilationExecutionSourceSupport<KotlinJsCompilation> {
|
||||
|
||||
override fun setExecutionSourceFrom(compilation: KotlinJsCompilation) = configureAllExecutions {
|
||||
setExecutionSourceFrom(compilation)
|
||||
}
|
||||
|
||||
override val executionSource: JsAggregatingExecutionSource
|
||||
get() = JsAggregatingExecutionSource(this)
|
||||
|
||||
private fun KotlinJsSubTarget.getChildTestExecution() = testRuns.maybeCreate(testRunName)
|
||||
|
||||
override fun getConfiguredExecutions(): Iterable<KotlinJsPlatformTestRun> = mutableListOf<KotlinJsPlatformTestRun>().apply {
|
||||
if (target.isNodejsConfigured) {
|
||||
add(target.nodejs.getChildTestExecution())
|
||||
}
|
||||
if (target.isBrowserConfigured) {
|
||||
add(target.browser.getChildTestExecution())
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureAllExecutions(configure: KotlinJsPlatformTestRun.() -> Unit) {
|
||||
val doConfigureInChildren: KotlinJsSubTarget.() -> Unit = {
|
||||
configure(getChildTestExecution())
|
||||
}
|
||||
|
||||
target.whenBrowserConfigured { doConfigureInChildren(this as KotlinJsSubTarget) }
|
||||
target.whenNodejsConfigured { doConfigureInChildren(this as KotlinJsSubTarget) }
|
||||
}
|
||||
}
|
||||
+53
-18
@@ -5,11 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js
|
||||
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator.Companion.runTaskNameSuffix
|
||||
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator.Companion.testTaskNameSuffix
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.TaskHolder
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBrowserDsl
|
||||
@@ -17,19 +16,22 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsNodeDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.subtargets.KotlinBrowserJs
|
||||
import org.jetbrains.kotlin.gradle.targets.js.subtargets.KotlinNodeJs
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestReport
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
|
||||
class KotlinJsTarget(project: Project, platformType: KotlinPlatformType) :
|
||||
KotlinOnlyTarget<KotlinJsCompilation>(project, platformType), KotlinJsTargetDsl {
|
||||
KotlinOnlyTarget<KotlinJsCompilation>(project, platformType),
|
||||
KotlinTargetWithTests<JsAggregatingExecutionSource, KotlinJsReportAggregatingTestRun>,
|
||||
KotlinJsTargetDsl
|
||||
{
|
||||
override lateinit var testRuns: NamedDomainObjectContainer<KotlinJsReportAggregatingTestRun>
|
||||
internal set
|
||||
|
||||
val testTaskName get() = lowerCamelCaseName(disambiguationClassifier, testTaskNameSuffix)
|
||||
val testTaskName get() = testRuns.getByName(KotlinTargetWithTests.DEFAULT_TEST_RUN_NAME).testTaskName
|
||||
val testTask: TaskHolder<KotlinTestReport>
|
||||
get() = project.kotlinTestRegistry.getOrCreateAggregatedTestTask(
|
||||
name = testTaskName,
|
||||
description = "Run JS tests for all platforms"
|
||||
)
|
||||
get() = checkNotNull(project.locateTask(testTaskName))
|
||||
|
||||
val runTaskName get() = lowerCamelCaseName(disambiguationClassifier, runTaskNameSuffix)
|
||||
val runTask
|
||||
@@ -37,23 +39,56 @@ class KotlinJsTarget(project: Project, platformType: KotlinPlatformType) :
|
||||
it.description = "Run js on all configured platforms"
|
||||
}
|
||||
|
||||
val browser by lazy {
|
||||
private val browserLazyDelegate = lazy {
|
||||
KotlinBrowserJs(this).also {
|
||||
it.configure()
|
||||
browserConfiguredHandlers.forEach { handler -> handler(it) }
|
||||
browserConfiguredHandlers.clear()
|
||||
}
|
||||
}
|
||||
val nodejs by lazy {
|
||||
KotlinNodeJs(this).also {
|
||||
it.configure()
|
||||
}
|
||||
}
|
||||
|
||||
private val browserConfiguredHandlers = mutableListOf<KotlinJsBrowserDsl.() -> Unit>()
|
||||
|
||||
val browser by browserLazyDelegate
|
||||
|
||||
internal val isBrowserConfigured: Boolean = browserLazyDelegate.isInitialized()
|
||||
|
||||
override fun browser(body: KotlinJsBrowserDsl.() -> Unit) {
|
||||
browser.body()
|
||||
body(browser)
|
||||
}
|
||||
|
||||
private val nodejsLazyDelegate = lazy {
|
||||
KotlinNodeJs(this).also {
|
||||
it.configure()
|
||||
nodejsConfiguredHandlers.forEach { handler -> handler(it) }
|
||||
nodejsConfiguredHandlers.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private val nodejsConfiguredHandlers = mutableListOf<KotlinJsNodeDsl.() -> Unit>()
|
||||
|
||||
val nodejs by nodejsLazyDelegate
|
||||
|
||||
internal val isNodejsConfigured: Boolean = nodejsLazyDelegate.isInitialized()
|
||||
|
||||
override fun nodejs(body: KotlinJsNodeDsl.() -> Unit) {
|
||||
nodejs.body()
|
||||
body(nodejs)
|
||||
}
|
||||
|
||||
fun whenBrowserConfigured(body: KotlinJsBrowserDsl.() -> Unit) {
|
||||
if (browserLazyDelegate.isInitialized()) {
|
||||
browser(body)
|
||||
} else {
|
||||
browserConfiguredHandlers += body
|
||||
}
|
||||
}
|
||||
|
||||
fun whenNodejsConfigured(body: KotlinJsNodeDsl.() -> Unit) {
|
||||
if (nodejsLazyDelegate.isInitialized()) {
|
||||
nodejs(body)
|
||||
} else {
|
||||
nodejsConfiguredHandlers += body
|
||||
}
|
||||
}
|
||||
|
||||
fun useCommonJs() {
|
||||
|
||||
+32
-16
@@ -5,29 +5,45 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js
|
||||
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.Kotlin2JsSourceSetProcessor
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinOnlyTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTestsConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestReport
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||
|
||||
open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
||||
KotlinTargetConfigurator<KotlinJsCompilation>(true, true, kotlinPluginVersion) {
|
||||
KotlinOnlyTargetConfigurator<KotlinJsCompilation, KotlinJsTarget>(true, true, kotlinPluginVersion),
|
||||
KotlinTargetWithTestsConfigurator<KotlinJsReportAggregatingTestRun, KotlinJsTarget> {
|
||||
|
||||
override fun configureTarget(target: KotlinOnlyTarget<KotlinJsCompilation>) {
|
||||
target as KotlinJsTarget
|
||||
override val testRunClass: Class<KotlinJsReportAggregatingTestRun> get() = KotlinJsReportAggregatingTestRun::class.java
|
||||
|
||||
super.configureTarget(target)
|
||||
}
|
||||
override fun createTestRun(
|
||||
name: String,
|
||||
target: KotlinJsTarget
|
||||
): KotlinJsReportAggregatingTestRun {
|
||||
val result = KotlinJsReportAggregatingTestRun(name, target)
|
||||
|
||||
override fun configureTest(target: KotlinOnlyTarget<KotlinJsCompilation>) {
|
||||
target as KotlinJsTarget
|
||||
val testTask = target.project.kotlinTestRegistry.getOrCreateAggregatedTestTask(
|
||||
name = result.testTaskName,
|
||||
description = "Run JS tests for all platforms"
|
||||
)
|
||||
|
||||
// always create jsTest task for compatibility (KT-31527)
|
||||
// actual tests tasks for browser and nodejs will be configured in KotlinJsSubTarget.configure
|
||||
target.testTask
|
||||
// workaround to avoid the infinite recursion in item factories of the target and the subtargets:
|
||||
target.testRuns.matching { it.name == name }.whenObjectAdded {
|
||||
it.configureAllExecutions {
|
||||
// do not do anything with the aggregated test run, but ensure that they are created
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
result.executionTask = testTask.getTaskOrProvider() as TaskProvider<KotlinTestReport>
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> {
|
||||
@@ -35,10 +51,10 @@ open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
||||
return Kotlin2JsSourceSetProcessor(compilation.target.project, tasksProvider, compilation, kotlinPluginVersion)
|
||||
}
|
||||
|
||||
override fun configureCompilations(platformTarget: KotlinOnlyTarget<KotlinJsCompilation>) {
|
||||
super.configureCompilations(platformTarget)
|
||||
override fun configureCompilations(target: KotlinJsTarget) {
|
||||
super.configureCompilations(target)
|
||||
|
||||
platformTarget.compilations.all {
|
||||
target.compilations.all {
|
||||
it.compileKotlinTask.kotlinOptions {
|
||||
moduleKind = "umd"
|
||||
sourceMap = true
|
||||
|
||||
+7
@@ -6,7 +6,10 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.dsl
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlatformTestRun
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExec
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
|
||||
@@ -27,6 +30,8 @@ interface KotlinJsTargetDsl {
|
||||
ConfigureUtil.configure(fn, this)
|
||||
}
|
||||
}
|
||||
|
||||
val testRuns: NamedDomainObjectContainer<KotlinJsReportAggregatingTestRun>
|
||||
}
|
||||
|
||||
interface KotlinJsSubTargetDsl {
|
||||
@@ -36,6 +41,8 @@ interface KotlinJsSubTargetDsl {
|
||||
ConfigureUtil.configure(fn, this)
|
||||
}
|
||||
}
|
||||
|
||||
val testRuns: NamedDomainObjectContainer<KotlinJsPlatformTestRun>
|
||||
}
|
||||
|
||||
interface KotlinJsBrowserDsl : KotlinJsSubTargetDsl {
|
||||
|
||||
+33
-10
@@ -5,18 +5,21 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.subtargets
|
||||
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlatformTestRun
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolverPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
@@ -31,6 +34,9 @@ abstract class KotlinJsSubTarget(
|
||||
val runTaskName = disambiguateCamelCased("run")
|
||||
val testTaskName = disambiguateCamelCased("test")
|
||||
|
||||
override val testRuns: NamedDomainObjectContainer<KotlinJsPlatformTestRun> =
|
||||
project.container(KotlinJsPlatformTestRun::class.java) { name -> KotlinJsPlatformTestRun(name, this) }
|
||||
|
||||
fun configure() {
|
||||
NpmResolverPlugin.apply(project)
|
||||
|
||||
@@ -47,17 +53,27 @@ abstract class KotlinJsSubTarget(
|
||||
lowerCamelCaseName(target.disambiguationClassifier, disambiguationClassifier, name)
|
||||
|
||||
private fun configureTests() {
|
||||
target.compilations.all { compilation ->
|
||||
if (compilation.name == KotlinCompilation.TEST_COMPILATION_NAME) {
|
||||
configureTests(compilation)
|
||||
}
|
||||
testRuns.all { configureTestRunDefaults(it) }
|
||||
testRuns.create(KotlinTargetWithTests.DEFAULT_TEST_RUN_NAME)
|
||||
}
|
||||
|
||||
protected open fun configureTestRunDefaults(testRun: KotlinJsPlatformTestRun) {
|
||||
target.compilations.matching { it.name == KotlinCompilation.TEST_COMPILATION_NAME }.all { compilation ->
|
||||
configureTestsRun(testRun, compilation)
|
||||
}
|
||||
}
|
||||
|
||||
abstract val testTaskDescription: String
|
||||
|
||||
private fun configureTests(compilation: KotlinJsCompilation) {
|
||||
val testJs = project.createOrRegisterTask<KotlinJsTest>(testTaskName) { testJs ->
|
||||
private fun configureTestsRun(testRun: KotlinJsPlatformTestRun, compilation: KotlinJsCompilation) {
|
||||
fun KotlinJsPlatformTestRun.subtargetTestTaskName(): String = disambiguateCamelCased(
|
||||
lowerCamelCaseName(
|
||||
name.takeIf { it != KotlinTargetWithTests.DEFAULT_TEST_RUN_NAME },
|
||||
AbstractKotlinTargetConfigurator.testTaskNameSuffix
|
||||
)
|
||||
)
|
||||
|
||||
val testJs = project.createOrRegisterTask<KotlinJsTest>(testRun.subtargetTestTaskName()) { testJs ->
|
||||
val compileTask = compilation.compileKotlinTask
|
||||
|
||||
testJs.group = LifecycleBasePlugin.VERIFICATION_GROUP
|
||||
@@ -77,7 +93,14 @@ abstract class KotlinJsSubTarget(
|
||||
testJs.configureConventions()
|
||||
}
|
||||
|
||||
target.project.kotlinTestRegistry.registerTestTask(testJs, target.testTask.doGetTask())
|
||||
testRun.executionTask = testJs.getTaskOrProvider() as TaskProvider<KotlinJsTest>
|
||||
|
||||
target.testRuns.matching { it.name == testRun.name }.all { parentTestRun ->
|
||||
target.project.kotlinTestRegistry.registerTestTask(
|
||||
testJs,
|
||||
parentTestRun.executionTask.get()
|
||||
)
|
||||
}
|
||||
|
||||
project.whenEvaluated {
|
||||
testJs.configure {
|
||||
@@ -101,6 +124,6 @@ abstract class KotlinJsSubTarget(
|
||||
protected abstract fun configureRun(compilation: KotlinJsCompilation)
|
||||
|
||||
override fun testTask(body: KotlinJsTest.() -> Unit) {
|
||||
(project.tasks.getByName(testTaskName) as KotlinJsTest).body()
|
||||
project.locateTask<KotlinJsTest>(testTaskName)!!.configure(body)
|
||||
}
|
||||
}
|
||||
+8
-4
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.jvm
|
||||
|
||||
import org.gradle.api.InvalidUserCodeException
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
@@ -23,9 +24,11 @@ import java.util.concurrent.Callable
|
||||
|
||||
class KotlinJvmTarget(
|
||||
project: Project
|
||||
) : KotlinOnlyTarget<KotlinJvmCompilation>(
|
||||
project, KotlinPlatformType.jvm
|
||||
) {
|
||||
) : KotlinOnlyTarget<KotlinJvmCompilation>(project, KotlinPlatformType.jvm),
|
||||
KotlinTargetWithTests<JvmClasspathTestRunSource, KotlinJvmTestRun> {
|
||||
|
||||
override lateinit var testRuns: NamedDomainObjectContainer<KotlinJvmTestRun>
|
||||
|
||||
var withJavaEnabled = false
|
||||
private set
|
||||
|
||||
@@ -162,4 +165,5 @@ class KotlinJvmTarget(
|
||||
project.addExtendsFromRelation(compilation.runtimeDependencyConfigurationName, configurationName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+38
-2
@@ -5,14 +5,50 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.jvm
|
||||
|
||||
import org.gradle.api.plugins.JavaBasePlugin
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||
|
||||
class KotlinJvmTargetConfigurator(kotlinPluginVersion: String) :
|
||||
KotlinTargetConfigurator<KotlinJvmCompilation>(true, true, kotlinPluginVersion) {
|
||||
KotlinOnlyTargetConfigurator<KotlinJvmCompilation, KotlinJvmTarget>(true, true, kotlinPluginVersion),
|
||||
KotlinTargetWithTestsConfigurator<KotlinJvmTestRun, KotlinJvmTarget> {
|
||||
|
||||
override val testRunClass: Class<KotlinJvmTestRun>
|
||||
get() = KotlinJvmTestRun::class.java
|
||||
|
||||
override fun createTestRun(
|
||||
name: String,
|
||||
target: KotlinJvmTarget
|
||||
): KotlinJvmTestRun = KotlinJvmTestRun(name, target).apply {
|
||||
val testTaskOrProvider = target.project.createOrRegisterTask<KotlinJvmTest>(testTaskName) { testTask ->
|
||||
testTask.targetName = target.disambiguationClassifier
|
||||
testTask.project.tasks.findByName(JavaBasePlugin.CHECK_TASK_NAME)?.dependsOn(testTask)
|
||||
}
|
||||
|
||||
executionTask = testTaskOrProvider.getTaskOrProvider() as TaskProvider<KotlinJvmTest>
|
||||
|
||||
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME)
|
||||
|
||||
setExecutionSourceFrom(testCompilation)
|
||||
|
||||
target.project.whenEvaluated {
|
||||
// use afterEvaluate to override the JavaPlugin defaults for Test tasks
|
||||
testTaskOrProvider.configure { testTask ->
|
||||
testTask.description = "Runs the tests of the $name test run."
|
||||
testTask.group = JavaBasePlugin.VERIFICATION_GROUP
|
||||
}
|
||||
}
|
||||
|
||||
target.project.kotlinTestRegistry.registerTestTask(testTaskOrProvider)
|
||||
}
|
||||
|
||||
override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> {
|
||||
val tasksProvider = KotlinTasksProvider(compilation.target.targetName)
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.targets.jvm
|
||||
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
|
||||
import org.jetbrains.kotlin.gradle.testing.KotlinTaskTestRun
|
||||
import org.jetbrains.kotlin.gradle.testing.requireCompilationOfTarget
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
internal class ClasspathOnlyTestRunSource(
|
||||
override val classpath: FileCollection,
|
||||
override val testClassesDirs: FileCollection
|
||||
) : JvmClasspathTestRunSource
|
||||
|
||||
internal open class JvmCompilationsTestRunSource(
|
||||
val classpathCompilations: Iterable<KotlinJvmCompilation>,
|
||||
val testCompilations: Iterable<KotlinJvmCompilation>
|
||||
) : JvmClasspathTestRunSource {
|
||||
private val project get() = testCompilations.first().target.project
|
||||
|
||||
override val testClassesDirs: FileCollection
|
||||
get() = project.files(testCompilations.map { it.output.classesDirs })
|
||||
|
||||
override val classpath: FileCollection
|
||||
get() = project.files(
|
||||
(testCompilations + classpathCompilations).distinct().map { it.output.allOutputs + it.runtimeDependencyFiles }
|
||||
)
|
||||
}
|
||||
|
||||
internal class SingleJvmCompilationTestRunSource(
|
||||
override val compilation: KotlinJvmCompilation
|
||||
) : JvmCompilationsTestRunSource(listOf(compilation), listOf(compilation)), CompilationExecutionSource<KotlinJvmCompilation>
|
||||
|
||||
open class KotlinJvmTestRun(testRunName: String, override val target: KotlinJvmTarget) :
|
||||
KotlinTaskTestRun<JvmClasspathTestRunSource, KotlinJvmTest>(testRunName, target),
|
||||
CompilationExecutionSourceSupport<KotlinJvmCompilation>,
|
||||
ClasspathTestRunSourceSupport {
|
||||
|
||||
override fun setExecutionSourceFrom(classpath: FileCollection, testClassesDirs: FileCollection) {
|
||||
executionSource = ClasspathOnlyTestRunSource(classpath, testClassesDirs)
|
||||
}
|
||||
|
||||
fun setExecutionSourceFrom(
|
||||
classpathCompilations: Iterable<KotlinJvmCompilation>,
|
||||
testClassesCompilations: Iterable<KotlinJvmCompilation>
|
||||
) {
|
||||
classpathCompilations.forEach { requireCompilationOfTarget(it, target) }
|
||||
executionSource = JvmCompilationsTestRunSource(classpathCompilations, testClassesCompilations)
|
||||
}
|
||||
|
||||
override fun setExecutionSourceFrom(compilation: KotlinJvmCompilation) {
|
||||
executionSource = SingleJvmCompilationTestRunSource(compilation)
|
||||
}
|
||||
|
||||
private var _executionSource: JvmClasspathTestRunSource by Delegates.notNull()
|
||||
|
||||
final override var executionSource: JvmClasspathTestRunSource
|
||||
get() = _executionSource
|
||||
private set(value) {
|
||||
setTestTaskClasspathAndClassesDirs(value.classpath, value.testClassesDirs)
|
||||
}
|
||||
|
||||
private fun setTestTaskClasspathAndClassesDirs(classpath: FileCollection, testClassesDirs: FileCollection) {
|
||||
executionTask.configure {
|
||||
it.classpath = classpath
|
||||
it.testClassesDirs = testClassesDirs
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
@@ -9,6 +9,9 @@ import org.gradle.api.internal.tasks.testing.*
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.api.tasks.testing.TestFilter
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTestRun
|
||||
|
||||
open class KotlinJvmTest : Test() {
|
||||
@Input
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ internal val Project.isKotlinGranularMetadataEnabled: Boolean
|
||||
get() = PropertiesProvider(rootProject).enableGranularSourceSetsMetadata == true
|
||||
|
||||
class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
||||
KotlinTargetConfigurator<KotlinCommonCompilation>(
|
||||
KotlinOnlyTargetConfigurator<KotlinCommonCompilation, KotlinMetadataTarget>(
|
||||
createDefaultSourceSets = false,
|
||||
createTestCompilation = false,
|
||||
kotlinPluginVersion = kotlinPluginVersion
|
||||
@@ -59,7 +59,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
||||
private val KotlinOnlyTarget<KotlinCommonCompilation>.apiElementsConfiguration: Configuration
|
||||
get() = project.configurations.getByName(apiElementsConfigurationName)
|
||||
|
||||
override fun configureTarget(target: KotlinOnlyTarget<KotlinCommonCompilation>) {
|
||||
override fun configureTarget(target: KotlinMetadataTarget) {
|
||||
super.configureTarget(target)
|
||||
|
||||
if (target.project.isKotlinGranularMetadataEnabled) {
|
||||
|
||||
+5
-5
@@ -12,14 +12,14 @@ import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinOnlyTargetConfigurator
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigurator
|
||||
|
||||
class KotlinMetadataTargetPreset(
|
||||
project: Project,
|
||||
kotlinPluginVersion: String
|
||||
) : KotlinOnlyTargetPreset<KotlinOnlyTarget<KotlinCommonCompilation>, KotlinCommonCompilation>(
|
||||
) : KotlinOnlyTargetPreset<KotlinMetadataTarget, KotlinCommonCompilation>(
|
||||
project,
|
||||
kotlinPluginVersion
|
||||
) {
|
||||
@@ -37,12 +37,12 @@ class KotlinMetadataTargetPreset(
|
||||
const val PRESET_NAME = "metadata"
|
||||
}
|
||||
|
||||
override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<KotlinCommonCompilation> =
|
||||
override fun createKotlinTargetConfigurator(): KotlinOnlyTargetConfigurator<KotlinCommonCompilation, KotlinMetadataTarget> =
|
||||
KotlinMetadataTargetConfigurator(kotlinPluginVersion)
|
||||
|
||||
override fun instantiateTarget(): KotlinOnlyTarget<KotlinCommonCompilation> = KotlinMetadataTarget(project)
|
||||
override fun instantiateTarget(): KotlinMetadataTarget = KotlinMetadataTarget(project)
|
||||
|
||||
override fun createTarget(name: String): KotlinOnlyTarget<KotlinCommonCompilation> =
|
||||
override fun createTarget(name: String): KotlinMetadataTarget =
|
||||
super.createTarget(name).apply {
|
||||
val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||
val commonMainSourceSet = project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME)
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.targets.native
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompilationExecutionSource
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetTestRun
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.TestExecutable
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
import org.jetbrains.kotlin.gradle.testing.KotlinTaskTestRun
|
||||
|
||||
class NativeBinaryTestRunSource(val binary: TestExecutable) :
|
||||
CompilationExecutionSource<KotlinNativeCompilation> {
|
||||
|
||||
override val compilation: KotlinNativeCompilation
|
||||
get() = binary.compilation
|
||||
}
|
||||
|
||||
interface KotlinNativeBinaryTestRun : KotlinTargetTestRun<NativeBinaryTestRunSource> {
|
||||
/**
|
||||
* Sets this test run to use the specified [testExecutable].
|
||||
*
|
||||
* This overrides other [executionSource] options.
|
||||
*/
|
||||
fun setExecutionSourceFrom(testExecutable: TestExecutable)
|
||||
}
|
||||
|
||||
open class DefaultKotlinNativeTestRun(testRunName: String, target: KotlinNativeTarget) :
|
||||
KotlinTaskTestRun<NativeBinaryTestRunSource, KotlinNativeTest>(testRunName, target),
|
||||
KotlinNativeBinaryTestRun {
|
||||
|
||||
private lateinit var _executionSource: NativeBinaryTestRunSource
|
||||
|
||||
final override var executionSource: NativeBinaryTestRunSource
|
||||
get() = _executionSource
|
||||
private set(value) {
|
||||
executionTask.configure {
|
||||
it.executable(value.binary.linkTask) { value.binary.outputFile }
|
||||
}
|
||||
_executionSource = value
|
||||
}
|
||||
|
||||
override fun setExecutionSourceFrom(testExecutable: TestExecutable) {
|
||||
require(testExecutable.target === target) {
|
||||
"Expected a test fbinary of target ${target.name}, " +
|
||||
"got the binary ${testExecutable.name} of target ${testExecutable.target.name}"
|
||||
}
|
||||
|
||||
executionSource = NativeBinaryTestRunSource(testExecutable)
|
||||
}
|
||||
}
|
||||
+14
-1
@@ -7,16 +7,20 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.gradle.util.WrapUtil
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetWithTests
|
||||
import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeBinaryTestRun
|
||||
import org.jetbrains.kotlin.gradle.targets.native.NativeBinaryTestRunSource
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
class KotlinNativeTarget(
|
||||
open class KotlinNativeTarget(
|
||||
project: Project,
|
||||
val konanTarget: KonanTarget
|
||||
) : KotlinOnlyTarget<KotlinNativeCompilation>(project, KotlinPlatformType.native) {
|
||||
@@ -61,4 +65,13 @@ class KotlinNativeTarget(
|
||||
String::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
open class KotlinNativeTargetWithTests(
|
||||
project: Project,
|
||||
konanTarget: KonanTarget
|
||||
) : KotlinNativeTarget(project, konanTarget), KotlinTargetWithTests<NativeBinaryTestRunSource, KotlinNativeBinaryTestRun> {
|
||||
|
||||
override lateinit var testRuns: NamedDomainObjectContainer<KotlinNativeBinaryTestRun>
|
||||
internal set
|
||||
}
|
||||
+46
-37
@@ -17,22 +17,24 @@ import org.gradle.api.internal.plugins.DefaultArtifactPublicationSet
|
||||
import org.gradle.api.plugins.BasePlugin
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.Exec
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.DefaultKotlinNativeTestRun
|
||||
import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeBinaryTestRun
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.gradle.testing.testTaskName
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
open class KotlinNativeTargetConfigurator(
|
||||
open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
private val kotlinPluginVersion: String
|
||||
) : AbstractKotlinTargetConfigurator<KotlinNativeTarget>(
|
||||
) : AbstractKotlinTargetConfigurator<T>(
|
||||
createDefaultSourceSets = true,
|
||||
createTestCompilation = true
|
||||
) {
|
||||
@@ -212,15 +214,14 @@ open class KotlinNativeTargetConfigurator(
|
||||
// endregion.
|
||||
|
||||
// region Configuration.
|
||||
override fun configureTarget(target: KotlinNativeTarget) {
|
||||
super.configureTarget(target)
|
||||
override fun configurePlatformSpecificModel(target: T) {
|
||||
configureBinaries(target)
|
||||
configureFrameworkExport(target)
|
||||
configureCInterops(target)
|
||||
warnAboutIncorrectDependencies(target)
|
||||
}
|
||||
|
||||
override fun configureArchivesAndComponent(target: KotlinNativeTarget): Unit = with(target.project) {
|
||||
override fun configureArchivesAndComponent(target: T): Unit = with(target.project) {
|
||||
tasks.create(target.artifactsTaskName)
|
||||
target.compilations.all {
|
||||
createKlibCompilationTask(it)
|
||||
@@ -231,35 +232,6 @@ open class KotlinNativeTargetConfigurator(
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureTest(target: KotlinNativeTarget): Unit = with(target.project) {
|
||||
// We create test binaries for all platforms.
|
||||
target.binaries.test(listOf(NativeBuildType.DEBUG)) {
|
||||
|
||||
// But run them only on host ones.
|
||||
if (target.konanTarget in listOf(KonanTarget.MACOS_X64, KonanTarget.MINGW_X64, KonanTarget.LINUX_X64)) {
|
||||
|
||||
val taskName = lowerCamelCaseName(target.disambiguationClassifier, testTaskNameSuffix)
|
||||
val testTask = createOrRegisterTask<KotlinNativeTest>(taskName) { testTask ->
|
||||
testTask.group = LifecycleBasePlugin.VERIFICATION_GROUP
|
||||
testTask.description = "Executes Kotlin/Native unit tests for target ${target.name}."
|
||||
testTask.targetName = compilation.target.targetName
|
||||
|
||||
testTask.enabled = target.konanTarget.isCurrentHost
|
||||
|
||||
testTask.executable { outputFile }
|
||||
testTask.workingDir = project.projectDir.absolutePath
|
||||
|
||||
testTask.onlyIf { outputFile.exists() }
|
||||
testTask.dependsOn(linkTaskName)
|
||||
|
||||
testTask.configureConventions()
|
||||
}
|
||||
|
||||
kotlinTestRegistry.registerTestTask(testTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
|
||||
target.compilations.all { compilation ->
|
||||
createCInteropTasks(compilation)
|
||||
@@ -306,6 +278,11 @@ open class KotlinNativeTargetConfigurator(
|
||||
project.tasks.getByName(it.compilation.binariesTaskName).dependsOn(it.linkTaskName)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We create test binaries for all platforms but test runs only for host platforms, see [KotlinNativeTargetWithTestsConfigurator]
|
||||
*/
|
||||
target.binaries.test(listOf(NativeBuildType.DEBUG)) { }
|
||||
}
|
||||
|
||||
fun configureFrameworkExport(target: KotlinNativeTarget) {
|
||||
@@ -335,7 +312,7 @@ open class KotlinNativeTargetConfigurator(
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineConfigurationsForTarget(target: KotlinNativeTarget) {
|
||||
override fun defineConfigurationsForTarget(target: T) {
|
||||
super.defineConfigurationsForTarget(target)
|
||||
val configurations = target.project.configurations
|
||||
|
||||
@@ -411,3 +388,35 @@ open class KotlinNativeTargetConfigurator(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinNativeTargetWithTestsConfigurator(kotlinPluginVersion: String)
|
||||
: KotlinNativeTargetConfigurator<KotlinNativeTargetWithTests>(kotlinPluginVersion),
|
||||
KotlinTargetWithTestsConfigurator<KotlinNativeBinaryTestRun, KotlinNativeTargetWithTests> {
|
||||
|
||||
override val testRunClass: Class<KotlinNativeBinaryTestRun>
|
||||
get() = KotlinNativeBinaryTestRun::class.java
|
||||
|
||||
override fun createTestRun(name: String, target: KotlinNativeTargetWithTests): KotlinNativeBinaryTestRun =
|
||||
DefaultKotlinNativeTestRun(name, target).apply {
|
||||
val project = target.project
|
||||
|
||||
val testTaskOrProvider = project.createOrRegisterTask<KotlinNativeTest>(testTaskName) { testTask ->
|
||||
testTask.group = LifecycleBasePlugin.VERIFICATION_GROUP
|
||||
testTask.description = "Executes Kotlin/Native unit tests for target ${target.name}."
|
||||
testTask.targetName = target.name
|
||||
|
||||
testTask.enabled = target.konanTarget.isCurrentHost
|
||||
|
||||
testTask.workingDir = project.projectDir.absolutePath
|
||||
|
||||
testTask.configureConventions()
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
executionTask = testTaskOrProvider.getTaskOrProvider() as TaskProvider<KotlinNativeTest>
|
||||
|
||||
setExecutionSourceFrom(target.binaries.getTest(NativeBuildType.DEBUG))
|
||||
|
||||
project.kotlinTestRegistry.registerTestTask(testTaskOrProvider)
|
||||
}
|
||||
}
|
||||
|
||||
+29
-7
@@ -17,12 +17,12 @@ import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
class KotlinNativeTargetPreset(
|
||||
abstract class AbstractKotlinNativeTargetPreset<T : KotlinNativeTarget>(
|
||||
private val name: String,
|
||||
val project: Project,
|
||||
val konanTarget: KonanTarget,
|
||||
private val kotlinPluginVersion: String
|
||||
) : KotlinTargetPreset<KotlinNativeTarget> {
|
||||
protected val kotlinPluginVersion: String
|
||||
) : KotlinTargetPreset<T> {
|
||||
|
||||
init {
|
||||
// This is required to obtain Kotlin/Native home in CLion plugin:
|
||||
@@ -69,19 +69,23 @@ class KotlinNativeTargetPreset(
|
||||
filesList?.map { dir -> dependencies.create(files(dir)) } ?: emptyList()
|
||||
}
|
||||
|
||||
override fun createTarget(name: String): KotlinNativeTarget {
|
||||
protected abstract fun createTargetConfigurator() : KotlinTargetConfigurator<T>
|
||||
|
||||
protected abstract fun instantiateTarget(name: String): T
|
||||
|
||||
override fun createTarget(name: String): T {
|
||||
setupNativeCompiler()
|
||||
|
||||
val result = KotlinNativeTarget(project, konanTarget).apply {
|
||||
val result = instantiateTarget(name).apply {
|
||||
targetName = name
|
||||
disambiguationClassifier = name
|
||||
preset = this@KotlinNativeTargetPreset
|
||||
preset = this@AbstractKotlinNativeTargetPreset
|
||||
|
||||
val compilationFactory = KotlinNativeCompilationFactory(project, this)
|
||||
compilations = project.container(compilationFactory.itemClass, compilationFactory)
|
||||
}
|
||||
|
||||
KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result)
|
||||
createTargetConfigurator().configureTarget(result)
|
||||
|
||||
// Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies.
|
||||
|
||||
@@ -114,6 +118,24 @@ class KotlinNativeTargetPreset(
|
||||
}
|
||||
}
|
||||
|
||||
open class KotlinNativeTargetPreset(name: String, project: Project, konanTarget: KonanTarget, kotlinPluginVersion: String) :
|
||||
AbstractKotlinNativeTargetPreset<KotlinNativeTarget>(name, project, konanTarget, kotlinPluginVersion) {
|
||||
|
||||
override fun createTargetConfigurator(): KotlinTargetConfigurator<KotlinNativeTarget> =
|
||||
KotlinNativeTargetConfigurator(kotlinPluginVersion)
|
||||
|
||||
override fun instantiateTarget(name: String): KotlinNativeTarget = KotlinNativeTarget(project, konanTarget)
|
||||
}
|
||||
|
||||
open class KotlinNativeTargetWithTestsPreset(name: String, project: Project, konanTarget: KonanTarget, kotlinPluginVersion: String) :
|
||||
AbstractKotlinNativeTargetPreset<KotlinNativeTargetWithTests>(name, project, konanTarget, kotlinPluginVersion) {
|
||||
|
||||
override fun createTargetConfigurator(): KotlinTargetConfigurator<KotlinNativeTargetWithTests> =
|
||||
KotlinNativeTargetWithTestsConfigurator(kotlinPluginVersion)
|
||||
|
||||
override fun instantiateTarget(name: String): KotlinNativeTargetWithTests = KotlinNativeTargetWithTests(project, konanTarget)
|
||||
}
|
||||
|
||||
internal val KonanTarget.isCurrentHost: Boolean
|
||||
get() = this == HostManager.host
|
||||
|
||||
|
||||
+34
-13
@@ -6,11 +6,11 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.native.tasks
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.SkipWhenEmpty
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.process.ProcessForkOptions
|
||||
import org.gradle.process.internal.DefaultProcessForkOptions
|
||||
import org.jetbrains.kotlin.compilerRunner.konanVersion
|
||||
@@ -21,14 +21,27 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinTest
|
||||
import org.jetbrains.kotlin.konan.KonanVersion
|
||||
import org.jetbrains.kotlin.konan.MetaVersion
|
||||
import java.io.File
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
open class KotlinNativeTest : KotlinTest() {
|
||||
@Suppress("LeakingThis")
|
||||
private val processOptions: ProcessForkOptions = DefaultProcessForkOptions(fileResolver)
|
||||
|
||||
@InputFile
|
||||
@SkipWhenEmpty
|
||||
val executableProperty: Property<File> = project.objects.property(File::class.java)
|
||||
@get:Internal
|
||||
val executableProperty: Property<FileCollection> = project.objects.property(FileCollection::class.java)
|
||||
|
||||
@get:InputFiles // use FileCollection & @InputFiles rather than @InputFile to allow for task dependencies built-into this FileCollection
|
||||
@get:SkipWhenEmpty
|
||||
@Suppress("UNUSED") // Gradle input
|
||||
internal val executableFiles: FileCollection // Gradle < 5.0 seems to not work properly with @InputFiles Property<FileCollection>
|
||||
get() = executableProperty.get()
|
||||
|
||||
private val executableFile
|
||||
get() = executableProperty.get().singleFile
|
||||
|
||||
init {
|
||||
onlyIf { executableFile.exists() }
|
||||
}
|
||||
|
||||
@Input
|
||||
var args: List<String> = emptyList()
|
||||
@@ -36,9 +49,9 @@ open class KotlinNativeTest : KotlinTest() {
|
||||
// Already taken into account in the executableProperty.
|
||||
@get:Internal
|
||||
var executable: File
|
||||
get() = executableProperty.get()
|
||||
get() = executableProperty.get().singleFile
|
||||
set(value) {
|
||||
executableProperty.set(value)
|
||||
executableProperty.set(project.files(value))
|
||||
}
|
||||
|
||||
@get:Input
|
||||
@@ -58,19 +71,27 @@ open class KotlinNativeTest : KotlinTest() {
|
||||
private fun <T> Property<T>.set(providerLambda: () -> T) = set(project.provider { providerLambda() })
|
||||
|
||||
fun executable(file: File) {
|
||||
executableProperty.set(file)
|
||||
executableProperty.set(project.files(file))
|
||||
}
|
||||
|
||||
fun executable(path: String) {
|
||||
executableProperty.set { project.file(path) }
|
||||
executableProperty.set { project.files(path) }
|
||||
}
|
||||
|
||||
fun executable(provider: () -> File) {
|
||||
executableProperty.set(provider)
|
||||
executableProperty.set(project.files(Callable { provider() }))
|
||||
}
|
||||
|
||||
fun executable(builtByTask: Task, provider: () -> File) {
|
||||
executableProperty.set(project.files(Callable { provider() }).builtBy(builtByTask))
|
||||
}
|
||||
|
||||
fun executable(provider: Provider<File>) {
|
||||
executableProperty.set(provider.map { project.files(it) })
|
||||
}
|
||||
|
||||
fun executable(provider: Closure<File>) {
|
||||
executableProperty.set(project.provider(provider))
|
||||
executableProperty.set(project.provider(provider).map { project.files(it) })
|
||||
}
|
||||
|
||||
fun environment(name: String, value: Any) {
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.testing
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.testing.AbstractTestTask
|
||||
import org.gradle.api.tasks.testing.TestFilter
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.execution.KotlinAggregateExecutionSource
|
||||
import org.jetbrains.kotlin.gradle.execution.KotlinAggregatingExecution
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinExecution.ExecutionSource
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestReport
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
|
||||
interface KotlinAggregatingTestRun<S : ExecutionSource, A : KotlinAggregateExecutionSource<S>, T : KotlinTestRun<S>> :
|
||||
KotlinAggregatingExecution<S, A, T>,
|
||||
KotlinTestRun<A> {
|
||||
|
||||
override fun filter(configureFilter: TestFilter.() -> Unit) {
|
||||
configureAllExecutions { filter(configureFilter) }
|
||||
}
|
||||
}
|
||||
|
||||
abstract class KotlinTaskTestRun<S : ExecutionSource, T : AbstractTestTask>(
|
||||
private val testRunName: String,
|
||||
override val target: KotlinTarget
|
||||
) : KotlinTargetTestRun<S>, ExecutionTaskHolder<T> {
|
||||
|
||||
override fun getName(): String =
|
||||
testRunName
|
||||
|
||||
override lateinit var executionTask: TaskProvider<T>
|
||||
internal set
|
||||
|
||||
override fun filter(configureFilter: TestFilter.() -> Unit) {
|
||||
executionTask.configure { task -> configureFilter(task.filter) }
|
||||
}
|
||||
}
|
||||
|
||||
internal val KotlinTargetTestRun<*>.testTaskName: String
|
||||
get() = lowerCamelCaseName(
|
||||
target.disambiguationClassifier,
|
||||
name.takeIf { it != KotlinTargetWithTests.DEFAULT_TEST_RUN_NAME }?.removeSuffix("Test"),
|
||||
AbstractKotlinTargetConfigurator.testTaskNameSuffix
|
||||
)
|
||||
|
||||
internal fun requireCompilationOfTarget(compilation: KotlinCompilation<*>, target: KotlinTarget) {
|
||||
require(compilation.target === target) {
|
||||
"Expected a compilation of target ${target.name}, " +
|
||||
"got the compilation ${compilation.name} of target ${compilation.target.name}"
|
||||
}
|
||||
}
|
||||
|
||||
abstract class KotlinReportAggregatingTestRun<E : ExecutionSource, A : KotlinAggregateExecutionSource<E>, T : KotlinTestRun<E>>(
|
||||
val testRunName: String
|
||||
) : KotlinAggregatingTestRun<E, A, T>,
|
||||
ExecutionTaskHolder<KotlinTestReport> {
|
||||
|
||||
override fun getName() = testRunName
|
||||
|
||||
override lateinit var executionTask: TaskProvider<KotlinTestReport>
|
||||
|
||||
override fun filter(configureFilter: TestFilter.() -> Unit) = configureAllExecutions { filter(configureFilter) }
|
||||
}
|
||||
Reference in New Issue
Block a user