[Gradle, JS] Reduce configuration cache state size by data deduplication
#KT-49037 Fixed
This commit is contained in:
committed by
Space
parent
18189ece48
commit
a1424489b7
+6
-4
@@ -19,6 +19,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.tasks.dependsOn
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.gradle.utils.unavailableValueError
|
||||
|
||||
internal class DukatCompilationResolverPlugin(
|
||||
@Transient
|
||||
@@ -26,7 +27,8 @@ internal class DukatCompilationResolverPlugin(
|
||||
) : CompilationResolverPlugin {
|
||||
val project get() = resolver.project
|
||||
val nodeJs get() = resolver.nodeJs
|
||||
val versions by lazy { nodeJs.versions }
|
||||
private val nodeJs_ get() = nodeJs ?: unavailableValueError("nodeJs")
|
||||
val versions by lazy { nodeJs_.versions }
|
||||
val npmProject by lazy { resolver.npmProject }
|
||||
val compilation get() = npmProject.compilation
|
||||
val compilationName by lazy {
|
||||
@@ -50,7 +52,7 @@ internal class DukatCompilationResolverPlugin(
|
||||
it.group = DUKAT_TASK_GROUP
|
||||
it.description = "Integrated generation Kotlin/JS external declarations for .d.ts files in $compilation"
|
||||
it.externalsOutputFormat = externalsOutputFormat
|
||||
it.dependsOn(nodeJs.npmInstallTaskProvider, npmProject.packageJsonTask)
|
||||
it.dependsOn(nodeJs_.npmInstallTaskProvider, npmProject.packageJsonTask)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +82,7 @@ internal class DukatCompilationResolverPlugin(
|
||||
) {
|
||||
it.group = DUKAT_TASK_GROUP
|
||||
it.description = "Generate Kotlin/JS external declarations for .d.ts files of all NPM dependencies in ${compilation}"
|
||||
it.dependsOn(nodeJs.npmInstallTaskProvider, npmProject.packageJsonTask)
|
||||
it.dependsOn(nodeJs_.npmInstallTaskProvider, npmProject.packageJsonTask)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +93,7 @@ internal class DukatCompilationResolverPlugin(
|
||||
externalNpmDependencies: Set<NpmDependency>,
|
||||
fileCollectionDependencies: Set<KotlinCompilationNpmResolver.FileCollectionExternalGradleDependency>
|
||||
) {
|
||||
if (nodeJs.experimental.discoverTypes) {
|
||||
if (nodeJs_.experimental.discoverTypes) {
|
||||
// todo: discoverTypes
|
||||
}
|
||||
}
|
||||
|
||||
+10
-7
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmR
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinProjectNpmResolver
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.utils.unavailableValueError
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
@@ -80,9 +81,9 @@ import java.io.File
|
||||
*
|
||||
* Note that in this case resolution process will be performed outside of task execution.
|
||||
*/
|
||||
class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension) {
|
||||
class KotlinNpmResolutionManager(@Transient private val nodeJsSettings: NodeJsRootExtension?) {
|
||||
private val forceFullResolve: Boolean by lazy {
|
||||
nodeJsSettings.rootProject.isInIdeaSync
|
||||
(nodeJsSettings ?: unavailableValueError("nodeJsSettings")).rootProject.isInIdeaSync
|
||||
}
|
||||
|
||||
internal val resolver = KotlinRootNpmResolver(nodeJsSettings, forceFullResolve)
|
||||
@@ -92,9 +93,11 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
internal var state: ResolutionState? = null
|
||||
}
|
||||
|
||||
private val stateHolderProvider = nodeJsSettings.rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
"npm-resolution-manager-state-holder", KotlinNpmResolutionManagerStateHolder::class.java) {
|
||||
}
|
||||
private val stateHolderProvider = (nodeJsSettings ?: unavailableValueError("nodeJsSettings"))
|
||||
.rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
"npm-resolution-manager-state-holder", KotlinNpmResolutionManagerStateHolder::class.java
|
||||
) {
|
||||
}
|
||||
|
||||
private val stateHolder get() = stateHolderProvider.get()
|
||||
|
||||
@@ -159,7 +162,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
return (state as ResolutionState.Installed).resolved
|
||||
}
|
||||
|
||||
val installUpToDate = nodeJsSettings.npmInstallTaskProvider?.get()?.state?.upToDate ?: false
|
||||
val installUpToDate = nodeJsSettings?.npmInstallTaskProvider?.get()?.state?.upToDate ?: false
|
||||
val forceUpToDate = installUpToDate && !forceFullResolve
|
||||
|
||||
val installation = prepareIfNeeded(requireUpToDateReason = reason, logger = logger)
|
||||
@@ -202,7 +205,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
when (state1) {
|
||||
is ResolutionState.Prepared -> alreadyResolved(state1.preparedInstallation)
|
||||
is ResolutionState.Configuring -> {
|
||||
val upToDate = nodeJsSettings.rootPackageJsonTaskProvider?.get()?.state?.upToDate ?: true
|
||||
val upToDate = nodeJsSettings?.rootPackageJsonTaskProvider?.get()?.state?.upToDate ?: true
|
||||
if (requireUpToDateReason != null && !upToDate) {
|
||||
error("NPM dependencies should be resolved $requireUpToDateReason")
|
||||
}
|
||||
|
||||
+14
-5
@@ -11,18 +11,19 @@ import org.gradle.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* NodeJS package manager API
|
||||
*/
|
||||
interface NpmApi {
|
||||
interface NpmApi : Serializable {
|
||||
fun setup(project: Project)
|
||||
|
||||
fun preparedFiles(nodeJs: NodeJsRootExtension): Collection<File>
|
||||
fun preparedFiles(nodeJs: NpmEnvironment): Collection<File>
|
||||
|
||||
fun prepareRootProject(
|
||||
rootProject: Project?,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
@@ -34,7 +35,7 @@ interface NpmApi {
|
||||
fun resolveRootProject(
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
command: String,
|
||||
isStandalone: Boolean,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
@@ -51,4 +52,12 @@ interface NpmApi {
|
||||
fun resolveOperationDescription(packageManagerTitle: String): String =
|
||||
"Resolving NPM dependencies using $packageManagerTitle"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class NpmEnvironment(
|
||||
val rootPackageDir: File,
|
||||
val nodeExecutable: String
|
||||
) : Serializable
|
||||
|
||||
internal val NodeJsRootExtension.asNpmEnvironment
|
||||
get() = NpmEnvironment(rootPackageDir, requireConfigured().nodeExecutable)
|
||||
|
||||
+8
-9
@@ -37,6 +37,7 @@ 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.topRealPath
|
||||
import org.jetbrains.kotlin.gradle.utils.unavailableValueError
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
@@ -61,6 +62,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
}
|
||||
|
||||
val nodeJs get() = rootResolver.nodeJs
|
||||
private val nodeJs_ get() = nodeJs ?: unavailableValueError("nodeJs")
|
||||
|
||||
val target get() = compilation.target
|
||||
|
||||
@@ -82,7 +84,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
npmProject.publicPackageJsonTaskName,
|
||||
listOf(compilation)
|
||||
) {
|
||||
it.dependsOn(nodeJs.npmInstallTaskProvider)
|
||||
it.dependsOn(nodeJs_.npmInstallTaskProvider)
|
||||
it.dependsOn(packageJsonTaskHolder)
|
||||
}.also { packageJsonTask ->
|
||||
if (compilation.isMain()) {
|
||||
@@ -187,7 +189,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
}
|
||||
|
||||
// We don't have `kotlin-js-test-runner` in NPM yet
|
||||
all.dependencies.add(nodeJs.versions.kotlinJsTestRunner.createDependency(project))
|
||||
all.dependencies.add(nodeJs_.versions.kotlinJsTestRunner.createDependency(project))
|
||||
|
||||
project.dependencies.add(
|
||||
all.name,
|
||||
@@ -413,12 +415,9 @@ internal class KotlinCompilationNpmResolver(
|
||||
var fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>,
|
||||
val projectPath: String
|
||||
) : Serializable {
|
||||
private val projectPackagesDir by lazy { compilationResolver.nodeJs.projectPackagesDir }
|
||||
private val rootDir by lazy { compilationResolver.nodeJs.rootProject.rootDir }
|
||||
|
||||
private val dukatPackageVersion by lazy {
|
||||
compilationResolver.nodeJs.versions.dukat
|
||||
}
|
||||
private val projectPackagesDir by lazy { compilationResolver.nodeJs_.projectPackagesDir }
|
||||
private val rootDir by lazy { compilationResolver.nodeJs_.rootProject.rootDir }
|
||||
private val dukatPackageVersion by lazy { compilationResolver.nodeJs_.versions.dukat }
|
||||
|
||||
@Transient
|
||||
internal lateinit var compilationResolver: KotlinCompilationNpmResolver
|
||||
@@ -464,7 +463,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
}
|
||||
.filterNotNull()
|
||||
|
||||
val toolsNpmDependencies = compilationResolver.rootResolver.nodeJs.taskRequirements
|
||||
val toolsNpmDependencies = compilationResolver.rootResolver.taskRequirements
|
||||
.getCompilationNpmRequirements(projectPath, compilationResolver.compilationDisambiguatedName)
|
||||
|
||||
val dukatIfNecessary = if (externalNpmDependencies.any { it.generateExternals }) {
|
||||
|
||||
+3
-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 org.jetbrains.kotlin.gradle.utils.unavailableValueError
|
||||
import java.io.Serializable
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@@ -55,7 +56,7 @@ internal class KotlinProjectNpmResolver(
|
||||
addContainerListeners()
|
||||
|
||||
project.whenEvaluated {
|
||||
val nodeJs = resolver.nodeJs
|
||||
val nodeJs = resolver.nodeJs ?: unavailableValueError("resolver.nodeJs")
|
||||
project.tasks.implementing(RequiresNpmDependencies::class)
|
||||
.configureEach { task ->
|
||||
if (task.enabled) {
|
||||
@@ -123,7 +124,7 @@ internal class KotlinProjectNpmResolver(
|
||||
return KotlinProjectNpmResolution(
|
||||
projectPath,
|
||||
byCompilation.values.mapNotNull { it.close() },
|
||||
resolver.nodeJs.taskRequirements.byTask
|
||||
resolver.taskRequirements.byTask
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+82
-35
@@ -14,34 +14,47 @@ 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.npm.CompositeNodeModulesCache
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModulesCache
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.TasksRequirements
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.plugins.RootResolverPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinProjectNpmResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinRootNpmResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnEnv
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnResolution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.toVersionString
|
||||
import org.jetbrains.kotlin.gradle.utils.ArchiveOperationsCompat
|
||||
import org.jetbrains.kotlin.gradle.utils.FileSystemOperationsCompat
|
||||
import org.jetbrains.kotlin.gradle.utils.unavailableValueError
|
||||
|
||||
/**
|
||||
* See [KotlinNpmResolutionManager] for details about resolution process.
|
||||
*
|
||||
* This class contains many transient properties to deduplicate data when configuration cache is used.
|
||||
* Regularly tasks share the same instance of this class, but with configuration cache each task that holds a reference to the instance will
|
||||
* create an own copy. We use build services as a single storage for the heavy state of this class.
|
||||
*/
|
||||
internal class KotlinRootNpmResolver internal constructor(
|
||||
val nodeJs: NodeJsRootExtension,
|
||||
@Transient
|
||||
val nodeJs: NodeJsRootExtension?,
|
||||
val forceFullResolve: Boolean
|
||||
) {
|
||||
val rootProject: Project
|
||||
get() = nodeJs.rootProject
|
||||
private val nodeJs_
|
||||
get() = nodeJs ?: unavailableValueError("nodeJs")
|
||||
|
||||
val rootProjectName by lazy {
|
||||
rootProject.name
|
||||
private val rootProject: Project?
|
||||
get() = nodeJs?.rootProject
|
||||
|
||||
private val rootProject_: Project
|
||||
get() = rootProject ?: unavailableValueError("rootProject")
|
||||
|
||||
private val rootProjectName by lazy {
|
||||
rootProject_.name
|
||||
}
|
||||
|
||||
val rootProjectVersion by lazy {
|
||||
rootProject.version.toString()
|
||||
private val rootProjectVersion by lazy {
|
||||
rootProject_.version.toString()
|
||||
}
|
||||
|
||||
enum class State {
|
||||
@@ -64,14 +77,15 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val archiveOperations by lazy { ArchiveOperationsCompat(rootProject) }
|
||||
private val fs by lazy { FileSystemOperationsCompat(rootProject) }
|
||||
private val archiveOperations by lazy { ArchiveOperationsCompat(rootProject_) }
|
||||
private val fs by lazy { FileSystemOperationsCompat(rootProject_) }
|
||||
|
||||
internal 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)
|
||||
}
|
||||
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 {
|
||||
@@ -80,31 +94,53 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
}
|
||||
|
||||
internal 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)
|
||||
}
|
||||
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()
|
||||
|
||||
@Transient
|
||||
private val yarnEnvironment_: Provider<YarnEnv>? = rootProject_.provider {
|
||||
YarnPlugin.apply(rootProject_).requireConfigured()
|
||||
}
|
||||
|
||||
@Transient
|
||||
private val npmEnvironment_: Provider<NpmEnvironment>? = rootProject_.provider {
|
||||
nodeJs_.asNpmEnvironment
|
||||
}
|
||||
|
||||
@Transient
|
||||
private val yarnResolutions_: Provider<List<YarnResolution>>? = rootProject_.provider {
|
||||
YarnPlugin.apply(rootProject_).resolutions
|
||||
}
|
||||
|
||||
@Transient
|
||||
private val taskRequirements_: TasksRequirements? = nodeJs_.taskRequirements
|
||||
|
||||
private val resolverStateHolder by lazy {
|
||||
rootProject.gradle.sharedServices.registerIfAbsent(
|
||||
rootProject_.gradle.sharedServices.registerIfAbsent(
|
||||
KotlinRootNpmResolverStateHolder::class.qualifiedName,
|
||||
KotlinRootNpmResolverStateHolder::class.java
|
||||
) {
|
||||
it.parameters.plugins.set(plugins_)
|
||||
it.parameters.projectResolvers.set(projectResolvers_)
|
||||
it.parameters.packageManager.set(nodeJs_.packageManager)
|
||||
it.parameters.yarnEnvironment.set(yarnEnvironment_?.get())
|
||||
it.parameters.npmEnvironment.set(npmEnvironment_?.get())
|
||||
it.parameters.yarnResolutions.set(yarnResolutions_?.get())
|
||||
it.parameters.taskRequirements.set(taskRequirements_)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,11 +165,23 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
private val projectResolvers
|
||||
get() = projectResolvers_ ?: configurationCacheProjectResolvers
|
||||
|
||||
val yarn by lazy {
|
||||
YarnPlugin.apply(rootProject)
|
||||
}
|
||||
private val packageManager
|
||||
get() = nodeJs?.packageManager ?: resolverStateHolder.get().parameters.packageManager.get()
|
||||
|
||||
internal val mayBeUpToDateTasksRegistry = MayBeUpToDatePackageJsonTasksRegistry.registerIfAbsent(rootProject)
|
||||
private val yarnEnvironment
|
||||
get() = yarnEnvironment_?.get() ?: resolverStateHolder.get().parameters.yarnEnvironment.get()
|
||||
|
||||
private val npmEnvironment
|
||||
get() = npmEnvironment_?.get() ?: resolverStateHolder.get().parameters.npmEnvironment.get()
|
||||
|
||||
private val yarnResolutions
|
||||
get() = yarnResolutions_?.get() ?: resolverStateHolder.get().parameters.yarnResolutions.get()
|
||||
|
||||
internal val taskRequirements
|
||||
get() = taskRequirements_ ?: resolverStateHolder.get().parameters.taskRequirements.get()
|
||||
|
||||
internal val mayBeUpToDateTasksRegistry =
|
||||
MayBeUpToDatePackageJsonTasksRegistry.registerIfAbsent(rootProject_)
|
||||
|
||||
fun alreadyResolvedMessage(action: String) = "Cannot $action. NodeJS projects already resolved."
|
||||
|
||||
@@ -194,14 +242,14 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
gradleNodeModules.close()
|
||||
compositeNodeModules.close()
|
||||
|
||||
nodeJs.packageManager.prepareRootProject(
|
||||
packageManager.prepareRootProject(
|
||||
rootProject,
|
||||
nodeJs,
|
||||
npmEnvironment,
|
||||
rootProjectName,
|
||||
rootProjectVersion,
|
||||
logger,
|
||||
allNpmPackages,
|
||||
yarn.resolutions
|
||||
yarnResolutions
|
||||
.associate { it.path to it.toVersionString() },
|
||||
forceFullResolve
|
||||
)
|
||||
@@ -232,13 +280,12 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
.values
|
||||
.flatMap { it.npmProjects }
|
||||
|
||||
val yarnConfigured = yarn.requireConfigured()
|
||||
nodeJs.packageManager.resolveRootProject(
|
||||
packageManager.resolveRootProject(
|
||||
services,
|
||||
logger,
|
||||
nodeJs,
|
||||
yarnConfigured.executable,
|
||||
yarnConfigured.standalone,
|
||||
npmEnvironment,
|
||||
yarnEnvironment.executable,
|
||||
yarnEnvironment.standalone,
|
||||
allNpmPackages,
|
||||
args
|
||||
)
|
||||
|
||||
+9
-1
@@ -8,17 +8,25 @@ 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.NpmApi
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmEnvironment
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.plugins.RootResolverPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnEnv
|
||||
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnResolution
|
||||
|
||||
// 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>
|
||||
val packageManager: Property<NpmApi>
|
||||
val yarnEnvironment: Property<YarnEnv>
|
||||
val npmEnvironment: Property<NpmEnvironment>
|
||||
val yarnResolutions: ListProperty<YarnResolution>
|
||||
val taskRequirements: Property<TasksRequirements>
|
||||
}
|
||||
|
||||
var initialized = false
|
||||
|
||||
+7
-4
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.*
|
||||
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.npm.asNpmEnvironment
|
||||
import org.jetbrains.kotlin.gradle.utils.unavailableValueError
|
||||
import java.io.File
|
||||
|
||||
open class KotlinNpmInstallTask : DefaultTask() {
|
||||
@@ -22,8 +25,8 @@ open class KotlinNpmInstallTask : DefaultTask() {
|
||||
}
|
||||
|
||||
@Transient
|
||||
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val resolutionManager = nodeJs.npmResolutionManager
|
||||
private val nodeJs: NodeJsRootExtension? = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val resolutionManager = (nodeJs ?: unavailableValueError("nodeJs")).npmResolutionManager
|
||||
|
||||
@Input
|
||||
val args: MutableList<String> = mutableListOf()
|
||||
@@ -40,12 +43,12 @@ open class KotlinNpmInstallTask : DefaultTask() {
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:InputFiles
|
||||
val preparedFiles: Collection<File> by lazy {
|
||||
nodeJs.packageManager.preparedFiles(nodeJs)
|
||||
(nodeJs ?: unavailableValueError("nodeJs")).packageManager.preparedFiles(nodeJs.asNpmEnvironment)
|
||||
}
|
||||
|
||||
@get:OutputFile
|
||||
val yarnLock: File by lazy {
|
||||
nodeJs.rootPackageDir.resolve("yarn.lock")
|
||||
(nodeJs ?: unavailableValueError("nodeJs")).rootPackageDir.resolve("yarn.lock")
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
|
||||
+4
-3
@@ -11,6 +11,7 @@ import org.gradle.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
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.NpmEnvironment
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
import java.io.File
|
||||
|
||||
@@ -23,12 +24,12 @@ class Yarn : NpmApi {
|
||||
override fun setup(project: Project) =
|
||||
getDelegate(project.rootProject).setup(project)
|
||||
|
||||
override fun preparedFiles(nodeJs: NodeJsRootExtension): Collection<File> =
|
||||
override fun preparedFiles(nodeJs: NpmEnvironment): Collection<File> =
|
||||
yarnWorkspaces.preparedFiles(nodeJs)
|
||||
|
||||
override fun prepareRootProject(
|
||||
rootProject: Project?,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
@@ -50,7 +51,7 @@ class Yarn : NpmApi {
|
||||
override fun resolveRootProject(
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
command: String,
|
||||
isStandalone: Boolean,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
|
||||
+3
-3
@@ -9,10 +9,10 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.gradle.internal.execWithProgress
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
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.Scope.PEER
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmEnvironment
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
import java.io.File
|
||||
|
||||
@@ -28,7 +28,7 @@ abstract class YarnBasics : NpmApi {
|
||||
fun yarnExec(
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
command: String,
|
||||
isStandalone: Boolean,
|
||||
dir: File,
|
||||
@@ -39,7 +39,7 @@ abstract class YarnBasics : NpmApi {
|
||||
val arguments = args +
|
||||
if (logger.isDebugEnabled) "--verbose" else ""
|
||||
|
||||
val nodeExecutable = nodeJs.requireConfigured().nodeExecutable
|
||||
val nodeExecutable = nodeJs.nodeExecutable
|
||||
exec.environment(
|
||||
"PATH",
|
||||
"$nodeExecutable${File.pathSeparator}${System.getenv("PATH")}"
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
data class YarnEnv(
|
||||
val downloadUrl: String,
|
||||
@@ -15,4 +16,4 @@ data class YarnEnv(
|
||||
val executable: String,
|
||||
val ivyDependency: String,
|
||||
val standalone: Boolean
|
||||
)
|
||||
) : Serializable
|
||||
|
||||
+2
-1
@@ -6,10 +6,11 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.buildNpmVersion
|
||||
import java.io.Serializable
|
||||
|
||||
class YarnResolution(
|
||||
val path: String
|
||||
) {
|
||||
) : Serializable {
|
||||
var includedVersions = mutableListOf<String>()
|
||||
var excludedVersions = mutableListOf<String>()
|
||||
|
||||
|
||||
+5
-5
@@ -8,15 +8,15 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmEnvironment
|
||||
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.resolved.KotlinCompilationNpmResolution
|
||||
import java.io.File
|
||||
|
||||
class YarnWorkspaces : YarnBasics() {
|
||||
override fun preparedFiles(nodeJs: NodeJsRootExtension): Collection<File> {
|
||||
override fun preparedFiles(nodeJs: NpmEnvironment): Collection<File> {
|
||||
return listOf(
|
||||
nodeJs
|
||||
.rootPackageDir
|
||||
@@ -26,7 +26,7 @@ class YarnWorkspaces : YarnBasics() {
|
||||
|
||||
override fun prepareRootProject(
|
||||
rootProject: Project?,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
@@ -48,7 +48,7 @@ class YarnWorkspaces : YarnBasics() {
|
||||
}
|
||||
|
||||
private fun prepareRootPackageJson(
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
@@ -70,7 +70,7 @@ class YarnWorkspaces : YarnBasics() {
|
||||
override fun resolveRootProject(
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
nodeJs: NpmEnvironment,
|
||||
command: String,
|
||||
isStandalone: Boolean,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle.tasks.internal
|
||||
|
||||
import org.jetbrains.kotlin.gradle.tasks.CleanDataTask
|
||||
import java.io.Serializable
|
||||
import java.time.Instant
|
||||
|
||||
/**
|
||||
@@ -16,7 +17,7 @@ import java.time.Instant
|
||||
* Now you will be able to access files via `CleanableStore["/path/to/dir"]["file/name"].use()`
|
||||
* and it would update usage of th store.
|
||||
*/
|
||||
interface CleanableStore {
|
||||
interface CleanableStore : Serializable {
|
||||
fun cleanDir(expirationDate: Instant)
|
||||
|
||||
operator fun get(fileName: String): DownloadedFile
|
||||
|
||||
+4
-1
@@ -22,4 +22,7 @@ internal fun Project.getSystemProperty(key: String): String? {
|
||||
} else {
|
||||
System.getProperty(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun unavailableValueError(propertyName: String): Nothing =
|
||||
error("'$propertyName' should be available at configuration time but unavailable on configuration cache reuse")
|
||||
Reference in New Issue
Block a user