Gradle, JS: replace NodeJs plugin and extension with NpmResolver plugin
This commit is contained in:
-1
@@ -147,7 +147,6 @@ internal open class ProcessedFilesCache(
|
||||
operator fun get(elementHash: ByteArray) = byHash[ByteArrayWrapper(elementHash)]
|
||||
|
||||
operator fun set(elementHash: ByteArray, element: Element) {
|
||||
elementHash.toHexString()
|
||||
byHash[ByteArrayWrapper(elementHash)] = element
|
||||
val target = element.target
|
||||
if (target != null) {
|
||||
|
||||
+8
@@ -9,6 +9,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
|
||||
class KotlinJsCompilation(
|
||||
@@ -20,4 +21,11 @@ class KotlinJsCompilation(
|
||||
|
||||
override val compileKotlinTask: Kotlin2JsCompile
|
||||
get() = super.compileKotlinTask as Kotlin2JsCompile
|
||||
|
||||
internal val packageJsonHandlers = mutableListOf<PackageJson.() -> Unit>()
|
||||
|
||||
@Suppress("unused")
|
||||
fun packageJson(handler: PackageJson.() -> Unit) {
|
||||
packageJsonHandlers.add(handler)
|
||||
}
|
||||
}
|
||||
+2
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBrowserDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsNodeDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.subtargets.KotlinBrowserJs
|
||||
import org.jetbrains.kotlin.gradle.targets.js.subtargets.KotlinNodeJs
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestReport
|
||||
|
||||
-4
@@ -20,10 +20,6 @@ open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
||||
target as KotlinJsTarget
|
||||
|
||||
super.configureTarget(target)
|
||||
|
||||
target.compilations.forEach { compilation ->
|
||||
KotlinPackageJsonTask.create(compilation)
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureTest(target: KotlinOnlyTarget<KotlinJsCompilation>) {
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.nodejs
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||
|
||||
open class NodeJsExtension(val project: Project) {
|
||||
internal val packageJsonHandlers = mutableListOf<PackageJson.() -> Unit>()
|
||||
|
||||
@Suppress("unused")
|
||||
fun packageJson(handler: PackageJson.() -> Unit) {
|
||||
packageJsonHandlers.add(handler)
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +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.nodejs
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
class NodeJsPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
val root = NodeJsRootPlugin.apply(target.rootProject)
|
||||
|
||||
if (target != target.rootProject) {
|
||||
target.extensions.create(NodeJsRootExtension.EXTENSION_NAME, NodeJsExtension::class.java, target)
|
||||
}
|
||||
|
||||
root.requireResolver().addProject(target)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun apply(project: Project): NodeJsExtension {
|
||||
project.plugins.apply(NodeJsPlugin::class.java)
|
||||
return project.extensions.getByName(NodeJsRootExtension.EXTENSION_NAME) as NodeJsExtension
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-17
@@ -13,13 +13,13 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.Yarn
|
||||
import java.io.File
|
||||
|
||||
open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) {
|
||||
open class NodeJsRootExtension(val rootProject: Project) {
|
||||
init {
|
||||
check(project.rootProject == project)
|
||||
check(rootProject.rootProject == rootProject)
|
||||
}
|
||||
|
||||
private val gradleHome = project.gradle.gradleUserHomeDir.also {
|
||||
project.logger.kotlinInfo("Storing cached files in $it")
|
||||
private val gradleHome = rootProject.gradle.gradleUserHomeDir.also {
|
||||
rootProject.logger.kotlinInfo("Storing cached files in $it")
|
||||
}
|
||||
|
||||
var installationDir = gradleHome.resolve("nodejs")
|
||||
@@ -33,13 +33,13 @@ open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) {
|
||||
var packageManager: NpmApi = Yarn
|
||||
|
||||
val nodeJsSetupTask: NodeJsSetupTask
|
||||
get() = project.tasks.getByName(NodeJsSetupTask.NAME) as NodeJsSetupTask
|
||||
get() = rootProject.tasks.getByName(NodeJsSetupTask.NAME) as NodeJsSetupTask
|
||||
|
||||
val npmInstallTask: KotlinNpmInstallTask
|
||||
get() = project.tasks.getByName(KotlinNpmInstallTask.NAME) as KotlinNpmInstallTask
|
||||
get() = rootProject.tasks.getByName(KotlinNpmInstallTask.NAME) as KotlinNpmInstallTask
|
||||
|
||||
val rootPackageDir: File
|
||||
get() = project.buildDir.resolve("js")
|
||||
get() = rootProject.buildDir.resolve("js")
|
||||
|
||||
val projectPackagesDir: File
|
||||
get() = rootPackageDir.resolve("packages")
|
||||
@@ -105,7 +105,7 @@ open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) {
|
||||
internal fun requireResolver(): KotlinRootNpmResolver =
|
||||
(resolutionState as? ResolutionState.Resolving ?: error("NPM Dependencies already resolved and installed")).resolver
|
||||
|
||||
internal fun resolveIfNeeded(project: Project): KotlinProjectNpmResolution {
|
||||
internal fun resolveIfNeeded(requireUpToDateReason: String? = null): KotlinRootNpmResolution {
|
||||
val state0 = _resolutionState
|
||||
val resolution = when (state0) {
|
||||
is ResolutionState.Resolved -> state0.resolved
|
||||
@@ -116,15 +116,21 @@ open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) {
|
||||
is ResolutionState.Resolved -> state1.resolved
|
||||
is ResolutionState.Resolving -> state1.resolver.close().also {
|
||||
_resolutionState = ResolutionState.Resolved(it)
|
||||
if (requireUpToDateReason != null && !it.wasUpToDate) {
|
||||
error("NPM dependencies should be resolved $requireUpToDateReason")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resolution[project]
|
||||
return resolution
|
||||
}
|
||||
|
||||
internal fun requireAlreadyResolved(project: Project, reason: String = ""): KotlinProjectNpmResolution =
|
||||
resolveIfNeeded(reason)[project]
|
||||
|
||||
internal fun getAlreadyResolvedOrNull(project: Project): KotlinProjectNpmResolution? {
|
||||
val state0 = resolutionState
|
||||
return when (state0) {
|
||||
@@ -133,19 +139,13 @@ open class NodeJsRootExtension(project: Project) : NodeJsExtension(project) {
|
||||
}
|
||||
}
|
||||
|
||||
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 requestedTaskDependencies = requireAlreadyResolved(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. " +
|
||||
"${it.createDependency(project)} 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."
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ internal class GradleNodeModulesCache(val nodeJs: NodeJsRootExtension) : AutoClo
|
||||
const val STATE_FILE_NAME = ".visited"
|
||||
}
|
||||
|
||||
val project: Project get() = nodeJs.project
|
||||
val project: Project get() = nodeJs.rootProject
|
||||
internal val dir = nodeJs.nodeModulesGradleCacheDir
|
||||
private val cache = ProcessedFilesCache(project, dir, STATE_FILE_NAME, "9")
|
||||
|
||||
|
||||
+5
-1
@@ -16,10 +16,14 @@ interface NpmApi {
|
||||
|
||||
fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution)
|
||||
|
||||
enum class Result {
|
||||
upToDate, executed
|
||||
}
|
||||
|
||||
fun resolveRootProject(
|
||||
rootProject: Project,
|
||||
subProjects: Collection<KotlinCompilationNpmResolution>
|
||||
)
|
||||
): Result
|
||||
|
||||
companion object {
|
||||
fun resolveOperationDescription(packageManagerTitle: String): String =
|
||||
|
||||
+2
-1
@@ -86,8 +86,9 @@ data class NpmDependency(
|
||||
private fun resolveProject(): KotlinCompilationNpmResolution? {
|
||||
val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
|
||||
// may return null only while resolving configuration in ConfigurationVisitor.visit
|
||||
val resolvedProject =
|
||||
if (isInIdeaSync) nodeJs.resolveIfNeeded(project)
|
||||
if (isInIdeaSync) nodeJs.resolveIfNeeded()[project]
|
||||
else nodeJs.getAlreadyResolvedOrNull(project)
|
||||
|
||||
return when (resolvedProject) {
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ open class NpmProject(val compilation: KotlinJsCompilation) {
|
||||
* Require [request] nodejs module and return canonical path to it's main js file.
|
||||
*/
|
||||
fun require(request: String): String {
|
||||
nodeJs.requireResolved(project)
|
||||
nodeJs.requireAlreadyResolved(project)
|
||||
return modules.require(request)
|
||||
}
|
||||
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
|
||||
class NpmResolverPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
val project = target
|
||||
val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
nodeJs.requireResolver().addProject(project)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun apply(project: Project) {
|
||||
project.plugins.apply(NpmResolverPlugin::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -19,7 +19,7 @@ import java.nio.file.Files
|
||||
* node_modules with symlinked packages and packages_imported
|
||||
*/
|
||||
class NpmSimpleLinker(val nodeJs: NodeJsRootExtension) {
|
||||
private val rootProject = nodeJs.project
|
||||
private val rootProject = nodeJs.rootProject
|
||||
private val rootProjectNodeModules = nodeJs.rootPackageDir.resolve(NpmProject.NODE_MODULES)
|
||||
|
||||
fun link(projects: Collection<KotlinCompilationNpmResolution>) {
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
|
||||
class KotlinRootNpmResolution(
|
||||
val wasUpToDate: Boolean,
|
||||
val rootProject: Project,
|
||||
private val projects: Map<Project, KotlinProjectNpmResolution>
|
||||
) : NodeJsRootExtension.ResolutionStateData {
|
||||
|
||||
+26
-7
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.fixSemver
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
@@ -33,6 +34,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
val nodeJs get() = resolver.nodeJs
|
||||
val target get() = compilation.target
|
||||
val project get() = target.project
|
||||
val packageJsonTaskHolder = KotlinPackageJsonTask.create(compilation)
|
||||
|
||||
override fun toString(): String = "KotlinCompilationNpmResolver(${npmProject.name})"
|
||||
|
||||
@@ -47,19 +49,31 @@ internal class KotlinCompilationNpmResolver(
|
||||
}
|
||||
|
||||
private var closed = false
|
||||
private var resolution: KotlinCompilationNpmResolution? = null
|
||||
private var resolveCalled = false
|
||||
|
||||
private val resolution: KotlinCompilationNpmResolution by lazy {
|
||||
check(!closed) { "$this already closed" }
|
||||
resolveCalled = true
|
||||
packageJsonProducer.createPackageJson()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from packageJson task
|
||||
*/
|
||||
fun resolve() {
|
||||
check(!closed) { "$this already closed" }
|
||||
check(resolution == null) { "$this already resolved" }
|
||||
check(!resolveCalled) { "$this already resolved" }
|
||||
|
||||
resolution = packageJsonProducer.createPackageJson()
|
||||
// call getter
|
||||
resolution
|
||||
}
|
||||
|
||||
fun close(): KotlinCompilationNpmResolution? {
|
||||
check(!closed) { "$this already closed" }
|
||||
val result = resolution
|
||||
closed = true
|
||||
return resolution
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createAggregatedConfiguration(): Configuration {
|
||||
@@ -87,7 +101,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
}
|
||||
|
||||
private fun createNpmToolsConfiguration(): Configuration? {
|
||||
val taskRequirements = projectResolver.getTaskRequirements(compilation)
|
||||
val taskRequirements = projectResolver.taskRequirements.getTaskRequirements(compilation)
|
||||
if (taskRequirements.isEmpty()) return null
|
||||
|
||||
val toolsConfiguration = project.configurations.create("${compilation.name}NpmTools")
|
||||
@@ -127,6 +141,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: rewrite when we get general way to have inter compilation dependencies
|
||||
if (compilation.name == KotlinCompilation.TEST_COMPILATION_NAME) {
|
||||
val main = compilation.target.compilations.findByName(KotlinCompilation.MAIN_COMPILATION_NAME) as KotlinJsCompilation
|
||||
internalDependencies.add(projectResolver[main])
|
||||
@@ -190,8 +205,10 @@ internal class KotlinCompilationNpmResolver(
|
||||
|
||||
fun createPackageJson(): KotlinCompilationNpmResolution {
|
||||
val resolvedInternalDependencies = internalDependencies.map {
|
||||
// check(it.resolveCalled) {
|
||||
// "Unresolved dependent npm package: ${this@KotlinCompilationNpmResolver} -> $it"
|
||||
// }
|
||||
it.resolution
|
||||
?: error("Unresolved dependent npm package: ${this@KotlinCompilationNpmResolver} -> $it")
|
||||
}
|
||||
val importedExternalGradleDependencies = externalGradleDependencies.mapNotNull {
|
||||
resolver.gradleNodeModules.get(it.dependency, it.artifact)
|
||||
@@ -202,6 +219,8 @@ internal class KotlinCompilationNpmResolver(
|
||||
fixSemver(project.version.toString())
|
||||
)
|
||||
|
||||
packageJson.main = npmProject.main
|
||||
|
||||
resolvedInternalDependencies.forEach {
|
||||
packageJson.dependencies[it.packageJson.name] = it.packageJson.version
|
||||
}
|
||||
@@ -214,7 +233,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
packageJson.dependencies[it.key] = chooseVersion(packageJson.dependencies[it.key], it.version)
|
||||
}
|
||||
|
||||
nodeJs.packageJsonHandlers.forEach {
|
||||
compilation.packageJsonHandlers.forEach {
|
||||
it(packageJson)
|
||||
}
|
||||
|
||||
|
||||
+50
-54
@@ -6,8 +6,10 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
@@ -15,6 +17,7 @@ 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.resolved.KotlinProjectNpmResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
|
||||
internal class KotlinProjectNpmResolver(
|
||||
val project: Project,
|
||||
@@ -26,59 +29,30 @@ internal class KotlinProjectNpmResolver(
|
||||
|
||||
operator fun get(compilation: KotlinJsCompilation): KotlinCompilationNpmResolver {
|
||||
check(compilation.target.project == project)
|
||||
requireContainerListeners()
|
||||
return byCompilation[compilation] ?: error("$compilation was not registered in $this")
|
||||
}
|
||||
|
||||
private var closed = false
|
||||
|
||||
val compilationResolvers: Collection<KotlinCompilationNpmResolver>
|
||||
get() {
|
||||
requireContainerListeners()
|
||||
return byCompilation.values
|
||||
}
|
||||
get() = byCompilation.values
|
||||
|
||||
private val taskRequirements = mutableMapOf<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>()
|
||||
private val requiredFromTasksByCompilation = mutableMapOf<KotlinJsCompilation, MutableList<RequiresNpmDependencies>>()
|
||||
val taskRequirements by lazy { TasksRequirements(this) }
|
||||
|
||||
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()
|
||||
}
|
||||
init {
|
||||
addContainerListeners()
|
||||
}
|
||||
|
||||
private fun addContainerListeners() {
|
||||
project.tasks.forEach { task ->
|
||||
if (task.enabled && task is RequiresNpmDependencies) {
|
||||
addTaskRequirements(task)
|
||||
}
|
||||
}
|
||||
|
||||
val kotlin = project.kotlinExtensionOrNull
|
||||
?: error("NpmResolverPlugin should be applied after kotlin plugin")
|
||||
|
||||
when (kotlin) {
|
||||
is KotlinSingleTargetExtension -> addTargetListeners(kotlin.target)
|
||||
is KotlinMultiplatformExtension -> kotlin.targets.forEach {
|
||||
addTargetListeners(it)
|
||||
}
|
||||
else -> error("Unsupported kotlin model: $kotlin")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,23 +76,6 @@ internal class KotlinProjectNpmResolver(
|
||||
byCompilation[compilation] = KotlinCompilationNpmResolver(this, compilation)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun addTaskRequirements(task: RequiresNpmDependencies) {
|
||||
check(!closed) { resolver.alreadyResolvedMessage("create task $task that requires npm dependencies") }
|
||||
|
||||
if (!_hasNodeModulesDependentTasks && task.nodeModulesRequired) {
|
||||
_hasNodeModulesDependentTasks = true
|
||||
}
|
||||
|
||||
val requirements = task.requiredNpmDependencies.toList()
|
||||
|
||||
taskRequirements[task] = requirements
|
||||
|
||||
requiredFromTasksByCompilation
|
||||
.getOrPut(task.compilation) { mutableListOf() }
|
||||
.add(task)
|
||||
}
|
||||
|
||||
fun close(): KotlinProjectNpmResolution {
|
||||
check(!closed)
|
||||
closed = true
|
||||
@@ -126,7 +83,46 @@ internal class KotlinProjectNpmResolver(
|
||||
return KotlinProjectNpmResolution(
|
||||
project,
|
||||
byCompilation.values.mapNotNull { it.close() },
|
||||
taskRequirements
|
||||
taskRequirements.byTask
|
||||
)
|
||||
}
|
||||
|
||||
class TasksRequirements(val projectNpmResolver: KotlinProjectNpmResolver) {
|
||||
val byTask = mutableMapOf<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>()
|
||||
val byCompilation = mutableMapOf<KotlinJsCompilation, MutableList<RequiresNpmDependencies>>()
|
||||
|
||||
fun getTaskRequirements(compilation: KotlinJsCompilation): Collection<RequiresNpmDependencies> =
|
||||
byCompilation[compilation] ?: listOf()
|
||||
|
||||
val hasNodeModulesDependentTasks: Boolean
|
||||
get() = _hasNodeModulesDependentTasks
|
||||
|
||||
@Volatile
|
||||
var _hasNodeModulesDependentTasks = false
|
||||
private set
|
||||
|
||||
init {
|
||||
projectNpmResolver.project.tasks.forEach { task ->
|
||||
if (task.enabled && task is RequiresNpmDependencies) {
|
||||
addTaskRequirements(task)
|
||||
task.dependsOn(projectNpmResolver[task.compilation].packageJsonTaskHolder.getTaskOrProvider())
|
||||
task.dependsOn(projectNpmResolver.resolver.nodeJs.npmInstallTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addTaskRequirements(task: RequiresNpmDependencies) {
|
||||
if (!_hasNodeModulesDependentTasks && task.nodeModulesRequired) {
|
||||
_hasNodeModulesDependentTasks = true
|
||||
}
|
||||
|
||||
val requirements = task.requiredNpmDependencies.toList()
|
||||
|
||||
byTask[task] = requirements
|
||||
|
||||
byCompilation
|
||||
.getOrPut(task.compilation) { mutableListOf() }
|
||||
.add(task)
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-10
@@ -9,10 +9,8 @@ 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.*
|
||||
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
|
||||
|
||||
@@ -26,7 +24,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResoluti
|
||||
*/
|
||||
internal class KotlinRootNpmResolver internal constructor(val nodeJs: NodeJsRootExtension) : NodeJsRootExtension.ResolutionStateData {
|
||||
val rootProject: Project
|
||||
get() = nodeJs.project
|
||||
get() = nodeJs.rootProject
|
||||
|
||||
private var closed: Boolean = false
|
||||
|
||||
@@ -73,16 +71,20 @@ internal class KotlinRootNpmResolver internal constructor(val nodeJs: NodeJsRoot
|
||||
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)
|
||||
val wasUpToDate = when {
|
||||
allNpmPackages.any { it.externalNpmDependencies.isNotEmpty() } -> {
|
||||
nodeJs.packageManager.resolveRootProject(rootProject, allNpmPackages) == NpmApi.Result.upToDate
|
||||
}
|
||||
projectResolvers.values.any { it.taskRequirements.hasNodeModulesDependentTasks } -> {
|
||||
NpmSimpleLinker(nodeJs).link(allNpmPackages)
|
||||
true // todo
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
|
||||
return KotlinRootNpmResolution(rootProject, projectResolutions)
|
||||
return KotlinRootNpmResolution(wasUpToDate, rootProject, projectResolutions)
|
||||
}
|
||||
|
||||
private fun removeOutdatedPackages(nodeJs: NodeJsRootExtension, allNpmPackages: List<KotlinCompilationNpmResolution>) {
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ open class KotlinNpmInstallTask : DefaultTask() {
|
||||
|
||||
@TaskAction
|
||||
fun resolve() {
|
||||
nodeJs.resolveIfNeeded(project)
|
||||
nodeJs.resolveIfNeeded()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+14
-14
@@ -35,6 +35,20 @@ open class KotlinPackageJsonTask : DefaultTask() {
|
||||
dependentResolver.npmProject.packageJsonTask
|
||||
}
|
||||
|
||||
@get:Input
|
||||
@get:Nested
|
||||
internal val producerInputs: KotlinCompilationNpmResolver.PackageJsonProducerInputs
|
||||
get() = producer.inputs
|
||||
|
||||
@get:OutputFile
|
||||
val packageJson: File
|
||||
get() = compilationResolver.npmProject.packageJsonFile
|
||||
|
||||
@TaskAction
|
||||
fun resolve() {
|
||||
compilationResolver.resolve()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(compilation: KotlinJsCompilation): TaskHolder<KotlinPackageJsonTask> {
|
||||
val target = compilation.target
|
||||
@@ -66,18 +80,4 @@ open class KotlinPackageJsonTask : DefaultTask() {
|
||||
return packageJsonTask
|
||||
}
|
||||
}
|
||||
|
||||
@get:Input
|
||||
@get:Nested
|
||||
internal val producerInputs: KotlinCompilationNpmResolver.PackageJsonProducerInputs
|
||||
get() = producer.inputs
|
||||
|
||||
@get:OutputFile
|
||||
val packageJson: File
|
||||
get() = compilationResolver.npmProject.packageJsonFile
|
||||
|
||||
@TaskAction
|
||||
fun resolve() {
|
||||
compilationResolver.resolve()
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -11,9 +11,10 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmResolverPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
|
||||
import org.jetbrains.kotlin.gradle.tasks.createOrRegisterTask
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||
@@ -31,7 +32,7 @@ abstract class KotlinJsSubTarget(
|
||||
val testTaskName = disambiguateCamelCased("test")
|
||||
|
||||
fun configure() {
|
||||
NodeJsPlugin.apply(project)
|
||||
NpmResolverPlugin.apply(project)
|
||||
|
||||
configureTests()
|
||||
configureRun()
|
||||
|
||||
+1
-1
@@ -21,5 +21,5 @@ object YarnSimple : YarnBasics() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveRootProject(rootProject: Project, subProjects: Collection<KotlinCompilationNpmResolution>) = Unit
|
||||
override fun resolveRootProject(rootProject: Project, subProjects: Collection<KotlinCompilationNpmResolution>) = NpmApi.Result.upToDate
|
||||
}
|
||||
+6
-10
@@ -14,21 +14,21 @@ import java.io.File
|
||||
object YarnWorkspaces : YarnBasics() {
|
||||
override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) = Unit
|
||||
|
||||
override fun resolveRootProject(rootProject: Project, subProjects: Collection<KotlinCompilationNpmResolution>) {
|
||||
override fun resolveRootProject(rootProject: Project, subProjects: Collection<KotlinCompilationNpmResolution>): NpmApi.Result {
|
||||
check(rootProject == rootProject.rootProject)
|
||||
setup(rootProject)
|
||||
resolveWorkspaces(rootProject, subProjects)
|
||||
return resolveWorkspaces(rootProject, subProjects)
|
||||
}
|
||||
|
||||
private fun resolveWorkspaces(
|
||||
rootProject: Project,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>
|
||||
) {
|
||||
): NpmApi.Result {
|
||||
val upToDateChecks = npmProjects.map {
|
||||
YarnUpToDateCheck(it.npmProject)
|
||||
}
|
||||
|
||||
if (upToDateChecks.all { it.upToDate }) return
|
||||
if (upToDateChecks.all { it.upToDate }) return NpmApi.Result.upToDate
|
||||
|
||||
val nodeJsWorldDir = NodeJsRootPlugin.apply(rootProject).rootPackageDir
|
||||
|
||||
@@ -40,6 +40,8 @@ object YarnWorkspaces : YarnBasics() {
|
||||
upToDateChecks.forEach {
|
||||
it.commit()
|
||||
}
|
||||
|
||||
return NpmApi.Result.executed
|
||||
}
|
||||
|
||||
private fun saveRootProjectWorkspacesPackageJson(
|
||||
@@ -54,12 +56,6 @@ object YarnWorkspaces : YarnBasics() {
|
||||
val importedProjectWorkspaces = YarnImportedPackagesVersionResolver(rootProject, npmProjects, nodeJsWorldDir).resolveAndUpdatePackages()
|
||||
|
||||
rootPackageJson.workspaces = npmProjectWorkspaces + importedProjectWorkspaces
|
||||
|
||||
val nodeJs = NodeJsRootPlugin.apply(rootProject)
|
||||
nodeJs.packageJsonHandlers.forEach {
|
||||
it(rootPackageJson)
|
||||
}
|
||||
|
||||
rootPackageJson.saveTo(
|
||||
nodeJsWorldDir.resolve(NpmProject.PACKAGE_JSON)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user