Gradle, JS: introduce RequiresNpmDependencies
#KT-30530
This commit is contained in:
+1
-17
@@ -15,9 +15,7 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
|
|||||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
|
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
|
||||||
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
||||||
|
|
||||||
class KotlinBrowserJs(
|
class KotlinBrowserJs(target: KotlinOnlyTarget<KotlinJsCompilation>) : KotlinJsInnerTargetConfigurator(target, "browser") {
|
||||||
target: KotlinOnlyTarget<KotlinJsCompilation>
|
|
||||||
) : KotlinJsInnerTargetConfigurator(target) {
|
|
||||||
private val versions = project.nodeJs.versions
|
private val versions = project.nodeJs.versions
|
||||||
|
|
||||||
override fun configureDefaultTestFramework(it: KotlinJsTest) {
|
override fun configureDefaultTestFramework(it: KotlinJsTest) {
|
||||||
@@ -32,16 +30,6 @@ class KotlinBrowserJs(
|
|||||||
val npmProject = project.npmProject
|
val npmProject = project.npmProject
|
||||||
val compileKotlinTask = compilation.compileKotlinTask
|
val compileKotlinTask = compilation.compileKotlinTask
|
||||||
|
|
||||||
compilation.dependencies {
|
|
||||||
runtimeOnly(versions.webpack)
|
|
||||||
runtimeOnly(versions.webpackCli)
|
|
||||||
runtimeOnly(versions.webpackBundleAnalyzer)
|
|
||||||
|
|
||||||
// for source map support
|
|
||||||
runtimeOnly(versions.sourceMapLoader.npm(project))
|
|
||||||
runtimeOnly(versions.sourceMapSupport.npm(project))
|
|
||||||
}
|
|
||||||
|
|
||||||
project.createOrRegisterTask<KotlinWebpack>(disambiguateCamelCased("webpack")) {
|
project.createOrRegisterTask<KotlinWebpack>(disambiguateCamelCased("webpack")) {
|
||||||
it.dependsOn(compileKotlinTask)
|
it.dependsOn(compileKotlinTask)
|
||||||
|
|
||||||
@@ -50,10 +38,6 @@ class KotlinBrowserJs(
|
|||||||
project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(it)
|
project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
compilation.dependencies {
|
|
||||||
runtimeOnly(npm("webpack-dev-server", "3.3.1"))
|
|
||||||
}
|
|
||||||
|
|
||||||
project.createOrRegisterTask<KotlinWebpack>(disambiguateCamelCased("run")) {
|
project.createOrRegisterTask<KotlinWebpack>(disambiguateCamelCased("run")) {
|
||||||
it.dependsOn(compileKotlinTask)
|
it.dependsOn(compileKotlinTask)
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -16,9 +16,11 @@ import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
|||||||
import org.jetbrains.kotlin.gradle.testing.internal.registerTestTask
|
import org.jetbrains.kotlin.gradle.testing.internal.registerTestTask
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
abstract class KotlinJsInnerTargetConfigurator(val target: KotlinOnlyTarget<KotlinJsCompilation>) {
|
abstract class KotlinJsInnerTargetConfigurator(
|
||||||
|
val target: KotlinOnlyTarget<KotlinJsCompilation>,
|
||||||
|
private val disambiguationClassifier: String
|
||||||
|
) {
|
||||||
val project get() = target.project
|
val project get() = target.project
|
||||||
private val disambiguationClassifier get() = "browser"
|
|
||||||
|
|
||||||
fun configure() {
|
fun configure() {
|
||||||
configureTests()
|
configureTests()
|
||||||
@@ -64,7 +66,6 @@ abstract class KotlinJsInnerTargetConfigurator(val target: KotlinOnlyTarget<Kotl
|
|||||||
compileTask.outputFile.exists()
|
compileTask.outputFile.exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
testJs.runtimeDependencyHandler = compilation
|
|
||||||
testJs.targetName = disambiguationClassifier
|
testJs.targetName = disambiguationClassifier
|
||||||
testJs.nodeModulesToLoad.add(compileTask.outputFile.name)
|
testJs.nodeModulesToLoad.add(compileTask.outputFile.name)
|
||||||
|
|
||||||
@@ -85,6 +86,7 @@ abstract class KotlinJsInnerTargetConfigurator(val target: KotlinOnlyTarget<Kotl
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun configureDefaultTestFramework(it: KotlinJsTest)
|
protected abstract fun configureDefaultTestFramework(it: KotlinJsTest)
|
||||||
|
|
||||||
fun configureRun() {
|
fun configureRun() {
|
||||||
target.compilations.all { compilation ->
|
target.compilations.all { compilation ->
|
||||||
if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) {
|
if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) {
|
||||||
|
|||||||
+7
-15
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.artifacts.ResolvedArtifact
|
import org.gradle.api.artifacts.ResolvedArtifact
|
||||||
import org.gradle.api.artifacts.ResolvedDependency
|
import org.gradle.api.artifacts.ResolvedDependency
|
||||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||||
@@ -27,30 +28,21 @@ internal class GradleNodeModulesBuilder(val project: Project) : AutoCloseable {
|
|||||||
GradleNodeModule(it, dir.resolve(it))
|
GradleNodeModule(it, dir.resolve(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun visitCompilation(compilation: KotlinCompilation<KotlinCommonOptions>) {
|
fun visitConfiguration(configuration: Configuration) {
|
||||||
val project = compilation.target.project
|
if (configuration.isCanBeResolved) {
|
||||||
|
configuration.resolvedConfiguration.firstLevelModuleDependencies.forEach {
|
||||||
// classpath
|
visitDependency(it)
|
||||||
compilation.relatedConfigurationNames.forEach { configurationName ->
|
|
||||||
val configuration = project.configurations.getByName(configurationName)
|
|
||||||
if (configuration.isCanBeResolved) {
|
|
||||||
configuration.resolvedConfiguration.firstLevelModuleDependencies.forEach {
|
|
||||||
visitDependency(compilation, it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun visitDependency(
|
private fun visitDependency(dependency: ResolvedDependency) {
|
||||||
compilation: KotlinCompilation<KotlinCommonOptions>,
|
|
||||||
dependency: ResolvedDependency
|
|
||||||
) {
|
|
||||||
if (!visited.add(dependency)) return
|
if (!visited.add(dependency)) return
|
||||||
|
|
||||||
visitArtifacts(dependency, dependency.moduleArtifacts)
|
visitArtifacts(dependency, dependency.moduleArtifacts)
|
||||||
|
|
||||||
dependency.children.forEach {
|
dependency.children.forEach {
|
||||||
visitDependency(compilation, it)
|
visitDependency(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-2
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.Dependency
|
||||||
|
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||||
|
|
||||||
class NpmPackages {
|
class NpmPackages {
|
||||||
val webpack = NpmPackageVersion("webpack", "4.29.6")
|
val webpack = NpmPackageVersion("webpack", "4.29.6")
|
||||||
@@ -17,6 +19,7 @@ class NpmPackages {
|
|||||||
val sourceMapSupport = NpmPackageVersion("source-map-support", "0.5.12")
|
val sourceMapSupport = NpmPackageVersion("source-map-support", "0.5.12")
|
||||||
|
|
||||||
val mocha = NpmPackageVersion("mocha", "6.1.2")
|
val mocha = NpmPackageVersion("mocha", "6.1.2")
|
||||||
|
val mochaTeamCityReporter = NpmPackageVersion("mocha-teamcity-reporter", ">=2.0.0")
|
||||||
|
|
||||||
val karma = NpmPackageVersion("karma", "4.0.1")
|
val karma = NpmPackageVersion("karma", "4.0.1")
|
||||||
val karmaTeamcityReporter = NpmPackageVersion("karma-teamcity-reporter", "1.1.0")
|
val karmaTeamcityReporter = NpmPackageVersion("karma-teamcity-reporter", "1.1.0")
|
||||||
@@ -32,8 +35,19 @@ class NpmPackages {
|
|||||||
val karmaWebpack = NpmPackageVersion("karma-webpack", "*")
|
val karmaWebpack = NpmPackageVersion("karma-webpack", "*")
|
||||||
|
|
||||||
val karmaSourceMapSupport = NpmPackageVersion("karma-source-map-support", "1.4.0")
|
val karmaSourceMapSupport = NpmPackageVersion("karma-source-map-support", "1.4.0")
|
||||||
|
|
||||||
|
val kotlinNodeJsTestRunner = KotlinGradleNpmPackage("test-nodejs-runner")
|
||||||
}
|
}
|
||||||
|
|
||||||
data class NpmPackageVersion(val name: String, var version: String) {
|
interface RequiredKotlinJsDependency {
|
||||||
fun npm(project: Project) = NpmDependency(project, null, name, version)
|
fun createDependency(project: Project): Dependency
|
||||||
|
}
|
||||||
|
|
||||||
|
data class NpmPackageVersion(val name: String, var version: String) : RequiredKotlinJsDependency {
|
||||||
|
override fun createDependency(project: Project) = NpmDependency(project, null, name, version)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class KotlinGradleNpmPackage(val simpleModuleName: String): RequiredKotlinJsDependency {
|
||||||
|
override fun createDependency(project: Project): Dependency =
|
||||||
|
project.dependencies.create("org.jetbrains.kotlin:kotlin-$simpleModuleName")
|
||||||
}
|
}
|
||||||
|
|||||||
+79
-9
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.gradle.targets.js.npm
|
|||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.gradle.api.execution.TaskExecutionGraph
|
||||||
import org.gradle.api.file.CopySpec
|
import org.gradle.api.file.CopySpec
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension
|
||||||
@@ -46,7 +48,23 @@ internal class NpmResolver private constructor(val rootProject: Project) {
|
|||||||
else {
|
else {
|
||||||
val resolver = NpmResolver(rootProject)
|
val resolver = NpmResolver(rootProject)
|
||||||
check(resolver.resolve(rootProject, null))
|
check(resolver.resolve(rootProject, null))
|
||||||
ResolvedNow(ResolvedProject(resolver.npmPackages))
|
ResolvedNow(ResolvedProject(resolver.npmPackages, resolver.requiredByTasks))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkRequiredDependencies(project: Project, target: RequiresNpmDependencies) {
|
||||||
|
val required = ProjectData[project.rootProject]?.resolved?.requiredByTasks
|
||||||
|
check(required != null) {
|
||||||
|
"NPM dependencies should be resolved before $target execution"
|
||||||
|
}
|
||||||
|
|
||||||
|
val targetRequired = required!![target]?.toSet() ?: setOf()
|
||||||
|
|
||||||
|
target.requiredNpmDependencies.forEach {
|
||||||
|
check(it in targetRequired) {
|
||||||
|
"$it required by $target after npm dependencies was resolved. " +
|
||||||
|
"This may be caused by changing $target configuration after npm dependencies resolution."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,9 +80,17 @@ internal class NpmResolver private constructor(val rootProject: Project) {
|
|||||||
private val packageManager = nodeJs.packageManager
|
private val packageManager = nodeJs.packageManager
|
||||||
private val hoistGradleNodeModules = npmProject.hoistGradleNodeModules
|
private val hoistGradleNodeModules = npmProject.hoistGradleNodeModules
|
||||||
private val npmPackages = mutableListOf<NpmPackage>()
|
private val npmPackages = mutableListOf<NpmPackage>()
|
||||||
|
private val requiredByTasks = mutableMapOf<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>()
|
||||||
private val gson = GsonBuilder()
|
private val gson = GsonBuilder()
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
.create()
|
.create()
|
||||||
|
private val readyTaskGraph: TaskExecutionGraph?
|
||||||
|
|
||||||
|
init {
|
||||||
|
var readyTaskGraph: TaskExecutionGraph? = null
|
||||||
|
rootProject.gradle.taskGraph.whenReady { readyTaskGraph = it }
|
||||||
|
this.readyTaskGraph = readyTaskGraph
|
||||||
|
}
|
||||||
|
|
||||||
class ProjectData(var resolved: ResolvedProject? = null) {
|
class ProjectData(var resolved: ResolvedProject? = null) {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -74,7 +100,10 @@ internal class NpmResolver private constructor(val rootProject: Project) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResolvedProject(val npmPackages: Collection<NpmPackage>) {
|
class ResolvedProject(
|
||||||
|
val npmPackages: Collection<NpmPackage>,
|
||||||
|
val requiredByTasks: Map<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>
|
||||||
|
) {
|
||||||
val dependencies by lazy {
|
val dependencies by lazy {
|
||||||
npmPackages.flatMapTo(mutableSetOf()) { it.npmDependencies }
|
npmPackages.flatMapTo(mutableSetOf()) { it.npmDependencies }
|
||||||
}
|
}
|
||||||
@@ -157,6 +186,8 @@ internal class NpmResolver private constructor(val rootProject: Project) {
|
|||||||
val packageJson = PackageJson(project.name, project.version.toString())
|
val packageJson = PackageJson(project.name, project.version.toString())
|
||||||
val npmDependencies = mutableSetOf<NpmDependency>()
|
val npmDependencies = mutableSetOf<NpmDependency>()
|
||||||
|
|
||||||
|
visitTasksRequiredDependencies(project, npmDependencies, gradleComponents)
|
||||||
|
|
||||||
visitNpmDependencies(project, npmDependencies, gradleComponents, packageJson)
|
visitNpmDependencies(project, npmDependencies, gradleComponents, packageJson)
|
||||||
|
|
||||||
if (!hoistGradleNodeModules || project == project.rootProject) {
|
if (!hoistGradleNodeModules || project == project.rootProject) {
|
||||||
@@ -178,6 +209,36 @@ internal class NpmResolver private constructor(val rootProject: Project) {
|
|||||||
else NpmPackage(project, packageJson, npmDependencies)
|
else NpmPackage(project, packageJson, npmDependencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun visitTasksRequiredDependencies(
|
||||||
|
project: Project,
|
||||||
|
npmDependencies: MutableSet<NpmDependency>,
|
||||||
|
gradleComponents: GradleNodeModulesBuilder
|
||||||
|
) {
|
||||||
|
var toolsDependenciesConfiguration: Configuration? = project.configurations.create("jsTools")
|
||||||
|
|
||||||
|
project.tasks.toList().forEach { task ->
|
||||||
|
if (task is RequiresNpmDependencies) {
|
||||||
|
if (readyTaskGraph?.hasTask(task) ?: task.enabled) {
|
||||||
|
val list = task.requiredNpmDependencies.toList()
|
||||||
|
|
||||||
|
requiredByTasks[task] = list
|
||||||
|
list.forEach { requiredDependency ->
|
||||||
|
val configuration: Configuration = toolsDependenciesConfiguration
|
||||||
|
?: project.configurations.create("jsTools").also { new ->
|
||||||
|
toolsDependenciesConfiguration = new
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.dependencies.add(requiredDependency.createDependency(project))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toolsDependenciesConfiguration != null) {
|
||||||
|
visitConfiguration(toolsDependenciesConfiguration!!, npmDependencies, gradleComponents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun visitNpmDependencies(
|
private fun visitNpmDependencies(
|
||||||
project: Project,
|
project: Project,
|
||||||
npmDependencies: MutableSet<NpmDependency>,
|
npmDependencies: MutableSet<NpmDependency>,
|
||||||
@@ -213,15 +274,10 @@ internal class NpmResolver private constructor(val rootProject: Project) {
|
|||||||
if (target.platformType == KotlinPlatformType.js) {
|
if (target.platformType == KotlinPlatformType.js) {
|
||||||
target.compilations.toList().forEach { compilation ->
|
target.compilations.toList().forEach { compilation ->
|
||||||
compilation.relatedConfigurationNames.forEach {
|
compilation.relatedConfigurationNames.forEach {
|
||||||
project.configurations.getByName(it).allDependencies.forEach { dependency ->
|
val configuration = project.configurations.getByName(it)
|
||||||
when (dependency) {
|
visitConfiguration(configuration, npmDependencies, gradleComponents)
|
||||||
is NpmDependency -> npmDependencies.add(dependency)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gradleComponents.visitCompilation(compilation)
|
|
||||||
|
|
||||||
if (compilation is KotlinJsCompilation) {
|
if (compilation is KotlinJsCompilation) {
|
||||||
visitKotlinJsCompilation(project, compilation)
|
visitKotlinJsCompilation(project, compilation)
|
||||||
|
|
||||||
@@ -233,6 +289,20 @@ internal class NpmResolver private constructor(val rootProject: Project) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun visitConfiguration(
|
||||||
|
configuration: Configuration,
|
||||||
|
npmDependencies: MutableSet<NpmDependency>,
|
||||||
|
gradleComponents: GradleNodeModulesBuilder
|
||||||
|
) {
|
||||||
|
gradleComponents.visitConfiguration(configuration)
|
||||||
|
|
||||||
|
configuration.allDependencies.forEach { dependency ->
|
||||||
|
when (dependency) {
|
||||||
|
is NpmDependency -> npmDependencies.add(dependency)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun visitKotlinJsCompilation(
|
private fun visitKotlinJsCompilation(
|
||||||
project: Project,
|
project: Project,
|
||||||
compilation: KotlinJsCompilation
|
compilation: KotlinJsCompilation
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* 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.npm
|
||||||
|
|
||||||
|
interface RequiresNpmDependencies {
|
||||||
|
val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
|
}
|
||||||
+9
-13
@@ -12,14 +12,14 @@ import org.gradle.process.internal.DefaultProcessForkOptions
|
|||||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
||||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProjectLayout
|
import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolver
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolver
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma
|
import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.mocha.KotlinMocha
|
import org.jetbrains.kotlin.gradle.targets.js.testing.mocha.KotlinMocha
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.nodejs.KotlinNodeJsTestRunner
|
import org.jetbrains.kotlin.gradle.targets.js.testing.nodejs.KotlinNodeJsTestRunner
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTest
|
import org.jetbrains.kotlin.gradle.tasks.KotlinTest
|
||||||
|
|
||||||
open class KotlinJsTest : KotlinTest() {
|
open class KotlinJsTest : KotlinTest(), RequiresNpmDependencies {
|
||||||
@Internal
|
@Internal
|
||||||
@SkipWhenEmpty
|
@SkipWhenEmpty
|
||||||
internal var testFramework: KotlinJsTestFramework? = null
|
internal var testFramework: KotlinJsTestFramework? = null
|
||||||
@@ -27,17 +27,17 @@ open class KotlinJsTest : KotlinTest() {
|
|||||||
@Input
|
@Input
|
||||||
var debug: Boolean = false
|
var debug: Boolean = false
|
||||||
|
|
||||||
@Internal
|
|
||||||
var runtimeDependencyHandler: HasKotlinDependencies? = null
|
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
var nodeModulesToLoad: MutableList<String> = mutableListOf()
|
var nodeModulesToLoad: MutableList<String> = mutableListOf()
|
||||||
|
|
||||||
|
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
|
get() = testFramework!!.requiredNpmDependencies
|
||||||
|
|
||||||
fun useNodeJs(body: KotlinNodeJsTestRunner.() -> Unit) = use(KotlinNodeJsTestRunner(), body)
|
fun useNodeJs(body: KotlinNodeJsTestRunner.() -> Unit) = use(KotlinNodeJsTestRunner(), body)
|
||||||
|
|
||||||
fun useMocha(body: KotlinMocha.() -> Unit) = use(KotlinMocha(), body)
|
fun useMocha(body: KotlinMocha.() -> Unit) = use(KotlinMocha(project), body)
|
||||||
|
|
||||||
fun useKarma(body: KotlinKarma.() -> Unit) = use(KotlinKarma(), body)
|
fun useKarma(body: KotlinKarma.() -> Unit) = use(KotlinKarma(project), body)
|
||||||
|
|
||||||
private inline fun <T : KotlinJsTestFramework> use(runner: T, body: T.() -> Unit): T {
|
private inline fun <T : KotlinJsTestFramework> use(runner: T, body: T.() -> Unit): T {
|
||||||
check(testFramework == null) {
|
check(testFramework == null) {
|
||||||
@@ -47,16 +47,12 @@ open class KotlinJsTest : KotlinTest() {
|
|||||||
val testFramework = runner.also(body)
|
val testFramework = runner.also(body)
|
||||||
this.testFramework = testFramework
|
this.testFramework = testFramework
|
||||||
|
|
||||||
val dependenciesHolder = runtimeDependencyHandler
|
|
||||||
if (dependenciesHolder != null) {
|
|
||||||
testFramework.configure(dependenciesHolder)
|
|
||||||
}
|
|
||||||
|
|
||||||
return testFramework
|
return testFramework
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun executeTests() {
|
override fun executeTests() {
|
||||||
NpmResolver.resolve(project)
|
NpmResolver.resolve(project)
|
||||||
|
NpmResolver.checkRequiredDependencies(project, this)
|
||||||
super.executeTests()
|
super.executeTests()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +61,7 @@ open class KotlinJsTest : KotlinTest() {
|
|||||||
|
|
||||||
NpmResolver.resolve(project)
|
NpmResolver.resolve(project)
|
||||||
|
|
||||||
forkOptions.workingDir = NpmProjectLayout[project].nodeWorkDir
|
forkOptions.workingDir = NpmProject[project].nodeWorkDir
|
||||||
forkOptions.executable = NodeJsPlugin.apply(project).root.environment.nodeExecutable
|
forkOptions.executable = NodeJsPlugin.apply(project).root.environment.nodeExecutable
|
||||||
|
|
||||||
val nodeJsArgs = mutableListOf<String>()
|
val nodeJsArgs = mutableListOf<String>()
|
||||||
|
|||||||
+2
-5
@@ -8,15 +8,12 @@ package org.jetbrains.kotlin.gradle.targets.js.testing
|
|||||||
import org.gradle.process.ProcessForkOptions
|
import org.gradle.process.ProcessForkOptions
|
||||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
||||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
||||||
|
|
||||||
interface KotlinJsTestFramework {
|
interface KotlinJsTestFramework : RequiresNpmDependencies {
|
||||||
fun createTestExecutionSpec(
|
fun createTestExecutionSpec(
|
||||||
task: KotlinJsTest,
|
task: KotlinJsTest,
|
||||||
forkOptions: ProcessForkOptions,
|
forkOptions: ProcessForkOptions,
|
||||||
nodeJsArgs: MutableList<String>
|
nodeJsArgs: MutableList<String>
|
||||||
): TCServiceMessagesTestExecutionSpec
|
): TCServiceMessagesTestExecutionSpec
|
||||||
|
|
||||||
fun configure(dependenciesHolder: HasKotlinDependencies) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+5
-9
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
|||||||
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmPackageVersion
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmPackageVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiredKotlinJsDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
|
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
|
||||||
@@ -24,6 +25,9 @@ class KotlinKarma(val project: Project) : KotlinJsTestFramework {
|
|||||||
|
|
||||||
private val versions = project.nodeJs.versions
|
private val versions = project.nodeJs.versions
|
||||||
|
|
||||||
|
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
|
get() = requiredDependencies.toList()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
requiredDependencies.add(versions.karma)
|
requiredDependencies.add(versions.karma)
|
||||||
|
|
||||||
@@ -49,7 +53,7 @@ class KotlinKarma(val project: Project) : KotlinJsTestFramework {
|
|||||||
|
|
||||||
fun useIe() = useBrowser("Ie", versions.karmaIeLauncher)
|
fun useIe() = useBrowser("Ie", versions.karmaIeLauncher)
|
||||||
|
|
||||||
fun useBrowser(id: String, dependency: NpmPackageVersion) {
|
private fun useBrowser(id: String, dependency: NpmPackageVersion) {
|
||||||
config.browsers.add(id)
|
config.browsers.add(id)
|
||||||
requiredDependencies.add(dependency)
|
requiredDependencies.add(dependency)
|
||||||
}
|
}
|
||||||
@@ -68,14 +72,6 @@ class KotlinKarma(val project: Project) : KotlinJsTestFramework {
|
|||||||
requiredDependencies.add(versions.karmaSourceMapSupport)
|
requiredDependencies.add(versions.karmaSourceMapSupport)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configure(dependenciesHolder: HasKotlinDependencies) {
|
|
||||||
dependenciesHolder.dependencies {
|
|
||||||
requiredDependencies.forEach {
|
|
||||||
npm(it.name, it.version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTestExecutionSpec(
|
override fun createTestExecutionSpec(
|
||||||
task: KotlinJsTest,
|
task: KotlinJsTest,
|
||||||
forkOptions: ProcessForkOptions,
|
forkOptions: ProcessForkOptions,
|
||||||
|
|||||||
+16
-11
@@ -5,23 +5,28 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.targets.js.testing.mocha
|
package org.jetbrains.kotlin.gradle.targets.js.testing.mocha
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
import org.gradle.process.ProcessForkOptions
|
import org.gradle.process.ProcessForkOptions
|
||||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
|
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
|
||||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
||||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProjectLayout
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinGradleNpmPackage
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiredKotlinJsDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
|
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
|
||||||
|
|
||||||
class KotlinMocha : KotlinJsTestFramework {
|
class KotlinMocha(val project: Project) : KotlinJsTestFramework {
|
||||||
override fun configure(dependenciesHolder: HasKotlinDependencies) {
|
private val versions = project.nodeJs.versions
|
||||||
dependenciesHolder.dependencies {
|
|
||||||
runtimeOnly(kotlin("test-nodejs-runner"))
|
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
runtimeOnly(npm("mocha", "6.1.2"))
|
get() = listOf(
|
||||||
runtimeOnly(npm("mocha-teamcity-reporter", ">=2.0.0"))
|
KotlinGradleNpmPackage("test-nodejs-runner"),
|
||||||
}
|
versions.mocha,
|
||||||
}
|
versions.mochaTeamCityReporter
|
||||||
|
)
|
||||||
|
|
||||||
override fun createTestExecutionSpec(
|
override fun createTestExecutionSpec(
|
||||||
task: KotlinJsTest,
|
task: KotlinJsTest,
|
||||||
@@ -31,7 +36,7 @@ class KotlinMocha : KotlinJsTestFramework {
|
|||||||
val clientSettings = TCServiceMessagesClientSettings(
|
val clientSettings = TCServiceMessagesClientSettings(
|
||||||
task.name,
|
task.name,
|
||||||
testNameSuffix = task.targetName,
|
testNameSuffix = task.targetName,
|
||||||
prepandSuiteName = true,
|
prependSuiteName = true,
|
||||||
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
|
stackTraceParser = ::parseNodeJsStackTraceAsJvm,
|
||||||
ignoreOutOfRootNodes = true
|
ignoreOutOfRootNodes = true
|
||||||
)
|
)
|
||||||
@@ -41,7 +46,7 @@ class KotlinMocha : KotlinJsTestFramework {
|
|||||||
task.nodeModulesToLoad.single()
|
task.nodeModulesToLoad.single()
|
||||||
)
|
)
|
||||||
|
|
||||||
val npmProjectLayout = NpmProjectLayout[task.project]
|
val npmProjectLayout = NpmProject[task.project]
|
||||||
|
|
||||||
val args = nodeJsArgs +
|
val args = nodeJsArgs +
|
||||||
nodeModules.map {
|
nodeModules.map {
|
||||||
|
|||||||
+10
-10
@@ -11,7 +11,10 @@ import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSetti
|
|||||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
||||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProjectLayout
|
import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinGradleNpmPackage
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmPackageVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiredKotlinJsDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
|
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||||
import org.jetbrains.kotlin.gradle.testing.IgnoredTestSuites
|
import org.jetbrains.kotlin.gradle.testing.IgnoredTestSuites
|
||||||
@@ -20,11 +23,8 @@ class KotlinNodeJsTestRunner : KotlinJsTestFramework {
|
|||||||
@Input
|
@Input
|
||||||
var ignoredTestSuites: IgnoredTestSuites = IgnoredTestSuites.showWithContents
|
var ignoredTestSuites: IgnoredTestSuites = IgnoredTestSuites.showWithContents
|
||||||
|
|
||||||
override fun configure(dependenciesHolder: HasKotlinDependencies) {
|
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
dependenciesHolder.dependencies {
|
get() = listOf(KotlinGradleNpmPackage("test-nodejs-runner"))
|
||||||
runtimeOnly(kotlin("test-nodejs-runner"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTestExecutionSpec(
|
override fun createTestExecutionSpec(
|
||||||
task: KotlinJsTest,
|
task: KotlinJsTest,
|
||||||
@@ -41,16 +41,16 @@ class KotlinNodeJsTestRunner : KotlinJsTestFramework {
|
|||||||
val clientSettings = TCServiceMessagesClientSettings(
|
val clientSettings = TCServiceMessagesClientSettings(
|
||||||
task.name,
|
task.name,
|
||||||
testNameSuffix = task.targetName,
|
testNameSuffix = task.targetName,
|
||||||
prepandSuiteName = true,
|
prependSuiteName = true,
|
||||||
stackTraceParser = ::parseNodeJsStackTraceAsJvm
|
stackTraceParser = ::parseNodeJsStackTraceAsJvm
|
||||||
)
|
)
|
||||||
|
|
||||||
val testRuntimeNodeModules = listOf(
|
val testRuntimeNodeModules = listOf(
|
||||||
"kotlin-test-nodejs-runner.js",
|
"kotlin-test-nodejs-runner/kotlin-test-nodejs-runner.js",
|
||||||
"kotlin-nodejs-source-map-support.js"
|
"kotlin-test-nodejs-runner/kotlin-nodejs-source-map-support.js"
|
||||||
)
|
)
|
||||||
|
|
||||||
val npmProjectLayout = NpmProjectLayout[task.project]
|
val npmProjectLayout = NpmProject[task.project]
|
||||||
|
|
||||||
val args = nodeJsArgs +
|
val args = nodeJsArgs +
|
||||||
testRuntimeNodeModules.map {
|
testRuntimeNodeModules.map {
|
||||||
|
|||||||
+30
-5
@@ -13,16 +13,19 @@ import org.gradle.deployment.internal.DeploymentHandle
|
|||||||
import org.gradle.deployment.internal.DeploymentRegistry
|
import org.gradle.deployment.internal.DeploymentRegistry
|
||||||
import org.gradle.process.internal.ExecHandle
|
import org.gradle.process.internal.ExecHandle
|
||||||
import org.gradle.process.internal.ExecHandleFactory
|
import org.gradle.process.internal.ExecHandleFactory
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationToRunnableFiles
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmPackageVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
|
||||||
import org.jetbrains.kotlin.gradle.testing.internal.reportsDir
|
import org.jetbrains.kotlin.gradle.testing.internal.reportsDir
|
||||||
import org.jetbrains.kotlin.gradle.utils.injected
|
import org.jetbrains.kotlin.gradle.utils.injected
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
open class KotlinWebpack : DefaultTask() {
|
open class KotlinWebpack : DefaultTask(), RequiresNpmDependencies {
|
||||||
|
private val versions by lazy { project.nodeJs.versions }
|
||||||
|
|
||||||
@get:Inject
|
@get:Inject
|
||||||
open val fileResolver: FileResolver
|
open val fileResolver: FileResolver
|
||||||
get() = injected
|
get() = injected
|
||||||
@@ -66,7 +69,26 @@ open class KotlinWebpack : DefaultTask() {
|
|||||||
@Optional
|
@Optional
|
||||||
var devServer: KotlinWebpackConfig.DevServer? = null
|
var devServer: KotlinWebpackConfig.DevServer? = null
|
||||||
|
|
||||||
internal fun createRunner() = KotlinWebpackRunner(
|
override val requiredNpmDependencies: Collection<NpmPackageVersion>
|
||||||
|
get() = mutableListOf<NpmPackageVersion>().also {
|
||||||
|
it.add(versions.webpack)
|
||||||
|
it.add(versions.webpackCli)
|
||||||
|
|
||||||
|
if (report) {
|
||||||
|
it.add(versions.webpackBundleAnalyzer)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceMaps) {
|
||||||
|
it.add(versions.sourceMapLoader)
|
||||||
|
it.add(versions.sourceMapSupport)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devServer != null) {
|
||||||
|
it.add(versions.webpackDevServer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createRunner() = KotlinWebpackRunner(
|
||||||
project,
|
project,
|
||||||
configFile,
|
configFile,
|
||||||
execHandleFactory,
|
execHandleFactory,
|
||||||
@@ -84,6 +106,9 @@ open class KotlinWebpack : DefaultTask() {
|
|||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun execute() {
|
fun execute() {
|
||||||
|
NpmResolver.resolve(project)
|
||||||
|
NpmResolver.checkRequiredDependencies(project, this)
|
||||||
|
|
||||||
val runner = createRunner()
|
val runner = createRunner()
|
||||||
|
|
||||||
if (project.gradle.startParameter.isContinuous) {
|
if (project.gradle.startParameter.isContinuous) {
|
||||||
|
|||||||
Reference in New Issue
Block a user