[Gradle, JS] rootPackageJson and kotlinNpmInstall cache-friendly
This commit is contained in:
committed by
Alexander Likhachev
parent
8c79baa998
commit
4566b7c6e5
+4
-1
@@ -44,7 +44,10 @@ abstract class DukatTask(
|
||||
@get:Internal
|
||||
@delegate:Transient
|
||||
val dts by lazy {
|
||||
val resolvedCompilation = nodeJs.npmResolutionManager.requireInstalled()[project.path][compilation]
|
||||
val resolvedCompilation = nodeJs.npmResolutionManager.requireInstalled(
|
||||
services,
|
||||
logger
|
||||
)[project.path][compilation]
|
||||
val dtsResolver = DtsResolver(resolvedCompilation.npmProject)
|
||||
dtsResolver.getAllDts(
|
||||
resolvedCompilation.externalNpmDependencies,
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ open class NodeJsRootExtension(@Transient val rootProject: Project) : Configurat
|
||||
val nodeJsSetupTaskProvider: TaskProvider<out NodeJsSetupTask>
|
||||
get() = rootProject.tasks.withType(NodeJsSetupTask::class.java).named(NodeJsSetupTask.NAME)
|
||||
|
||||
val npmInstallTaskProvider: TaskProvider<out KotlinNpmInstallTask>
|
||||
get() = rootProject.tasks.withType(KotlinNpmInstallTask::class.java).named(KotlinNpmInstallTask.NAME)
|
||||
val npmInstallTaskProvider: TaskProvider<out KotlinNpmInstallTask>?
|
||||
get() = rootProject?.tasks?.withType(KotlinNpmInstallTask::class.java)?.named(KotlinNpmInstallTask.NAME)
|
||||
|
||||
val packageJsonUmbrellaTaskProvider: TaskProvider<Task>
|
||||
get() = rootProject.tasks.named(PACKAGE_JSON_UMBRELLA_TASK_NAME)
|
||||
|
||||
+26
-15
@@ -6,8 +6,10 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
import org.gradle.api.Incubating
|
||||
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.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
@@ -116,7 +118,10 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
}
|
||||
|
||||
@Incubating
|
||||
internal fun requireInstalled() = installIfNeeded(reason = "")
|
||||
internal fun requireInstalled(
|
||||
services: ServiceRegistry,
|
||||
logger: Logger
|
||||
) = installIfNeeded(reason = "", services = services, logger = logger)
|
||||
|
||||
internal fun requireConfiguringState(): KotlinRootNpmResolver =
|
||||
(this.state as? ResolutionState.Configuring ?: error("NPM Dependencies already resolved and installed")).resolver
|
||||
@@ -124,23 +129,25 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
internal fun isConfiguringState(): Boolean =
|
||||
this.state is ResolutionState.Configuring
|
||||
|
||||
internal fun prepare() = prepareIfNeeded(requireNotPrepared = true)
|
||||
internal fun prepare(logger: Logger) = prepareIfNeeded(requireNotPrepared = true, logger = logger)
|
||||
|
||||
internal fun installIfNeeded(
|
||||
reason: String? = "",
|
||||
args: List<String> = emptyList()
|
||||
args: List<String> = emptyList(),
|
||||
services: ServiceRegistry,
|
||||
logger: Logger
|
||||
): KotlinRootNpmResolution {
|
||||
synchronized(this) {
|
||||
if (state is ResolutionState.Installed) {
|
||||
return (state as ResolutionState.Installed).resolved
|
||||
}
|
||||
|
||||
val installUpToDate = nodeJsSettings.npmInstallTaskProvider.get().state.upToDate
|
||||
val installUpToDate = nodeJsSettings.npmInstallTaskProvider?.get()?.state?.upToDate ?: false
|
||||
val forceUpToDate = installUpToDate && !forceFullResolve
|
||||
|
||||
val installation = prepareIfNeeded(requireUpToDateReason = reason)
|
||||
val installation = prepareIfNeeded(requireUpToDateReason = reason, logger = logger)
|
||||
val resolution = installation
|
||||
.install(forceUpToDate, args)
|
||||
.install(forceUpToDate, args, services, logger)
|
||||
state = ResolutionState.Installed(resolution)
|
||||
|
||||
installation.closePlugins(resolution)
|
||||
@@ -149,8 +156,8 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
}
|
||||
}
|
||||
|
||||
internal fun requireAlreadyInstalled(project: Project, reason: String = ""): KotlinProjectNpmResolution =
|
||||
installIfNeeded(reason = reason)[project.path]
|
||||
// internal fun requireAlreadyInstalled(project: Project, reason: String = ""): KotlinProjectNpmResolution =
|
||||
// installIfNeeded(reason = reason)[project.path]
|
||||
|
||||
internal val packageJsonFiles: Collection<File>
|
||||
get() = state.npmProjects.map { it.packageJsonFile }
|
||||
@@ -162,7 +169,8 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
*/
|
||||
private fun prepareIfNeeded(
|
||||
requireUpToDateReason: String? = null,
|
||||
requireNotPrepared: Boolean = false
|
||||
requireNotPrepared: Boolean = false,
|
||||
logger: Logger
|
||||
): KotlinRootNpmResolver.Installation {
|
||||
fun alreadyResolved(installation: KotlinRootNpmResolver.Installation): KotlinRootNpmResolver.Installation {
|
||||
if (requireNotPrepared) error("Project already prepared")
|
||||
@@ -183,7 +191,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
error("NPM dependencies should be resolved $requireUpToDateReason")
|
||||
}
|
||||
|
||||
state1.resolver.prepareInstallation().also {
|
||||
state1.resolver.prepareInstallation(logger).also {
|
||||
this.state = ResolutionState.Prepared(it)
|
||||
}
|
||||
}
|
||||
@@ -196,23 +204,26 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
|
||||
}
|
||||
|
||||
internal fun getNpmDependencyResolvedCompilation(npmDependency: NpmDependency): KotlinCompilationNpmResolution? {
|
||||
val project = npmDependency.project.path
|
||||
val project = npmDependency.project!!
|
||||
val projectPath = project.path
|
||||
val services = (project as ProjectInternal).services
|
||||
val logger = project.logger
|
||||
|
||||
val resolvedProject =
|
||||
if (forceFullResolve) {
|
||||
installIfNeeded(reason = null)[project]
|
||||
installIfNeeded(reason = null, services = services, logger = logger)[projectPath]
|
||||
} else {
|
||||
// may return null only during npm resolution
|
||||
// (it can be called since NpmDependency added to configuration that
|
||||
// requires resolve to build package.json, in this case we should just skip this call)
|
||||
val state0 = state
|
||||
when (state0) {
|
||||
is ResolutionState.Prepared -> state0.preparedInstallation[project]
|
||||
is ResolutionState.Prepared -> state0.preparedInstallation[projectPath]
|
||||
is ResolutionState.Configuring -> {
|
||||
return null
|
||||
//error("Cannot use NpmDependency before :kotlinNpmInstall task execution")
|
||||
}
|
||||
is ResolutionState.Installed -> state0.resolved[project]
|
||||
is ResolutionState.Installed -> state0.resolved[projectPath]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-3
@@ -6,6 +6,9 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
|
||||
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.resolved.KotlinCompilationNpmResolution
|
||||
import java.io.File
|
||||
|
||||
@@ -17,16 +20,23 @@ interface NpmApi {
|
||||
|
||||
fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution)
|
||||
|
||||
fun preparedFiles(project: Project): Collection<File>
|
||||
fun preparedFiles(nodeJs: NodeJsRootExtension): Collection<File>
|
||||
|
||||
fun prepareRootProject(
|
||||
rootProject: Project,
|
||||
rootProject: Project?,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
subProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
resolutions: Map<String, String>
|
||||
)
|
||||
|
||||
fun resolveRootProject(
|
||||
rootProject: Project,
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
yarnHome: File,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
skipExecution: Boolean,
|
||||
cliArgs: List<String>
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ import java.io.File
|
||||
|
||||
data class NpmDependency(
|
||||
@Transient
|
||||
internal val project: Project,
|
||||
internal val project: Project?,
|
||||
private val name: String,
|
||||
private val version: String,
|
||||
val scope: Scope = Scope.NORMAL,
|
||||
@@ -82,7 +82,7 @@ data class NpmDependency(
|
||||
// (it can be called since NpmDependency added to configuration that
|
||||
// requires resolve to build package.json, in this case we should just skip this call)
|
||||
private fun resolveProject(): KotlinCompilationNpmResolution? {
|
||||
val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
val nodeJs = NodeJsRootPlugin.apply(project!!.rootProject)
|
||||
return nodeJs.npmResolutionManager.getNpmDependencyResolvedCompilation(this)
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ data class NpmDependency(
|
||||
|
||||
override fun toString() = "$key: $version"
|
||||
|
||||
override fun getFiles(): FileCollection = project.files(resolve(true))
|
||||
override fun getFiles(): FileCollection = project!!.files(resolve(true))
|
||||
|
||||
override fun getName() = name
|
||||
|
||||
@@ -100,7 +100,7 @@ data class NpmDependency(
|
||||
|
||||
override fun contentEquals(dependency: Dependency) = this == dependency
|
||||
|
||||
override fun getTargetComponentId() = DefaultLibraryBinaryIdentifier(project.path, key, "npm")
|
||||
override fun getTargetComponentId() = DefaultLibraryBinaryIdentifier(project!!.path, key, "npm")
|
||||
|
||||
override fun copy(): Dependency = this.copy(name = name)
|
||||
|
||||
|
||||
+4
-5
@@ -8,13 +8,12 @@ package org.jetbrains.kotlin.gradle.targets.js.npm
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.internal.hash.FileHasher
|
||||
import org.gradle.internal.service.ServiceRegistry
|
||||
import org.jetbrains.kotlin.daemon.common.toHexString
|
||||
import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
|
||||
import java.io.File
|
||||
|
||||
class PackageJsonUpToDateCheck(val npmProject: NpmProject) {
|
||||
val project: Project
|
||||
get() = npmProject.project
|
||||
class PackageJsonUpToDateCheck(val services: ServiceRegistry, val npmProject: NpmProject) {
|
||||
|
||||
private val NpmProject.packageJsonHashFile: File
|
||||
get() = dir.resolve("package.json.hash")
|
||||
@@ -24,10 +23,10 @@ class PackageJsonUpToDateCheck(val npmProject: NpmProject) {
|
||||
if (packageJsonHashFile.exists()) packageJsonHashFile.readText() else null
|
||||
}
|
||||
|
||||
private val packageJsonFile = npmProject.prePackageJsonFile
|
||||
private val packageJsonFile = npmProject.packageJsonFile
|
||||
|
||||
private val hash by lazy {
|
||||
val hasher = (project as ProjectInternal).services.get(FileHasher::class.java)
|
||||
val hasher = services.get(FileHasher::class.java)
|
||||
hasher.hash(packageJsonFile).toByteArray().toHexString()
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -27,7 +27,10 @@ constructor(
|
||||
private val nodeJs = npmProject.nodeJs
|
||||
|
||||
private val compilationResolution
|
||||
get() = nodeJs.npmResolutionManager.requireInstalled()[project.path][npmProject.compilation]
|
||||
get() = nodeJs.npmResolutionManager.requireInstalled(
|
||||
services,
|
||||
logger
|
||||
)[project.path][npmProject.compilation]
|
||||
|
||||
init {
|
||||
// TODO: temporary workaround for configuration cache enabled builds
|
||||
|
||||
+2
-5
@@ -14,8 +14,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.*
|
||||
class KotlinCompilationNpmResolution(
|
||||
@Transient
|
||||
private val _project: Project?,
|
||||
@Transient
|
||||
private val _npmProject: NpmProject?,
|
||||
val npmProject: NpmProject,
|
||||
val internalDependencies: Collection<KotlinCompilationNpmResolution>,
|
||||
val internalCompositeDependencies: Collection<GradleNodeModule>,
|
||||
val externalGradleDependencies: Collection<GradleNodeModule>,
|
||||
@@ -24,14 +23,12 @@ class KotlinCompilationNpmResolution(
|
||||
) {
|
||||
val project
|
||||
get() = _project!!
|
||||
val npmProject
|
||||
get() = _npmProject!!
|
||||
|
||||
val externalNpmDependencies
|
||||
get() = _externalNpmDependencies
|
||||
.map {
|
||||
NpmDependency(
|
||||
project = project,
|
||||
project = _project,
|
||||
name = it.name,
|
||||
version = it.version,
|
||||
scope = it.scope,
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
|
||||
import org.gradle.api.Project
|
||||
|
||||
internal class KotlinRootNpmResolution(
|
||||
val rootProject: Project,
|
||||
val rootProject: Project?,
|
||||
internal val projects: Map<String, KotlinProjectNpmResolution>
|
||||
) {
|
||||
operator fun get(project: String) = projects[project] ?: KotlinProjectNpmResolution.empty(project)
|
||||
|
||||
+1
-2
@@ -59,7 +59,6 @@ internal class KotlinCompilationNpmResolver(
|
||||
resolver.compositeNodeModules
|
||||
}
|
||||
|
||||
@Transient
|
||||
val npmProject = compilation.npmProject
|
||||
|
||||
val compilationName = compilation.name
|
||||
@@ -463,7 +462,7 @@ internal class KotlinCompilationNpmResolver(
|
||||
|
||||
return KotlinCompilationNpmResolution(
|
||||
if (compilation != null) project else null,
|
||||
if (compilation != null) npmProject else null,
|
||||
npmProject,
|
||||
resolvedInternalDependencies,
|
||||
compositeDependencies,
|
||||
importedExternalGradleDependencies,
|
||||
|
||||
+28
-10
@@ -6,7 +6,8 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.logging.Logger
|
||||
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
|
||||
@@ -22,7 +23,6 @@ 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.tasks.registerTask
|
||||
|
||||
/**
|
||||
* See [KotlinNpmResolutionManager] for details about resolution process.
|
||||
@@ -34,6 +34,14 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
val rootProject: Project
|
||||
get() = nodeJs.rootProject
|
||||
|
||||
val rootProjectName by lazy {
|
||||
rootProject.name
|
||||
}
|
||||
|
||||
val rootProjectVersion by lazy {
|
||||
rootProject.version.toString()
|
||||
}
|
||||
|
||||
val plugins = mutableListOf<RootResolverPlugin>().also {
|
||||
it.add(DukatRootResolverPlugin(this))
|
||||
}
|
||||
@@ -51,6 +59,10 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
val compositeNodeModules = CompositeNodeModulesCache(nodeJs)
|
||||
val projectResolvers = mutableMapOf<String, KotlinProjectNpmResolver>()
|
||||
|
||||
val yarn by lazy {
|
||||
YarnPlugin.apply(rootProject)
|
||||
}
|
||||
|
||||
fun alreadyResolvedMessage(action: String) = "Cannot $action. NodeJS projects already resolved."
|
||||
|
||||
@Synchronized
|
||||
@@ -95,7 +107,7 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
/**
|
||||
* Don't use directly, use [KotlinNpmResolutionManager.installIfNeeded] instead.
|
||||
*/
|
||||
internal fun prepareInstallation(): Installation {
|
||||
internal fun prepareInstallation(logger: Logger): Installation {
|
||||
synchronized(this@KotlinRootNpmResolver) {
|
||||
check(state == State.CONFIGURING) {
|
||||
"Projects must be configuring"
|
||||
@@ -109,14 +121,15 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
|
||||
gradleNodeModules.close()
|
||||
|
||||
val yarn = YarnPlugin.apply(rootProject)
|
||||
|
||||
nodeJs.packageManager.prepareRootProject(
|
||||
rootProject,
|
||||
nodeJs,
|
||||
rootProjectName,
|
||||
rootProjectVersion,
|
||||
logger,
|
||||
allNpmPackages,
|
||||
yarn.resolutions
|
||||
.associate { it.path to it.toVersionString() }
|
||||
)
|
||||
.associate { it.path to it.toVersionString() })
|
||||
|
||||
return Installation(
|
||||
projectResolutions
|
||||
@@ -130,7 +143,9 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
|
||||
internal fun install(
|
||||
forceUpToDate: Boolean,
|
||||
args: List<String>
|
||||
args: List<String>,
|
||||
services: ServiceRegistry,
|
||||
logger: Logger
|
||||
): KotlinRootNpmResolution {
|
||||
synchronized(this@KotlinRootNpmResolver) {
|
||||
check(state == State.PROJECTS_CLOSED) {
|
||||
@@ -147,12 +162,15 @@ internal class KotlinRootNpmResolver internal constructor(
|
||||
// we should call it even kotlinNpmInstall task is up-to-date (skipPackageManager is true)
|
||||
// because our upToDateChecks saves state for next execution
|
||||
val upToDateChecks = allNpmPackages.map {
|
||||
PackageJsonUpToDateCheck(it.npmProject)
|
||||
PackageJsonUpToDateCheck(services, it.npmProject)
|
||||
}
|
||||
val upToDate = forceUpToDate || upToDateChecks.all { it.upToDate }
|
||||
|
||||
nodeJs.packageManager.resolveRootProject(
|
||||
nodeJs.rootProject,
|
||||
services,
|
||||
logger,
|
||||
nodeJs,
|
||||
yarn.requireConfigured().home,
|
||||
allNpmPackages,
|
||||
upToDate,
|
||||
args
|
||||
|
||||
+6
-3
@@ -11,7 +11,6 @@ import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.utils.disableTaskOnConfigurationCacheBuild
|
||||
import java.io.File
|
||||
|
||||
open class KotlinNpmInstallTask : DefaultTask() {
|
||||
@@ -44,7 +43,7 @@ open class KotlinNpmInstallTask : DefaultTask() {
|
||||
|
||||
@get:InputFiles
|
||||
val preparedFiles: Collection<File> by lazy {
|
||||
nodeJs.packageManager.preparedFiles(project)
|
||||
nodeJs.packageManager.preparedFiles(nodeJs)
|
||||
}
|
||||
|
||||
// avoid using node_modules as output directory, as it is significantly slows down build
|
||||
@@ -58,7 +57,11 @@ open class KotlinNpmInstallTask : DefaultTask() {
|
||||
|
||||
@TaskAction
|
||||
fun resolve() {
|
||||
resolutionManager.installIfNeeded(args = args)
|
||||
resolutionManager.installIfNeeded(
|
||||
args = args,
|
||||
services = services,
|
||||
logger = logger
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+2
-2
@@ -107,9 +107,9 @@ open class KotlinPackageJsonTask : DefaultTask() {
|
||||
task.inputs.file(packageJsonTask.map { it.packageJson })
|
||||
}
|
||||
|
||||
nodeJs.rootPackageJsonTaskProvider?.configure { it.mustRunAfter(packageJsonTask) }
|
||||
nodeJs.rootPackageJsonTaskProvider!!.configure { it.mustRunAfter(packageJsonTask) }
|
||||
|
||||
compilation.compileKotlinTaskProvider.dependsOn(npmInstallTask)
|
||||
compilation.compileKotlinTaskProvider.dependsOn(npmInstallTask!!)
|
||||
compilation.compileKotlinTaskProvider.dependsOn(packageJsonTask)
|
||||
|
||||
return packageJsonTask
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ open class RootPackageJsonTask : DefaultTask() {
|
||||
|
||||
@TaskAction
|
||||
fun resolve() {
|
||||
resolutionManager.prepare()
|
||||
resolutionManager.prepare(logger)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
-1
@@ -250,7 +250,6 @@ constructor(
|
||||
|
||||
@TaskAction
|
||||
fun doExecute() {
|
||||
println(services.get(org.gradle.internal.logging.progress.ProgressLoggerFactory::class.java))
|
||||
// nodeJs.npmResolutionManager?.checkRequiredDependencies(this)
|
||||
|
||||
val runner = createRunner()
|
||||
|
||||
+24
-7
@@ -6,6 +6,9 @@
|
||||
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.NpmDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
@@ -25,29 +28,43 @@ class Yarn : NpmApi {
|
||||
override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) =
|
||||
getDelegate(resolvedNpmProject.project).resolveProject(resolvedNpmProject)
|
||||
|
||||
override fun preparedFiles(project: Project): Collection<File> =
|
||||
getDelegate(project).preparedFiles(project)
|
||||
override fun preparedFiles(nodeJs: NodeJsRootExtension): Collection<File> =
|
||||
yarnWorkspaces.preparedFiles(nodeJs)
|
||||
|
||||
override fun prepareRootProject(
|
||||
rootProject: Project,
|
||||
rootProject: Project?,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
subProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
resolutions: Map<String, String>
|
||||
) = getDelegate(rootProject.project)
|
||||
) = yarnWorkspaces
|
||||
.prepareRootProject(
|
||||
rootProject,
|
||||
nodeJs,
|
||||
rootProjectName,
|
||||
rootProjectVersion,
|
||||
logger,
|
||||
subProjects,
|
||||
resolutions
|
||||
)
|
||||
|
||||
override fun resolveRootProject(
|
||||
rootProject: Project,
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
yarnHome: File,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
skipExecution: Boolean,
|
||||
cliArgs: List<String>
|
||||
) {
|
||||
getDelegate(rootProject.project)
|
||||
yarnWorkspaces
|
||||
.resolveRootProject(
|
||||
rootProject,
|
||||
services,
|
||||
logger,
|
||||
nodeJs,
|
||||
yarnHome,
|
||||
npmProjects,
|
||||
skipExecution,
|
||||
cliArgs
|
||||
|
||||
+10
-7
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
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.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||
@@ -25,19 +28,19 @@ abstract class YarnBasics : NpmApi {
|
||||
}
|
||||
|
||||
fun yarnExec(
|
||||
project: Project,
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
yarnHome: File,
|
||||
dir: File,
|
||||
description: String,
|
||||
args: List<String>
|
||||
) {
|
||||
val nodeJs = NodeJsRootPlugin.apply(project)
|
||||
val yarnPlugin = YarnPlugin.apply(project)
|
||||
|
||||
(project as ProjectInternal).services.execWithProgress(description) { exec ->
|
||||
services.execWithProgress(description) { exec ->
|
||||
exec.executable = nodeJs.requireConfigured().nodeExecutable
|
||||
exec.args = listOf(yarnPlugin.requireConfigured().home.resolve("bin/yarn.js").absolutePath) +
|
||||
exec.args = listOf(yarnHome.resolve("bin/yarn.js").absolutePath) +
|
||||
args +
|
||||
if (project.logger.isDebugEnabled) "--verbose" else ""
|
||||
if (logger.isDebugEnabled) "--verbose" else ""
|
||||
exec.workingDir = dir
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||
|
||||
import com.google.gson.Gson
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModule
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson
|
||||
@@ -15,7 +16,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmR
|
||||
import java.io.File
|
||||
|
||||
class YarnImportedPackagesVersionResolver(
|
||||
private val rootProject: Project,
|
||||
private val logger: Logger,
|
||||
private val npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
private val nodeJsWorldDir: File
|
||||
) {
|
||||
@@ -53,7 +54,7 @@ class YarnImportedPackagesVersionResolver(
|
||||
modules.groupBy { it.name }.forEach { (name, versions) ->
|
||||
val selected: GradleNodeModule = if (versions.size > 1) {
|
||||
val sorted = versions.sortedBy { it.semver }
|
||||
rootProject.logger.warn(
|
||||
logger.warn(
|
||||
"There are multiple versions of \"$name\" used in nodejs build: ${sorted.joinToString(", ") { it.version }}. " +
|
||||
"Only latest version will be used."
|
||||
)
|
||||
|
||||
+4
-1
@@ -17,7 +17,10 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.implementing
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
|
||||
|
||||
open class YarnRootExtension(val project: Project) : ConfigurationPhaseAware<YarnEnv>() {
|
||||
open class YarnRootExtension(
|
||||
@Transient
|
||||
val project: Project
|
||||
) : ConfigurationPhaseAware<YarnEnv>() {
|
||||
init {
|
||||
check(project == project.rootProject)
|
||||
}
|
||||
|
||||
+27
-12
@@ -6,6 +6,11 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.yarn
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
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.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJsonUpToDateCheck
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
@@ -17,28 +22,38 @@ class YarnSimple : YarnBasics() {
|
||||
|
||||
val project = resolvedNpmProject.project
|
||||
|
||||
PackageJsonUpToDateCheck(resolvedNpmProject.npmProject).updateIfNeeded {
|
||||
yarnExec(
|
||||
project,
|
||||
resolvedNpmProject.npmProject.dir,
|
||||
NpmApi.resolveOperationDescription("yarn for ${project.path}"),
|
||||
emptyList()
|
||||
)
|
||||
yarnLockReadTransitiveDependencies(resolvedNpmProject.npmProject.dir, resolvedNpmProject.externalNpmDependencies)
|
||||
}
|
||||
// PackageJsonUpToDateCheck(resolvedNpmProject.npmProject).updateIfNeeded {
|
||||
// yarnExec(
|
||||
// (project as ProjectInternal).services,
|
||||
// project.logger,
|
||||
// NodeJsRootPlugin.apply(project),
|
||||
// YarnPlugin.apply(project).requireConfigured().home,
|
||||
// resolvedNpmProject.npmProject.dir,
|
||||
// NpmApi.resolveOperationDescription("yarn for ${project.path}"),
|
||||
// emptyList()
|
||||
// )
|
||||
// yarnLockReadTransitiveDependencies(resolvedNpmProject.npmProject.dir, resolvedNpmProject.externalNpmDependencies)
|
||||
// }
|
||||
}
|
||||
|
||||
override fun preparedFiles(project: Project): Collection<File> =
|
||||
override fun preparedFiles(nodeJs: NodeJsRootExtension): Collection<File> =
|
||||
emptyList()
|
||||
|
||||
override fun prepareRootProject(
|
||||
rootProject: Project,
|
||||
rootProject: Project?,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
subProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
resolutions: Map<String, String>
|
||||
) = Unit
|
||||
|
||||
override fun resolveRootProject(
|
||||
rootProject: Project,
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
yarnHome: File,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
skipExecution: Boolean,
|
||||
cliArgs: List<String>
|
||||
|
||||
+37
-15
@@ -6,6 +6,9 @@
|
||||
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.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmApi
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
|
||||
@@ -16,37 +19,49 @@ import java.io.File
|
||||
class YarnWorkspaces : YarnBasics() {
|
||||
override fun resolveProject(resolvedNpmProject: KotlinCompilationNpmResolution) = Unit
|
||||
|
||||
override fun preparedFiles(project: Project): Collection<File> {
|
||||
override fun preparedFiles(nodeJs: NodeJsRootExtension): Collection<File> {
|
||||
return listOf(
|
||||
NodeJsRootPlugin.apply(project.rootProject)
|
||||
nodeJs
|
||||
.rootPackageDir
|
||||
.resolve(NpmProject.PACKAGE_JSON)
|
||||
)
|
||||
}
|
||||
|
||||
override fun prepareRootProject(
|
||||
rootProject: Project,
|
||||
rootProject: Project?,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
subProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
resolutions: Map<String, String>
|
||||
) {
|
||||
check(rootProject == rootProject.rootProject)
|
||||
setup(rootProject)
|
||||
// check(rootProject == rootProject.rootProject)
|
||||
rootProject?.let { setup(it) }
|
||||
return prepareRootPackageJson(
|
||||
rootProject,
|
||||
nodeJs,
|
||||
rootProjectName,
|
||||
rootProjectVersion,
|
||||
logger,
|
||||
subProjects,
|
||||
resolutions
|
||||
)
|
||||
}
|
||||
|
||||
private fun prepareRootPackageJson(
|
||||
rootProject: Project,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
resolutions: Map<String, String>
|
||||
) {
|
||||
val rootPackageJsonFile = preparedFiles(rootProject).single()
|
||||
val rootPackageJsonFile = preparedFiles(nodeJs).single()
|
||||
|
||||
saveRootProjectWorkspacesPackageJson(
|
||||
rootProject,
|
||||
rootProjectName,
|
||||
rootProjectVersion,
|
||||
logger,
|
||||
npmProjects,
|
||||
resolutions,
|
||||
rootPackageJsonFile
|
||||
@@ -54,16 +69,21 @@ class YarnWorkspaces : YarnBasics() {
|
||||
}
|
||||
|
||||
override fun resolveRootProject(
|
||||
rootProject: Project,
|
||||
services: ServiceRegistry,
|
||||
logger: Logger,
|
||||
nodeJs: NodeJsRootExtension,
|
||||
yarnHome: File,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
skipExecution: Boolean,
|
||||
cliArgs: List<String>
|
||||
) {
|
||||
val nodeJs = NodeJsRootPlugin.apply(rootProject)
|
||||
val nodeJsWorldDir = nodeJs.rootPackageDir
|
||||
|
||||
yarnExec(
|
||||
rootProject,
|
||||
services,
|
||||
logger,
|
||||
nodeJs,
|
||||
yarnHome,
|
||||
nodeJsWorldDir,
|
||||
NpmApi.resolveOperationDescription("yarn"),
|
||||
cliArgs
|
||||
@@ -74,18 +94,20 @@ class YarnWorkspaces : YarnBasics() {
|
||||
}
|
||||
|
||||
private fun saveRootProjectWorkspacesPackageJson(
|
||||
rootProject: Project,
|
||||
rootProjectName: String,
|
||||
rootProjectVersion: String,
|
||||
logger: Logger,
|
||||
npmProjects: Collection<KotlinCompilationNpmResolution>,
|
||||
resolutions: Map<String, String>,
|
||||
rootPackageJsonFile: File
|
||||
) {
|
||||
val nodeJsWorldDir = rootPackageJsonFile.parentFile
|
||||
val rootPackageJson = PackageJson(rootProject.name, rootProject.version.toString())
|
||||
val rootPackageJson = PackageJson(rootProjectName, rootProjectVersion)
|
||||
rootPackageJson.private = true
|
||||
|
||||
val npmProjectWorkspaces = npmProjects.map { it.npmProject.dir.relativeTo(nodeJsWorldDir).path }
|
||||
val importedProjectWorkspaces =
|
||||
YarnImportedPackagesVersionResolver(rootProject, npmProjects, nodeJsWorldDir).resolveAndUpdatePackages()
|
||||
YarnImportedPackagesVersionResolver(logger, npmProjects, nodeJsWorldDir).resolveAndUpdatePackages()
|
||||
|
||||
rootPackageJson.workspaces = npmProjectWorkspaces + importedProjectWorkspaces
|
||||
rootPackageJson.resolutions = resolutions
|
||||
|
||||
Reference in New Issue
Block a user