From dff48b251d2d70f8a35cabcdcc84efb56ea9b1c1 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Tue, 2 Jul 2019 13:07:28 +0300 Subject: [PATCH] Gradle, JS: rework extension registering and resolver phasing This allows to resolve projects lazily. #KT-32393 Fixed #KT-31565 #KT-32015 #KT-31917 --- .../gradle/internal/ProcessedFilesCache.kt | 1 + .../targets/js/KotlinJsTargetConfigurator.kt | 18 +- .../gradle/targets/js/nodejs/NodeJsExec.kt | 63 ++++- .../targets/js/nodejs/NodeJsExtension.kt | 16 +- .../gradle/targets/js/nodejs/NodeJsPlugin.kt | 67 +---- .../targets/js/nodejs/NodeJsRootExtension.kt | 77 +++++- .../targets/js/nodejs/NodeJsRootPlugin.kt | 41 ++++ .../targets/js/nodejs/NodeJsSetupTask.kt | 3 +- .../targets/js/npm/GradleNodeModuleBuilder.kt | 2 +- .../targets/js/npm/GradleNodeModulesCache.kt | 27 +-- .../kotlin/gradle/targets/js/npm/NpmApi.kt | 6 +- .../gradle/targets/js/npm/NpmDependency.kt | 15 +- .../targets/js/npm/NpmGradleDependencies.kt | 21 -- .../gradle/targets/js/npm/NpmProject.kt | 18 +- .../gradle/targets/js/npm/NpmSimpleLinker.kt | 18 +- ...e.kt => KotlinCompilationNpmResolution.kt} | 11 +- .../js/npm/resolved/KotlinNpmResolution.kt | 12 - .../resolved/KotlinProjectNpmResolution.kt | 10 +- .../npm/resolved/KotlinRootNpmResolution.kt | 20 ++ .../resolver/KotlinCompilationNpmResolver.kt | 228 +++++++++++------- .../js/npm/resolver/KotlinNpmResolver.kt | 160 ------------ .../npm/resolver/KotlinProjectNpmResolver.kt | 101 +++++--- .../js/npm/resolver/KotlinRootNpmResolver.kt | 96 ++++++++ .../js/npm/tasks/KotlinNpmInstallTask.kt | 20 +- .../js/npm/tasks/KotlinPackageJsonTask.kt | 73 ++++-- .../targets/js/subtargets/KotlinBrowserJs.kt | 2 +- .../js/subtargets/KotlinJsSubTarget.kt | 6 +- .../targets/js/subtargets/KotlinNodeJs.kt | 34 +-- .../gradle/targets/js/testing/KotlinJsTest.kt | 8 +- .../targets/js/webpack/KotlinWebpack.kt | 3 +- .../kotlin/gradle/targets/js/yarn/Yarn.kt | 6 +- .../gradle/targets/js/yarn/YarnBasics.kt | 5 +- .../YarnImportedPackagesVersionResolver.kt | 6 +- .../gradle/targets/js/yarn/YarnPlugin.kt | 4 +- .../targets/js/yarn/YarnRootExtension.kt | 5 +- .../gradle/targets/js/yarn/YarnSetupTask.kt | 4 +- .../gradle/targets/js/yarn/YarnSimple.kt | 8 +- .../gradle/targets/js/yarn/YarnWorkspaces.kt | 12 +- .../org.jetbrains.kotlin.nodejs.properties | 1 - ...etbrains.kotlin.platform.nodejs.properties | 1 - 40 files changed, 697 insertions(+), 532 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmGradleDependencies.kt rename libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/{NpmProjectPackage.kt => KotlinCompilationNpmResolution.kt} (64%) delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinNpmResolution.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinNpmResolver.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinRootNpmResolver.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.nodejs.properties delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.platform.nodejs.properties diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/ProcessedFilesCache.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/ProcessedFilesCache.kt index df82a08d833..c92fb5b2f30 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/ProcessedFilesCache.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/ProcessedFilesCache.kt @@ -143,6 +143,7 @@ internal open class ProcessedFilesCache( deleteTarget(it) } + stateFile.parentFile.mkdirs() stateFile.writer().use { gson.toJson(new, it) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt index c62192d08a2..9dea1329563 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt @@ -10,11 +10,8 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget -import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask -import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider -import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) : KotlinTargetConfigurator(true, true, kotlinPluginVersion) { @@ -24,19 +21,8 @@ open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) : super.configureTarget(target) - target.compilations.forEach { - val npmResolveTask = target.project.nodeJs.root.npmInstallTask - val npmProject = it.npmProject - - val packageJsonTaskName = npmProject.packageJsonTaskName - npmResolveTask.dependsOn(packageJsonTaskName) - - target.project.createOrRegisterTask(packageJsonTaskName) { task -> - task.compilation = it - task.description = "Create package.json file for $it" - } - - it.compileKotlinTask.dependsOn(npmResolveTask) + target.compilations.forEach { compilation -> + KotlinPackageJsonTask.create(compilation) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt index ce9a06e33bb..85d89d0419d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt @@ -6,12 +6,65 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs import org.gradle.api.tasks.AbstractExecTask +import org.gradle.api.tasks.Input +import org.jetbrains.kotlin.gradle.plugin.TaskHolder +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency +import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies +import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject +import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask -open class NodeJsExec : AbstractExecTask(NodeJsExec::class.java) { - init { - val nodeJs = NodeJsPlugin.apply(project).root - dependsOn(nodeJs.npmInstallTask) +open class NodeJsExec : AbstractExecTask(NodeJsExec::class.java), RequiresNpmDependencies { + lateinit var nodeJs: NodeJsRootExtension + override lateinit var compilation: KotlinJsCompilation - executable = nodeJs.environment.nodeExecutable + @Input + var sourceMapStackTraces = true + + override val nodeModulesRequired: Boolean + get() = true + + override val requiredNpmDependencies: Collection + get() = mutableListOf().also { + if (sourceMapStackTraces) { + it.add(nodeJs.versions.kotlinNodeJsTestRunner) + } + } + + override fun exec() { + if (sourceMapStackTraces) { + args( + "--require", + compilation.npmProject.require("kotlin-test-nodejs-runner/kotlin-nodejs-source-map-support") + ) + } + + super.exec() + } + + companion object { + fun create( + compilation: KotlinJsCompilation, + name: String, + providedNodeJs: NodeJsRootExtension? = null, + configuration: NodeJsExec.() -> Unit = {} + ): TaskHolder { + val target = compilation.target + val project = target.project + val nodeJs = providedNodeJs ?: NodeJsRootPlugin.apply(project).root + + return project.createOrRegisterTask(name) { + it.nodeJs = nodeJs + it.compilation = compilation + it.executable = nodeJs.environment.nodeExecutable + it.dependsOn(nodeJs.npmInstallTask) + + val compileKotlinTask = compilation.compileKotlinTask + it.dependsOn(nodeJs.npmInstallTask, compileKotlinTask) + it.args(compileKotlinTask.outputFile) + + it.configuration() + } + } } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExtension.kt index 3cac8dee4a4..68df82bd148 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExtension.kt @@ -9,9 +9,9 @@ import org.gradle.api.Project import org.jetbrains.kotlin.gradle.targets.js.NpmVersions import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson -open class NodeJsExtension(val project: Project) { - val root: NodeJsRootExtension - get() = this as? NodeJsRootExtension ?: NodeJsRootExtension[project] +open class NodeJsExtension(val project: Project, root: NodeJsRootExtension?) { + @Suppress("LeakingThis") + val root: NodeJsRootExtension = root ?: this as NodeJsRootExtension internal val packageJsonHandlers = mutableListOf Unit>() @@ -21,11 +21,11 @@ open class NodeJsExtension(val project: Project) { fun packageJson(handler: PackageJson.() -> Unit) { packageJsonHandlers.add(handler) } - - companion object { - operator fun get(project: Project) = NodeJsPlugin.apply(project) - } } val Project.nodeJs: NodeJsExtension - get() = NodeJsExtension[this] \ No newline at end of file + get() { + val project = this + project.plugins.apply(NodeJsPlugin::class.java) + return project.extensions.getByName(NodeJsRootExtension.EXTENSION_NAME) as NodeJsExtension + } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlugin.kt index 11adbaeb591..91870b67b09 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsPlugin.kt @@ -1,62 +1,21 @@ +/* + * 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.nodejs import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.plugins.BasePlugin -import org.gradle.api.tasks.Delete -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension.Companion.EXTENSION_NAME -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask -open class NodeJsPlugin : Plugin { - override fun apply(project: Project): Unit = project.run { - check(project == project.rootProject) { - "NodeJsPlugin can be applied only to root project" +class NodeJsPlugin : Plugin { + override fun apply(target: Project) { + val root = NodeJsRootPlugin.apply(target.rootProject) as NodeJsRootExtension + + if (target != target.rootProject) { + target.extensions.create(NodeJsRootExtension.EXTENSION_NAME, NodeJsExtension::class.java, target, root) } - this.extensions.create(EXTENSION_NAME, NodeJsRootExtension::class.java, this) - - val setupTask = tasks.create(NodeJsSetupTask.NAME, NodeJsSetupTask::class.java) { - it.group = TASKS_GROUP_NAME - it.description = "Download and install a local node/npm version" - } - - tasks.create(KotlinNpmInstallTask.NAME, KotlinNpmInstallTask::class.java) { - it.dependsOn(setupTask) - it.outputs.upToDateWhen { false } - it.group = TASKS_GROUP_NAME - it.description = "Find, download and link NPM dependencies and projects" - } - - setupCleanNodeModulesTask(project) - - allprojects { - if (it != project) { - it.extensions.create(EXTENSION_NAME, NodeJsExtension::class.java, this) - } - } + root.requireResolver().addProject(target) } - - private fun setupCleanNodeModulesTask(project: Project) { - project.tasks.create("cleanKotlinNodeModules", Delete::class.java) { - it.description = "Deletes nodeJs projects created during build" - it.group = BasePlugin.BUILD_GROUP - it.delete.add(project.nodeJs.root.rootPackageDir) - } - - project.tasks.create("cleanKotlinGradleNodeModules", Delete::class.java) { - it.description = "Deletes node modules imported from gradle external modules" - it.group = BasePlugin.BUILD_GROUP - it.delete.add(project.nodeJs.root.nodeModulesGradleCacheDir) - } - } - - companion object { - const val TASKS_GROUP_NAME: String = "nodeJs" - - fun apply(project: Project): NodeJsExtension { - val rootProject = project.rootProject - rootProject.plugins.apply(NodeJsPlugin::class.java) - return rootProject.extensions.getByName(EXTENSION_NAME) as NodeJsExtension - } - } -} +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt index b799ba54221..6ef8fd3fc50 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt @@ -2,12 +2,21 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs import org.gradle.api.Project import org.jetbrains.kotlin.gradle.logging.kotlinInfo +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi +import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResolution +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResolution +import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask import org.jetbrains.kotlin.gradle.targets.js.yarn.Yarn import java.io.File -open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) { +open class NodeJsRootExtension(project: Project) : NodeJsExtension(project, null) { + init { + check(project.rootProject == project) + } + private val gradleHome = project.gradle.gradleUserHomeDir.also { project.logger.kotlinInfo("Storing cached files in $it") } @@ -75,9 +84,71 @@ open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) { } } + internal val resolutionState: ResolutionState + get() = _resolutionState + + @Volatile + private var _resolutionState: ResolutionState = ResolutionState.Resolving(KotlinRootNpmResolver(this)) + + internal sealed class ResolutionState : ResolutionStateData { + class Resolving(val resolver: KotlinRootNpmResolver) : ResolutionState(), ResolutionStateData by resolver + class Resolved(val resolved: KotlinRootNpmResolution) : ResolutionState(), ResolutionStateData by resolved + } + + interface ResolutionStateData { + val compilations: Collection + } + + internal fun requireResolver(): KotlinRootNpmResolver = + (resolutionState as? ResolutionState.Resolving ?: error("NPM Dependencies already resolved and installed")).resolver + + internal fun resolveIfNeeded(project: Project): KotlinProjectNpmResolution { + val state0 = _resolutionState + val resolution = when (state0) { + is ResolutionState.Resolved -> state0.resolved + is ResolutionState.Resolving -> { + synchronized(this) { + val state1 = _resolutionState + when (state1) { + is ResolutionState.Resolved -> state1.resolved + is ResolutionState.Resolving -> state1.resolver.close().also { + _resolutionState = ResolutionState.Resolved(it) + } + } + } + } + } + + return resolution[project] + } + + internal fun getAlreadyResolvedOrNull(project: Project): KotlinProjectNpmResolution? { + val state0 = resolutionState + return when (state0) { + is ResolutionState.Resolved -> state0.resolved[project] + is ResolutionState.Resolving -> null + } + } + + internal fun requireResolved(project: Project, reason: String = ""): KotlinProjectNpmResolution = + getAlreadyResolvedOrNull(project) ?: error("NPM dependencies should be resolved $reason") + + internal fun checkRequiredDependencies(project: Project, target: RequiresNpmDependencies) { + val requestedTaskDependencies = requireResolved( + project, + "before $target execution" + ).taskRequirements + val targetRequired = requestedTaskDependencies[target]?.toSet() ?: setOf() + + target.requiredNpmDependencies.forEach { + check(it in targetRequired) { + "$it required by $target was not found resolved at the time of nodejs package manager call. " + + "This may be caused by changing $target configuration after npm dependencies resolution." + } + } + } + companion object { const val EXTENSION_NAME: String = "kotlinNodeJs" - - operator fun get(project: Project) = NodeJsPlugin.apply(project.rootProject) as NodeJsRootExtension } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt new file mode 100644 index 00000000000..eea36bb209b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootPlugin.kt @@ -0,0 +1,41 @@ +package org.jetbrains.kotlin.gradle.targets.js.nodejs + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.BasePlugin +import org.gradle.api.tasks.Delete +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension.Companion.EXTENSION_NAME +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask + +open class NodeJsRootPlugin : Plugin { + override fun apply(project: Project): Unit = project.run { + project.plugins.apply(BasePlugin::class.java) + + check(project == project.rootProject) { + "NodeJsRootPlugin can be applied only to root project" + } + + val root = this.extensions.create(EXTENSION_NAME, NodeJsRootExtension::class.java, this) + + val setupTask = tasks.create(NodeJsSetupTask.NAME, NodeJsSetupTask::class.java) { + it.group = TASKS_GROUP_NAME + it.description = "Download and install a local node/npm version" + } + + tasks.create(KotlinNpmInstallTask.NAME, KotlinNpmInstallTask::class.java) { + it.dependsOn(setupTask) + it.group = TASKS_GROUP_NAME + it.description = "Find, download and link NPM dependencies and projects" + } + } + + companion object { + const val TASKS_GROUP_NAME: String = "nodeJs" + + fun apply(project: Project): NodeJsExtension { + val rootProject = project.rootProject + rootProject.plugins.apply(NodeJsRootPlugin::class.java) + return rootProject.extensions.getByName(EXTENSION_NAME) as NodeJsExtension + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt index efba502bd80..4b39b4206fb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsSetupTask.kt @@ -11,7 +11,7 @@ import java.io.File import java.net.URI open class NodeJsSetupTask : DefaultTask() { - private val settings = project.nodeJs.root + private val settings get() = project.nodeJs.root private val env by lazy { settings.environment } val ivyDependency: String @@ -21,6 +21,7 @@ open class NodeJsSetupTask : DefaultTask() { @OutputDirectory get() = env.nodeDir init { + @Suppress("LeakingThis") onlyIf { settings.download && !env.nodeBinDir.isDirectory } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt index eef7b1ef484..5972a5ebaf1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModuleBuilder.kt @@ -18,7 +18,7 @@ import java.io.File internal class GradleNodeModuleBuilder( val project: Project, val dependency: ResolvedDependency, - val artifacts: Set, + val artifacts: Collection, val cache: GradleNodeModulesCache ) { var srcPackageJsonFile: File? = null diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModulesCache.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModulesCache.kt index 6e516478387..6e80c885554 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModulesCache.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/GradleNodeModulesCache.kt @@ -6,44 +6,43 @@ package org.jetbrains.kotlin.gradle.targets.js.npm import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ResolvedArtifact import org.gradle.api.artifacts.ResolvedDependency -import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.jetbrains.kotlin.gradle.internal.ProcessedFilesCache -import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension /** * Cache for storing already created [GradleNodeModule]s */ -internal class GradleNodeModulesCache(val project: Project) : AutoCloseable { +internal class GradleNodeModulesCache(val nodeJs: NodeJsRootExtension) : AutoCloseable { companion object { const val STATE_FILE_NAME = ".visited" } - internal val dir = project.nodeJs.root.nodeModulesGradleCacheDir + val project: Project get() = nodeJs.project + internal val dir = nodeJs.root.nodeModulesGradleCacheDir private val cache = ProcessedFilesCache(project, dir, STATE_FILE_NAME, "8") - fun ensureImported( - artifact: ResolvedArtifact, + @Synchronized + fun get( dependency: ResolvedDependency, - artifacts: MutableSet, - result: NpmGradleDependencies - ) { + artifact: ResolvedArtifact + ): GradleNodeModule? { val key = cache.getOrCompute(artifact.file) { - val module = GradleNodeModuleBuilder(project, dependency, artifacts, this) + val module = GradleNodeModuleBuilder(project, dependency, listOf(artifact), this) module.visitArtifacts() module.rebuild()?.let { it.name + ":" + it.version } } - if (key != null) { + return if (key != null) { val (name, version) = key.split(":") - result.externalModules.add(GradleNodeModule(name, version, importedPackageDir(dir, name, version))) - } + GradleNodeModule(name, version, importedPackageDir(dir, name, version)) + } else null } + @Synchronized override fun close() { cache.close() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmApi.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmApi.kt index b1ad3faf853..c6375b2afaa 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmApi.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmApi.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.gradle.targets.js.npm import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution /** * NodeJS package manager API @@ -14,11 +14,11 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage interface NpmApi { fun setup(project: Project) - fun resolveProject(resolvedNpmProject: NpmProjectPackage) + fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) fun resolveRootProject( rootProject: Project, - subProjects: Collection + subProjects: Collection ) companion object { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt index a23514b74de..ee002ac8cb1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmDependency.kt @@ -16,9 +16,10 @@ import org.gradle.api.internal.artifacts.dependencies.SelfResolvingDependencyInt import org.gradle.api.tasks.TaskDependency import org.gradle.internal.component.local.model.DefaultLibraryBinaryIdentifier import org.jetbrains.kotlin.gradle.internal.isInIdeaSync +import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResolution -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage -import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution +import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver import java.io.File data class NpmDependency( @@ -83,14 +84,16 @@ data class NpmDependency( } } - private fun resolveProject(): NpmProjectPackage? { + private fun resolveProject(): KotlinCompilationNpmResolution? { + val nodeJs = project.nodeJs.root + val resolvedProject = - if (isInIdeaSync) KotlinNpmResolver.resolveIfNeeded(project) - else KotlinNpmResolver.getAlreadyResolvedOrNull(project) + if (isInIdeaSync) nodeJs.resolveIfNeeded(project) + else nodeJs.getAlreadyResolvedOrNull(project) return when (resolvedProject) { null -> null - else -> findIn(resolvedProject) ?: error("Project hierarchy is already resolved in NPM without $this") + else -> findIn(resolvedProject) ?: error("NPM project resolved without $this") } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmGradleDependencies.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmGradleDependencies.kt deleted file mode 100644 index 80c817fb341..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmGradleDependencies.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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 - -import org.gradle.api.Project - -/** - * Gradle dependencies for [NpmProject]. - */ -class NpmGradleDependencies { - val internalModules = mutableSetOf() - val externalModules = mutableSetOf() - - fun addAll(other: NpmGradleDependencies) { - internalModules.addAll(other.internalModules) - externalModules.addAll(other.externalModules) - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmProject.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmProject.kt index 7fc4624e08e..eb09a599b1d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmProject.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmProject.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs -import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask import java.io.File val KotlinJsCompilation.npmProject: NpmProject @@ -22,14 +22,17 @@ val KotlinJsCompilation.npmProject: NpmProject * Basic info for [NpmProject] created from [compilation]. * This class contains only basic info. * - * More info can be obtained from [NpmProjectPackage], which is available after project resolution (after [NpmResolveTask] execution). + * More info can be obtained from [KotlinCompilationNpmResolution], which is available after project resolution (after [KotlinNpmInstallTask] execution). */ open class NpmProject(val compilation: KotlinJsCompilation) { val name: String get() = buildNpmProjectName() + val nodeJs + get() = project.nodeJs.root + val dir: File - get() = project.nodeJs.root.projectPackagesDir.resolve(name) + get() = nodeJs.projectPackagesDir.resolve(name) val target: KotlinTarget get() = compilation.target @@ -46,6 +49,9 @@ open class NpmProject(val compilation: KotlinJsCompilation) { val packageJsonTaskName: String get() = compilation.disambiguateName("packageJson") + val packageJsonTask: KotlinPackageJsonTask + get() = project.tasks.getByName(packageJsonTaskName) as KotlinPackageJsonTask + val main: String get() = "kotlin/$name.js" @@ -54,11 +60,11 @@ open class NpmProject(val compilation: KotlinJsCompilation) { } private val rootNodeModules: NpmProjectModules? - get() = NpmProjectModules(project.nodeJs.root.rootPackageDir) + get() = NpmProjectModules(nodeJs.rootPackageDir) fun useTool(exec: ExecSpec, tool: String, vararg args: String) { exec.workingDir = dir - exec.executable = project.nodeJs.root.environment.nodeExecutable + exec.executable = nodeJs.environment.nodeExecutable exec.args = listOf(require(tool)) + args } @@ -66,7 +72,7 @@ open class NpmProject(val compilation: KotlinJsCompilation) { * Require [request] nodejs module and return canonical path to it's main js file. */ fun require(request: String): String { - KotlinNpmResolver.requireResolved(project) + nodeJs.requireResolved(project) return modules.require(request) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmSimpleLinker.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmSimpleLinker.kt index 399a8d15430..1ff867052a2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmSimpleLinker.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmSimpleLinker.kt @@ -7,8 +7,9 @@ package org.jetbrains.kotlin.gradle.targets.js.npm import com.google.gson.stream.JsonWriter import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution import java.io.ByteArrayInputStream import java.io.File import java.io.StringWriter @@ -18,10 +19,11 @@ import java.nio.file.Files * Handles simple case, when there are no npm depenencies required, but some tasks steel needs * node_modules with symlinked packages and packages_imported */ -class NpmSimpleLinker(val rootProject: Project) { - private val rootProjectNodeModules = rootProject.nodeJs.root.rootPackageDir.resolve(NpmProject.NODE_MODULES) +class NpmSimpleLinker(val nodeJs: NodeJsRootExtension) { + private val rootProject = nodeJs.project + private val rootProjectNodeModules = nodeJs.rootPackageDir.resolve(NpmProject.NODE_MODULES) - fun link(projects: Collection) { + fun link(projects: Collection) { rootProjectNodeModules.listFiles()?.forEach { val path = it.toPath() when { @@ -43,7 +45,7 @@ class NpmSimpleLinker(val rootProject: Project) { // packages_imported projects.flatMapTo(mutableSetOf()) { - it.gradleDependencies.externalModules.map { gradleNodeModule -> gradleNodeModule } + it.externalGradleDependencies }.forEach { fsLinker.link(getNodeModulePath(it.name), it.path.canonicalFile) } @@ -59,10 +61,10 @@ class NpmSimpleLinker(val rootProject: Project) { } fun createFSLinker(): FSLinker = - if (rootProject.nodeJs.root.environment.isWindows) WindowsJunctionFsLinker(rootProject, rootProjectNodeModules) + if (nodeJs.environment.isWindows) WindowsJunctionFsLinker(rootProject, rootProjectNodeModules, nodeJs) else JavaFsLinker() - class WindowsJunctionFsLinker(val project: Project, val dir: File) : FSLinker { + class WindowsJunctionFsLinker(val project: Project, val dir: File, val nodeJs: NodeJsRootExtension) : FSLinker { val js = StringBuilder() init { @@ -84,7 +86,7 @@ class NpmSimpleLinker(val rootProject: Project) { override fun execute() { val result = project.exec { exec -> exec.workingDir = dir - exec.executable = project.nodeJs.root.environment.nodeExecutable + exec.executable = nodeJs.environment.nodeExecutable exec.standardInput = ByteArrayInputStream(js.toString().toByteArray()) exec.standardOutput = System.`out` exec.errorOutput = System.err diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/NpmProjectPackage.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinCompilationNpmResolution.kt similarity index 64% rename from libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/NpmProjectPackage.kt rename to libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinCompilationNpmResolution.kt index d262584c375..7f93b7cb170 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/NpmProjectPackage.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinCompilationNpmResolution.kt @@ -6,18 +6,19 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.resolved import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModule import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmGradleDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson /** - * [NpmProject] full package info + * Resolved [NpmProject] */ -class NpmProjectPackage( +class KotlinCompilationNpmResolution( val project: Project, val npmProject: NpmProject, - val npmDependencies: Collection, - val gradleDependencies: NpmGradleDependencies, + val internalDependencies: Collection, + val externalGradleDependencies: Collection, + val externalNpmDependencies: Collection, val packageJson: PackageJson ) \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinNpmResolution.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinNpmResolution.kt deleted file mode 100644 index c84d76a97b2..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinNpmResolution.kt +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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.resolved - -import org.gradle.api.Project - -class KotlinNpmResolution(private val projects: Map) { - operator fun get(project: Project) = projects[project] ?: KotlinProjectNpmResolution.empty(project) -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinProjectNpmResolution.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinProjectNpmResolution.kt index 9df26a59b6a..acf60ef933e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinProjectNpmResolution.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinProjectNpmResolution.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.resolved import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies @@ -16,14 +15,13 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies */ class KotlinProjectNpmResolution( val project: Project, - val npmProjects: List, + val npmProjects: List, val taskRequirements: Map> ) { - val npmProjectsByCompilation: Map = npmProjects.associateBy { it.npmProject.compilation } - val npmProjectsByNpmDependency: Map = - mutableMapOf().also { result -> + val npmProjectsByNpmDependency: Map = + mutableMapOf().also { result -> npmProjects.forEach { npmPackage -> - npmPackage.npmDependencies.forEach { npmDependency -> + npmPackage.externalNpmDependencies.forEach { npmDependency -> result[npmDependency] = npmPackage } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt new file mode 100644 index 00000000000..cd800ca4855 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolved/KotlinRootNpmResolution.kt @@ -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.npm.resolved + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension + +class KotlinRootNpmResolution( + val rootProject: Project, + private val projects: Map +) : NodeJsRootExtension.ResolutionStateData { + operator fun get(project: Project) = projects[project] ?: KotlinProjectNpmResolution.empty(project) + + override val compilations: Collection + get() = projects.values.flatMap { it.npmProjects.map { it.npmProject.compilation } } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt index 7d9b30c8f1b..f2144ea57e9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt @@ -10,27 +10,56 @@ import org.gradle.api.artifacts.ResolvedArtifact import org.gradle.api.artifacts.ResolvedDependency import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.attributes.Usage +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf -import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs -import org.jetbrains.kotlin.gradle.targets.js.npm.* -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency +import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson +import org.jetbrains.kotlin.gradle.targets.js.npm.fixSemver +import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution +import java.io.File +import java.io.Serializable internal class KotlinCompilationNpmResolver( val projectResolver: KotlinProjectNpmResolver, val compilation: KotlinJsCompilation ) { val resolver = projectResolver.resolver + val npmProject = compilation.npmProject + val nodeJs get() = resolver.nodeJs val target get() = compilation.target val project get() = target.project + override fun toString(): String = "KotlinCompilationNpmResolver(${npmProject.name})" + val aggregatedConfiguration: Configuration by lazy { createAggregatedConfiguration() } - val projectPackage by lazy { - createPackageJson(aggregatedConfiguration) + val packageJsonProducer: PackageJsonProducer by lazy { + val visitor = ConfigurationVisitor() + visitor.visit(aggregatedConfiguration) + visitor.toPackageJsonProducer() + } + + private var closed = false + private var resolution: KotlinCompilationNpmResolution? = null + + fun resolve() { + check(!closed) { "$this already closed" } + check(resolution == null) { "$this already resolved" } + + resolution = packageJsonProducer.createPackageJson() + } + + fun close(): KotlinCompilationNpmResolution? { + check(!closed) { "$this already closed" } + closed = true + return resolution } private fun createAggregatedConfiguration(): Configuration { @@ -58,8 +87,8 @@ internal class KotlinCompilationNpmResolver( } private fun createNpmToolsConfiguration(): Configuration? { - val taskRequirements = projectResolver.requiredFromTasksByCompilation[compilation] - ?.takeIf { it.isNotEmpty() } ?: return null + val taskRequirements = projectResolver.getTaskRequirements(compilation) + if (taskRequirements.isEmpty()) return null val toolsConfiguration = project.configurations.create("${compilation.name}NpmTools") @@ -77,93 +106,130 @@ internal class KotlinCompilationNpmResolver( return toolsConfiguration } - private fun createPackageJson(configuration: Configuration): NpmProjectPackage { - val npmProject = compilation.npmProject - val name = npmProject.name - val packageJson = PackageJson( - name, - fixSemver(project.version.toString()) - ) - val npmDependencies = mutableSetOf() - val gradleDependencies = NpmGradleDependencies() + data class ExternalGradleDependency( + val dependency: ResolvedDependency, + val artifact: ResolvedArtifact + ) - packageJson.main = npmProject.main + inner class ConfigurationVisitor { + private val internalDependencies = mutableSetOf() + private val externalGradleDependencies = mutableSetOf() + private val externalNpmDependencies = mutableSetOf() - collectDependenciesFromConfiguration(configuration, gradleDependencies) - - configuration.allDependencies.forEach { dependency -> - when (dependency) { - is NpmDependency -> npmDependencies.add(dependency) - } - } - - npmDependencies.forEach { - packageJson.dependencies[it.key] = chooseVersion(packageJson.dependencies[it.key], it.version) - } - - gradleDependencies.externalModules.forEach { - packageJson.dependencies[it.name] = it.version - } - - gradleDependencies.internalModules.forEach { target -> - val targetResolver = resolver.findDependentResolver(project, target) - if (targetResolver != null) { - val targetPackageJson = targetResolver.projectPackage.packageJson - packageJson.dependencies[targetPackageJson.name] = targetPackageJson.version - } - } - - project.nodeJs.packageJsonHandlers.forEach { - it(packageJson) - } - - val npmPackage = NpmProjectPackage( - project, - npmProject, - npmDependencies, - gradleDependencies, - packageJson - ) - npmPackage.packageJson.saveTo(npmProject.packageJsonFile) - - return npmPackage - } - - fun chooseVersion(oldVersion: String?, newVersion: String): String = - oldVersion ?: newVersion // todo: real versions conflict resolution - - - private fun collectDependenciesFromConfiguration(configuration: Configuration, result: NpmGradleDependencies) { - if (configuration.isCanBeResolved) { + fun visit(configuration: Configuration) { configuration.resolvedConfiguration.firstLevelModuleDependencies.forEach { - visitDependency(it, result) + visitDependency(it) + } + + configuration.allDependencies.forEach { dependency -> + when (dependency) { + is NpmDependency -> externalNpmDependencies.add(dependency) + } + } + + if (compilation.name == KotlinCompilation.TEST_COMPILATION_NAME) { + val main = compilation.target.compilations.findByName(KotlinCompilation.MAIN_COMPILATION_NAME) as KotlinJsCompilation + internalDependencies.add(projectResolver[main]) } } - } - private fun visitDependency(dependency: ResolvedDependency, result: NpmGradleDependencies) { - visitArtifacts(dependency, dependency.moduleArtifacts, result) + private fun visitDependency(dependency: ResolvedDependency) { + visitArtifacts(dependency, dependency.moduleArtifacts) - dependency.children.forEach { - visitDependency(it, result) + dependency.children.forEach { + visitDependency(it) + } } + + private fun visitArtifacts( + dependency: ResolvedDependency, + artifacts: MutableSet + ) { + artifacts.forEach { artifact -> + val componentIdentifier = artifact.id.componentIdentifier + if (componentIdentifier is ProjectComponentIdentifier) { + val dependentProject = project.findProject(componentIdentifier.projectPath) + ?: error("Cannot find project ${componentIdentifier.projectPath}") + + val dependentResolver = resolver.findDependentResolver(project, dependentProject) + if (dependentResolver != null) { + internalDependencies.add(dependentResolver) + } + } else { + externalGradleDependencies.add(ExternalGradleDependency(dependency, artifact)) + } + } + } + + fun toPackageJsonProducer() = PackageJsonProducer(internalDependencies, externalGradleDependencies, externalNpmDependencies) } - private fun visitArtifacts( - dependency: ResolvedDependency, - artifacts: MutableSet, - result: NpmGradleDependencies + class PackageJsonProducerInputs( + @get:Input + val internalDependencies: Collection, + + @get:InputFiles + val externalGradleDependencies: Collection, + + @get:Input + val externalDependencies: Collection + ) : Serializable + + @Suppress("MemberVisibilityCanBePrivate") + inner class PackageJsonProducer( + val internalDependencies: Collection, + val externalGradleDependencies: Collection, + val externalNpmDependencies: Collection ) { - artifacts.forEach { artifact -> - val componentIdentifier = artifact.id.componentIdentifier - if (componentIdentifier is ProjectComponentIdentifier) { - val dependentProject = project.findProject(componentIdentifier.projectPath) - ?: error("Cannot find project ${componentIdentifier.projectPath}") + val inputs: PackageJsonProducerInputs + get() = PackageJsonProducerInputs( + internalDependencies.map { it.npmProject.name }, + externalGradleDependencies.map { it.artifact.file }, + externalNpmDependencies.map { "${it.key}:${it.version}" } + ) - result.internalModules.add(dependentProject) - } else { - resolver.gradleNodeModules.ensureImported(artifact, dependency, artifacts, result) + fun createPackageJson(): KotlinCompilationNpmResolution { + val resolvedInternalDependencies = internalDependencies.map { + it.resolution ?: error("Unresolved dependent npm package: ${this@KotlinCompilationNpmResolver} -> $it") } + val importedExternalGradleDependencies = externalGradleDependencies.mapNotNull { + resolver.gradleNodeModules.get(it.dependency, it.artifact) + } + + val packageJson = PackageJson( + npmProject.name, + fixSemver(project.version.toString()) + ) + + resolvedInternalDependencies.forEach { + packageJson.dependencies[it.packageJson.name] = it.packageJson.version + } + + importedExternalGradleDependencies.forEach { + packageJson.dependencies[it.name] = it.version + } + + externalNpmDependencies.forEach { + packageJson.dependencies[it.key] = chooseVersion(packageJson.dependencies[it.key], it.version) + } + + nodeJs.packageJsonHandlers.forEach { + it(packageJson) + } + + packageJson.saveTo(npmProject.packageJsonFile) + + return KotlinCompilationNpmResolution( + project, + npmProject, + resolvedInternalDependencies, + importedExternalGradleDependencies, + externalNpmDependencies, + packageJson + ) } + + private fun chooseVersion(oldVersion: String?, newVersion: String): String = + oldVersion ?: newVersion // todo: real versions conflict resolution } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinNpmResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinNpmResolver.kt deleted file mode 100644 index 980ae0c4463..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinNpmResolver.kt +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.resolver - -import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension -import org.jetbrains.kotlin.gradle.targets.js.npm.* -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinNpmResolution -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResolution -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage - -/** - * Generates `package.json` file for [NpmProject] with npm or js dependencies and - * runs selected [NodeJsRootExtension.packageManager] to download and install all of it's dependencies. - * - * All [NpmDependency] for configurations related to kotlin/js will be added to `package.json`. - * For external gradle modules, fake npm packages will be created and added to `package.json` - * as path to directory. - */ -internal class KotlinNpmResolver private constructor(val rootProject: Project) { - companion object { - private sealed class State { - class Resolving(val resolver: KotlinNpmResolver) : State() - class Resolved(val resolved: KotlinNpmResolution) : State() - } - - @Volatile - private var initializedRootProject: Project? = null - private var state: State? = null - - private fun getState(rootProject: Project): State { - check(rootProject == rootProject.rootProject) - - if (initializedRootProject == null) { - synchronized(this) { - if (initializedRootProject == null) { - initializedRootProject = rootProject - state = State.Resolving(KotlinNpmResolver(rootProject)) - } - } - } - - check(initializedRootProject == rootProject) - - return state!! - } - - private fun setResolution(resolution: KotlinNpmResolution) { - state = State.Resolved(resolution) - } - - fun getResolver(rootProject: Project): KotlinNpmResolver = - (getState(rootProject) as? State.Resolving ?: error("NPM Dependencies already resolved and installed")) - .resolver - - fun resolveIfNeeded(project: Project): KotlinProjectNpmResolution { - val state = getState(project.rootProject) - val resolution = when (state) { - is State.Resolved -> state.resolved - is State.Resolving -> state.resolver.installAndClose() - } - return resolution[project] - } - - fun getAlreadyResolvedOrNull(project: Project): KotlinProjectNpmResolution? { - val state = getState(project.rootProject) - return when (state) { - is State.Resolved -> state.resolved[project] - is State.Resolving -> null - } - } - - fun requireResolved(project: Project, reason: String = ""): KotlinProjectNpmResolution = - getAlreadyResolvedOrNull(project) ?: error("NPM dependencies should be resolved $reason") - - fun checkRequiredDependencies(project: Project, target: RequiresNpmDependencies) { - val requestedTaskDependencies = requireResolved( - project, - "before $target execution" - ).taskRequirements - val targetRequired = requestedTaskDependencies[target]?.toSet() ?: setOf() - - target.requiredNpmDependencies.forEach { - check(it in targetRequired) { - "$it required by $target was not found resolved at the time of nodejs package manager call. " + - "This may be caused by changing $target configuration after npm dependencies resolution." - } - } - } - } - - val gradleNodeModules = GradleNodeModulesCache(rootProject) - val projectResolvers = mutableMapOf() - - init { - if (rootProject.logger.isDebugEnabled) { - rootProject.logger.debug("KotlinNpmResolver initialization triggered at: ${Thread.currentThread().stackTrace.joinToString("\n")}") - } - - rootProject.allprojects.toList().forEach { - projectResolvers[it] = KotlinProjectNpmResolver(it, this) - } - } - - fun installAndClose(): KotlinNpmResolution { - if (rootProject.logger.isDebugEnabled) { - rootProject.logger.debug("KotlinNpmResolver installation triggered at: ${Thread.currentThread().stackTrace.joinToString("\n")}") - } - - val nodeJs = NodeJsPlugin.apply(rootProject).root - val packageManager = nodeJs.packageManager - val allNpmPackages = projectResolvers.values.flatMap { it.byCompilation.values.map { it.projectPackage } } - - removeOutdatedPackages(nodeJs, allNpmPackages) - gradleNodeModules.close() - - if (allNpmPackages.any { it.npmDependencies.isNotEmpty() }) { - packageManager.resolveRootProject(rootProject, allNpmPackages) - } else if (projectResolvers.values.any { it.hasNodeModulesDependentTasks }) { - NpmSimpleLinker(rootProject).link(allNpmPackages) - } - - val resolution = KotlinNpmResolution(projectResolvers.values.map { it.toResolved() }.associateBy { it.project }) - setResolution(resolution) - return resolution - } - - private fun removeOutdatedPackages(nodeJs: NodeJsRootExtension, allNpmPackages: List) { - val packages = allNpmPackages.mapTo(mutableSetOf()) { it.npmProject.name } - nodeJs.projectPackagesDir.listFiles()?.forEach { - if (it.name !in packages) { - it.deleteRecursively() - } - } - } - - fun findDependentResolver(src: Project, target: Project): KotlinCompilationNpmResolver? { - // todo: proper finding using KotlinTargetComponent.findUsageContext - val targetResolver = getResolver(target.rootProject).projectResolvers[target] ?: return null - val mainCompilations = - targetResolver.byCompilation.entries.filter { it.key.name == KotlinCompilation.MAIN_COMPILATION_NAME } - - return if (mainCompilations.isNotEmpty()) { - if (mainCompilations.size > 1) { - error( - "Cannot resolve project dependency $src -> $target." + - "Dependency to project with multiple js compilation not supported yet." - ) - } - - mainCompilations.single().value - } else null - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinProjectNpmResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinProjectNpmResolver.kt index 8ecf8ab1623..28a1f889924 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinProjectNpmResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinProjectNpmResolver.kt @@ -18,56 +18,96 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResol internal class KotlinProjectNpmResolver( val project: Project, - val resolver: KotlinNpmResolver + val resolver: KotlinRootNpmResolver ) { - val byCompilation = mutableMapOf() + override fun toString(): String = "ProjectNpmResolver($project)" - private val taskRequirements = mutableMapOf>() - val requiredFromTasksByCompilation = mutableMapOf>() - var hasNodeModulesDependentTasks = false - private set + private val byCompilation = mutableMapOf() - init { - visit() + operator fun get(compilation: KotlinJsCompilation): KotlinCompilationNpmResolver { + check(compilation.target.project == project) + requireContainerListeners() + return byCompilation[compilation] ?: error("$compilation was not registered in $this") } - fun visit() { - project.tasks.toList().forEach { task -> + private var closed = false + + val compilationResolvers: Collection + get() { + requireContainerListeners() + return byCompilation.values + } + + private val taskRequirements = mutableMapOf>() + private val requiredFromTasksByCompilation = mutableMapOf>() + + fun getTaskRequirements(compilation: KotlinJsCompilation): Collection { + requireContainerListeners() + return requiredFromTasksByCompilation[compilation] ?: listOf() + } + + val hasNodeModulesDependentTasks: Boolean + get() { + requireContainerListeners() + return _hasNodeModulesDependentTasks + } + + @Volatile + var _hasNodeModulesDependentTasks = false + private set + + var listenersInstalled = false + + @Synchronized + private fun requireContainerListeners() { + if (!listenersInstalled) { + listenersInstalled = true + addContainerListeners() + } + } + + private fun addContainerListeners() { + project.tasks.forEach { task -> if (task.enabled && task is RequiresNpmDependencies) { addTaskRequirements(task) } } val kotlin = project.kotlinExtensionOrNull - - if (kotlin != null) { - when (kotlin) { - is KotlinSingleTargetExtension -> visitTarget(kotlin.target) - is KotlinMultiplatformExtension -> kotlin.targets.forEach { - visitTarget(it) - } + when (kotlin) { + is KotlinSingleTargetExtension -> addTargetListeners(kotlin.target) + is KotlinMultiplatformExtension -> kotlin.targets.forEach { + addTargetListeners(it) } } } - private fun visitTarget(target: KotlinTarget) { + private fun addTargetListeners(target: KotlinTarget) { + check(!closed) { resolver.alreadyResolvedMessage("add target $target") } + if (target.platformType == KotlinPlatformType.js) { - target.compilations.toList().forEach { compilation -> + target.compilations.forEach { compilation -> if (compilation is KotlinJsCompilation) { // compilation may be KotlinWithJavaTarget for old Kotlin2JsPlugin - visitCompilation(compilation) + addCompilation(compilation) } } } } - private fun visitCompilation(compilation: KotlinJsCompilation) { + @Synchronized + private fun addCompilation(compilation: KotlinJsCompilation) { + check(!closed) { resolver.alreadyResolvedMessage("add compilation $compilation") } + byCompilation[compilation] = KotlinCompilationNpmResolver(this, compilation) } + @Synchronized private fun addTaskRequirements(task: RequiresNpmDependencies) { - if (!hasNodeModulesDependentTasks && task.nodeModulesRequired) { - hasNodeModulesDependentTasks = true + check(!closed) { resolver.alreadyResolvedMessage("create task $task that requires npm dependencies") } + + if (!_hasNodeModulesDependentTasks && task.nodeModulesRequired) { + _hasNodeModulesDependentTasks = true } val requirements = task.requiredNpmDependencies.toList() @@ -79,9 +119,14 @@ internal class KotlinProjectNpmResolver( .add(task) } - fun toResolved() = KotlinProjectNpmResolution( - project, - byCompilation.values.map { it.projectPackage }, - taskRequirements - ) + fun close(): KotlinProjectNpmResolution { + check(!closed) + closed = true + + return KotlinProjectNpmResolution( + project, + byCompilation.values.mapNotNull { it.close() }, + taskRequirements + ) + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinRootNpmResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinRootNpmResolver.kt new file mode 100644 index 00000000000..ab2c67602dd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinRootNpmResolver.kt @@ -0,0 +1,96 @@ +/* + * 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.resolver + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModulesCache +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmSimpleLinker +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResolution + +/** + * Generates `package.json` file for [NpmProject] with npm or js dependencies and + * runs selected [NodeJsRootExtension.packageManager] to download and install all of it's dependencies. + * + * All [NpmDependency] for configurations related to kotlin/js will be added to `package.json`. + * For external gradle modules, fake npm packages will be created and added to `package.json` + * as path to directory. + */ +internal class KotlinRootNpmResolver internal constructor(val nodeJs: NodeJsRootExtension) : NodeJsRootExtension.ResolutionStateData { + val rootProject: Project + get() = nodeJs.project + + private var closed: Boolean = false + + val gradleNodeModules = GradleNodeModulesCache(nodeJs) + private val projectResolvers = mutableMapOf() + + fun alreadyResolvedMessage(action: String) = "Cannot $action. NodeJS projects already resolved." + + @Synchronized + fun addProject(target: Project) { + check(!closed) { alreadyResolvedMessage("add new project: $target") } + projectResolvers[target] = KotlinProjectNpmResolver(target, this) + } + + operator fun get(project: Project) = projectResolvers[project] ?: error("$project is not configured for JS usage") + + override val compilations: Collection + get() = projectResolvers.values.flatMap { it.compilationResolvers.map { it.compilation } } + + fun findDependentResolver(src: Project, target: Project): KotlinCompilationNpmResolver? { + // todo: proper finding using KotlinTargetComponent.findUsageContext + val targetResolver = this[target] + val mainCompilations = targetResolver.compilationResolvers.filter { it.compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME } + + return if (mainCompilations.isNotEmpty()) { + if (mainCompilations.size > 1) { + error( + "Cannot resolve project dependency $src -> $target." + + "Dependency to project with multiple js compilation not supported yet." + ) + } + + mainCompilations.single() + } else null + } + + /** + * Don't use directly, use [NodeJsRootExtension.resolveIfNeeded] instead. + */ + internal fun close(): KotlinRootNpmResolution { + check(!closed) + closed = true + + val projectResolutions = projectResolvers.values.map { it.close() }.associateBy { it.project } + val allNpmPackages = projectResolutions.values.flatMap { it.npmProjects } + + removeOutdatedPackages(nodeJs, allNpmPackages) + gradleNodeModules.close() + + if (allNpmPackages.any { it.externalNpmDependencies.isNotEmpty() }) { + nodeJs.packageManager.resolveRootProject(rootProject, allNpmPackages) + } else if (projectResolvers.values.any { it.hasNodeModulesDependentTasks }) { + NpmSimpleLinker(nodeJs).link(allNpmPackages) + } + + return KotlinRootNpmResolution(rootProject, projectResolutions) + } + + private fun removeOutdatedPackages(nodeJs: NodeJsRootExtension, allNpmPackages: List) { + val packages = allNpmPackages.mapTo(mutableSetOf()) { it.npmProject.name } + nodeJs.projectPackagesDir.listFiles()?.forEach { + if (it.name !in packages) { + it.deleteRecursively() + } + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt index c0c8d996262..c29e6756448 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinNpmInstallTask.kt @@ -7,30 +7,30 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.tasks import org.gradle.api.DefaultTask import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction +import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject -import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver +import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver import java.io.File open class KotlinNpmInstallTask : DefaultTask() { - private val resolver: KotlinNpmResolver - get() = KotlinNpmResolver.getResolver(project) - init { check(project == project.rootProject) } + @Suppress("unused") @get:InputFiles val packageJsonFiles: Collection - get() = resolver.projectResolvers.values.flatMap { projectResolver -> - projectResolver.byCompilation.keys.map { compilation -> - compilation.npmProject.packageJsonFile - } - } + get() = project.nodeJs.root.resolutionState.compilations.map { it.npmProject.packageJsonFile } + + @get:OutputFile + val yarnLock: File + get() = project.nodeJs.root.rootPackageDir.resolve("yarn.lock") @TaskAction fun resolve() { - resolver.installAndClose() + project.nodeJs.root.resolveIfNeeded(project) } companion object { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt index ccc809c63d3..7cd5dbf7619 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/tasks/KotlinPackageJsonTask.kt @@ -6,34 +6,79 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.tasks import org.gradle.api.DefaultTask -import org.gradle.api.artifacts.Configuration -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal +import org.gradle.api.plugins.BasePlugin +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Nested import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction +import org.jetbrains.kotlin.gradle.plugin.TaskHolder import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver -import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver +import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask import java.io.File -class KotlinPackageJsonTask : DefaultTask() { - @Internal - lateinit var compilation: KotlinJsCompilation +open class KotlinPackageJsonTask : DefaultTask() { + private lateinit var nodeJs: NodeJsRootExtension + private lateinit var compilation: KotlinJsCompilation - private val compilationResolver: KotlinCompilationNpmResolver - get() = KotlinNpmResolver.getResolver(project.rootProject).projectResolvers[project]!!.byCompilation[compilation]!! + private val compilationResolver + get() = nodeJs.requireResolver()[project][compilation] - @get:InputFiles - val configuration: Configuration - get() = compilationResolver.aggregatedConfiguration + private val producer: KotlinCompilationNpmResolver.PackageJsonProducer + get() = compilationResolver.packageJsonProducer + + private fun findDependentTasks(): Collection = + producer.internalDependencies.map { dependentResolver -> + dependentResolver.npmProject.packageJsonTask + } + + companion object { + fun create(compilation: KotlinJsCompilation): TaskHolder { + val target = compilation.target + val project = target.project + val npmProject = compilation.npmProject + val nodeJs = project.nodeJs.root + + val rootClean = project.rootProject.tasks.getByName(BasePlugin.CLEAN_TASK_NAME) + val npmInstallTask = nodeJs.npmInstallTask + val packageJsonTaskName = npmProject.packageJsonTaskName + val packageJsonTask = project.createOrRegisterTask(packageJsonTaskName) { task -> + task.nodeJs = nodeJs + task.compilation = compilation + task.description = "Create package.json file for $compilation" + task.group = NodeJsRootPlugin.TASKS_GROUP_NAME + + @Suppress("UnstableApiUsage") + task.dependsOn(target.project.provider{ task.findDependentTasks() }) + task.mustRunAfter(rootClean) + } + + npmInstallTask.mustRunAfter(rootClean, packageJsonTask.getTaskOrProvider()) + + compilation.compileKotlinTask.dependsOn( + npmInstallTask, + packageJsonTask.getTaskOrProvider() + ) + + return packageJsonTask + } + } + + @get:Input + @get:Nested + internal val producerInputs: KotlinCompilationNpmResolver.PackageJsonProducerInputs + get() = producer.inputs @get:OutputFile val packageJson: File - get() = compilation.npmProject.packageJsonFile + get() = compilationResolver.npmProject.packageJsonFile @TaskAction fun resolve() { - compilationResolver.projectPackage + compilationResolver.resolve() } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt index 6c9eeeec611..1400b6fb766 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt @@ -59,7 +59,7 @@ class KotlinBrowserJs(target: KotlinJsTarget) : it.dependsOn( target.project.nodeJs.root.npmInstallTask, compileKotlinTask, - compilation.processResourcesTaskName + target.project.tasks.getByName(compilation.processResourcesTaskName) ) it.bin = "webpack-dev-server/bin/webpack-dev-server.js" diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinJsSubTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinJsSubTarget.kt index ca376b46dda..129d7b27f4b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinJsSubTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinJsSubTarget.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.plugin.whenEvaluated 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.NodeJsPlugin +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest @@ -30,6 +30,8 @@ abstract class KotlinJsSubTarget( val testTaskName = disambiguateCamelCased("test") fun configure() { + project.nodeJs + configureTests() configureRun() @@ -66,7 +68,7 @@ abstract class KotlinJsSubTarget( private fun configureTests(compilation: KotlinJsCompilation) { // apply plugin (cannot be done at task instantiation time) - val nodeJs = NodeJsPlugin.apply(target.project).root + val nodeJs = NodeJsRootPlugin.apply(target.project).root val testJs = project.createOrRegisterTask(testTaskName) { testJs -> val compileTask = compilation.compileKotlinTask diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinNodeJs.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinNodeJs.kt index 56a7aefac11..9bd5b507169 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinNodeJs.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinNodeJs.kt @@ -31,39 +31,7 @@ class KotlinNodeJs(target: KotlinJsTarget) : } override fun configureRun(compilation: KotlinJsCompilation) { - val project = target.project - - "true".toBoolean() - - val runTaskHolder = project.createOrRegisterTask(disambiguateCamelCased("run")) { runTask -> - runTask.description = "run compiled js in nodejs" - - val compileKotlinTask = compilation.compileKotlinTask - runTask.dependsOn(target.project.nodeJs.root.npmInstallTask, compileKotlinTask) - - runTask.args(compileKotlinTask.outputFile) - } - - addSourceMapSupport(compilation, runTaskHolder) - + val runTaskHolder = NodeJsExec.create(compilation, disambiguateCamelCased("run")) target.runTask.dependsOn(runTaskHolder.getTaskOrProvider()) } - - private fun addSourceMapSupport( - compilation: KotlinJsCompilation, - runTaskHolder: TaskHolder - ) { - compilation.dependencies { - runtimeOnly(kotlin("test-nodejs-runner")) - } - - target.project.nodeJs.root.npmInstallTask.doLast { - runTaskHolder.configure { runTask -> - runTask.args( - "--require", - compilation.npmProject.require("kotlin-test-nodejs-runner/kotlin-nodejs-source-map-support") - ) - } - } - } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt index 5d6bf02d77c..64047d94ace 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt @@ -12,9 +12,9 @@ import org.gradle.process.internal.DefaultProcessForkOptions import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin -import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency +import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs 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.testing.karma.KotlinKarma @@ -92,14 +92,14 @@ open class KotlinJsTest : KotlinTest(), RequiresNpmDependencies { } override fun executeTests() { - KotlinNpmResolver.checkRequiredDependencies(project, this) + project.nodeJs.root.checkRequiredDependencies(project, this) super.executeTests() } override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec { val forkOptions = DefaultProcessForkOptions(fileResolver) forkOptions.workingDir = compilation.npmProject.dir - forkOptions.executable = NodeJsPlugin.apply(project).root.environment.nodeExecutable + forkOptions.executable = NodeJsRootPlugin.apply(project).root.environment.nodeExecutable val nodeJsArgs = mutableListOf() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt index ef53b186fe7..32b9bfe1b68 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt @@ -17,7 +17,6 @@ import org.gradle.process.internal.ExecHandleFactory import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs import org.jetbrains.kotlin.gradle.targets.js.NpmPackageVersion -import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.testing.internal.reportsDir @@ -127,7 +126,7 @@ open class KotlinWebpack : DefaultTask(), RequiresNpmDependencies { @TaskAction fun doExecute() { - KotlinNpmResolver.checkRequiredDependencies(project, this) + project.nodeJs.root.checkRequiredDependencies(project, this) val runner = createRunner() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/Yarn.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/Yarn.kt index af1aabf495b..bca3fe3cd14 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/Yarn.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/Yarn.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn import org.gradle.api.Project import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution object Yarn : NpmApi { private fun getDelegate(project: Project): NpmApi = @@ -17,9 +17,9 @@ object Yarn : NpmApi { override fun setup(project: Project) = getDelegate(project.rootProject).setup(project) - override fun resolveProject(resolvedNpmProject: NpmProjectPackage) = + override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) = getDelegate(resolvedNpmProject.project).resolveProject(resolvedNpmProject) - override fun resolveRootProject(rootProject: Project, subProjects: Collection) = + override fun resolveRootProject(rootProject: Project, subProjects: Collection) = getDelegate(rootProject.project).resolveRootProject(rootProject, subProjects) } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt index 8b5f5ce4b65..f0d5b02f6c4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnBasics.kt @@ -7,10 +7,9 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn import org.gradle.api.Project import org.jetbrains.kotlin.gradle.internal.execWithProgress -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject import java.io.File abstract class YarnBasics : NpmApi { @@ -24,7 +23,7 @@ abstract class YarnBasics : NpmApi { description: String, vararg args: String ) { - val nodeJsEnv = NodeJsPlugin.apply(project).root.environment + val nodeJsEnv = NodeJsRootPlugin.apply(project).root.environment val yarnEnv = YarnPlugin.apply(project).environment project.execWithProgress(description) { exec -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnImportedPackagesVersionResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnImportedPackagesVersionResolver.kt index 7ea0c444992..70d5e38ac28 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnImportedPackagesVersionResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnImportedPackagesVersionResolver.kt @@ -9,19 +9,19 @@ import com.google.gson.Gson import org.gradle.api.Project import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModule import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson import java.io.File class YarnImportedPackagesVersionResolver( private val rootProject: Project, - private val npmProjects: Collection, + private val npmProjects: Collection, private val nodeJsWorldDir: File ) { private val resolvedVersion = mutableMapOf() private val importedProjectWorkspaces = mutableListOf() private val externalModules = npmProjects.flatMapTo(mutableSetOf()) { - it.gradleDependencies.externalModules + it.externalGradleDependencies } fun resolveAndUpdatePackages(): MutableList { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnPlugin.kt index 073f24bb154..fe06628ee66 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnPlugin.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn import org.gradle.api.Plugin import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin open class YarnPlugin : Plugin { override fun apply(project: Project): Unit = project.run { @@ -15,7 +15,7 @@ open class YarnPlugin : Plugin { "YarnPlugin can be applied only to root project" } - val nodeJs = NodeJsPlugin.apply(this).root + val nodeJs = NodeJsRootPlugin.apply(this).root this.extensions.create(YarnRootExtension.YARN, YarnRootExtension::class.java, this) tasks.create(YarnSetupTask.NAME, YarnSetupTask::class.java) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnRootExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnRootExtension.kt index bd4b48080e0..4d02f485868 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnRootExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnRootExtension.kt @@ -7,8 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn import org.gradle.api.Project import org.jetbrains.kotlin.gradle.logging.kotlinInfo -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin -import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin open class YarnRootExtension(val project: Project) { private val gradleHome = project.gradle.gradleUserHomeDir.also { @@ -29,7 +28,7 @@ open class YarnRootExtension(val project: Project) { get() = !disableWorkspaces internal fun executeSetup() { - NodeJsPlugin.apply(project).root.executeSetup() + NodeJsRootPlugin.apply(project).root.executeSetup() val env = environment if (!env.home.isDirectory) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt index ddf6633cd3b..cec82bb7ec4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSetupTask.kt @@ -9,7 +9,7 @@ import de.undercouch.gradle.tasks.download.DownloadAction import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.OutputDirectory -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import java.io.File import javax.xml.ws.Action @@ -26,7 +26,7 @@ open class YarnSetupTask : DefaultTask() { @OutputDirectory get() = env.home init { - group = NodeJsPlugin.TASKS_GROUP_NAME + group = NodeJsRootPlugin.TASKS_GROUP_NAME description = "Download and install a local yarn version" onlyIf { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSimple.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSimple.kt index 380d4e300e5..083a42f1f8c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSimple.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnSimple.kt @@ -7,19 +7,19 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn import org.gradle.api.Project import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution object YarnSimple : YarnBasics() { - override fun resolveProject(resolvedNpmProject: NpmProjectPackage) { + override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) { setup(resolvedNpmProject.project.rootProject) val project = resolvedNpmProject.project YarnUpToDateCheck(resolvedNpmProject.npmProject).updateIfNeeded { yarnExec(project, resolvedNpmProject.npmProject.dir, NpmApi.resolveOperationDescription("yarn for ${project.path}")) - yarnLockReadTransitiveDependencies(resolvedNpmProject.npmProject.dir, resolvedNpmProject.npmDependencies) + yarnLockReadTransitiveDependencies(resolvedNpmProject.npmProject.dir, resolvedNpmProject.externalNpmDependencies) } } - override fun resolveRootProject(rootProject: Project, subProjects: Collection) = Unit + override fun resolveRootProject(rootProject: Project, subProjects: Collection) = Unit } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnWorkspaces.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnWorkspaces.kt index 739fc79d9ce..8d76fb5b671 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnWorkspaces.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/yarn/YarnWorkspaces.kt @@ -8,13 +8,13 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn import org.gradle.api.Project import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs import org.jetbrains.kotlin.gradle.targets.js.npm.* -import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage +import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution import java.io.File object YarnWorkspaces : YarnBasics() { - override fun resolveProject(resolvedNpmProject: NpmProjectPackage) = Unit + override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) = Unit - override fun resolveRootProject(rootProject: Project, subProjects: Collection) { + override fun resolveRootProject(rootProject: Project, subProjects: Collection) { check(rootProject == rootProject.rootProject) setup(rootProject) resolveWorkspaces(rootProject, subProjects) @@ -22,7 +22,7 @@ object YarnWorkspaces : YarnBasics() { private fun resolveWorkspaces( rootProject: Project, - npmProjects: Collection + npmProjects: Collection ) { val upToDateChecks = npmProjects.map { YarnUpToDateCheck(it.npmProject) @@ -35,7 +35,7 @@ object YarnWorkspaces : YarnBasics() { saveRootProjectWorkspacesPackageJson(rootProject, npmProjects, nodeJsWorldDir) yarnExec(rootProject, nodeJsWorldDir, NpmApi.resolveOperationDescription("yarn")) - yarnLockReadTransitiveDependencies(nodeJsWorldDir, npmProjects.flatMap { it.npmDependencies }) + yarnLockReadTransitiveDependencies(nodeJsWorldDir, npmProjects.flatMap { it.externalNpmDependencies }) upToDateChecks.forEach { it.commit() @@ -44,7 +44,7 @@ object YarnWorkspaces : YarnBasics() { private fun saveRootProjectWorkspacesPackageJson( rootProject: Project, - npmProjects: Collection, + npmProjects: Collection, nodeJsWorldDir: File ) { val rootPackageJson = PackageJson(rootProject.name, rootProject.version.toString()) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.nodejs.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.nodejs.properties deleted file mode 100644 index c5b1feac01b..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.nodejs.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.platform.nodejs.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.platform.nodejs.properties deleted file mode 100644 index c5b1feac01b..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.platform.nodejs.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin \ No newline at end of file