Gradle, JS: rework extension registering and resolver phasing
This allows to resolve projects lazily. #KT-32393 Fixed #KT-31565 #KT-32015 #KT-31917
This commit is contained in:
+1
@@ -143,6 +143,7 @@ internal open class ProcessedFilesCache(
|
|||||||
deleteTarget(it)
|
deleteTarget(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stateFile.parentFile.mkdirs()
|
||||||
stateFile.writer().use {
|
stateFile.writer().use {
|
||||||
gson.toJson(new, it)
|
gson.toJson(new, it)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-16
@@ -10,11 +10,8 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetConfigurator
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
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.tasks.KotlinPackageJsonTask
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||||
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
|
||||||
|
|
||||||
open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
||||||
KotlinTargetConfigurator<KotlinJsCompilation>(true, true, kotlinPluginVersion) {
|
KotlinTargetConfigurator<KotlinJsCompilation>(true, true, kotlinPluginVersion) {
|
||||||
@@ -24,19 +21,8 @@ open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
|||||||
|
|
||||||
super.configureTarget(target)
|
super.configureTarget(target)
|
||||||
|
|
||||||
target.compilations.forEach {
|
target.compilations.forEach { compilation ->
|
||||||
val npmResolveTask = target.project.nodeJs.root.npmInstallTask
|
KotlinPackageJsonTask.create(compilation)
|
||||||
val npmProject = it.npmProject
|
|
||||||
|
|
||||||
val packageJsonTaskName = npmProject.packageJsonTaskName
|
|
||||||
npmResolveTask.dependsOn(packageJsonTaskName)
|
|
||||||
|
|
||||||
target.project.createOrRegisterTask<KotlinPackageJsonTask>(packageJsonTaskName) { task ->
|
|
||||||
task.compilation = it
|
|
||||||
task.description = "Create package.json file for $it"
|
|
||||||
}
|
|
||||||
|
|
||||||
it.compileKotlinTask.dependsOn(npmResolveTask)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+58
-5
@@ -6,12 +6,65 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.nodejs
|
package org.jetbrains.kotlin.gradle.targets.js.nodejs
|
||||||
|
|
||||||
import org.gradle.api.tasks.AbstractExecTask
|
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>(NodeJsExec::class.java) {
|
open class NodeJsExec : AbstractExecTask<NodeJsExec>(NodeJsExec::class.java), RequiresNpmDependencies {
|
||||||
init {
|
lateinit var nodeJs: NodeJsRootExtension
|
||||||
val nodeJs = NodeJsPlugin.apply(project).root
|
override lateinit var compilation: KotlinJsCompilation
|
||||||
dependsOn(nodeJs.npmInstallTask)
|
|
||||||
|
|
||||||
executable = nodeJs.environment.nodeExecutable
|
@Input
|
||||||
|
var sourceMapStackTraces = true
|
||||||
|
|
||||||
|
override val nodeModulesRequired: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
|
get() = mutableListOf<RequiredKotlinJsDependency>().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<NodeJsExec> {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+8
-8
@@ -9,9 +9,9 @@ import org.gradle.api.Project
|
|||||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||||
|
|
||||||
open class NodeJsExtension(val project: Project) {
|
open class NodeJsExtension(val project: Project, root: NodeJsRootExtension?) {
|
||||||
val root: NodeJsRootExtension
|
@Suppress("LeakingThis")
|
||||||
get() = this as? NodeJsRootExtension ?: NodeJsRootExtension[project]
|
val root: NodeJsRootExtension = root ?: this as NodeJsRootExtension
|
||||||
|
|
||||||
internal val packageJsonHandlers = mutableListOf<PackageJson.() -> Unit>()
|
internal val packageJsonHandlers = mutableListOf<PackageJson.() -> Unit>()
|
||||||
|
|
||||||
@@ -21,11 +21,11 @@ open class NodeJsExtension(val project: Project) {
|
|||||||
fun packageJson(handler: PackageJson.() -> Unit) {
|
fun packageJson(handler: PackageJson.() -> Unit) {
|
||||||
packageJsonHandlers.add(handler)
|
packageJsonHandlers.add(handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
operator fun get(project: Project) = NodeJsPlugin.apply(project)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val Project.nodeJs: NodeJsExtension
|
val Project.nodeJs: NodeJsExtension
|
||||||
get() = NodeJsExtension[this]
|
get() {
|
||||||
|
val project = this
|
||||||
|
project.plugins.apply(NodeJsPlugin::class.java)
|
||||||
|
return project.extensions.getByName(NodeJsRootExtension.EXTENSION_NAME) as NodeJsExtension
|
||||||
|
}
|
||||||
+13
-54
@@ -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
|
package org.jetbrains.kotlin.gradle.targets.js.nodejs
|
||||||
|
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
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<Project> {
|
class NodeJsPlugin : Plugin<Project> {
|
||||||
override fun apply(project: Project): Unit = project.run {
|
override fun apply(target: Project) {
|
||||||
check(project == project.rootProject) {
|
val root = NodeJsRootPlugin.apply(target.rootProject) as NodeJsRootExtension
|
||||||
"NodeJsPlugin can be applied only to root project"
|
|
||||||
|
if (target != target.rootProject) {
|
||||||
|
target.extensions.create(NodeJsRootExtension.EXTENSION_NAME, NodeJsExtension::class.java, target, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.extensions.create(EXTENSION_NAME, NodeJsRootExtension::class.java, this)
|
root.requireResolver().addProject(target)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+74
-3
@@ -2,12 +2,21 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
|
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.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.npm.tasks.KotlinNpmInstallTask
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.Yarn
|
import org.jetbrains.kotlin.gradle.targets.js.yarn.Yarn
|
||||||
import java.io.File
|
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 {
|
private val gradleHome = project.gradle.gradleUserHomeDir.also {
|
||||||
project.logger.kotlinInfo("Storing cached files in $it")
|
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<KotlinJsCompilation>
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
companion object {
|
||||||
const val EXTENSION_NAME: String = "kotlinNodeJs"
|
const val EXTENSION_NAME: String = "kotlinNodeJs"
|
||||||
|
|
||||||
operator fun get(project: Project) = NodeJsPlugin.apply(project.rootProject) as NodeJsRootExtension
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+41
@@ -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<Project> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -11,7 +11,7 @@ import java.io.File
|
|||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
open class NodeJsSetupTask : DefaultTask() {
|
open class NodeJsSetupTask : DefaultTask() {
|
||||||
private val settings = project.nodeJs.root
|
private val settings get() = project.nodeJs.root
|
||||||
private val env by lazy { settings.environment }
|
private val env by lazy { settings.environment }
|
||||||
|
|
||||||
val ivyDependency: String
|
val ivyDependency: String
|
||||||
@@ -21,6 +21,7 @@ open class NodeJsSetupTask : DefaultTask() {
|
|||||||
@OutputDirectory get() = env.nodeDir
|
@OutputDirectory get() = env.nodeDir
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@Suppress("LeakingThis")
|
||||||
onlyIf {
|
onlyIf {
|
||||||
settings.download && !env.nodeBinDir.isDirectory
|
settings.download && !env.nodeBinDir.isDirectory
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ import java.io.File
|
|||||||
internal class GradleNodeModuleBuilder(
|
internal class GradleNodeModuleBuilder(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val dependency: ResolvedDependency,
|
val dependency: ResolvedDependency,
|
||||||
val artifacts: Set<ResolvedArtifact>,
|
val artifacts: Collection<ResolvedArtifact>,
|
||||||
val cache: GradleNodeModulesCache
|
val cache: GradleNodeModulesCache
|
||||||
) {
|
) {
|
||||||
var srcPackageJsonFile: File? = null
|
var srcPackageJsonFile: File? = null
|
||||||
|
|||||||
+13
-14
@@ -6,44 +6,43 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Configuration
|
|
||||||
import org.gradle.api.artifacts.ResolvedArtifact
|
import org.gradle.api.artifacts.ResolvedArtifact
|
||||||
import org.gradle.api.artifacts.ResolvedDependency
|
import org.gradle.api.artifacts.ResolvedDependency
|
||||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
|
||||||
import org.jetbrains.kotlin.gradle.internal.ProcessedFilesCache
|
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
|
* Cache for storing already created [GradleNodeModule]s
|
||||||
*/
|
*/
|
||||||
internal class GradleNodeModulesCache(val project: Project) : AutoCloseable {
|
internal class GradleNodeModulesCache(val nodeJs: NodeJsRootExtension) : AutoCloseable {
|
||||||
companion object {
|
companion object {
|
||||||
const val STATE_FILE_NAME = ".visited"
|
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")
|
private val cache = ProcessedFilesCache(project, dir, STATE_FILE_NAME, "8")
|
||||||
|
|
||||||
fun ensureImported(
|
@Synchronized
|
||||||
artifact: ResolvedArtifact,
|
fun get(
|
||||||
dependency: ResolvedDependency,
|
dependency: ResolvedDependency,
|
||||||
artifacts: MutableSet<ResolvedArtifact>,
|
artifact: ResolvedArtifact
|
||||||
result: NpmGradleDependencies
|
): GradleNodeModule? {
|
||||||
) {
|
|
||||||
val key = cache.getOrCompute(artifact.file) {
|
val key = cache.getOrCompute(artifact.file) {
|
||||||
val module = GradleNodeModuleBuilder(project, dependency, artifacts, this)
|
val module = GradleNodeModuleBuilder(project, dependency, listOf(artifact), this)
|
||||||
module.visitArtifacts()
|
module.visitArtifacts()
|
||||||
module.rebuild()?.let {
|
module.rebuild()?.let {
|
||||||
it.name + ":" + it.version
|
it.name + ":" + it.version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key != null) {
|
return if (key != null) {
|
||||||
val (name, version) = key.split(":")
|
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() {
|
override fun close() {
|
||||||
cache.close()
|
cache.close()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage
|
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NodeJS package manager API
|
* NodeJS package manager API
|
||||||
@@ -14,11 +14,11 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage
|
|||||||
interface NpmApi {
|
interface NpmApi {
|
||||||
fun setup(project: Project)
|
fun setup(project: Project)
|
||||||
|
|
||||||
fun resolveProject(resolvedNpmProject: NpmProjectPackage)
|
fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution)
|
||||||
|
|
||||||
fun resolveRootProject(
|
fun resolveRootProject(
|
||||||
rootProject: Project,
|
rootProject: Project,
|
||||||
subProjects: Collection<NpmProjectPackage>
|
subProjects: Collection<KotlinCompilationNpmResolution>
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+9
-6
@@ -16,9 +16,10 @@ import org.gradle.api.internal.artifacts.dependencies.SelfResolvingDependencyInt
|
|||||||
import org.gradle.api.tasks.TaskDependency
|
import org.gradle.api.tasks.TaskDependency
|
||||||
import org.gradle.internal.component.local.model.DefaultLibraryBinaryIdentifier
|
import org.gradle.internal.component.local.model.DefaultLibraryBinaryIdentifier
|
||||||
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
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.KotlinProjectNpmResolution
|
||||||
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.resolver.KotlinNpmResolver
|
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
data class NpmDependency(
|
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 =
|
val resolvedProject =
|
||||||
if (isInIdeaSync) KotlinNpmResolver.resolveIfNeeded(project)
|
if (isInIdeaSync) nodeJs.resolveIfNeeded(project)
|
||||||
else KotlinNpmResolver.getAlreadyResolvedOrNull(project)
|
else nodeJs.getAlreadyResolvedOrNull(project)
|
||||||
|
|
||||||
return when (resolvedProject) {
|
return when (resolvedProject) {
|
||||||
null -> null
|
null -> null
|
||||||
else -> findIn(resolvedProject) ?: error("Project hierarchy is already resolved in NPM without $this")
|
else -> findIn(resolvedProject) ?: error("NPM project resolved without $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-21
@@ -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<Project>()
|
|
||||||
val externalModules = mutableSetOf<GradleNodeModule>()
|
|
||||||
|
|
||||||
fun addAll(other: NpmGradleDependencies) {
|
|
||||||
internalModules.addAll(other.internalModules)
|
|
||||||
externalModules.addAll(other.externalModules)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+12
-6
@@ -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.KotlinJsCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
|
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver
|
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
val KotlinJsCompilation.npmProject: NpmProject
|
val KotlinJsCompilation.npmProject: NpmProject
|
||||||
@@ -22,14 +22,17 @@ val KotlinJsCompilation.npmProject: NpmProject
|
|||||||
* Basic info for [NpmProject] created from [compilation].
|
* Basic info for [NpmProject] created from [compilation].
|
||||||
* This class contains only basic info.
|
* 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) {
|
open class NpmProject(val compilation: KotlinJsCompilation) {
|
||||||
val name: String
|
val name: String
|
||||||
get() = buildNpmProjectName()
|
get() = buildNpmProjectName()
|
||||||
|
|
||||||
|
val nodeJs
|
||||||
|
get() = project.nodeJs.root
|
||||||
|
|
||||||
val dir: File
|
val dir: File
|
||||||
get() = project.nodeJs.root.projectPackagesDir.resolve(name)
|
get() = nodeJs.projectPackagesDir.resolve(name)
|
||||||
|
|
||||||
val target: KotlinTarget
|
val target: KotlinTarget
|
||||||
get() = compilation.target
|
get() = compilation.target
|
||||||
@@ -46,6 +49,9 @@ open class NpmProject(val compilation: KotlinJsCompilation) {
|
|||||||
val packageJsonTaskName: String
|
val packageJsonTaskName: String
|
||||||
get() = compilation.disambiguateName("packageJson")
|
get() = compilation.disambiguateName("packageJson")
|
||||||
|
|
||||||
|
val packageJsonTask: KotlinPackageJsonTask
|
||||||
|
get() = project.tasks.getByName(packageJsonTaskName) as KotlinPackageJsonTask
|
||||||
|
|
||||||
val main: String
|
val main: String
|
||||||
get() = "kotlin/$name.js"
|
get() = "kotlin/$name.js"
|
||||||
|
|
||||||
@@ -54,11 +60,11 @@ open class NpmProject(val compilation: KotlinJsCompilation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val rootNodeModules: NpmProjectModules?
|
private val rootNodeModules: NpmProjectModules?
|
||||||
get() = NpmProjectModules(project.nodeJs.root.rootPackageDir)
|
get() = NpmProjectModules(nodeJs.rootPackageDir)
|
||||||
|
|
||||||
fun useTool(exec: ExecSpec, tool: String, vararg args: String) {
|
fun useTool(exec: ExecSpec, tool: String, vararg args: String) {
|
||||||
exec.workingDir = dir
|
exec.workingDir = dir
|
||||||
exec.executable = project.nodeJs.root.environment.nodeExecutable
|
exec.executable = nodeJs.environment.nodeExecutable
|
||||||
exec.args = listOf(require(tool)) + args
|
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.
|
* Require [request] nodejs module and return canonical path to it's main js file.
|
||||||
*/
|
*/
|
||||||
fun require(request: String): String {
|
fun require(request: String): String {
|
||||||
KotlinNpmResolver.requireResolved(project)
|
nodeJs.requireResolved(project)
|
||||||
return modules.require(request)
|
return modules.require(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-8
@@ -7,8 +7,9 @@ package org.jetbrains.kotlin.gradle.targets.js.npm
|
|||||||
|
|
||||||
import com.google.gson.stream.JsonWriter
|
import com.google.gson.stream.JsonWriter
|
||||||
import org.gradle.api.Project
|
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.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.ByteArrayInputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.StringWriter
|
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
|
* Handles simple case, when there are no npm depenencies required, but some tasks steel needs
|
||||||
* node_modules with symlinked packages and packages_imported
|
* node_modules with symlinked packages and packages_imported
|
||||||
*/
|
*/
|
||||||
class NpmSimpleLinker(val rootProject: Project) {
|
class NpmSimpleLinker(val nodeJs: NodeJsRootExtension) {
|
||||||
private val rootProjectNodeModules = rootProject.nodeJs.root.rootPackageDir.resolve(NpmProject.NODE_MODULES)
|
private val rootProject = nodeJs.project
|
||||||
|
private val rootProjectNodeModules = nodeJs.rootPackageDir.resolve(NpmProject.NODE_MODULES)
|
||||||
|
|
||||||
fun link(projects: Collection<NpmProjectPackage>) {
|
fun link(projects: Collection<KotlinCompilationNpmResolution>) {
|
||||||
rootProjectNodeModules.listFiles()?.forEach {
|
rootProjectNodeModules.listFiles()?.forEach {
|
||||||
val path = it.toPath()
|
val path = it.toPath()
|
||||||
when {
|
when {
|
||||||
@@ -43,7 +45,7 @@ class NpmSimpleLinker(val rootProject: Project) {
|
|||||||
|
|
||||||
// packages_imported
|
// packages_imported
|
||||||
projects.flatMapTo(mutableSetOf()) {
|
projects.flatMapTo(mutableSetOf()) {
|
||||||
it.gradleDependencies.externalModules.map { gradleNodeModule -> gradleNodeModule }
|
it.externalGradleDependencies
|
||||||
}.forEach {
|
}.forEach {
|
||||||
fsLinker.link(getNodeModulePath(it.name), it.path.canonicalFile)
|
fsLinker.link(getNodeModulePath(it.name), it.path.canonicalFile)
|
||||||
}
|
}
|
||||||
@@ -59,10 +61,10 @@ class NpmSimpleLinker(val rootProject: Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createFSLinker(): FSLinker =
|
fun createFSLinker(): FSLinker =
|
||||||
if (rootProject.nodeJs.root.environment.isWindows) WindowsJunctionFsLinker(rootProject, rootProjectNodeModules)
|
if (nodeJs.environment.isWindows) WindowsJunctionFsLinker(rootProject, rootProjectNodeModules, nodeJs)
|
||||||
else JavaFsLinker()
|
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()
|
val js = StringBuilder()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -84,7 +86,7 @@ class NpmSimpleLinker(val rootProject: Project) {
|
|||||||
override fun execute() {
|
override fun execute() {
|
||||||
val result = project.exec { exec ->
|
val result = project.exec { exec ->
|
||||||
exec.workingDir = dir
|
exec.workingDir = dir
|
||||||
exec.executable = project.nodeJs.root.environment.nodeExecutable
|
exec.executable = nodeJs.environment.nodeExecutable
|
||||||
exec.standardInput = ByteArrayInputStream(js.toString().toByteArray())
|
exec.standardInput = ByteArrayInputStream(js.toString().toByteArray())
|
||||||
exec.standardOutput = System.`out`
|
exec.standardOutput = System.`out`
|
||||||
exec.errorOutput = System.err
|
exec.errorOutput = System.err
|
||||||
|
|||||||
+6
-5
@@ -6,18 +6,19 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
|
package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
|
||||||
|
|
||||||
import org.gradle.api.Project
|
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.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.NpmProject
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [NpmProject] full package info
|
* Resolved [NpmProject]
|
||||||
*/
|
*/
|
||||||
class NpmProjectPackage(
|
class KotlinCompilationNpmResolution(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val npmProject: NpmProject,
|
val npmProject: NpmProject,
|
||||||
val npmDependencies: Collection<NpmDependency>,
|
val internalDependencies: Collection<KotlinCompilationNpmResolution>,
|
||||||
val gradleDependencies: NpmGradleDependencies,
|
val externalGradleDependencies: Collection<GradleNodeModule>,
|
||||||
|
val externalNpmDependencies: Collection<NpmDependency>,
|
||||||
val packageJson: PackageJson
|
val packageJson: PackageJson
|
||||||
)
|
)
|
||||||
-12
@@ -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<Project, KotlinProjectNpmResolution>) {
|
|
||||||
operator fun get(project: Project) = projects[project] ?: KotlinProjectNpmResolution.empty(project)
|
|
||||||
}
|
|
||||||
+4
-6
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
|
package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
|
||||||
|
|
||||||
import org.gradle.api.Project
|
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.RequiredKotlinJsDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
||||||
@@ -16,14 +15,13 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
|||||||
*/
|
*/
|
||||||
class KotlinProjectNpmResolution(
|
class KotlinProjectNpmResolution(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val npmProjects: List<NpmProjectPackage>,
|
val npmProjects: List<KotlinCompilationNpmResolution>,
|
||||||
val taskRequirements: Map<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>
|
val taskRequirements: Map<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>
|
||||||
) {
|
) {
|
||||||
val npmProjectsByCompilation: Map<KotlinJsCompilation, NpmProjectPackage> = npmProjects.associateBy { it.npmProject.compilation }
|
val npmProjectsByNpmDependency: Map<NpmDependency, KotlinCompilationNpmResolution> =
|
||||||
val npmProjectsByNpmDependency: Map<NpmDependency, NpmProjectPackage> =
|
mutableMapOf<NpmDependency, KotlinCompilationNpmResolution>().also { result ->
|
||||||
mutableMapOf<NpmDependency, NpmProjectPackage>().also { result ->
|
|
||||||
npmProjects.forEach { npmPackage ->
|
npmProjects.forEach { npmPackage ->
|
||||||
npmPackage.npmDependencies.forEach { npmDependency ->
|
npmPackage.externalNpmDependencies.forEach { npmDependency ->
|
||||||
result[npmDependency] = npmPackage
|
result[npmDependency] = npmPackage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.targets.js.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<Project, KotlinProjectNpmResolution>
|
||||||
|
) : NodeJsRootExtension.ResolutionStateData {
|
||||||
|
operator fun get(project: Project) = projects[project] ?: KotlinProjectNpmResolution.empty(project)
|
||||||
|
|
||||||
|
override val compilations: Collection<KotlinJsCompilation>
|
||||||
|
get() = projects.values.flatMap { it.npmProjects.map { it.npmProject.compilation } }
|
||||||
|
}
|
||||||
+147
-81
@@ -10,27 +10,56 @@ import org.gradle.api.artifacts.ResolvedArtifact
|
|||||||
import org.gradle.api.artifacts.ResolvedDependency
|
import org.gradle.api.artifacts.ResolvedDependency
|
||||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||||
import org.gradle.api.attributes.Usage
|
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.KotlinJsCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
||||||
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
|
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.NpmProjectPackage
|
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(
|
internal class KotlinCompilationNpmResolver(
|
||||||
val projectResolver: KotlinProjectNpmResolver,
|
val projectResolver: KotlinProjectNpmResolver,
|
||||||
val compilation: KotlinJsCompilation
|
val compilation: KotlinJsCompilation
|
||||||
) {
|
) {
|
||||||
val resolver = projectResolver.resolver
|
val resolver = projectResolver.resolver
|
||||||
|
val npmProject = compilation.npmProject
|
||||||
|
val nodeJs get() = resolver.nodeJs
|
||||||
val target get() = compilation.target
|
val target get() = compilation.target
|
||||||
val project get() = target.project
|
val project get() = target.project
|
||||||
|
|
||||||
|
override fun toString(): String = "KotlinCompilationNpmResolver(${npmProject.name})"
|
||||||
|
|
||||||
val aggregatedConfiguration: Configuration by lazy {
|
val aggregatedConfiguration: Configuration by lazy {
|
||||||
createAggregatedConfiguration()
|
createAggregatedConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
val projectPackage by lazy {
|
val packageJsonProducer: PackageJsonProducer by lazy {
|
||||||
createPackageJson(aggregatedConfiguration)
|
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 {
|
private fun createAggregatedConfiguration(): Configuration {
|
||||||
@@ -58,8 +87,8 @@ internal class KotlinCompilationNpmResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createNpmToolsConfiguration(): Configuration? {
|
private fun createNpmToolsConfiguration(): Configuration? {
|
||||||
val taskRequirements = projectResolver.requiredFromTasksByCompilation[compilation]
|
val taskRequirements = projectResolver.getTaskRequirements(compilation)
|
||||||
?.takeIf { it.isNotEmpty() } ?: return null
|
if (taskRequirements.isEmpty()) return null
|
||||||
|
|
||||||
val toolsConfiguration = project.configurations.create("${compilation.name}NpmTools")
|
val toolsConfiguration = project.configurations.create("${compilation.name}NpmTools")
|
||||||
|
|
||||||
@@ -77,93 +106,130 @@ internal class KotlinCompilationNpmResolver(
|
|||||||
return toolsConfiguration
|
return toolsConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPackageJson(configuration: Configuration): NpmProjectPackage {
|
data class ExternalGradleDependency(
|
||||||
val npmProject = compilation.npmProject
|
val dependency: ResolvedDependency,
|
||||||
val name = npmProject.name
|
val artifact: ResolvedArtifact
|
||||||
val packageJson = PackageJson(
|
)
|
||||||
name,
|
|
||||||
fixSemver(project.version.toString())
|
|
||||||
)
|
|
||||||
val npmDependencies = mutableSetOf<NpmDependency>()
|
|
||||||
val gradleDependencies = NpmGradleDependencies()
|
|
||||||
|
|
||||||
packageJson.main = npmProject.main
|
inner class ConfigurationVisitor {
|
||||||
|
private val internalDependencies = mutableSetOf<KotlinCompilationNpmResolver>()
|
||||||
|
private val externalGradleDependencies = mutableSetOf<ExternalGradleDependency>()
|
||||||
|
private val externalNpmDependencies = mutableSetOf<NpmDependency>()
|
||||||
|
|
||||||
collectDependenciesFromConfiguration(configuration, gradleDependencies)
|
fun visit(configuration: Configuration) {
|
||||||
|
|
||||||
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) {
|
|
||||||
configuration.resolvedConfiguration.firstLevelModuleDependencies.forEach {
|
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) {
|
private fun visitDependency(dependency: ResolvedDependency) {
|
||||||
visitArtifacts(dependency, dependency.moduleArtifacts, result)
|
visitArtifacts(dependency, dependency.moduleArtifacts)
|
||||||
|
|
||||||
dependency.children.forEach {
|
dependency.children.forEach {
|
||||||
visitDependency(it, result)
|
visitDependency(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun visitArtifacts(
|
||||||
|
dependency: ResolvedDependency,
|
||||||
|
artifacts: MutableSet<ResolvedArtifact>
|
||||||
|
) {
|
||||||
|
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(
|
class PackageJsonProducerInputs(
|
||||||
dependency: ResolvedDependency,
|
@get:Input
|
||||||
artifacts: MutableSet<ResolvedArtifact>,
|
val internalDependencies: Collection<String>,
|
||||||
result: NpmGradleDependencies
|
|
||||||
|
@get:InputFiles
|
||||||
|
val externalGradleDependencies: Collection<File>,
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
val externalDependencies: Collection<String>
|
||||||
|
) : Serializable
|
||||||
|
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
inner class PackageJsonProducer(
|
||||||
|
val internalDependencies: Collection<KotlinCompilationNpmResolver>,
|
||||||
|
val externalGradleDependencies: Collection<ExternalGradleDependency>,
|
||||||
|
val externalNpmDependencies: Collection<NpmDependency>
|
||||||
) {
|
) {
|
||||||
artifacts.forEach { artifact ->
|
val inputs: PackageJsonProducerInputs
|
||||||
val componentIdentifier = artifact.id.componentIdentifier
|
get() = PackageJsonProducerInputs(
|
||||||
if (componentIdentifier is ProjectComponentIdentifier) {
|
internalDependencies.map { it.npmProject.name },
|
||||||
val dependentProject = project.findProject(componentIdentifier.projectPath)
|
externalGradleDependencies.map { it.artifact.file },
|
||||||
?: error("Cannot find project ${componentIdentifier.projectPath}")
|
externalNpmDependencies.map { "${it.key}:${it.version}" }
|
||||||
|
)
|
||||||
|
|
||||||
result.internalModules.add(dependentProject)
|
fun createPackageJson(): KotlinCompilationNpmResolution {
|
||||||
} else {
|
val resolvedInternalDependencies = internalDependencies.map {
|
||||||
resolver.gradleNodeModules.ensureImported(artifact, dependency, artifacts, result)
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
-160
@@ -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<Project, KotlinProjectNpmResolver>()
|
|
||||||
|
|
||||||
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<NpmProjectPackage>) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+73
-28
@@ -18,56 +18,96 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResol
|
|||||||
|
|
||||||
internal class KotlinProjectNpmResolver(
|
internal class KotlinProjectNpmResolver(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val resolver: KotlinNpmResolver
|
val resolver: KotlinRootNpmResolver
|
||||||
) {
|
) {
|
||||||
val byCompilation = mutableMapOf<KotlinJsCompilation, KotlinCompilationNpmResolver>()
|
override fun toString(): String = "ProjectNpmResolver($project)"
|
||||||
|
|
||||||
private val taskRequirements = mutableMapOf<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>()
|
private val byCompilation = mutableMapOf<KotlinJsCompilation, KotlinCompilationNpmResolver>()
|
||||||
val requiredFromTasksByCompilation = mutableMapOf<KotlinJsCompilation, MutableList<RequiresNpmDependencies>>()
|
|
||||||
var hasNodeModulesDependentTasks = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
init {
|
operator fun get(compilation: KotlinJsCompilation): KotlinCompilationNpmResolver {
|
||||||
visit()
|
check(compilation.target.project == project)
|
||||||
|
requireContainerListeners()
|
||||||
|
return byCompilation[compilation] ?: error("$compilation was not registered in $this")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun visit() {
|
private var closed = false
|
||||||
project.tasks.toList().forEach { task ->
|
|
||||||
|
val compilationResolvers: Collection<KotlinCompilationNpmResolver>
|
||||||
|
get() {
|
||||||
|
requireContainerListeners()
|
||||||
|
return byCompilation.values
|
||||||
|
}
|
||||||
|
|
||||||
|
private val taskRequirements = mutableMapOf<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>()
|
||||||
|
private val requiredFromTasksByCompilation = mutableMapOf<KotlinJsCompilation, MutableList<RequiresNpmDependencies>>()
|
||||||
|
|
||||||
|
fun getTaskRequirements(compilation: KotlinJsCompilation): Collection<RequiresNpmDependencies> {
|
||||||
|
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) {
|
if (task.enabled && task is RequiresNpmDependencies) {
|
||||||
addTaskRequirements(task)
|
addTaskRequirements(task)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val kotlin = project.kotlinExtensionOrNull
|
val kotlin = project.kotlinExtensionOrNull
|
||||||
|
when (kotlin) {
|
||||||
if (kotlin != null) {
|
is KotlinSingleTargetExtension -> addTargetListeners(kotlin.target)
|
||||||
when (kotlin) {
|
is KotlinMultiplatformExtension -> kotlin.targets.forEach {
|
||||||
is KotlinSingleTargetExtension -> visitTarget(kotlin.target)
|
addTargetListeners(it)
|
||||||
is KotlinMultiplatformExtension -> kotlin.targets.forEach {
|
|
||||||
visitTarget(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun visitTarget(target: KotlinTarget) {
|
private fun addTargetListeners(target: KotlinTarget) {
|
||||||
|
check(!closed) { resolver.alreadyResolvedMessage("add target $target") }
|
||||||
|
|
||||||
if (target.platformType == KotlinPlatformType.js) {
|
if (target.platformType == KotlinPlatformType.js) {
|
||||||
target.compilations.toList().forEach { compilation ->
|
target.compilations.forEach { compilation ->
|
||||||
if (compilation is KotlinJsCompilation) {
|
if (compilation is KotlinJsCompilation) {
|
||||||
// compilation may be KotlinWithJavaTarget for old Kotlin2JsPlugin
|
// 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)
|
byCompilation[compilation] = KotlinCompilationNpmResolver(this, compilation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
private fun addTaskRequirements(task: RequiresNpmDependencies) {
|
private fun addTaskRequirements(task: RequiresNpmDependencies) {
|
||||||
if (!hasNodeModulesDependentTasks && task.nodeModulesRequired) {
|
check(!closed) { resolver.alreadyResolvedMessage("create task $task that requires npm dependencies") }
|
||||||
hasNodeModulesDependentTasks = true
|
|
||||||
|
if (!_hasNodeModulesDependentTasks && task.nodeModulesRequired) {
|
||||||
|
_hasNodeModulesDependentTasks = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val requirements = task.requiredNpmDependencies.toList()
|
val requirements = task.requiredNpmDependencies.toList()
|
||||||
@@ -79,9 +119,14 @@ internal class KotlinProjectNpmResolver(
|
|||||||
.add(task)
|
.add(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toResolved() = KotlinProjectNpmResolution(
|
fun close(): KotlinProjectNpmResolution {
|
||||||
project,
|
check(!closed)
|
||||||
byCompilation.values.map { it.projectPackage },
|
closed = true
|
||||||
taskRequirements
|
|
||||||
)
|
return KotlinProjectNpmResolution(
|
||||||
|
project,
|
||||||
|
byCompilation.values.mapNotNull { it.close() },
|
||||||
|
taskRequirements
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+96
@@ -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<Project, KotlinProjectNpmResolver>()
|
||||||
|
|
||||||
|
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<KotlinJsCompilation>
|
||||||
|
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<KotlinCompilationNpmResolution>) {
|
||||||
|
val packages = allNpmPackages.mapTo(mutableSetOf()) { it.npmProject.name }
|
||||||
|
nodeJs.projectPackagesDir.listFiles()?.forEach {
|
||||||
|
if (it.name !in packages) {
|
||||||
|
it.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-10
@@ -7,30 +7,30 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
|
|||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.tasks.InputFiles
|
import org.gradle.api.tasks.InputFiles
|
||||||
|
import org.gradle.api.tasks.OutputFile
|
||||||
import org.gradle.api.tasks.TaskAction
|
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.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
|
import java.io.File
|
||||||
|
|
||||||
open class KotlinNpmInstallTask : DefaultTask() {
|
open class KotlinNpmInstallTask : DefaultTask() {
|
||||||
private val resolver: KotlinNpmResolver
|
|
||||||
get() = KotlinNpmResolver.getResolver(project)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
check(project == project.rootProject)
|
check(project == project.rootProject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
val packageJsonFiles: Collection<File>
|
val packageJsonFiles: Collection<File>
|
||||||
get() = resolver.projectResolvers.values.flatMap { projectResolver ->
|
get() = project.nodeJs.root.resolutionState.compilations.map { it.npmProject.packageJsonFile }
|
||||||
projectResolver.byCompilation.keys.map { compilation ->
|
|
||||||
compilation.npmProject.packageJsonFile
|
@get:OutputFile
|
||||||
}
|
val yarnLock: File
|
||||||
}
|
get() = project.nodeJs.root.rootPackageDir.resolve("yarn.lock")
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun resolve() {
|
fun resolve() {
|
||||||
resolver.installAndClose()
|
project.nodeJs.root.resolveIfNeeded(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+59
-14
@@ -6,34 +6,79 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
|
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.plugins.BasePlugin
|
||||||
import org.gradle.api.tasks.InputFiles
|
import org.gradle.api.tasks.Input
|
||||||
import org.gradle.api.tasks.Internal
|
import org.gradle.api.tasks.Nested
|
||||||
import org.gradle.api.tasks.OutputFile
|
import org.gradle.api.tasks.OutputFile
|
||||||
import org.gradle.api.tasks.TaskAction
|
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.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.npmProject
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
|
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
|
import java.io.File
|
||||||
|
|
||||||
class KotlinPackageJsonTask : DefaultTask() {
|
open class KotlinPackageJsonTask : DefaultTask() {
|
||||||
@Internal
|
private lateinit var nodeJs: NodeJsRootExtension
|
||||||
lateinit var compilation: KotlinJsCompilation
|
private lateinit var compilation: KotlinJsCompilation
|
||||||
|
|
||||||
private val compilationResolver: KotlinCompilationNpmResolver
|
private val compilationResolver
|
||||||
get() = KotlinNpmResolver.getResolver(project.rootProject).projectResolvers[project]!!.byCompilation[compilation]!!
|
get() = nodeJs.requireResolver()[project][compilation]
|
||||||
|
|
||||||
@get:InputFiles
|
private val producer: KotlinCompilationNpmResolver.PackageJsonProducer
|
||||||
val configuration: Configuration
|
get() = compilationResolver.packageJsonProducer
|
||||||
get() = compilationResolver.aggregatedConfiguration
|
|
||||||
|
private fun findDependentTasks(): Collection<KotlinPackageJsonTask> =
|
||||||
|
producer.internalDependencies.map { dependentResolver ->
|
||||||
|
dependentResolver.npmProject.packageJsonTask
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun create(compilation: KotlinJsCompilation): TaskHolder<KotlinPackageJsonTask> {
|
||||||
|
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<KotlinPackageJsonTask>(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
|
@get:OutputFile
|
||||||
val packageJson: File
|
val packageJson: File
|
||||||
get() = compilation.npmProject.packageJsonFile
|
get() = compilationResolver.npmProject.packageJsonFile
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun resolve() {
|
fun resolve() {
|
||||||
compilationResolver.projectPackage
|
compilationResolver.resolve()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -59,7 +59,7 @@ class KotlinBrowserJs(target: KotlinJsTarget) :
|
|||||||
it.dependsOn(
|
it.dependsOn(
|
||||||
target.project.nodeJs.root.npmInstallTask,
|
target.project.nodeJs.root.npmInstallTask,
|
||||||
compileKotlinTask,
|
compileKotlinTask,
|
||||||
compilation.processResourcesTaskName
|
target.project.tasks.getByName(compilation.processResourcesTaskName)
|
||||||
)
|
)
|
||||||
|
|
||||||
it.bin = "webpack-dev-server/bin/webpack-dev-server.js"
|
it.bin = "webpack-dev-server/bin/webpack-dev-server.js"
|
||||||
|
|||||||
+4
-2
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
|
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl
|
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.nodejs.nodeJs
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||||
@@ -30,6 +30,8 @@ abstract class KotlinJsSubTarget(
|
|||||||
val testTaskName = disambiguateCamelCased("test")
|
val testTaskName = disambiguateCamelCased("test")
|
||||||
|
|
||||||
fun configure() {
|
fun configure() {
|
||||||
|
project.nodeJs
|
||||||
|
|
||||||
configureTests()
|
configureTests()
|
||||||
configureRun()
|
configureRun()
|
||||||
|
|
||||||
@@ -66,7 +68,7 @@ abstract class KotlinJsSubTarget(
|
|||||||
|
|
||||||
private fun configureTests(compilation: KotlinJsCompilation) {
|
private fun configureTests(compilation: KotlinJsCompilation) {
|
||||||
// apply plugin (cannot be done at task instantiation time)
|
// 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<KotlinJsTest>(testTaskName) { testJs ->
|
val testJs = project.createOrRegisterTask<KotlinJsTest>(testTaskName) { testJs ->
|
||||||
val compileTask = compilation.compileKotlinTask
|
val compileTask = compilation.compileKotlinTask
|
||||||
|
|||||||
+1
-33
@@ -31,39 +31,7 @@ class KotlinNodeJs(target: KotlinJsTarget) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun configureRun(compilation: KotlinJsCompilation) {
|
override fun configureRun(compilation: KotlinJsCompilation) {
|
||||||
val project = target.project
|
val runTaskHolder = NodeJsExec.create(compilation, disambiguateCamelCased("run"))
|
||||||
|
|
||||||
"true".toBoolean()
|
|
||||||
|
|
||||||
val runTaskHolder = project.createOrRegisterTask<NodeJsExec>(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)
|
|
||||||
|
|
||||||
target.runTask.dependsOn(runTaskHolder.getTaskOrProvider())
|
target.runTask.dependsOn(runTaskHolder.getTaskOrProvider())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addSourceMapSupport(
|
|
||||||
compilation: KotlinJsCompilation,
|
|
||||||
runTaskHolder: TaskHolder<NodeJsExec>
|
|
||||||
) {
|
|
||||||
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")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+4
-4
@@ -12,9 +12,9 @@ import org.gradle.process.internal.DefaultProcessForkOptions
|
|||||||
import org.gradle.util.ConfigureUtil
|
import org.gradle.util.ConfigureUtil
|
||||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
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.NodeJsRootPlugin
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinNpmResolver
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
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.RequiresNpmDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma
|
import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma
|
||||||
@@ -92,14 +92,14 @@ open class KotlinJsTest : KotlinTest(), RequiresNpmDependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun executeTests() {
|
override fun executeTests() {
|
||||||
KotlinNpmResolver.checkRequiredDependencies(project, this)
|
project.nodeJs.root.checkRequiredDependencies(project, this)
|
||||||
super.executeTests()
|
super.executeTests()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
|
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
|
||||||
val forkOptions = DefaultProcessForkOptions(fileResolver)
|
val forkOptions = DefaultProcessForkOptions(fileResolver)
|
||||||
forkOptions.workingDir = compilation.npmProject.dir
|
forkOptions.workingDir = compilation.npmProject.dir
|
||||||
forkOptions.executable = NodeJsPlugin.apply(project).root.environment.nodeExecutable
|
forkOptions.executable = NodeJsRootPlugin.apply(project).root.environment.nodeExecutable
|
||||||
|
|
||||||
val nodeJsArgs = mutableListOf<String>()
|
val nodeJsArgs = mutableListOf<String>()
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -17,7 +17,6 @@ import org.gradle.process.internal.ExecHandleFactory
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.NpmPackageVersion
|
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.RequiresNpmDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||||
import org.jetbrains.kotlin.gradle.testing.internal.reportsDir
|
import org.jetbrains.kotlin.gradle.testing.internal.reportsDir
|
||||||
@@ -127,7 +126,7 @@ open class KotlinWebpack : DefaultTask(), RequiresNpmDependencies {
|
|||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun doExecute() {
|
fun doExecute() {
|
||||||
KotlinNpmResolver.checkRequiredDependencies(project, this)
|
project.nodeJs.root.checkRequiredDependencies(project, this)
|
||||||
|
|
||||||
val runner = createRunner()
|
val runner = createRunner()
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi
|
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 {
|
object Yarn : NpmApi {
|
||||||
private fun getDelegate(project: Project): NpmApi =
|
private fun getDelegate(project: Project): NpmApi =
|
||||||
@@ -17,9 +17,9 @@ object Yarn : NpmApi {
|
|||||||
override fun setup(project: Project) =
|
override fun setup(project: Project) =
|
||||||
getDelegate(project.rootProject).setup(project)
|
getDelegate(project.rootProject).setup(project)
|
||||||
|
|
||||||
override fun resolveProject(resolvedNpmProject: NpmProjectPackage) =
|
override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) =
|
||||||
getDelegate(resolvedNpmProject.project).resolveProject(resolvedNpmProject)
|
getDelegate(resolvedNpmProject.project).resolveProject(resolvedNpmProject)
|
||||||
|
|
||||||
override fun resolveRootProject(rootProject: Project, subProjects: Collection<NpmProjectPackage>) =
|
override fun resolveRootProject(rootProject: Project, subProjects: Collection<KotlinCompilationNpmResolution>) =
|
||||||
getDelegate(rootProject.project).resolveRootProject(rootProject, subProjects)
|
getDelegate(rootProject.project).resolveRootProject(rootProject, subProjects)
|
||||||
}
|
}
|
||||||
+2
-3
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.internal.execWithProgress
|
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.NpmApi
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class YarnBasics : NpmApi {
|
abstract class YarnBasics : NpmApi {
|
||||||
@@ -24,7 +23,7 @@ abstract class YarnBasics : NpmApi {
|
|||||||
description: String,
|
description: String,
|
||||||
vararg args: String
|
vararg args: String
|
||||||
) {
|
) {
|
||||||
val nodeJsEnv = NodeJsPlugin.apply(project).root.environment
|
val nodeJsEnv = NodeJsRootPlugin.apply(project).root.environment
|
||||||
val yarnEnv = YarnPlugin.apply(project).environment
|
val yarnEnv = YarnPlugin.apply(project).environment
|
||||||
|
|
||||||
project.execWithProgress(description) { exec ->
|
project.execWithProgress(description) { exec ->
|
||||||
|
|||||||
+3
-3
@@ -9,19 +9,19 @@ import com.google.gson.Gson
|
|||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModule
|
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.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 org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class YarnImportedPackagesVersionResolver(
|
class YarnImportedPackagesVersionResolver(
|
||||||
private val rootProject: Project,
|
private val rootProject: Project,
|
||||||
private val npmProjects: Collection<NpmProjectPackage>,
|
private val npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||||
private val nodeJsWorldDir: File
|
private val nodeJsWorldDir: File
|
||||||
) {
|
) {
|
||||||
private val resolvedVersion = mutableMapOf<String, String>()
|
private val resolvedVersion = mutableMapOf<String, String>()
|
||||||
private val importedProjectWorkspaces = mutableListOf<String>()
|
private val importedProjectWorkspaces = mutableListOf<String>()
|
||||||
private val externalModules = npmProjects.flatMapTo(mutableSetOf()) {
|
private val externalModules = npmProjects.flatMapTo(mutableSetOf()) {
|
||||||
it.gradleDependencies.externalModules
|
it.externalGradleDependencies
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resolveAndUpdatePackages(): MutableList<String> {
|
fun resolveAndUpdatePackages(): MutableList<String> {
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
|||||||
|
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
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<Project> {
|
open class YarnPlugin : Plugin<Project> {
|
||||||
override fun apply(project: Project): Unit = project.run {
|
override fun apply(project: Project): Unit = project.run {
|
||||||
@@ -15,7 +15,7 @@ open class YarnPlugin : Plugin<Project> {
|
|||||||
"YarnPlugin can be applied only to root project"
|
"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)
|
this.extensions.create(YarnRootExtension.YARN, YarnRootExtension::class.java, this)
|
||||||
tasks.create(YarnSetupTask.NAME, YarnSetupTask::class.java) {
|
tasks.create(YarnSetupTask.NAME, YarnSetupTask::class.java) {
|
||||||
|
|||||||
+2
-3
@@ -7,8 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
|
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
|
||||||
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
|
|
||||||
|
|
||||||
open class YarnRootExtension(val project: Project) {
|
open class YarnRootExtension(val project: Project) {
|
||||||
private val gradleHome = project.gradle.gradleUserHomeDir.also {
|
private val gradleHome = project.gradle.gradleUserHomeDir.also {
|
||||||
@@ -29,7 +28,7 @@ open class YarnRootExtension(val project: Project) {
|
|||||||
get() = !disableWorkspaces
|
get() = !disableWorkspaces
|
||||||
|
|
||||||
internal fun executeSetup() {
|
internal fun executeSetup() {
|
||||||
NodeJsPlugin.apply(project).root.executeSetup()
|
NodeJsRootPlugin.apply(project).root.executeSetup()
|
||||||
|
|
||||||
val env = environment
|
val env = environment
|
||||||
if (!env.home.isDirectory) {
|
if (!env.home.isDirectory) {
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@ import de.undercouch.gradle.tasks.download.DownloadAction
|
|||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.tasks.Input
|
import org.gradle.api.tasks.Input
|
||||||
import org.gradle.api.tasks.OutputDirectory
|
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 java.io.File
|
||||||
import javax.xml.ws.Action
|
import javax.xml.ws.Action
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ open class YarnSetupTask : DefaultTask() {
|
|||||||
@OutputDirectory get() = env.home
|
@OutputDirectory get() = env.home
|
||||||
|
|
||||||
init {
|
init {
|
||||||
group = NodeJsPlugin.TASKS_GROUP_NAME
|
group = NodeJsRootPlugin.TASKS_GROUP_NAME
|
||||||
description = "Download and install a local yarn version"
|
description = "Download and install a local yarn version"
|
||||||
|
|
||||||
onlyIf {
|
onlyIf {
|
||||||
|
|||||||
+4
-4
@@ -7,19 +7,19 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi
|
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() {
|
object YarnSimple : YarnBasics() {
|
||||||
override fun resolveProject(resolvedNpmProject: NpmProjectPackage) {
|
override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) {
|
||||||
setup(resolvedNpmProject.project.rootProject)
|
setup(resolvedNpmProject.project.rootProject)
|
||||||
|
|
||||||
val project = resolvedNpmProject.project
|
val project = resolvedNpmProject.project
|
||||||
|
|
||||||
YarnUpToDateCheck(resolvedNpmProject.npmProject).updateIfNeeded {
|
YarnUpToDateCheck(resolvedNpmProject.npmProject).updateIfNeeded {
|
||||||
yarnExec(project, resolvedNpmProject.npmProject.dir, NpmApi.resolveOperationDescription("yarn for ${project.path}"))
|
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<NpmProjectPackage>) = Unit
|
override fun resolveRootProject(rootProject: Project, subProjects: Collection<KotlinCompilationNpmResolution>) = Unit
|
||||||
}
|
}
|
||||||
+6
-6
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
|||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
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
|
import java.io.File
|
||||||
|
|
||||||
object YarnWorkspaces : YarnBasics() {
|
object YarnWorkspaces : YarnBasics() {
|
||||||
override fun resolveProject(resolvedNpmProject: NpmProjectPackage) = Unit
|
override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) = Unit
|
||||||
|
|
||||||
override fun resolveRootProject(rootProject: Project, subProjects: Collection<NpmProjectPackage>) {
|
override fun resolveRootProject(rootProject: Project, subProjects: Collection<KotlinCompilationNpmResolution>) {
|
||||||
check(rootProject == rootProject.rootProject)
|
check(rootProject == rootProject.rootProject)
|
||||||
setup(rootProject)
|
setup(rootProject)
|
||||||
resolveWorkspaces(rootProject, subProjects)
|
resolveWorkspaces(rootProject, subProjects)
|
||||||
@@ -22,7 +22,7 @@ object YarnWorkspaces : YarnBasics() {
|
|||||||
|
|
||||||
private fun resolveWorkspaces(
|
private fun resolveWorkspaces(
|
||||||
rootProject: Project,
|
rootProject: Project,
|
||||||
npmProjects: Collection<NpmProjectPackage>
|
npmProjects: Collection<KotlinCompilationNpmResolution>
|
||||||
) {
|
) {
|
||||||
val upToDateChecks = npmProjects.map {
|
val upToDateChecks = npmProjects.map {
|
||||||
YarnUpToDateCheck(it.npmProject)
|
YarnUpToDateCheck(it.npmProject)
|
||||||
@@ -35,7 +35,7 @@ object YarnWorkspaces : YarnBasics() {
|
|||||||
saveRootProjectWorkspacesPackageJson(rootProject, npmProjects, nodeJsWorldDir)
|
saveRootProjectWorkspacesPackageJson(rootProject, npmProjects, nodeJsWorldDir)
|
||||||
|
|
||||||
yarnExec(rootProject, nodeJsWorldDir, NpmApi.resolveOperationDescription("yarn"))
|
yarnExec(rootProject, nodeJsWorldDir, NpmApi.resolveOperationDescription("yarn"))
|
||||||
yarnLockReadTransitiveDependencies(nodeJsWorldDir, npmProjects.flatMap { it.npmDependencies })
|
yarnLockReadTransitiveDependencies(nodeJsWorldDir, npmProjects.flatMap { it.externalNpmDependencies })
|
||||||
|
|
||||||
upToDateChecks.forEach {
|
upToDateChecks.forEach {
|
||||||
it.commit()
|
it.commit()
|
||||||
@@ -44,7 +44,7 @@ object YarnWorkspaces : YarnBasics() {
|
|||||||
|
|
||||||
private fun saveRootProjectWorkspacesPackageJson(
|
private fun saveRootProjectWorkspacesPackageJson(
|
||||||
rootProject: Project,
|
rootProject: Project,
|
||||||
npmProjects: Collection<NpmProjectPackage>,
|
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||||
nodeJsWorldDir: File
|
nodeJsWorldDir: File
|
||||||
) {
|
) {
|
||||||
val rootPackageJson = PackageJson(rootProject.name, rootProject.version.toString())
|
val rootPackageJson = PackageJson(rootProject.name, rootProject.version.toString())
|
||||||
|
|||||||
-1
@@ -1 +0,0 @@
|
|||||||
implementation-class=org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
implementation-class=org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
|
||||||
Reference in New Issue
Block a user