[Gradle, JS] Remove redundant composites in K/JS Gradle Plugin

KT-47351
This commit is contained in:
Ilya Goncharov
2023-03-23 10:13:00 +00:00
committed by Space Team
parent 9407ec35e3
commit d14a55d775
12 changed files with 5 additions and 242 deletions
@@ -11,7 +11,6 @@ import org.gradle.api.Task
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.targets.js.MultiplePluginDeclarationDetector
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.npm.UsesKotlinNpmResolutionManager
@@ -62,17 +61,10 @@ open class NodeJsRootPlugin : Plugin<Project> {
nodeJs.nodeModulesGradleCacheDir
)
val compositeNodeModulesProvider: Provider<CompositeNodeModulesCache> = CompositeNodeModulesCache.registerIfAbsent(
project,
project.projectDir,
nodeJs.nodeModulesGradleCacheDir
)
val setupFileHasherTask = project.registerTask<KotlinNpmCachesSetup>(KotlinNpmCachesSetup.NAME) {
it.description = "Setup file hasher for caches"
it.gradleNodeModules.set(gradleNodeModulesProvider)
it.compositeNodeModules.set(compositeNodeModulesProvider)
}
val npmInstall = project.registerTask<KotlinNpmInstallTask>(KotlinNpmInstallTask.NAME) {
@@ -122,7 +114,6 @@ open class NodeJsRootPlugin : Plugin<Project> {
}
)
it.parameters.gradleNodeModulesProvider.set(gradleNodeModulesProvider)
it.parameters.compositeNodeModulesProvider.set(compositeNodeModulesProvider)
}
YarnPlugin.apply(project)
@@ -157,13 +148,6 @@ open class NodeJsRootPlugin : Plugin<Project> {
null
)
private val Project.compositeNodeModules
get() = CompositeNodeModulesCache.registerIfAbsent(
this,
null,
null
)
val Project.kotlinNpmResolutionManager: Provider<KotlinNpmResolutionManager>
get() {
val npmResolutionManager = project.gradle.sharedServices.registerIfAbsent(
@@ -177,7 +161,6 @@ open class NodeJsRootPlugin : Plugin<Project> {
project.tasks.withType<UsesKotlinNpmResolutionManager>().configureEach { task ->
task.usesService(npmResolutionManager)
task.usesService(gradleNodeModules)
task.usesService(compositeNodeModules)
}
}
@@ -1,45 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.targets.js.npm
import java.io.File
/**
* Creates fake NodeJS module directory from given composite [dependency].
*/
internal class CompositeNodeModuleBuilder(
val srcDir: File,
val cacheDir: File
) {
var srcPackageJsonFile: File = srcDir
fun rebuild(): File? {
check(srcPackageJsonFile.isFile) {
"Unable to read package.json of composite build"
}
val packageJson = fromSrcPackageJson(srcPackageJsonFile)!!
// yarn requires semver
packageJson.version = fixSemver(packageJson.version)
val importedPackageDir = importedPackageDir(cacheDir, packageJson.name, packageJson.version)
packageJson.main = srcDir.parentFile.resolve(packageJson.main!!)
.relativeToOrNull(importedPackageDir)
?.path
?: throw IllegalStateException("Unable to link composite builds for Kotlin/JS which have different roots")
return makeNodeModule(cacheDir, packageJson)
}
}
private fun makeNodeModule(
container: File,
packageJson: PackageJson
): File {
return makeNodeModule(container, packageJson) {}
}
@@ -1,77 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Internal
import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.SingleActionPerProject
import java.io.File
internal interface UsesCompositeNodeModulesCache : Task {
@get:Internal
val compositeNodeModules: Property<CompositeNodeModulesCache>
}
/**
* Cache for storing already created [GradleNodeModule]s
*/
abstract class CompositeNodeModulesCache : AbstractNodeModulesCache() {
override val type: String
get() = "composite"
override fun buildImportedPackage(
name: String,
version: String,
file: File
): File? {
val module = CompositeNodeModuleBuilder(file, parameters.cacheDir.get().asFile)
return module.rebuild()
}
companion object {
private val serviceClass = CompositeNodeModulesCache::class.java
private val serviceName = serviceClass.name
private fun registerIfAbsentImpl(
project: Project,
rootProjectDir: File?,
cacheDir: File?
): Provider<CompositeNodeModulesCache> {
project.gradle.sharedServices.registrations.findByName(serviceName)?.let {
@Suppress("UNCHECKED_CAST")
return it.service as Provider<CompositeNodeModulesCache>
}
val message = {
"Build service Composite Node Modules should be already registered"
}
requireNotNull(rootProjectDir, message)
requireNotNull(cacheDir, message)
return project.gradle.sharedServices.registerIfAbsent(serviceName, serviceClass) {
it.parameters.rootProjectDir.set(rootProjectDir)
it.parameters.cacheDir.set(cacheDir)
}
}
fun registerIfAbsent(
project: Project,
rootProjectDir: File?,
cacheDir: File?
) = registerIfAbsentImpl(project, rootProjectDir, cacheDir).also { serviceProvider ->
SingleActionPerProject.run(project, UsesCompositeNodeModulesCache::class.java.name) {
project.tasks.withType<UsesCompositeNodeModulesCache>().configureEach { task ->
task.usesService(serviceProvider)
}
}
}
}
}
@@ -51,7 +51,6 @@ abstract class KotlinNpmResolutionManager : BuildService<KotlinNpmResolutionMana
val packageJsonHandlers: MapProperty<String, List<PackageJson.() -> Unit>>
val gradleNodeModulesProvider: Property<GradleNodeModulesCache>
val compositeNodeModulesProvider: Property<CompositeNodeModulesCache>
}
val resolution
@@ -31,7 +31,6 @@ class KotlinRootNpmResolution(
): Installation {
synchronized(projects) {
npmResolutionManager.parameters.gradleNodeModulesProvider.get().close()
npmResolutionManager.parameters.compositeNodeModulesProvider.get().close()
val projectResolutions: List<PreparedKotlinCompilationNpmResolution> = projects.values.flatMap { it.npmProjects }.map { it.close(npmResolutionManager, logger) }
npmEnvironment.packageManager.prepareRootProject(
@@ -14,7 +14,6 @@ import java.io.Serializable
*/
class PreparedKotlinCompilationNpmResolution(
val npmProjectDir: File,
val internalCompositeDependencies: Collection<GradleNodeModule>,
val externalGradleDependencies: Collection<GradleNodeModule>,
val externalNpmDependencies: Collection<NpmDependencyDeclaration>,
) : Serializable
@@ -15,7 +15,6 @@ import java.io.File
class KotlinCompilationNpmResolution(
var internalDependencies: Collection<InternalDependency>,
var internalCompositeDependencies: Collection<CompositeDependency>,
var externalGradleDependencies: Collection<FileExternalGradleDependency>,
var externalNpmDependencies: Collection<NpmDependencyDeclaration>,
var fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>,
@@ -34,7 +33,6 @@ class KotlinCompilationNpmResolution(
val inputs: PackageJsonProducerInputs
get() = PackageJsonProducerInputs(
internalDependencies.map { it.projectName },
internalCompositeDependencies.flatMap { it.getPackages() },
externalGradleDependencies.map { it.file },
externalNpmDependencies.map { it.uniqueRepresentation() },
fileCollectionDependencies.flatMap { it.files }
@@ -115,17 +113,6 @@ class KotlinCompilationNpmResolution(
it.dependencies
}.filter { it.scope != NpmDependency.Scope.DEV }
val compositeDependencies = internalCompositeDependencies.flatMap { dependency ->
dependency.getPackages()
.map { file ->
npmResolutionManager.parameters.compositeNodeModulesProvider.get().get(
dependency.dependencyName,
dependency.dependencyVersion,
file
)
}
}.filterNotNull()
val toolsNpmDependencies = tasksRequirements
.getCompilationNpmRequirements(projectPath, compilationDisambiguatedName)
@@ -143,10 +130,6 @@ class KotlinCompilationNpmResolution(
packageJsonHandlers
)
compositeDependencies.forEach {
packageJson.dependencies[it.name] = it.version
}
packageJsonHandlers.forEach {
it(packageJson)
}
@@ -157,7 +140,6 @@ class KotlinCompilationNpmResolution(
return PreparedKotlinCompilationNpmResolution(
npmProjectDir,
compositeDependencies,
importedExternalGradleDependencies,
allNpmDependencies,
)
@@ -144,7 +144,6 @@ class KotlinCompilationNpmResolver(
inner class ConfigurationVisitor {
private val internalDependencies = mutableSetOf<InternalDependency>()
private val internalCompositeDependencies = mutableSetOf<CompositeDependency>()
private val externalGradleDependencies = mutableSetOf<ExternalGradleDependency>()
private val externalNpmDependencies = mutableSetOf<NpmDependencyDeclaration>()
private val fileCollectionDependencies = mutableSetOf<FileCollectionExternalGradleDependency>()
@@ -244,7 +243,6 @@ class KotlinCompilationNpmResolver(
fun toPackageJsonProducer() = KotlinCompilationNpmResolution(
internalDependencies,
internalCompositeDependencies,
externalGradleDependencies.map {
FileExternalGradleDependency(
it.dependency.moduleName,
@@ -13,12 +13,6 @@ class PackageJsonProducerInputs(
@get:Input
val internalDependencies: Collection<String>,
@get:PathSensitive(PathSensitivity.ABSOLUTE)
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
@get:InputFiles
val internalCompositeDependencies: Collection<File>,
@get:PathSensitive(PathSensitivity.ABSOLUTE)
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
@@ -6,20 +6,14 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.hash.FileHasher
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.UsesCompositeNodeModulesCache
import org.jetbrains.kotlin.gradle.targets.js.npm.UsesGradleNodeModulesCache
import javax.inject.Inject
abstract class KotlinNpmCachesSetup :
DefaultTask(),
UsesGradleNodeModulesCache,
UsesCompositeNodeModulesCache {
UsesGradleNodeModulesCache {
@get:Inject
open val fileHasher: FileHasher
get() = throw UnsupportedOperationException()
@@ -27,7 +21,6 @@ abstract class KotlinNpmCachesSetup :
@TaskAction
fun setup() {
gradleNodeModules.get().fileHasher = fileHasher
compositeNodeModules.get().fileHasher = fileHasher
}
companion object {
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.
import org.jetbrains.kotlin.gradle.targets.js.npm.*
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinCompilationNpmResolver
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.PACKAGE_JSON_UMBRELLA_TASK_NAME
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.PackageJsonProducerInputs
import org.jetbrains.kotlin.gradle.tasks.registerTask
import java.io.File
@@ -26,8 +25,7 @@ import java.io.File
abstract class KotlinPackageJsonTask :
DefaultTask(),
UsesKotlinNpmResolutionManager,
UsesGradleNodeModulesCache,
UsesCompositeNodeModulesCache {
UsesGradleNodeModulesCache {
// Only in configuration phase
// Not part of configuration caching
@@ -43,9 +41,6 @@ abstract class KotlinPackageJsonTask :
private fun findDependentTasks(): Collection<Any> =
compilationResolver.compilationNpmResolution.internalDependencies.map { dependency ->
nodeJs.resolver[dependency.projectPath][dependency.compilationName].npmProject.packageJsonTaskPath
} + compilationResolver.compilationNpmResolution.internalCompositeDependencies.map { dependency ->
dependency.includedBuild?.task(":$PACKAGE_JSON_UMBRELLA_TASK_NAME") ?: error("includedBuild instance is not available")
dependency.includedBuild.task(":${RootPackageJsonTask.NAME}")
}
// -----
@@ -115,7 +110,6 @@ abstract class KotlinPackageJsonTask :
val packageJsonUmbrella = nodeJsTaskProviders.packageJsonUmbrellaTaskProvider
val npmResolutionManager = project.kotlinNpmResolutionManager
val gradleNodeModules = GradleNodeModulesCache.registerIfAbsent(project, null, null)
val compositeNodeModules = CompositeNodeModulesCache.registerIfAbsent(project, null, null)
val packageJsonTask = project.registerTask<KotlinPackageJsonTask>(packageJsonTaskName) { task ->
task.compilationDisambiguatedName.set(compilation.disambiguatedName)
task.description = "Create package.json file for $compilation"
@@ -127,9 +121,6 @@ abstract class KotlinPackageJsonTask :
task.gradleNodeModules.value(gradleNodeModules)
.disallowChanges()
task.compositeNodeModules.value(compositeNodeModules)
.disallowChanges()
task.packageJson.set(compilation.npmProject.packageJsonFile)
task.onlyIf {
@@ -5,12 +5,8 @@
package org.jetbrains.kotlin.gradle.targets.js.yarn
import com.google.gson.Gson
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
import org.jetbrains.kotlin.gradle.targets.js.npm.fileVersion
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.PreparedKotlinCompilationNpmResolution
import java.io.File
@@ -25,22 +21,13 @@ class YarnImportedPackagesVersionResolver(
it.externalGradleDependencies
}
private val internalCompositeModules = npmProjects.flatMapTo(mutableSetOf()) {
it.internalCompositeDependencies
}
fun resolveAndUpdatePackages(): MutableList<String> {
resolve(externalModules, true)
resolve(internalCompositeModules, true)
if (resolvedVersion.isNotEmpty()) {
updatePackages(internalCompositeModules)
}
resolve(externalModules)
return importedProjectWorkspaces
}
private fun resolve(modules: MutableSet<GradleNodeModule>, isWorkspace: Boolean) {
private fun resolve(modules: MutableSet<GradleNodeModule>) {
modules.groupBy { it.name }.forEach { (name, versions) ->
val selected: GradleNodeModule = if (versions.size > 1) {
val sorted = versions.sortedBy { it.semver }
@@ -56,49 +43,9 @@ class YarnImportedPackagesVersionResolver(
selected
} else versions.single()
if (isWorkspace) {
importedProjectWorkspaces.add(selected.path.relativeTo(nodeJsWorldDir).path)
}
importedProjectWorkspaces.add(selected.path.relativeTo(nodeJsWorldDir).path)
}
}
private fun updatePackages(modules: MutableSet<GradleNodeModule>) {
modules.forEach {
val packageJsonFile = it.path.resolve(NpmProject.PACKAGE_JSON)
val packageJson = packageJsonFile.reader().use {
Gson().fromJson<PackageJson>(it, PackageJson::class.java)
}
writePackageJson(
packageJson = packageJson,
path = packageJsonFile,
forceWrite = false
)
}
}
private fun writePackageJson(
packageJson: PackageJson,
path: File,
forceWrite: Boolean
) {
val updates = listOf(packageJson.dependencies, packageJson.devDependencies).map { updateVersionsMap(it) }
if (forceWrite || updates.any { it }) {
packageJson.saveTo(path)
}
}
private fun updateVersionsMap(map: MutableMap<String, String>): Boolean {
var doneSomething = false
map.iterator().forEachRemaining {
val resolved = resolvedVersion[it.key]
if (resolved != null && it.value != resolved.version) {
it.setValue(fileVersion(resolved.file))
doneSomething = true
}
}
return doneSomething
}
}
private data class ResolvedNpmDependency(