[Gradle, JS] Store RootNpmResolver's heavy state in build service params
That heavy state was duplicated in serialized state of each task that has access to it transitively. #KT-45294 Fixed
This commit is contained in:
+3
-1
@@ -5,11 +5,13 @@
|
||||
|
||||
package $package
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Package versions used by tasks
|
||||
*/
|
||||
// DO NOT MODIFY DIRECTLY! Use org.jetbrains.kotlin.generators.gradle.targets.js.MainKt
|
||||
class $class {
|
||||
class $class : Serializable {
|
||||
#foreach( $dep in $dependencies )
|
||||
val $dep.camelize() = NpmPackageVersion("$dep.name", "$dep.version")
|
||||
#end
|
||||
|
||||
+4
-4
@@ -24,7 +24,6 @@ import java.security.MessageDigest
|
||||
* @param version When updating logic in `compute`, `version` should be increased to invalidate cache
|
||||
*/
|
||||
internal open class ProcessedFilesCache(
|
||||
val logger: Logger,
|
||||
val projectDir: File,
|
||||
val targetDir: File,
|
||||
stateFileName: String,
|
||||
@@ -174,7 +173,8 @@ internal open class ProcessedFilesCache(
|
||||
try {
|
||||
GsonBuilder().setPrettyPrinting().create().newJsonReader(stateFile.reader()).use { readFrom(it) }
|
||||
} catch (e: Throwable) {
|
||||
logger.warn("Cannot read $stateFile", e)
|
||||
System.err.println("Cannot read $stateFile")
|
||||
e.printStackTrace()
|
||||
if (targetDir.exists()) {
|
||||
targetDir.deleteRecursively()
|
||||
}
|
||||
@@ -209,14 +209,14 @@ internal open class ProcessedFilesCache(
|
||||
|
||||
if (old != null) {
|
||||
if (checkTarget(old.target)) return old.target
|
||||
else logger.warn("Cannot find ${File(targetDir.relativeTo(projectDir), old.target!!)}, rebuilding")
|
||||
else System.err.println("Cannot find ${File(targetDir.relativeTo(projectDir), old.target!!)}, rebuilding")
|
||||
}
|
||||
|
||||
val key = compute()?.relativeTo(targetDir)?.toString()
|
||||
val existedTarget = state.byTarget[key]
|
||||
if (key != null && existedTarget != null) {
|
||||
if (!File(existedTarget.src).exists()) {
|
||||
logger.warn("Removing cache for removed source `${existedTarget.src}`")
|
||||
System.err.println("Removing cache for removed source `${existedTarget.src}`")
|
||||
state.remove(existedTarget)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -5,11 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Package versions used by tasks
|
||||
*/
|
||||
// DO NOT MODIFY DIRECTLY! Use org.jetbrains.kotlin.generators.gradle.targets.js.MainKt
|
||||
class NpmVersions {
|
||||
class NpmVersions : Serializable {
|
||||
val dukat = NpmPackageVersion("dukat", "0.5.8-rc.4")
|
||||
val webpack4 = NpmPackageVersion("webpack", "4.46.0")
|
||||
val sourceMapLoader1 = NpmPackageVersion("source-map-loader", "1.1.3")
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@ package org.jetbrains.kotlin.gradle.targets.js
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||
import java.io.Serializable
|
||||
|
||||
interface RequiredKotlinJsDependency {
|
||||
interface RequiredKotlinJsDependency : Serializable {
|
||||
fun createDependency(project: Project, scope: NpmDependency.Scope = NpmDependency.Scope.DEV): Dependency
|
||||
}
|
||||
+5
-3
@@ -21,11 +21,13 @@ import org.jetbrains.kotlin.gradle.tasks.dependsOn
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
|
||||
internal class DukatCompilationResolverPlugin(
|
||||
@Transient
|
||||
private val resolver: KotlinCompilationNpmResolver
|
||||
) : CompilationResolverPlugin {
|
||||
val project get() = resolver.project
|
||||
val nodeJs get() = resolver.nodeJs
|
||||
val npmProject get() = resolver.npmProject
|
||||
val versions by lazy { nodeJs.versions }
|
||||
val npmProject by lazy { resolver.npmProject }
|
||||
val compilation get() = npmProject.compilation
|
||||
val compilationName by lazy {
|
||||
compilation.disambiguatedName
|
||||
@@ -83,7 +85,7 @@ internal class DukatCompilationResolverPlugin(
|
||||
}
|
||||
|
||||
override fun hookDependencies(
|
||||
internalDependencies: Set<KotlinCompilationNpmResolver>,
|
||||
internalDependencies: Set<KotlinCompilationNpmResolver.InternalDependency>,
|
||||
internalCompositeDependencies: Set<KotlinCompilationNpmResolver.CompositeDependency>,
|
||||
externalGradleDependencies: Set<KotlinCompilationNpmResolver.ExternalGradleDependency>,
|
||||
externalNpmDependencies: Set<NpmDependency>,
|
||||
@@ -107,7 +109,7 @@ internal class DukatCompilationResolverPlugin(
|
||||
}
|
||||
|
||||
DukatExecutor(
|
||||
nodeJs.versions,
|
||||
versions,
|
||||
DtsResolver(npmProject).getAllDts(externalNpmDependencies),
|
||||
externalsOutputFormat,
|
||||
npmProject,
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResoluti
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver
|
||||
|
||||
internal class DukatRootResolverPlugin(val resolver: KotlinRootNpmResolver) : RootResolverPlugin {
|
||||
internal class DukatRootResolverPlugin(val forceFullResolve: Boolean) : RootResolverPlugin {
|
||||
val compilations = mutableListOf<DukatCompilationResolverPlugin>()
|
||||
|
||||
override fun createCompilationResolverPlugins(resolver: KotlinCompilationNpmResolver): List<DukatCompilationResolverPlugin> {
|
||||
@@ -20,7 +20,7 @@ internal class DukatRootResolverPlugin(val resolver: KotlinRootNpmResolver) : Ro
|
||||
}
|
||||
|
||||
override fun close(resolution: KotlinRootNpmResolution) {
|
||||
if (resolver.forceFullResolve) {
|
||||
if (forceFullResolve) {
|
||||
// inside idea import
|
||||
compilations.forEach {
|
||||
it.executeDukatIfNeeded(true, resolution)
|
||||
|
||||
+2
-1
@@ -20,8 +20,9 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.Yarn
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
open class NodeJsRootExtension(@Transient val rootProject: Project) : ConfigurationPhaseAware<NodeJsEnv>() {
|
||||
open class NodeJsRootExtension(@Transient val rootProject: Project) : ConfigurationPhaseAware<NodeJsEnv>(), Serializable {
|
||||
init {
|
||||
check(rootProject.rootProject == rootProject)
|
||||
}
|
||||
|
||||
+7
-3
@@ -2,25 +2,29 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.FileSystemOperations
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.utils.ArchiveOperationsCompat
|
||||
import org.jetbrains.kotlin.gradle.utils.FileSystemOperationsCompat
|
||||
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import javax.inject.Inject
|
||||
|
||||
@CacheableTask
|
||||
open class NodeJsSetupTask : DefaultTask() {
|
||||
abstract class NodeJsSetupTask : DefaultTask() {
|
||||
@Transient
|
||||
private val settings = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val env by lazy { settings.requireConfigured() }
|
||||
private val fs = FileSystemOperationsCompat(project)
|
||||
private val archiveOperations = ArchiveOperationsCompat(project)
|
||||
private val shouldDownload = settings.download
|
||||
|
||||
@get:Inject
|
||||
internal open val fs: FileSystemOperations
|
||||
get() = error("Should be injected")
|
||||
|
||||
val ivyDependency: String
|
||||
@Input get() = env.ivyDependency
|
||||
|
||||
|
||||
+2
-1
@@ -10,8 +10,9 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependencyDeclaration
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.toDeclaration
|
||||
import java.io.Serializable
|
||||
|
||||
class TasksRequirements {
|
||||
class TasksRequirements : Serializable {
|
||||
private val _byTask = mutableMapOf<String, Set<RequiredKotlinJsDependency>>()
|
||||
private val byCompilation = mutableMapOf<String, MutableSet<NpmDependencyDeclaration>>()
|
||||
|
||||
|
||||
+12
-10
@@ -6,25 +6,29 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.internal.hash.FileHasher
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.services.BuildService
|
||||
import org.gradle.api.services.BuildServiceParameters
|
||||
import org.jetbrains.kotlin.gradle.internal.ProcessedFilesCache
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Cache for storing already created [GradleNodeModule]s
|
||||
*/
|
||||
internal abstract class AbstractNodeModulesCache(nodeJs: NodeJsRootExtension) : AutoCloseable {
|
||||
internal abstract class AbstractNodeModulesCache : AutoCloseable, BuildService<AbstractNodeModulesCache.Parameters> {
|
||||
internal interface Parameters : BuildServiceParameters {
|
||||
val rootProjectDir: DirectoryProperty
|
||||
val cacheDir: DirectoryProperty
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val STATE_FILE_NAME = ".visited"
|
||||
}
|
||||
|
||||
internal val dir = nodeJs.nodeModulesGradleCacheDir
|
||||
private val cache = ProcessedFilesCache(
|
||||
nodeJs.rootProject.logger,
|
||||
nodeJs.rootProject.projectDir,
|
||||
dir,
|
||||
parameters.rootProjectDir.get().asFile,
|
||||
parameters.cacheDir.get().asFile,
|
||||
STATE_FILE_NAME,
|
||||
"9"
|
||||
)
|
||||
@@ -52,8 +56,6 @@ internal abstract class AbstractNodeModulesCache(nodeJs: NodeJsRootExtension) :
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronized as tasks from configuration cache run in parallel and every task has it's own modules cache
|
||||
@Synchronized
|
||||
fun makeNodeModule(
|
||||
container: File,
|
||||
packageJson: PackageJson,
|
||||
|
||||
+3
-2
@@ -5,19 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Cache for storing already created [GradleNodeModule]s
|
||||
*/
|
||||
internal class CompositeNodeModulesCache(nodeJs: NodeJsRootExtension) : AbstractNodeModulesCache(nodeJs) {
|
||||
internal abstract class CompositeNodeModulesCache : AbstractNodeModulesCache() {
|
||||
override fun buildImportedPackage(
|
||||
name: String,
|
||||
version: String,
|
||||
file: File
|
||||
): File? {
|
||||
val module = CompositeNodeModuleBuilder(file, dir)
|
||||
val module = CompositeNodeModuleBuilder(file, parameters.cacheDir.get().asFile)
|
||||
return module.rebuild()
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -6,11 +6,12 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Fake NodeJS module directory created from Gradle external module
|
||||
*/
|
||||
data class GradleNodeModule(val name: String, val version: String, val path: File) {
|
||||
data class GradleNodeModule(val name: String, val version: String, val path: File) : Serializable {
|
||||
val semver: SemVer
|
||||
get() = SemVer.from(version)
|
||||
}
|
||||
-1
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.targets.js.JS
|
||||
import org.jetbrains.kotlin.gradle.targets.js.JS_MAP
|
||||
import org.jetbrains.kotlin.gradle.targets.js.META_JS
|
||||
|
||||
+12
-7
@@ -5,27 +5,32 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
import org.gradle.api.file.FileSystemOperations
|
||||
import org.jetbrains.kotlin.gradle.utils.ArchiveOperationsCompat
|
||||
import org.jetbrains.kotlin.gradle.utils.FileSystemOperationsCompat
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Cache for storing already created [GradleNodeModule]s
|
||||
*/
|
||||
internal class GradleNodeModulesCache(nodeJs: NodeJsRootExtension) : AbstractNodeModulesCache(nodeJs) {
|
||||
@Transient
|
||||
private val project = nodeJs.rootProject
|
||||
internal abstract class GradleNodeModulesCache : AbstractNodeModulesCache() {
|
||||
|
||||
private val fs = FileSystemOperationsCompat(project)
|
||||
private val archiveOperations = ArchiveOperationsCompat(project)
|
||||
// TODO: replace by injected service org.gradle.api.file.FileSystemOperations once min support Gradle is 6.2
|
||||
// https://github.com/gradle/gradle/commit/d02b9d84c08dba64775fb9581e3280f88d319a21
|
||||
@Transient
|
||||
lateinit var fs: FileSystemOperationsCompat
|
||||
|
||||
// TODO: replace by injected service org.gradle.api.file.ArchiveOperations once min supported Gradle is 6.6
|
||||
@Transient
|
||||
lateinit var archiveOperations: ArchiveOperationsCompat
|
||||
|
||||
override fun buildImportedPackage(
|
||||
name: String,
|
||||
version: String,
|
||||
file: File
|
||||
): File? {
|
||||
val module = GradleNodeModuleBuilder(fs, archiveOperations, name, version, listOf(file), dir)
|
||||
val module = GradleNodeModuleBuilder(fs, archiveOperations, name, version, listOf(file), parameters.cacheDir.get().asFile)
|
||||
module.visitArtifacts()
|
||||
return module.rebuild()
|
||||
}
|
||||
|
||||
+23
-6
@@ -10,6 +10,8 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.services.BuildService
|
||||
import org.gradle.api.services.BuildServiceParameters
|
||||
import org.gradle.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
@@ -85,9 +87,22 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
|
||||
internal val resolver = KotlinRootNpmResolver(nodeJsSettings, forceFullResolve)
|
||||
|
||||
@Volatile
|
||||
private var state: ResolutionState =
|
||||
ResolutionState.Configuring(resolver)
|
||||
internal abstract class KotlinNpmResolutionManagerStateHolder : BuildService<BuildServiceParameters.None> {
|
||||
@Volatile
|
||||
internal var state: ResolutionState? = null
|
||||
}
|
||||
|
||||
private val stateHolderProvider = nodeJsSettings.rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
"npm-resolution-manager-state-holder", KotlinNpmResolutionManagerStateHolder::class.java) {
|
||||
}
|
||||
|
||||
private val stateHolder get() = stateHolderProvider.get()
|
||||
|
||||
private var state: ResolutionState
|
||||
get() = stateHolder.state ?: ResolutionState.Configuring(resolver)
|
||||
set(value) {
|
||||
stateHolder.state = value
|
||||
}
|
||||
|
||||
internal sealed class ResolutionState {
|
||||
abstract val npmProjects: List<NpmProject>
|
||||
@@ -139,7 +154,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
services: ServiceRegistry,
|
||||
logger: Logger
|
||||
): KotlinRootNpmResolution {
|
||||
synchronized(this) {
|
||||
synchronized(stateHolder) {
|
||||
if (state is ResolutionState.Installed) {
|
||||
return (state as ResolutionState.Installed).resolved
|
||||
}
|
||||
@@ -178,9 +193,11 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
|
||||
val state0 = this.state
|
||||
return when (state0) {
|
||||
is ResolutionState.Prepared -> alreadyResolved(state0.preparedInstallation)
|
||||
is ResolutionState.Prepared -> {
|
||||
alreadyResolved(state0.preparedInstallation)
|
||||
}
|
||||
is ResolutionState.Configuring -> {
|
||||
synchronized(this) {
|
||||
synchronized(stateHolder) {
|
||||
val state1 = this.state
|
||||
when (state1) {
|
||||
is ResolutionState.Prepared -> alreadyResolved(state1.preparedInstallation)
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
import org.gradle.api.tasks.Input
|
||||
import java.io.Serializable
|
||||
|
||||
data class NpmDependencyDeclaration(
|
||||
@Input
|
||||
@@ -16,7 +17,7 @@ data class NpmDependencyDeclaration(
|
||||
val version: String,
|
||||
@Input
|
||||
val generateExternals: Boolean
|
||||
)
|
||||
) : Serializable
|
||||
|
||||
fun NpmDependencyDeclaration.uniqueRepresentation() =
|
||||
"$scope $name:$version, $generateExternals"
|
||||
|
||||
+6
-1
@@ -14,6 +14,7 @@ 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 java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
val KotlinJsCompilation.npmProject: NpmProject
|
||||
get() = NpmProject(this)
|
||||
@@ -24,7 +25,7 @@ val KotlinJsCompilation.npmProject: NpmProject
|
||||
*
|
||||
* More info can be obtained from [KotlinCompilationNpmResolution], which is available after project resolution (after [KotlinNpmInstallTask] execution).
|
||||
*/
|
||||
open class NpmProject(@Transient val compilation: KotlinJsCompilation) {
|
||||
open class NpmProject(@Transient val compilation: KotlinJsCompilation) : Serializable {
|
||||
val compilationName = compilation.disambiguatedName
|
||||
|
||||
val name: String by lazy {
|
||||
@@ -59,6 +60,10 @@ open class NpmProject(@Transient val compilation: KotlinJsCompilation) {
|
||||
val packageJsonTask: KotlinPackageJsonTask
|
||||
get() = project.tasks.getByName(packageJsonTaskName) as KotlinPackageJsonTask
|
||||
|
||||
val packageJsonTaskPath by lazy {
|
||||
packageJsonTask.path
|
||||
}
|
||||
|
||||
val dist: File
|
||||
get() = dir.resolve(DIST_FOLDER)
|
||||
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@ import com.google.gson.JsonObject
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject.Companion.NODE_MODULES
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject.Companion.PACKAGE_JSON
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Search modules in node_modules according to https://nodejs.org/api/modules.html.
|
||||
@@ -19,7 +20,7 @@ open class NpmProjectModules(
|
||||
val packageJsonEntries: Collection<String> = listOf("main", "module", "browser"),
|
||||
val indexFileNames: Collection<String> = listOf(INDEX_FILE_NAME),
|
||||
val indexFileSuffixes: Collection<String> = listOf(JS_SUFFIX)
|
||||
) {
|
||||
) : Serializable {
|
||||
/**
|
||||
* Require [request] nodejs module and return canonical path to it's main js file.
|
||||
*/
|
||||
|
||||
+2
-1
@@ -13,12 +13,13 @@ import org.gradle.api.GradleException
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
// Gson set nulls reflectively no matter on default values and non-null types
|
||||
class PackageJson(
|
||||
var name: String,
|
||||
var version: String
|
||||
) {
|
||||
) : Serializable {
|
||||
internal val customFields = mutableMapOf<String, Any?>()
|
||||
|
||||
val empty: Boolean
|
||||
|
||||
+3
-2
@@ -7,10 +7,11 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.plugins
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
|
||||
import java.io.Serializable
|
||||
|
||||
internal interface CompilationResolverPlugin {
|
||||
internal interface CompilationResolverPlugin : Serializable {
|
||||
fun hookDependencies(
|
||||
internalDependencies: Set<KotlinCompilationNpmResolver>,
|
||||
internalDependencies: Set<KotlinCompilationNpmResolver.InternalDependency>,
|
||||
internalCompositeDependencies: Set<KotlinCompilationNpmResolver.CompositeDependency>,
|
||||
externalGradleDependencies: Set<KotlinCompilationNpmResolver.ExternalGradleDependency>,
|
||||
externalNpmDependencies: Set<NpmDependency>,
|
||||
|
||||
+2
-1
@@ -7,8 +7,9 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.plugins
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
|
||||
import java.io.Serializable
|
||||
|
||||
internal interface RootResolverPlugin {
|
||||
internal interface RootResolverPlugin : Serializable {
|
||||
fun createCompilationResolverPlugins(resolver: KotlinCompilationNpmResolver): List<CompilationResolverPlugin>
|
||||
fun close(resolution: KotlinRootNpmResolution)
|
||||
}
|
||||
+2
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Resolved [NpmProject]
|
||||
@@ -19,7 +20,7 @@ class KotlinCompilationNpmResolution(
|
||||
val externalGradleDependencies: Collection<GradleNodeModule>,
|
||||
private val _externalNpmDependencies: Collection<NpmDependencyDeclaration>,
|
||||
val packageJson: PackageJson
|
||||
) {
|
||||
) : Serializable {
|
||||
val project
|
||||
get() = _project!!
|
||||
|
||||
|
||||
+90
-110
@@ -5,20 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
|
||||
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.FileCollectionDependency
|
||||
import org.gradle.api.artifacts.ResolvedArtifact
|
||||
import org.gradle.api.artifacts.ResolvedDependency
|
||||
import org.gradle.api.artifacts.*
|
||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.initialization.IncludedBuild
|
||||
import org.gradle.api.internal.artifacts.DefaultProjectComponentIdentifier
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.PathSensitive
|
||||
import org.gradle.api.tasks.PathSensitivity
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.bundling.Zip
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
@@ -38,10 +30,8 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.gradle.utils.CompositeProjectComponentArtifactMetadata
|
||||
import org.jetbrains.kotlin.gradle.utils.`is`
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
import org.jetbrains.kotlin.gradle.utils.topRealPath
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
import java.io.*
|
||||
|
||||
/**
|
||||
* See [KotlinNpmResolutionManager] for details about resolution process.
|
||||
@@ -51,49 +41,27 @@ internal class KotlinCompilationNpmResolver(
|
||||
val projectResolver: KotlinProjectNpmResolver,
|
||||
@Transient
|
||||
val compilation: KotlinJsCompilation
|
||||
) {
|
||||
) : Serializable {
|
||||
@Transient
|
||||
val resolver = projectResolver.resolver
|
||||
|
||||
private val gradleNodeModules by lazy {
|
||||
resolver.gradleNodeModules
|
||||
}
|
||||
|
||||
private val compositeNodeModules by lazy {
|
||||
resolver.compositeNodeModules
|
||||
}
|
||||
var rootResolver = projectResolver.resolver
|
||||
|
||||
val npmProject = compilation.npmProject
|
||||
|
||||
val compilationDisambiguatedName = compilation.disambiguatedName
|
||||
|
||||
val npmName by lazy {
|
||||
npmProject.name
|
||||
}
|
||||
|
||||
val npmVersion by lazy {
|
||||
project.version.toString()
|
||||
}
|
||||
|
||||
val npmMain by lazy {
|
||||
npmProject.main
|
||||
}
|
||||
|
||||
val prePackageJsonFile by lazy {
|
||||
npmProject.prePackageJsonFile
|
||||
}
|
||||
|
||||
val nodeJs get() = resolver.nodeJs
|
||||
|
||||
val taskRequirements by lazy {
|
||||
nodeJs.taskRequirements
|
||||
}
|
||||
val nodeJs get() = rootResolver.nodeJs
|
||||
|
||||
val target get() = compilation.target
|
||||
|
||||
val project get() = target.project
|
||||
|
||||
private val packageJsonHandlers by project.provider {
|
||||
val projectPath = project.path
|
||||
|
||||
val packageJsonHandlers by lazy {
|
||||
compilation.packageJsonHandlers
|
||||
}
|
||||
|
||||
@@ -132,16 +100,24 @@ internal class KotlinCompilationNpmResolver(
|
||||
|
||||
override fun toString(): String = "KotlinCompilationNpmResolver(${npmProject.name})"
|
||||
|
||||
@delegate:Transient
|
||||
private val aggregatedConfiguration: Configuration by lazy {
|
||||
createAggregatedConfiguration()
|
||||
}
|
||||
|
||||
val packageJsonProducer: PackageJsonProducer by lazy {
|
||||
private val packageJsonProducer_: PackageJsonProducer by lazy {
|
||||
val visitor = ConfigurationVisitor()
|
||||
visitor.visit(aggregatedConfiguration)
|
||||
visitor.toPackageJsonProducer()
|
||||
visitor.toPackageJsonProducer().also { it.compilationResolver = this }
|
||||
}
|
||||
|
||||
val packageJsonProducer: PackageJsonProducer
|
||||
get() {
|
||||
val packageJsonProducer = packageJsonProducer_
|
||||
packageJsonProducer.compilationResolver = this
|
||||
return packageJsonProducer
|
||||
}
|
||||
|
||||
private var closed = false
|
||||
private var resolution: KotlinCompilationNpmResolution? = null
|
||||
|
||||
@@ -159,7 +135,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
fun getResolutionOrResolveIfForced(): KotlinCompilationNpmResolution? {
|
||||
if (resolution != null) return resolution
|
||||
if (packageJsonTaskHolder == null || packageJsonTaskHolder.get().state.upToDate) return resolve(skipWriting = true)
|
||||
if (resolver.forceFullResolve && resolution == null) {
|
||||
if (rootResolver.forceFullResolve && resolution == null) {
|
||||
// need to force all NPM tasks to be configured in IDEA import
|
||||
project.tasks.implementing(RequiresNpmDependencies::class).all {}
|
||||
return resolve()
|
||||
@@ -216,26 +192,35 @@ internal class KotlinCompilationNpmResolver(
|
||||
data class ExternalGradleDependency(
|
||||
val dependency: ResolvedDependency,
|
||||
val artifact: ResolvedArtifact
|
||||
)
|
||||
): Serializable
|
||||
|
||||
data class FileCollectionExternalGradleDependency(
|
||||
val fileCollection: FileCollection,
|
||||
val files: Collection<File>,
|
||||
val dependencyVersion: String?
|
||||
)
|
||||
): Serializable
|
||||
|
||||
data class FileExternalGradleDependency(
|
||||
val dependencyName: String,
|
||||
val dependencyVersion: String,
|
||||
val file: File
|
||||
)
|
||||
) : Serializable
|
||||
|
||||
data class CompositeDependency(
|
||||
val dependency: ResolvedDependency,
|
||||
val includedBuild: IncludedBuild
|
||||
)
|
||||
val dependencyName: String,
|
||||
val dependencyVersion: String,
|
||||
val includedBuildDir: File,
|
||||
@Transient
|
||||
val includedBuild: IncludedBuild?
|
||||
) : Serializable
|
||||
|
||||
data class InternalDependency(
|
||||
val projectPath: String,
|
||||
val compilationName: String,
|
||||
val projectName: String
|
||||
) : Serializable
|
||||
|
||||
inner class ConfigurationVisitor {
|
||||
private val internalDependencies = mutableSetOf<KotlinCompilationNpmResolver>()
|
||||
private val internalDependencies = mutableSetOf<InternalDependency>()
|
||||
private val internalCompositeDependencies = mutableSetOf<CompositeDependency>()
|
||||
private val externalGradleDependencies = mutableSetOf<ExternalGradleDependency>()
|
||||
private val externalNpmDependencies = mutableSetOf<NpmDependency>()
|
||||
@@ -249,14 +234,14 @@ internal class KotlinCompilationNpmResolver(
|
||||
configuration.allDependencies.forEach { dependency ->
|
||||
when (dependency) {
|
||||
is NpmDependency -> externalNpmDependencies.add(dependency)
|
||||
is FileCollectionDependency -> fileCollectionDependencies.add(FileCollectionExternalGradleDependency(dependency.files, dependency.version))
|
||||
is FileCollectionDependency -> fileCollectionDependencies.add(FileCollectionExternalGradleDependency(dependency.files.files, dependency.version))
|
||||
}
|
||||
}
|
||||
|
||||
//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])
|
||||
internalDependencies.add(InternalDependency(projectResolver.project.path, main.disambiguatedName, projectResolver[main].npmProject.name))
|
||||
}
|
||||
|
||||
val hasPublicNpmDependencies = externalNpmDependencies.isNotEmpty()
|
||||
@@ -332,7 +317,9 @@ internal class KotlinCompilationNpmResolver(
|
||||
|
||||
(componentIdentifier as DefaultProjectComponentIdentifier).let { identifier ->
|
||||
val includedBuild = project.gradle.includedBuild(identifier.identityPath.topRealPath().name!!)
|
||||
internalCompositeDependencies.add(CompositeDependency(dependency, includedBuild))
|
||||
internalCompositeDependencies.add(
|
||||
CompositeDependency(dependency.moduleName, dependency.moduleVersion, includedBuild.projectDir, includedBuild)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,17 +329,23 @@ internal class KotlinCompilationNpmResolver(
|
||||
val dependentProject = project.findProject(componentIdentifier.projectPath)
|
||||
?: error("Cannot find project ${componentIdentifier.projectPath}")
|
||||
|
||||
resolver.findDependentResolver(project, dependentProject)
|
||||
rootResolver.findDependentResolver(project, dependentProject)
|
||||
?.forEach { dependentResolver ->
|
||||
internalDependencies.add(dependentResolver)
|
||||
internalDependencies.add(InternalDependency(dependentResolver.projectPath, dependentResolver.compilationDisambiguatedName, dependentResolver.npmProject.name))
|
||||
}
|
||||
}
|
||||
|
||||
fun toPackageJsonProducer() = PackageJsonProducer(
|
||||
internalDependencies,
|
||||
internalCompositeDependencies,
|
||||
externalGradleDependencies,
|
||||
externalNpmDependencies,
|
||||
externalGradleDependencies.map {
|
||||
FileExternalGradleDependency(
|
||||
it.dependency.moduleName,
|
||||
it.dependency.moduleVersion,
|
||||
it.artifact.file
|
||||
)
|
||||
},
|
||||
externalNpmDependencies.map { it.toDeclaration() },
|
||||
fileCollectionDependencies
|
||||
)
|
||||
}
|
||||
@@ -374,56 +367,44 @@ internal class KotlinCompilationNpmResolver(
|
||||
|
||||
@get:Input
|
||||
val fileCollectionDependencies: Collection<File>
|
||||
) : Serializable
|
||||
)
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
inner class PackageJsonProducer(
|
||||
val internalDependencies: Collection<KotlinCompilationNpmResolver>,
|
||||
val internalCompositeDependencies: Collection<CompositeDependency>,
|
||||
@Transient
|
||||
val externalGradleDependencies: Collection<ExternalGradleDependency>,
|
||||
@Transient
|
||||
val externalNpmDependencies: Collection<NpmDependency>,
|
||||
val fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>
|
||||
) {
|
||||
val externalNpmDependencyDeclarations by lazy {
|
||||
externalNpmDependencies.map {
|
||||
it.toDeclaration()
|
||||
}
|
||||
}
|
||||
class PackageJsonProducer(
|
||||
var internalDependencies: Collection<InternalDependency>,
|
||||
var internalCompositeDependencies: Collection<CompositeDependency>,
|
||||
var externalGradleDependencies: Collection<FileExternalGradleDependency>,
|
||||
var externalNpmDependencies: Collection<NpmDependencyDeclaration>,
|
||||
var fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>
|
||||
) : Serializable {
|
||||
private val projectPackagesDir by lazy { compilationResolver.nodeJs.projectPackagesDir }
|
||||
private val rootDir by lazy { compilationResolver.nodeJs.rootProject.rootDir }
|
||||
|
||||
val fileExternalGradleDependencies by lazy {
|
||||
externalGradleDependencies.map {
|
||||
FileExternalGradleDependency(
|
||||
it.dependency.moduleName,
|
||||
it.dependency.moduleVersion,
|
||||
it.artifact.file
|
||||
)
|
||||
}
|
||||
}
|
||||
@Transient
|
||||
internal lateinit var compilationResolver: KotlinCompilationNpmResolver
|
||||
|
||||
val inputs: PackageJsonProducerInputs
|
||||
get() = PackageJsonProducerInputs(
|
||||
internalDependencies.map { it.npmProject.name },
|
||||
internalDependencies.map { it.projectName },
|
||||
internalCompositeDependencies.flatMap { it.getPackages() },
|
||||
fileExternalGradleDependencies.map { it.file },
|
||||
externalNpmDependencyDeclarations.map { it.uniqueRepresentation() },
|
||||
fileCollectionDependencies.map{ it.fileCollection }.flatMap { it.files }
|
||||
externalGradleDependencies.map { it.file },
|
||||
externalNpmDependencies.map { it.uniqueRepresentation() },
|
||||
fileCollectionDependencies.flatMap{ it.files }
|
||||
)
|
||||
|
||||
fun createPackageJson(skipWriting: Boolean): KotlinCompilationNpmResolution {
|
||||
val resolvedInternalDependencies = internalDependencies.map {
|
||||
it.getResolutionOrResolveIfForced()
|
||||
?: error("Unresolved dependent npm package: ${this@KotlinCompilationNpmResolver} -> $it")
|
||||
compilationResolver.rootResolver[it.projectPath][it.compilationName].getResolutionOrResolveIfForced()
|
||||
?: error("Unresolved dependent npm package: ${compilationResolver} -> $it")
|
||||
}
|
||||
val importedExternalGradleDependencies = fileExternalGradleDependencies.mapNotNull {
|
||||
gradleNodeModules.get(it.dependencyName, it.dependencyVersion, it.file)
|
||||
val importedExternalGradleDependencies = externalGradleDependencies.mapNotNull {
|
||||
compilationResolver.rootResolver.gradleNodeModules.get(it.dependencyName, it.dependencyVersion, it.file)
|
||||
} + fileCollectionDependencies.flatMap { dependency ->
|
||||
dependency.fileCollection.files
|
||||
dependency.files
|
||||
// Gradle can hash with FileHasher only files and only existed files
|
||||
.filter { it.isFile }
|
||||
.map { file ->
|
||||
gradleNodeModules.get(
|
||||
compilationResolver.rootResolver.gradleNodeModules.get(
|
||||
file.name,
|
||||
dependency.dependencyVersion ?: "0.0.1",
|
||||
file
|
||||
@@ -434,26 +415,26 @@ internal class KotlinCompilationNpmResolver(
|
||||
val compositeDependencies = internalCompositeDependencies.flatMap { dependency ->
|
||||
dependency.getPackages()
|
||||
.map { file ->
|
||||
compositeNodeModules.get(
|
||||
dependency.dependency.moduleName,
|
||||
dependency.dependency.moduleVersion,
|
||||
compilationResolver.rootResolver.compositeNodeModules.get(
|
||||
dependency.dependencyName,
|
||||
dependency.dependencyVersion,
|
||||
file
|
||||
)
|
||||
}
|
||||
}
|
||||
.filterNotNull()
|
||||
|
||||
val toolsNpmDependencies = taskRequirements
|
||||
.getCompilationNpmRequirements(compilationDisambiguatedName)
|
||||
val toolsNpmDependencies = compilationResolver.rootResolver.nodeJs.taskRequirements
|
||||
.getCompilationNpmRequirements(compilationResolver.compilationDisambiguatedName)
|
||||
|
||||
val allNpmDependencies = externalNpmDependencyDeclarations + toolsNpmDependencies
|
||||
val allNpmDependencies = externalNpmDependencies + toolsNpmDependencies
|
||||
|
||||
val packageJson = packageJson(
|
||||
npmName,
|
||||
npmVersion,
|
||||
npmMain,
|
||||
compilationResolver.npmProject.name,
|
||||
compilationResolver.npmVersion,
|
||||
compilationResolver.npmProject.main,
|
||||
allNpmDependencies,
|
||||
packageJsonHandlers
|
||||
compilationResolver.packageJsonHandlers
|
||||
)
|
||||
|
||||
compositeDependencies.forEach {
|
||||
@@ -468,17 +449,18 @@ internal class KotlinCompilationNpmResolver(
|
||||
packageJson.dependencies[it.name] = fileVersion(it.path)
|
||||
}
|
||||
|
||||
packageJsonHandlers.forEach {
|
||||
compilationResolver.packageJsonHandlers.forEach {
|
||||
it(packageJson)
|
||||
}
|
||||
|
||||
if (!skipWriting) {
|
||||
packageJson.saveTo(prePackageJsonFile)
|
||||
packageJson.saveTo(compilationResolver.npmProject.prePackageJsonFile)
|
||||
}
|
||||
|
||||
return KotlinCompilationNpmResolution(
|
||||
if (compilation != null) project else null,
|
||||
npmProject,
|
||||
@Suppress("SENSELESS_COMPARISON")
|
||||
if (compilationResolver.compilation != null) compilationResolver.project else null,
|
||||
compilationResolver.npmProject,
|
||||
compositeDependencies,
|
||||
importedExternalGradleDependencies,
|
||||
allNpmDependencies,
|
||||
@@ -487,9 +469,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
}
|
||||
|
||||
private fun CompositeDependency.getPackages(): List<File> {
|
||||
val packages = includedBuild
|
||||
.projectDir
|
||||
.resolve(nodeJs.projectPackagesDir.relativeTo(nodeJs.rootProject.rootDir))
|
||||
val packages = includedBuildDir.resolve(projectPackagesDir.relativeTo(rootDir))
|
||||
return packages
|
||||
.list()
|
||||
?.map { packages.resolve(it) }
|
||||
|
||||
+4
-2
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
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.testing.KotlinJsTest
|
||||
import java.io.Serializable
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
@@ -27,8 +28,9 @@ import kotlin.reflect.KClass
|
||||
internal class KotlinProjectNpmResolver(
|
||||
@Transient
|
||||
val project: Project,
|
||||
val resolver: KotlinRootNpmResolver
|
||||
) {
|
||||
@Transient
|
||||
var resolver: KotlinRootNpmResolver
|
||||
) : Serializable {
|
||||
override fun toString(): String = "ProjectNpmResolver($project)"
|
||||
|
||||
private val projectPath by lazy { project.path }
|
||||
|
||||
+81
-8
@@ -7,12 +7,14 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dukat.DukatRootResolverPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.TasksRequirements
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.CompositeNodeModulesCache
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModulesCache
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager
|
||||
@@ -23,6 +25,8 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResol
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.toVersionString
|
||||
import org.jetbrains.kotlin.gradle.utils.ArchiveOperationsCompat
|
||||
import org.jetbrains.kotlin.gradle.utils.FileSystemOperationsCompat
|
||||
|
||||
/**
|
||||
* See [KotlinNpmResolutionManager] for details about resolution process.
|
||||
@@ -42,22 +46,90 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
rootProject.version.toString()
|
||||
}
|
||||
|
||||
val plugins = mutableListOf<RootResolverPlugin>().also {
|
||||
it.add(DukatRootResolverPlugin(this))
|
||||
}
|
||||
|
||||
enum class State {
|
||||
CONFIGURING,
|
||||
PROJECTS_CLOSED,
|
||||
INSTALLED
|
||||
}
|
||||
|
||||
@Transient
|
||||
@Volatile
|
||||
private var state: State = State.CONFIGURING
|
||||
private var state_: State? = State.CONFIGURING
|
||||
|
||||
val gradleNodeModules = GradleNodeModulesCache(nodeJs)
|
||||
val compositeNodeModules = CompositeNodeModulesCache(nodeJs)
|
||||
val projectResolvers = mutableMapOf<String, KotlinProjectNpmResolver>()
|
||||
private var state
|
||||
get() = state_ ?: resolverStateHolder.get().state
|
||||
set(value) {
|
||||
if (state_ != null) {
|
||||
state_ = value
|
||||
} else {
|
||||
resolverStateHolder.get().state = value
|
||||
}
|
||||
}
|
||||
|
||||
private val archiveOperations by lazy { ArchiveOperationsCompat(rootProject) }
|
||||
private val fs by lazy { FileSystemOperationsCompat(rootProject) }
|
||||
|
||||
private val gradleNodeModulesProvider: Provider<GradleNodeModulesCache> =
|
||||
rootProject.gradle.sharedServices.registerIfAbsent("gradle-node-modules", GradleNodeModulesCache::class.java) {
|
||||
it.parameters.cacheDir.set(nodeJs.nodeModulesGradleCacheDir)
|
||||
it.parameters.rootProjectDir.set(rootProject.projectDir)
|
||||
}
|
||||
|
||||
val gradleNodeModules: GradleNodeModulesCache
|
||||
get() = gradleNodeModulesProvider.get().also {
|
||||
it.archiveOperations = archiveOperations
|
||||
it.fs = fs
|
||||
}
|
||||
|
||||
private val compositeNodeModulesProvider: Provider<CompositeNodeModulesCache> =
|
||||
rootProject.gradle.sharedServices.registerIfAbsent("composite-node-modules", CompositeNodeModulesCache::class.java) {
|
||||
it.parameters.cacheDir.set(nodeJs.nodeModulesGradleCacheDir)
|
||||
it.parameters.rootProjectDir.set(rootProject.projectDir)
|
||||
}
|
||||
|
||||
val compositeNodeModules: CompositeNodeModulesCache
|
||||
get() = compositeNodeModulesProvider.get()
|
||||
|
||||
@Suppress("RedundantNullableReturnType")
|
||||
@Transient
|
||||
private val plugins_: MutableList<RootResolverPlugin>? = mutableListOf<RootResolverPlugin>().also {
|
||||
it.add(DukatRootResolverPlugin(forceFullResolve))
|
||||
}
|
||||
|
||||
@Suppress("RedundantNullableReturnType")
|
||||
@Transient
|
||||
private val projectResolvers_: MutableMap<String, KotlinProjectNpmResolver>? = mutableMapOf()
|
||||
|
||||
private val resolverStateHolder by lazy {
|
||||
rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
KotlinRootNpmResolverStateHolder::class.qualifiedName,
|
||||
KotlinRootNpmResolverStateHolder::class.java
|
||||
) {
|
||||
it.parameters.plugins.set(plugins_)
|
||||
it.parameters.projectResolvers.set(projectResolvers_)
|
||||
}
|
||||
}
|
||||
|
||||
private val configurationCacheProjectResolvers: MutableMap<String, KotlinProjectNpmResolver>
|
||||
get() {
|
||||
val stateHolder = resolverStateHolder.get()
|
||||
val projResolvers = stateHolder.parameters.projectResolvers.get()
|
||||
if (stateHolder.initialized) return projResolvers
|
||||
projResolvers.forEach { (_, value) ->
|
||||
value.resolver = this
|
||||
value.compilationResolvers.forEach { compResolver ->
|
||||
compResolver.rootResolver = this
|
||||
}
|
||||
}
|
||||
stateHolder.initialized = true
|
||||
return projResolvers
|
||||
}
|
||||
|
||||
val plugins
|
||||
get() = plugins_ ?: resolverStateHolder.get().parameters.plugins.get()
|
||||
|
||||
val projectResolvers
|
||||
get() = projectResolvers_ ?: configurationCacheProjectResolvers
|
||||
|
||||
val yarn by lazy {
|
||||
YarnPlugin.apply(rootProject)
|
||||
@@ -120,6 +192,7 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
val allNpmPackages = projectResolutions.values.flatMap { it.npmProjects }
|
||||
|
||||
gradleNodeModules.close()
|
||||
compositeNodeModules.close()
|
||||
|
||||
nodeJs.packageManager.prepareRootProject(
|
||||
rootProject,
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.provider.ListProperty
|
||||
import org.gradle.api.provider.MapProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.services.BuildService
|
||||
import org.gradle.api.services.BuildServiceParameters
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.TasksRequirements
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.plugins.RootResolverPlugin
|
||||
|
||||
// We use this service as a single storage for duplicated data in configuration cache
|
||||
internal abstract class KotlinRootNpmResolverStateHolder : BuildService<KotlinRootNpmResolverStateHolder.Parameters> {
|
||||
interface Parameters : BuildServiceParameters {
|
||||
val plugins: ListProperty<RootResolverPlugin>
|
||||
val projectResolvers: MapProperty<String, KotlinProjectNpmResolver>
|
||||
}
|
||||
|
||||
var initialized = false
|
||||
|
||||
@Volatile
|
||||
var state = KotlinRootNpmResolver.State.CONFIGURING
|
||||
}
|
||||
+3
-3
@@ -59,10 +59,10 @@ open class KotlinPackageJsonTask : DefaultTask() {
|
||||
}
|
||||
|
||||
private fun findDependentTasks(): Collection<Any> =
|
||||
producer.internalDependencies.map { dependentResolver ->
|
||||
dependentResolver.npmProject.packageJsonTask
|
||||
producer.internalDependencies.map { dependency ->
|
||||
npmResolutionManager.resolver[dependency.projectPath][dependency.compilationName].npmProject.packageJsonTaskPath
|
||||
} + producer.internalCompositeDependencies.map { dependency ->
|
||||
dependency.includedBuild.task(":$PACKAGE_JSON_UMBRELLA_TASK_NAME")
|
||||
dependency.includedBuild?.task(":$PACKAGE_JSON_UMBRELLA_TASK_NAME") ?: "includedBuild instance is not available"
|
||||
}
|
||||
|
||||
@get:Input
|
||||
|
||||
+4
-3
@@ -32,6 +32,7 @@ import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||
import org.gradle.api.tasks.testing.TestDescriptor
|
||||
import org.gradle.util.GradleVersion
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
const val minSupportedGradleVersion = "6.1"
|
||||
|
||||
@@ -75,7 +76,7 @@ internal fun checkGradleCompatibility(
|
||||
internal val AbstractArchiveTask.archivePathCompatible: File
|
||||
get() = archiveFile.get().asFile
|
||||
|
||||
internal class ArchiveOperationsCompat(@Transient private val project: Project) {
|
||||
internal class ArchiveOperationsCompat(@Transient private val project: Project) : Serializable {
|
||||
private val archiveOperations: Any? = try {
|
||||
(project as ProjectInternal).services.get(ArchiveOperations::class.java)
|
||||
} catch (e: NoClassDefFoundError) {
|
||||
@@ -98,7 +99,7 @@ internal class ArchiveOperationsCompat(@Transient private val project: Project)
|
||||
}
|
||||
}
|
||||
|
||||
internal class FileSystemOperationsCompat(@Transient private val project: Project) {
|
||||
internal class FileSystemOperationsCompat(@Transient private val project: Project) : Serializable {
|
||||
private val fileSystemOperations: Any? = try {
|
||||
(project as ProjectInternal).services.get(FileSystemOperations::class.java)
|
||||
} catch (e: NoClassDefFoundError) {
|
||||
@@ -124,4 +125,4 @@ internal interface LegacyTestDescriptorInternal : TestDescriptor {
|
||||
fun getOwnerBuildOperationId(): Any?
|
||||
|
||||
fun getClassDisplayName(): String?
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user