[Gradle, JS] Build service npm resolution manager does not contain packageJsonHandlers

^KT-60469 fixed
This commit is contained in:
Ilya Goncharov
2023-08-15 09:10:10 +00:00
committed by Space Team
parent 80200fc3c5
commit a5893d4bee
12 changed files with 55 additions and 48 deletions
@@ -53,7 +53,7 @@ abstract class JsIrConfigurationCacheIT : KGPBaseTest() {
} }
@DisplayName("configuration cache is reused when idea.version system property is changed in browser project") @DisplayName("configuration cache is reused when idea.version system property is changed in browser project")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_7_5) @GradleTestVersions(minVersion = TestVersions.Gradle.G_8_0)
@GradleTest @GradleTest
fun testBrowserDistributionOnIdeaPropertyChange(gradleVersion: GradleVersion) { fun testBrowserDistributionOnIdeaPropertyChange(gradleVersion: GradleVersion) {
project("kotlin-js-browser-project", gradleVersion) { project("kotlin-js-browser-project", gradleVersion) {
@@ -1136,6 +1136,7 @@ class Kotlin2JsIrGradlePluginIT : KGPBaseTest() {
assertEquals(JsonNull.INSTANCE, jso.get("customField2").asJsonNull) assertEquals(JsonNull.INSTANCE, jso.get("customField2").asJsonNull)
assertEquals(JsonNull.INSTANCE, jso.get("customField3").asJsonNull) assertEquals(JsonNull.INSTANCE, jso.get("customField3").asJsonNull)
assertEquals(JsonNull.INSTANCE, jso.get("customField4").asJsonObject.get("foo").asJsonNull) assertEquals(JsonNull.INSTANCE, jso.get("customField4").asJsonObject.get("foo").asJsonNull)
assertEquals("@as/main", jso.get("customField5").asString)
} }
} }
} }
@@ -47,11 +47,13 @@ kotlin {
binaries.executable() binaries.executable()
compilations.named("main") { compilations.named("main") {
val nameOfModule = this@named.name
packageJson { packageJson {
customField("customField1", mapOf("one" to 1, "two" to 2)) customField("customField1", mapOf("one" to 1, "two" to 2))
customField("customField2", null) customField("customField2", null)
customField("customField3" to null) customField("customField3" to null)
customField("customField4", mapOf("foo" to null)) customField("customField4", mapOf("foo" to null))
customField("customField5", "@as/${nameOfModule}")
} }
} }
} }
@@ -9,6 +9,7 @@
package org.jetbrains.kotlin.gradle.plugin.mpp package org.jetbrains.kotlin.gradle.plugin.mpp
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.attributes.AttributeContainer import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions
@@ -78,9 +79,9 @@ open class KotlinJsCompilation @Inject internal constructor(
override val compileTaskProvider: TaskProvider<Kotlin2JsCompile> override val compileTaskProvider: TaskProvider<Kotlin2JsCompile>
get() = compilation.compileTaskProvider as TaskProvider<Kotlin2JsCompile> get() = compilation.compileTaskProvider as TaskProvider<Kotlin2JsCompile>
internal val packageJsonHandlers = mutableListOf<PackageJson.() -> Unit>() internal val packageJsonHandlers = mutableListOf<Action<PackageJson>>()
fun packageJson(handler: PackageJson.() -> Unit) { fun packageJson(handler: Action<PackageJson>) {
packageJsonHandlers.add(handler) packageJsonHandlers.add(handler)
} }
@@ -109,13 +109,6 @@ open class NodeJsRootPlugin : Plugin<Project> {
nodeJs.resolver.close() nodeJs.resolver.close()
} }
) )
it.parameters.packageJsonHandlers.set(
objectFactory.providerWithLazyConvention {
nodeJs.resolver.compilations.associate { compilation ->
"${compilation.project.path}:${compilation.disambiguatedName}" to compilation.packageJsonHandlers
}
}
)
it.parameters.gradleNodeModulesProvider.set(gradleNodeModulesProvider) it.parameters.gradleNodeModulesProvider.set(gradleNodeModulesProvider)
} }
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.services.BuildService import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters import org.gradle.api.services.BuildServiceParameters
@@ -47,9 +46,6 @@ abstract class KotlinNpmResolutionManager : BuildService<KotlinNpmResolutionMana
interface Parameters : BuildServiceParameters { interface Parameters : BuildServiceParameters {
val resolution: Property<KotlinRootNpmResolution> val resolution: Property<KotlinRootNpmResolution>
// pulled up from compilation resolver since it was failing with ClassNotFoundException on deserialization, see KT-49061
val packageJsonHandlers: MapProperty<String, List<PackageJson.() -> Unit>>
val gradleNodeModulesProvider: Property<GradleNodeModulesCache> val gradleNodeModulesProvider: Property<GradleNodeModulesCache>
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.targets.js.npm package org.jetbrains.kotlin.gradle.targets.js.npm
import com.google.gson.* import com.google.gson.*
import org.gradle.api.Action
import org.gradle.api.GradleException import org.gradle.api.GradleException
import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
import java.io.File import java.io.File
@@ -122,7 +123,7 @@ internal fun packageJson(
version: String, version: String,
main: String, main: String,
npmDependencies: Collection<NpmDependencyDeclaration>, npmDependencies: Collection<NpmDependencyDeclaration>,
packageJsonHandlers: List<PackageJson.() -> Unit> packageJsonHandlers: List<Action<PackageJson>>
): PackageJson { ): PackageJson {
val packageJson = PackageJson( val packageJson = PackageJson(
@@ -150,7 +151,7 @@ internal fun packageJson(
} }
packageJsonHandlers.forEach { packageJsonHandlers.forEach {
it(packageJson) it.execute(packageJson)
} }
return packageJson return packageJson
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.gradle.targets.js.npm package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Action
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.OutputFile
@@ -38,22 +41,24 @@ abstract class PublicPackageJsonTask :
@get:Internal @get:Internal
abstract val npmProjectMain: Property<String> abstract val npmProjectMain: Property<String>
private val packageJsonHandlers: List<PackageJson.() -> Unit> @get:Internal
get() = npmResolutionManager.get().parameters.packageJsonHandlers.get() abstract val packageJsonHandlers: ListProperty<Action<PackageJson>>
.getValue("$projectPath:${compilationDisambiguatedName.get()}")
@get:Input @get:Input
val packageJsonCustomFields: Map<String, Any?> internal val packageJsonInputHandlers: Provider<PackageJson> by lazy {
get() = PackageJson(fakePackageJsonValue, fakePackageJsonValue) packageJsonHandlers.map { packageJsonHandlersList ->
.apply { PackageJson(fakePackageJsonValue, fakePackageJsonValue)
packageJsonHandlers.forEach { it() } .apply {
}.customFields packageJsonHandlersList.forEach { it.execute(this) }
}
}
}
private val compilationResolution private val compilationResolution
get() = npmResolutionManager.get().resolution.get()[projectPath][compilationDisambiguatedName.get()] get() = npmResolutionManager.get().resolution.get()[projectPath][compilationDisambiguatedName.get()]
.getResolutionOrPrepare( .getResolutionOrPrepare(
npmResolutionManager.get(), npmResolutionManager.get(),
packageJsonHandlers,
logger logger
) )
@@ -78,7 +83,7 @@ abstract class PublicPackageJsonTask :
projectVersion, projectVersion,
npmProjectMain.get(), npmProjectMain.get(),
externalDependencies, externalDependencies,
packageJsonHandlers packageJsonHandlers.get()
).let { packageJson -> ).let { packageJson ->
packageJson.main = "${npmProjectName.get()}.js" packageJson.main = "${npmProjectName.get()}.js"
@@ -32,7 +32,7 @@ class KotlinRootNpmResolution(
synchronized(projects) { synchronized(projects) {
npmResolutionManager.parameters.gradleNodeModulesProvider.get().close() npmResolutionManager.parameters.gradleNodeModulesProvider.get().close()
val projectResolutions: List<PreparedKotlinCompilationNpmResolution> = projects.values.flatMap { it.npmProjects }.map { it.close(npmResolutionManager, logger) } val projectResolutions: List<PreparedKotlinCompilationNpmResolution> = projects.values.flatMap { it.npmProjects }.map { it.close() }
npmEnvironment.packageManager.prepareRootProject( npmEnvironment.packageManager.prepareRootProject(
npmEnvironment, npmEnvironment,
rootProjectName, rootProjectName,
@@ -5,7 +5,9 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
import org.gradle.api.Action
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.provider.ListProperty
import org.jetbrains.kotlin.gradle.targets.js.nodejs.TasksRequirements 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.*
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.PreparedKotlinCompilationNpmResolution import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.PreparedKotlinCompilationNpmResolution
@@ -39,12 +41,13 @@ class KotlinCompilationNpmResolution(
) )
private var closed = false private var closed = false
private var resolution: PreparedKotlinCompilationNpmResolution? = null internal var resolution: PreparedKotlinCompilationNpmResolution? = null
@Synchronized @Synchronized
fun prepareWithDependencies( fun prepareWithDependencies(
skipWriting: Boolean = false, skipWriting: Boolean = false,
npmResolutionManager: KotlinNpmResolutionManager, npmResolutionManager: KotlinNpmResolutionManager,
packageJsonHandlers: ListProperty<Action<PackageJson>>,
logger: Logger logger: Logger
): PreparedKotlinCompilationNpmResolution { ): PreparedKotlinCompilationNpmResolution {
check(resolution == null) { "$this already resolved" } check(resolution == null) { "$this already resolved" }
@@ -52,6 +55,7 @@ class KotlinCompilationNpmResolution(
return createPreparedResolution( return createPreparedResolution(
skipWriting, skipWriting,
npmResolutionManager, npmResolutionManager,
packageJsonHandlers,
logger logger
).also { ).also {
resolution = it resolution = it
@@ -61,29 +65,29 @@ class KotlinCompilationNpmResolution(
@Synchronized @Synchronized
fun getResolutionOrPrepare( fun getResolutionOrPrepare(
npmResolutionManager: KotlinNpmResolutionManager, npmResolutionManager: KotlinNpmResolutionManager,
packageJsonHandlers: ListProperty<Action<PackageJson>>,
logger: Logger, logger: Logger,
): PreparedKotlinCompilationNpmResolution { ): PreparedKotlinCompilationNpmResolution {
return resolution ?: prepareWithDependencies( return resolution ?: prepareWithDependencies(
skipWriting = true, skipWriting = true,
npmResolutionManager, npmResolutionManager,
packageJsonHandlers,
logger logger
) )
} }
@Synchronized @Synchronized
fun close( fun close(): PreparedKotlinCompilationNpmResolution {
npmResolutionManager: KotlinNpmResolutionManager,
logger: Logger,
): PreparedKotlinCompilationNpmResolution {
check(!closed) { "$this already closed" } check(!closed) { "$this already closed" }
closed = true closed = true
return getResolutionOrPrepare(npmResolutionManager, logger) return resolution!!
} }
fun createPreparedResolution( fun createPreparedResolution(
skipWriting: Boolean, skipWriting: Boolean,
npmResolutionManager: KotlinNpmResolutionManager, npmResolutionManager: KotlinNpmResolutionManager,
packageJsonHandlers: ListProperty<Action<PackageJson>>,
logger: Logger logger: Logger
): PreparedKotlinCompilationNpmResolution { ): PreparedKotlinCompilationNpmResolution {
val rootResolver = npmResolutionManager.parameters.resolution.get() val rootResolver = npmResolutionManager.parameters.resolution.get()
@@ -93,6 +97,7 @@ class KotlinCompilationNpmResolution(
val compilationNpmResolution: KotlinCompilationNpmResolution = rootResolver[it.projectPath][it.compilationName] val compilationNpmResolution: KotlinCompilationNpmResolution = rootResolver[it.projectPath][it.compilationName]
compilationNpmResolution.getResolutionOrPrepare( compilationNpmResolution.getResolutionOrPrepare(
npmResolutionManager, npmResolutionManager,
packageJsonHandlers,
logger logger
) )
} }
@@ -120,20 +125,17 @@ class KotlinCompilationNpmResolution(
val otherNpmDependencies = toolsNpmDependencies + transitiveNpmDependencies val otherNpmDependencies = toolsNpmDependencies + transitiveNpmDependencies
val allNpmDependencies = disambiguateDependencies(externalNpmDependencies, otherNpmDependencies, logger) val allNpmDependencies = disambiguateDependencies(externalNpmDependencies, otherNpmDependencies, logger)
val packageJsonHandlers =
npmResolutionManager.parameters.packageJsonHandlers.get()["$projectPath:${compilationDisambiguatedName}"]
?: emptyList()
val packageJson = packageJson( val packageJson = packageJson(
npmProjectName, npmProjectName,
npmProjectVersion, npmProjectVersion,
npmProjectMain, npmProjectMain,
allNpmDependencies, allNpmDependencies,
packageJsonHandlers packageJsonHandlers.get()
) )
packageJsonHandlers.forEach { packageJsonHandlers.get().forEach {
it(packageJson) it.execute(packageJson)
} }
if (!skipWriting) { if (!skipWriting) {
@@ -72,6 +72,7 @@ class KotlinCompilationNpmResolver(
it.dependsOn(packageJsonTaskHolder) it.dependsOn(packageJsonTaskHolder)
it.compilationDisambiguatedName.set(compilation.disambiguatedName) it.compilationDisambiguatedName.set(compilation.disambiguatedName)
it.packageJsonHandlers.set(compilation.packageJsonHandlers)
it.npmResolutionManager.value(npmResolutionManager) it.npmResolutionManager.value(npmResolutionManager)
.disallowChanges() .disallowChanges()
@@ -5,9 +5,12 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
import org.gradle.api.Action
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.work.DisableCachingByDefault import org.gradle.work.DisableCachingByDefault
import org.gradle.work.NormalizeLineEndings import org.gradle.work.NormalizeLineEndings
@@ -55,19 +58,19 @@ abstract class KotlinPackageJsonTask :
@get:Internal @get:Internal
abstract val compilationDisambiguatedName: Property<String> abstract val compilationDisambiguatedName: Property<String>
private val packageJsonHandlers: List<PackageJson.() -> Unit> @get:Internal
get() = npmResolutionManager.get().parameters.packageJsonHandlers.get() abstract val packageJsonHandlers: ListProperty<Action<PackageJson>>
.getValue("$projectPath:${compilationDisambiguatedName.get()}")
@get:Input @get:Input
val packageJsonCustomFields: Map<String, Any?> by lazy { internal val packageJsonInputHandlers: Provider<PackageJson> by lazy {
PackageJson(fakePackageJsonValue, fakePackageJsonValue) packageJsonHandlers.map { packageJsonHandlersList ->
.apply { PackageJson(fakePackageJsonValue, fakePackageJsonValue)
packageJsonHandlers.forEach { it() } .apply {
}.customFields packageJsonHandlersList.forEach { it.execute(this) }
}
}
} }
@get:Input @get:Input
internal val toolsNpmDependencies: List<String> by lazy { internal val toolsNpmDependencies: List<String> by lazy {
nodeJs.taskRequirements nodeJs.taskRequirements
@@ -112,6 +115,7 @@ abstract class KotlinPackageJsonTask :
npmResolutionManager.get().resolution.get()[projectPath][compilationDisambiguatedName.get()] npmResolutionManager.get().resolution.get()[projectPath][compilationDisambiguatedName.get()]
.prepareWithDependencies( .prepareWithDependencies(
npmResolutionManager = npmResolutionManager.get(), npmResolutionManager = npmResolutionManager.get(),
packageJsonHandlers = packageJsonHandlers,
logger = logger logger = logger
) )
} }
@@ -130,6 +134,7 @@ abstract class KotlinPackageJsonTask :
val gradleNodeModules = GradleNodeModulesCache.registerIfAbsent(project, null, null) val gradleNodeModules = GradleNodeModulesCache.registerIfAbsent(project, null, null)
val packageJsonTask = project.registerTask<KotlinPackageJsonTask>(packageJsonTaskName) { task -> val packageJsonTask = project.registerTask<KotlinPackageJsonTask>(packageJsonTaskName) { task ->
task.compilationDisambiguatedName.set(compilation.disambiguatedName) task.compilationDisambiguatedName.set(compilation.disambiguatedName)
task.packageJsonHandlers.set(compilation.packageJsonHandlers)
task.description = "Create package.json file for $compilation" task.description = "Create package.json file for $compilation"
task.group = NodeJsRootPlugin.TASKS_GROUP_NAME task.group = NodeJsRootPlugin.TASKS_GROUP_NAME