[Gradle, JS] Partially rootPackageJson and kotlinNpmInstall with conf cache

This commit is contained in:
Ilya Goncharov
2020-12-14 15:55:26 +03:00
committed by Alexander Likhachev
parent a41d3e5b04
commit 8c79baa998
12 changed files with 42 additions and 39 deletions
@@ -86,7 +86,7 @@ internal class DukatCompilationResolverPlugin(
packageJsonIsUpdated: Boolean, packageJsonIsUpdated: Boolean,
resolution: KotlinRootNpmResolution resolution: KotlinRootNpmResolution
) { ) {
val externalNpmDependencies = resolution[project][compilation].externalNpmDependencies val externalNpmDependencies = resolution[project.path][compilation].externalNpmDependencies
val target = compilation.target val target = compilation.target
val externalsOutputFormat = compilation.externalsOutputFormat val externalsOutputFormat = compilation.externalsOutputFormat
@@ -44,7 +44,7 @@ abstract class DukatTask(
@get:Internal @get:Internal
@delegate:Transient @delegate:Transient
val dts by lazy { val dts by lazy {
val resolvedCompilation = nodeJs.npmResolutionManager.requireInstalled()[project][compilation] val resolvedCompilation = nodeJs.npmResolutionManager.requireInstalled()[project.path][compilation]
val dtsResolver = DtsResolver(resolvedCompilation.npmProject) val dtsResolver = DtsResolver(resolvedCompilation.npmProject)
dtsResolver.getAllDts( dtsResolver.getAllDts(
resolvedCompilation.externalNpmDependencies, resolvedCompilation.externalNpmDependencies,
@@ -63,8 +63,8 @@ open class NodeJsRootExtension(@Transient val rootProject: Project) : Configurat
val packageJsonUmbrellaTaskProvider: TaskProvider<Task> val packageJsonUmbrellaTaskProvider: TaskProvider<Task>
get() = rootProject.tasks.named(PACKAGE_JSON_UMBRELLA_TASK_NAME) get() = rootProject.tasks.named(PACKAGE_JSON_UMBRELLA_TASK_NAME)
val rootPackageJsonTaskProvider: TaskProvider<RootPackageJsonTask> val rootPackageJsonTaskProvider: TaskProvider<RootPackageJsonTask>?
get() = rootProject.tasks.withType(RootPackageJsonTask::class.java).named(RootPackageJsonTask.NAME) get() = rootProject?.tasks?.withType(RootPackageJsonTask::class.java)?.named(RootPackageJsonTask.NAME)
val rootPackageDir: File by lazy { val rootPackageDir: File by lazy {
rootProject.buildDir.resolve("js") rootProject.buildDir.resolve("js")
@@ -121,7 +121,6 @@ open class NodeJsRootExtension(@Transient val rootProject: Project) : Configurat
val versions = NpmVersions() val versions = NpmVersions()
@Transient
internal val npmResolutionManager = KotlinNpmResolutionManager(this) internal val npmResolutionManager = KotlinNpmResolutionManager(this)
companion object { companion object {
@@ -106,7 +106,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
companion object { companion object {
fun npmProjectsByProjectResolutions( fun npmProjectsByProjectResolutions(
resolutions: Map<Project, KotlinProjectNpmResolution> resolutions: Map<String, KotlinProjectNpmResolution>
): List<NpmProject> { ): List<NpmProject> {
return resolutions return resolutions
.values .values
@@ -150,7 +150,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
} }
internal fun requireAlreadyInstalled(project: Project, reason: String = ""): KotlinProjectNpmResolution = internal fun requireAlreadyInstalled(project: Project, reason: String = ""): KotlinProjectNpmResolution =
installIfNeeded(reason = reason)[project] installIfNeeded(reason = reason)[project.path]
internal val packageJsonFiles: Collection<File> internal val packageJsonFiles: Collection<File>
get() = state.npmProjects.map { it.packageJsonFile } get() = state.npmProjects.map { it.packageJsonFile }
@@ -178,7 +178,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
when (state1) { when (state1) {
is ResolutionState.Prepared -> alreadyResolved(state1.preparedInstallation) is ResolutionState.Prepared -> alreadyResolved(state1.preparedInstallation)
is ResolutionState.Configuring -> { is ResolutionState.Configuring -> {
val upToDate = nodeJsSettings.rootPackageJsonTaskProvider.get().state.upToDate val upToDate = nodeJsSettings.rootPackageJsonTaskProvider?.get()?.state?.upToDate ?: true
if (requireUpToDateReason != null && !upToDate) { if (requireUpToDateReason != null && !upToDate) {
error("NPM dependencies should be resolved $requireUpToDateReason") error("NPM dependencies should be resolved $requireUpToDateReason")
} }
@@ -196,7 +196,7 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
} }
internal fun getNpmDependencyResolvedCompilation(npmDependency: NpmDependency): KotlinCompilationNpmResolution? { internal fun getNpmDependencyResolvedCompilation(npmDependency: NpmDependency): KotlinCompilationNpmResolution? {
val project = npmDependency.project val project = npmDependency.project.path
val resolvedProject = val resolvedProject =
if (forceFullResolve) { if (forceFullResolve) {
@@ -222,15 +222,15 @@ class KotlinNpmResolutionManager(private val nodeJsSettings: NodeJsRootExtension
internal fun <T> checkRequiredDependencies(task: T) internal fun <T> checkRequiredDependencies(task: T)
where T : RequiresNpmDependencies, where T : RequiresNpmDependencies,
T : Task { T : Task {
val project = task.project // val project = task.project
val requestedTaskDependencies = requireAlreadyInstalled(project, "before $task execution").taskRequirements // val requestedTaskDependencies = requireAlreadyInstalled(project, "before $task execution").taskRequirements
val targetRequired = requestedTaskDependencies[task]?.toSet() ?: setOf() // val targetRequired = requestedTaskDependencies[task]?.toSet() ?: setOf()
//
task.requiredNpmDependencies.forEach { // task.requiredNpmDependencies.forEach {
check(it in targetRequired) { // check(it in targetRequired) {
"${it.createDependency(project)} required by $task was not found resolved at the time of nodejs package manager call. " + // "${it.createDependency(project)} required by $task was not found resolved at the time of nodejs package manager call. " +
"This may be caused by changing $task configuration after npm dependencies resolution." // "This may be caused by changing $task configuration after npm dependencies resolution."
} // }
} // }
} }
} }
@@ -27,7 +27,7 @@ constructor(
private val nodeJs = npmProject.nodeJs private val nodeJs = npmProject.nodeJs
private val compilationResolution private val compilationResolution
get() = nodeJs.npmResolutionManager.requireInstalled()[project][npmProject.compilation] get() = nodeJs.npmResolutionManager.requireInstalled()[project.path][npmProject.compilation]
init { init {
// TODO: temporary workaround for configuration cache enabled builds // TODO: temporary workaround for configuration cache enabled builds
@@ -16,11 +16,11 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
* Info about NPM projects inside particular gradle [project]. * Info about NPM projects inside particular gradle [project].
*/ */
class KotlinProjectNpmResolution( class KotlinProjectNpmResolution(
val project: Project, val project: String,
val npmProjects: List<KotlinCompilationNpmResolution>, val npmProjects: List<KotlinCompilationNpmResolution>,
val taskRequirements: Map<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>> val taskRequirements: Map<RequiresNpmDependencies, Collection<RequiredKotlinJsDependency>>?
) { ) {
val npmProjectsByNpmDependency: Map<NpmDependency, KotlinCompilationNpmResolution> = val npmProjectsByNpmDependency: Map<NpmDependency, KotlinCompilationNpmResolution> by lazy {
mutableMapOf<NpmDependency, KotlinCompilationNpmResolution>().also { result -> mutableMapOf<NpmDependency, KotlinCompilationNpmResolution>().also { result ->
npmProjects.forEach { npmPackage -> npmProjects.forEach { npmPackage ->
npmPackage.externalNpmDependencies.forEach { npmDependency -> npmPackage.externalNpmDependencies.forEach { npmDependency ->
@@ -28,15 +28,16 @@ class KotlinProjectNpmResolution(
} }
} }
} }
}
val byCompilation by lazy { npmProjects.associateBy { it.npmProject.compilation } } val byCompilation by lazy { npmProjects.associateBy { it.npmProject.compilation.name } }
operator fun get(compilation: KotlinJsCompilation): KotlinCompilationNpmResolution { operator fun get(compilation: KotlinJsCompilation): KotlinCompilationNpmResolution {
check(compilation.target.project == project) check(compilation.target.project.path == project)
return byCompilation.getValue(compilation) return byCompilation.getValue(compilation.name)
} }
companion object { companion object {
fun empty(project: Project) = KotlinProjectNpmResolution(project, listOf(), mapOf()) fun empty(project: String) = KotlinProjectNpmResolution(project, listOf(), mapOf())
} }
} }
@@ -9,7 +9,7 @@ import org.gradle.api.Project
internal class KotlinRootNpmResolution( internal class KotlinRootNpmResolution(
val rootProject: Project, val rootProject: Project,
internal val projects: Map<Project, KotlinProjectNpmResolution> internal val projects: Map<String, KotlinProjectNpmResolution>
) { ) {
operator fun get(project: Project) = projects[project] ?: KotlinProjectNpmResolution.empty(project) operator fun get(project: String) = projects[project] ?: KotlinProjectNpmResolution.empty(project)
} }
@@ -25,16 +25,19 @@ import kotlin.reflect.KClass
* See [KotlinNpmResolutionManager] for details about resolution process. * See [KotlinNpmResolutionManager] for details about resolution process.
*/ */
internal class KotlinProjectNpmResolver( internal class KotlinProjectNpmResolver(
@Transient
val project: Project, val project: Project,
val resolver: KotlinRootNpmResolver val resolver: KotlinRootNpmResolver
) { ) {
override fun toString(): String = "ProjectNpmResolver($project)" override fun toString(): String = "ProjectNpmResolver($project)"
private val byCompilation = mutableMapOf<KotlinJsCompilation, KotlinCompilationNpmResolver>() private val projectPath by lazy { project.path }
private val byCompilation = mutableMapOf<String, KotlinCompilationNpmResolver>()
operator fun get(compilation: KotlinJsCompilation): KotlinCompilationNpmResolver { operator fun get(compilation: KotlinJsCompilation): KotlinCompilationNpmResolver {
check(compilation.target.project == project) check(compilation.target.project == project)
return byCompilation[compilation] ?: error("$compilation was not registered in $this") return byCompilation[compilation.name] ?: error("$compilation was not registered in $this")
} }
private var closed = false private var closed = false
@@ -103,7 +106,7 @@ internal class KotlinProjectNpmResolver(
private fun addCompilation(compilation: KotlinJsCompilation) { private fun addCompilation(compilation: KotlinJsCompilation) {
check(!closed) { resolver.alreadyResolvedMessage("add compilation $compilation") } check(!closed) { resolver.alreadyResolvedMessage("add compilation $compilation") }
byCompilation[compilation] = KotlinCompilationNpmResolver(this, compilation) byCompilation[compilation.name] = KotlinCompilationNpmResolver(this, compilation)
} }
fun close(): KotlinProjectNpmResolution { fun close(): KotlinProjectNpmResolution {
@@ -111,9 +114,9 @@ internal class KotlinProjectNpmResolver(
closed = true closed = true
return KotlinProjectNpmResolution( return KotlinProjectNpmResolution(
project, projectPath,
byCompilation.values.mapNotNull { it.close() }, byCompilation.values.mapNotNull { it.close() },
resolver.nodeJs.taskRequirements.byTask resolver.nodeJs.taskRequirements?.byTask
) )
} }
} }
@@ -124,8 +124,8 @@ internal class KotlinRootNpmResolver internal constructor(
} }
} }
open inner class Installation(val projectResolutions: Map<Project, KotlinProjectNpmResolution>) { open inner class Installation(val projectResolutions: Map<String, KotlinProjectNpmResolution>) {
operator fun get(project: Project) = operator fun get(project: String) =
projectResolutions[project] ?: KotlinProjectNpmResolution.empty(project) projectResolutions[project] ?: KotlinProjectNpmResolution.empty(project)
internal fun install( internal fun install(
@@ -30,7 +30,7 @@ open class KotlinNpmInstallTask : DefaultTask() {
init { init {
// TODO: temporary workaround for configuration cache enabled builds // TODO: temporary workaround for configuration cache enabled builds
disableTaskOnConfigurationCacheBuild { resolutionManager.toString() } // disableTaskOnConfigurationCacheBuild { resolutionManager.toString() }
} }
@Input @Input
@@ -107,7 +107,7 @@ open class KotlinPackageJsonTask : DefaultTask() {
task.inputs.file(packageJsonTask.map { it.packageJson }) 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) compilation.compileKotlinTaskProvider.dependsOn(packageJsonTask)
@@ -31,7 +31,7 @@ open class RootPackageJsonTask : DefaultTask() {
init { init {
// TODO: temporary workaround for configuration cache enabled builds // TODO: temporary workaround for configuration cache enabled builds
disableTaskOnConfigurationCacheBuild { resolutionManager.toString() } // disableTaskOnConfigurationCacheBuild { resolutionManager.toString() }
} }
@get:OutputFile @get:OutputFile