Gradle, js: implement NpmSimpleLinker for cases when there are no npm dependencies
This commit is contained in:
+1
-1
@@ -10,4 +10,4 @@ import java.io.File
|
|||||||
/**
|
/**
|
||||||
* Fake NodeJS module directory created from Gradle external module
|
* Fake NodeJS module directory created from Gradle external module
|
||||||
*/
|
*/
|
||||||
class GradleNodeModule(val name: String, val version: String, val path: File)
|
data class GradleNodeModule(val name: String, val version: String, val path: File)
|
||||||
+2
-1
@@ -15,5 +15,6 @@ class NpmProjectPackage(
|
|||||||
val npmProject: NpmProject,
|
val npmProject: NpmProject,
|
||||||
val npmDependencies: Collection<NpmDependency>,
|
val npmDependencies: Collection<NpmDependency>,
|
||||||
val gradleDependencies: NpmGradleDependencies,
|
val gradleDependencies: NpmGradleDependencies,
|
||||||
val packageJson: PackageJson
|
val packageJson: PackageJson,
|
||||||
|
val hasNodeModulesDependentTasks: Boolean
|
||||||
)
|
)
|
||||||
+10
-7
@@ -28,17 +28,16 @@ internal class NpmProjectVisitor(val resolver: NpmResolver, val project: Project
|
|||||||
private val byCompilation = mutableMapOf<KotlinJsCompilation, NpmProjectPackage>()
|
private val byCompilation = mutableMapOf<KotlinJsCompilation, NpmProjectPackage>()
|
||||||
private val byNpmDependency = mutableMapOf<NpmDependency, NpmProjectPackage>()
|
private val byNpmDependency = mutableMapOf<NpmDependency, NpmProjectPackage>()
|
||||||
private val taskRequirements = mutableMapOf<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>()
|
private val taskRequirements = mutableMapOf<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>()
|
||||||
private val requiredFromTasksByCompilation = mutableMapOf<KotlinJsCompilation, MutableList<Dependency>>()
|
private val requiredFromTasksByCompilation = mutableMapOf<KotlinJsCompilation, MutableList<RequiresNpmDependencies>>()
|
||||||
|
|
||||||
private fun addTaskRequirements(task: RequiresNpmDependencies) {
|
private fun addTaskRequirements(task: RequiresNpmDependencies) {
|
||||||
val requirements = task.requiredNpmDependencies.toList()
|
val requirements = task.requiredNpmDependencies.toList()
|
||||||
|
|
||||||
taskRequirements[task] = requirements
|
taskRequirements[task] = requirements
|
||||||
|
|
||||||
val requiredDependenciesList = requiredFromTasksByCompilation.getOrPut(task.compilation) { mutableListOf() }
|
requiredFromTasksByCompilation
|
||||||
requirements.forEach { requiredDependency ->
|
.getOrPut(task.compilation) { mutableListOf() }
|
||||||
requiredDependenciesList.add(requiredDependency.createDependency(project))
|
.add(task)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addNpmProject(resolved: NpmProjectPackage) {
|
private fun addNpmProject(resolved: NpmProjectPackage) {
|
||||||
@@ -111,10 +110,14 @@ internal class NpmProjectVisitor(val resolver: NpmResolver, val project: Project
|
|||||||
packageJson.main = npmProject.main
|
packageJson.main = npmProject.main
|
||||||
|
|
||||||
val requiredByTasks = requiredFromTasksByCompilation[compilation]
|
val requiredByTasks = requiredFromTasksByCompilation[compilation]
|
||||||
|
var nodeModulesRequired = false
|
||||||
if (requiredByTasks != null && requiredByTasks.isNotEmpty()) {
|
if (requiredByTasks != null && requiredByTasks.isNotEmpty()) {
|
||||||
val configuration = project.configurations.create("$name-jsTools")
|
val configuration = project.configurations.create("$name-jsTools")
|
||||||
requiredByTasks.forEach {
|
requiredByTasks.forEach {
|
||||||
configuration.dependencies.add(it)
|
if (it.nodeModulesRequired) nodeModulesRequired = true
|
||||||
|
it.requiredNpmDependencies.forEach { requirement ->
|
||||||
|
configuration.dependencies.add(requirement.createDependency(project))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
configuration.resolve()
|
configuration.resolve()
|
||||||
visitConfiguration(configuration, npmDependencies, gradleDeps)
|
visitConfiguration(configuration, npmDependencies, gradleDeps)
|
||||||
@@ -139,7 +142,7 @@ internal class NpmProjectVisitor(val resolver: NpmResolver, val project: Project
|
|||||||
it(packageJson)
|
it(packageJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
val npmPackage = NpmProjectPackage(project, npmProject, npmDependencies, gradleDeps, packageJson)
|
val npmPackage = NpmProjectPackage(project, npmProject, npmDependencies, gradleDeps, packageJson, nodeModulesRequired)
|
||||||
npmPackage.packageJson.saveTo(npmProject.packageJsonFile)
|
npmPackage.packageJson.saveTo(npmProject.packageJsonFile)
|
||||||
|
|
||||||
resolver.packageManager.resolveProject(npmPackage)
|
resolver.packageManager.resolveProject(npmPackage)
|
||||||
|
|||||||
+7
-2
@@ -9,7 +9,9 @@ import org.gradle.api.Project
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolver.ResolutionCallResult.*
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolver.ResolutionCallResult.*
|
||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates `package.json` file for [NpmProject] with npm or js dependencies and
|
* Generates `package.json` file for [NpmProject] with npm or js dependencies and
|
||||||
@@ -92,9 +94,12 @@ internal class NpmResolver private constructor(val rootProject: Project) : AutoC
|
|||||||
|
|
||||||
fun resolve() {
|
fun resolve() {
|
||||||
resolve(rootProject)
|
resolve(rootProject)
|
||||||
if (allNpmPackages.isNotEmpty()) {
|
removeOutdatedPackages()
|
||||||
removeOutdatedPackages()
|
|
||||||
|
if (allNpmPackages.any { it.npmDependencies.isNotEmpty() }) {
|
||||||
packageManager.resolveRootProject(rootProject, allNpmPackages)
|
packageManager.resolveRootProject(rootProject, allNpmPackages)
|
||||||
|
} else if (allNpmPackages.any { it.hasNodeModulesDependentTasks }) {
|
||||||
|
NpmSimpleLinker(rootProject).link(allNpmPackages)
|
||||||
}
|
}
|
||||||
|
|
||||||
close()
|
close()
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.nodeJs
|
||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles simple case, when there are no npm depenencies required, but some tasks steel needs
|
||||||
|
* node_modules with symlinked packages and packages_imported
|
||||||
|
*/
|
||||||
|
class NpmSimpleLinker(rootProject: Project) {
|
||||||
|
private val rootProjectNodeModules = rootProject.nodeJs.root.rootPackageDir.resolve(NpmProject.NODE_MODULES)
|
||||||
|
|
||||||
|
fun link(projects: Collection<NpmProjectPackage>) {
|
||||||
|
rootProjectNodeModules.listFiles()?.forEach {
|
||||||
|
val path = it.toPath()
|
||||||
|
when {
|
||||||
|
Files.isSymbolicLink(path) ->
|
||||||
|
Files.delete(path)
|
||||||
|
else -> it.deleteRecursively()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProjectNodeModules.mkdirs()
|
||||||
|
|
||||||
|
// packages
|
||||||
|
projects.forEach {
|
||||||
|
Files.createSymbolicLink(getNodeModulePath(it.npmProject.name), it.npmProject.dir.canonicalFile.toPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
// packages_imported
|
||||||
|
projects.flatMapTo(mutableSetOf()) {
|
||||||
|
it.gradleDependencies.externalModules.map { gradleNodeModule -> gradleNodeModule }
|
||||||
|
}.forEach {
|
||||||
|
Files.createSymbolicLink(getNodeModulePath(it.name), it.path.canonicalFile.toPath())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getNodeModulePath(name: String) =
|
||||||
|
rootProjectNodeModules.resolve(name).canonicalFile.toPath()
|
||||||
|
}
|
||||||
+1
@@ -10,5 +10,6 @@ import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
|||||||
|
|
||||||
interface RequiresNpmDependencies {
|
interface RequiresNpmDependencies {
|
||||||
val compilation: KotlinJsCompilation
|
val compilation: KotlinJsCompilation
|
||||||
|
val nodeModulesRequired: Boolean
|
||||||
val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
}
|
}
|
||||||
+3
@@ -50,6 +50,9 @@ open class KotlinJsTest : KotlinTest(), RequiresNpmDependencies {
|
|||||||
val nodeModulesToLoad: List<String>
|
val nodeModulesToLoad: List<String>
|
||||||
@Internal get() = listOf("./" + compilation.npmProject.main)
|
@Internal get() = listOf("./" + compilation.npmProject.main)
|
||||||
|
|
||||||
|
override val nodeModulesRequired: Boolean
|
||||||
|
@Internal get() = testFramework!!.nodeModulesRequired
|
||||||
|
|
||||||
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
|
||||||
@Internal get() = testFramework!!.requiredNpmDependencies
|
@Internal get() = testFramework!!.requiredNpmDependencies
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.targets.js.testing
|
|||||||
|
|
||||||
import org.gradle.process.ProcessForkOptions
|
import org.gradle.process.ProcessForkOptions
|
||||||
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
|
||||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
||||||
|
|
||||||
interface KotlinJsTestFramework : RequiresNpmDependencies {
|
interface KotlinJsTestFramework : RequiresNpmDependencies {
|
||||||
@@ -18,4 +17,7 @@ interface KotlinJsTestFramework : RequiresNpmDependencies {
|
|||||||
forkOptions: ProcessForkOptions,
|
forkOptions: ProcessForkOptions,
|
||||||
nodeJsArgs: MutableList<String>
|
nodeJsArgs: MutableList<String>
|
||||||
): TCServiceMessagesTestExecutionSpec
|
): TCServiceMessagesTestExecutionSpec
|
||||||
|
|
||||||
|
override val nodeModulesRequired: Boolean
|
||||||
|
get() = true
|
||||||
}
|
}
|
||||||
+3
@@ -95,6 +95,9 @@ open class KotlinWebpack : DefaultTask(), RequiresNpmDependencies {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override val nodeModulesRequired: Boolean
|
||||||
|
@Internal get() = true
|
||||||
|
|
||||||
override val requiredNpmDependencies: Collection<NpmPackageVersion>
|
override val requiredNpmDependencies: Collection<NpmPackageVersion>
|
||||||
@Internal get() = mutableListOf<NpmPackageVersion>().also {
|
@Internal get() = mutableListOf<NpmPackageVersion>().also {
|
||||||
it.add(versions.webpack)
|
it.add(versions.webpack)
|
||||||
|
|||||||
Reference in New Issue
Block a user