[Gradle, JS] Migrate KotlinWebpack output files configuration to lazy API

#KT-56357 Fixed
This commit is contained in:
Alexander.Likhachev
2023-02-01 15:49:20 +01:00
committed by Space Team
parent ecc1475cb9
commit 6ab64e0f7c
7 changed files with 101 additions and 47 deletions
@@ -5,9 +5,18 @@
package org.jetbrains.kotlin.gradle.targets.js.dsl
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import java.io.File
interface Distribution {
@Deprecated("Use `distributionName` instead", ReplaceWith("distributionName"))
var name: String?
val distributionName: Property<String>
@Deprecated("Use `outputDirectory` instead", ReplaceWith("outputDirectory"))
var directory: File
val outputDirectory: DirectoryProperty
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.Distribution
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsBinaryContainer.Companion.generateBinaryName
import org.jetbrains.kotlin.gradle.targets.js.subtargets.DefaultDistribution
import org.jetbrains.kotlin.gradle.targets.js.subtargets.createDefaultDistribution
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
@@ -32,7 +33,7 @@ sealed class JsIrBinary(
override val mode: KotlinJsBinaryMode
) : JsBinary {
override val distribution: Distribution =
DefaultDistribution(compilation.target.project, name)
createDefaultDistribution(compilation.target.project, name)
val linkTaskName: String = linkTaskName()
@@ -93,9 +94,9 @@ class Executable(
mode
) {
override val distribution: Distribution =
DefaultDistribution(
createDefaultDistribution(
compilation.target.project,
if (mode == KotlinJsBinaryMode.PRODUCTION) null else super.distribution.name
if (mode == KotlinJsBinaryMode.PRODUCTION) null else super.distribution.distributionName
)
val executeTaskBaseName: String =
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
import org.gradle.api.Action
import org.gradle.api.Task
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Copy
import org.gradle.language.base.plugins.LifecycleBasePlugin
@@ -14,6 +15,8 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJsDce
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.distsDirectory
import org.jetbrains.kotlin.gradle.report.BuildMetricsService
import org.jetbrains.kotlin.gradle.targets.js.addWasmExperimentalArguments
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDceDsl
@@ -114,6 +117,8 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
binary as Executable
val mode = binary.mode
val distsDirectory = project.distsDirectory
val archivesName = project.archivesName
val runTask = registerSubTargetTask<KotlinWebpack>(
disambiguateCamelCased(
@@ -123,6 +128,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
listOf(compilation)
) { task ->
task.dependsOn(binary.linkSyncTask)
task.outputDirectory.convention(distsDirectory).finalizeValueOnRead()
webpackMajorVersion.choose(
{ task.args.add(0, "serve") },
@@ -179,7 +185,8 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
inputFilesDirectory = binary.linkSyncTask.map { it.destinationDir },
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
configurationActions = runTaskConfigurations,
nodeJs = nodeJs
nodeJs = nodeJs,
defaultArchivesName = archivesName,
)
}
@@ -206,6 +213,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
binary as Executable
val mode = binary.mode
val archivesName = project.archivesName
val distributeResourcesTask = registerSubTargetTask<Copy>(
disambiguateCamelCased(
@@ -225,7 +233,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
listOf(compilation)
) { task ->
task.description = "build webpack ${mode.name.toLowerCaseAsciiOnly()} bundle"
task._destinationDirectory = binary.distribution.directory
task.outputDirectory.fileValue(binary.distribution.directory).finalizeValueOnRead()
BuildMetricsService.registerIfAbsent(project)?.let {
task.buildMetricsService.value(it)
@@ -243,7 +251,8 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
inputFilesDirectory = binary.linkSyncTask.map { it.destinationDir },
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
configurationActions = webpackTaskConfigurations,
nodeJs = nodeJs
nodeJs = nodeJs,
defaultArchivesName = archivesName,
)
}
@@ -276,7 +285,8 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
inputFilesDirectory: Provider<File>,
entryModuleName: Provider<String>,
configurationActions: List<Action<KotlinWebpack>>,
nodeJs: NodeJsRootExtension
nodeJs: NodeJsRootExtension,
defaultArchivesName: Property<String>,
) {
dependsOn(
nodeJs.npmInstallTaskProvider,
@@ -290,6 +300,8 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
this.entryModuleName.set(entryModuleName)
mainOutputFileName.convention(defaultArchivesName.orElse("main").map { "$it.js" }).finalizeValueOnRead()
configurationActions.forEach { configure ->
configure.execute(this)
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.DEVELOPMENT
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.PRODUCTION
import org.jetbrains.kotlin.gradle.targets.js.subtargets.DefaultDistribution
import org.jetbrains.kotlin.gradle.targets.js.subtargets.KotlinJsSubTarget
import org.jetbrains.kotlin.gradle.targets.js.subtargets.createDefaultDistribution
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import javax.inject.Inject
@@ -116,7 +117,7 @@ constructor(
override val compilation: KotlinJsCompilation = jsCompilation
override val name: String = name
override val mode: KotlinJsBinaryMode = type
override val distribution: Distribution = DefaultDistribution(jsCompilation.target.project)
override val distribution: Distribution = createDefaultDistribution(jsCompilation.target.project)
}
}
)
@@ -6,21 +6,42 @@
package org.jetbrains.kotlin.gradle.targets.js.subtargets
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.distsDirectory
import org.jetbrains.kotlin.gradle.targets.js.dsl.Distribution
import org.jetbrains.kotlin.gradle.utils.property
import java.io.File
internal fun createDefaultDistribution(project: Project, name: String? = null) =
DefaultDistribution(project, project.objects.property(name))
internal fun createDefaultDistribution(project: Project, name: Property<String>?) =
DefaultDistribution(project, project.objects.property<String>().apply {
if (name != null) {
value(name)
}
})
class DefaultDistribution(
private val project: Project,
override var name: String? = null
override val distributionName: Property<String>,
) : Distribution {
@Deprecated("Use `distributionName` instead", ReplaceWith("distributionName"))
override var name: String?
get() = distributionName.orNull
set(value) {
distributionName.set(value)
}
override var directory: File by property {
project.buildDir
.let { buildDir ->
name?.let { buildDir.resolve(it) }
?: project.distsDirectory.asFile.get()
}
}
@Deprecated("Use `outputDirectory` instead", ReplaceWith("outputDirectory"))
override var directory: File
get() = outputDirectory.get().asFile
set(value) {
outputDirectory.set(value)
}
override val outputDirectory: DirectoryProperty = project.objects.directoryProperty().convention(
distributionName.flatMap { project.layout.buildDirectory.dir(it) }.orElse(project.distsDirectory)
)
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.subtargets
import org.gradle.api.Action
import org.gradle.api.Task
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.TaskProvider
import org.gradle.language.base.plugins.LifecycleBasePlugin
@@ -17,6 +18,8 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.isTest
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.distsDirectory
import org.jetbrains.kotlin.gradle.report.BuildMetricsService
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.dsl.*
@@ -47,7 +50,7 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
private val webpackTaskConfigurations: MutableList<Action<KotlinWebpack>> = mutableListOf()
private val runTaskConfigurations: MutableList<Action<KotlinWebpack>> = mutableListOf()
private val dceConfigurations: MutableList<Action<KotlinJsDce>> = mutableListOf()
private val distribution: Distribution = DefaultDistribution(project)
private val distribution: Distribution = createDefaultDistribution(project)
private val propertiesProvider = PropertiesProvider(project)
private val webpackMajorVersion
get() = propertiesProvider.webpackMajorVersion
@@ -142,6 +145,8 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
compilation.binaries
.all { binary ->
val type = binary.mode
val distsDirectory = project.distsDirectory
val archivesName = project.archivesName
val runTask = registerSubTargetTask<KotlinWebpack>(
disambiguateCamelCased(
@@ -150,6 +155,7 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
),
listOf(compilation)
) { task ->
task.outputDirectory.convention(distsDirectory).finalizeValueOnRead()
webpackMajorVersion.choose(
{ task.args.add(0, "serve") },
{ task.bin = "webpack-dev-server/bin/webpack-dev-server.js" }
@@ -186,7 +192,8 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
devDceTaskProvider = devDceTaskProvider,
mode = type,
configurationActions = runTaskConfigurations,
nodeJs = nodeJs
nodeJs = nodeJs,
defaultArchivesName = archivesName,
)
}
@@ -224,6 +231,7 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
compilation.binaries
.all { binary ->
val type = binary.mode
val archivesName = project.archivesName
val webpackTask = registerSubTargetTask<KotlinWebpack>(
disambiguateCamelCased(
@@ -238,7 +246,7 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
)
task.description = "build webpack ${type.name.toLowerCaseAsciiOnly()} bundle"
task._destinationDirectory = distribution.directory
task.outputDirectory.fileValue(distribution.directory).finalizeValueOnRead()
BuildMetricsService.registerIfAbsent(project)?.let {
task.buildMetricsService.value(it)
@@ -250,7 +258,8 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
devDceTaskProvider = devDceTaskProvider,
mode = type,
configurationActions = webpackTaskConfigurations,
nodeJs = nodeJs
nodeJs = nodeJs,
defaultArchivesName = archivesName,
)
}
@@ -277,7 +286,8 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
devDceTaskProvider: TaskProvider<KotlinJsDceTask>,
mode: KotlinJsBinaryMode,
configurationActions: List<Action<KotlinWebpack>>,
nodeJs: NodeJsRootExtension
nodeJs: NodeJsRootExtension,
defaultArchivesName: Property<String>,
) {
dependsOn(
nodeJs.npmInstallTaskProvider,
@@ -310,6 +320,8 @@ abstract class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
resolveFromModulesFirst = true
mainOutputFileName.convention(defaultArchivesName.orElse("main").map { "$it.js" }).finalizeValueOnRead()
configurationActions.forEach { configure ->
configure.execute(this)
}
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.distsDirectory
import org.jetbrains.kotlin.gradle.report.UsesBuildMetricsService
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWebpackRulesContainer
@@ -42,6 +41,7 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode
import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.injected
import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
import java.io.File
import javax.inject.Inject
@@ -140,36 +140,34 @@ constructor(
)
@get:Internal
@Deprecated("use destinationDirectory instead", ReplaceWith("destinationDirectory"))
val outputPath: File
get() = destinationDirectory
@get:Internal
internal var _destinationDirectory: File? = null
private val defaultDestinationDirectory by lazy {
project.distsDirectory.asFile.get()
}
@get:OutputDirectory
@Deprecated("Use `outputDirectory` instead", ReplaceWith("outputDirectory"))
var destinationDirectory: File
get() = _destinationDirectory ?: defaultDestinationDirectory
get() = outputDirectory.asFile.get()
set(value) {
_destinationDirectory = value
outputDirectory.set(value)
}
private val defaultOutputFileName by lazy {
project.archivesName.orNull + ".js"
}
@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty
@get:Internal
var outputFileName: String by property {
defaultOutputFileName
}
@Deprecated("Use `mainOutputFileName` instead", ReplaceWith("mainOutputFileName"))
var outputFileName: String
get() = mainOutputFileName.get()
set(value) {
mainOutputFileName.set(value)
}
@get:Internal
abstract val mainOutputFileName: Property<String>
@get:Internal
@Deprecated("Use `mainOutputFile` instead", ReplaceWith("mainOutputFile"))
open val outputFile: File
get() = destinationDirectory.resolve(outputFileName)
get() = mainOutputFile.get().asFile
@get:Internal
val mainOutputFile: Provider<RegularFile> = objects.providerWithLazyConvention { outputDirectory.file(mainOutputFileName) }.flatMap { it }
private val projectDir = project.projectDir
@@ -220,7 +218,7 @@ constructor(
}
/**
* [forNpmDependencies] is used to avoid querying [destinationDirectory] before task execution.
* [forNpmDependencies] is used to avoid querying [outputDirectory] before task execution.
* Otherwise, Gradle will fail the build.
*/
private fun createWebpackConfig(forNpmDependencies: Boolean = false) = KotlinWebpackConfig(
@@ -228,8 +226,8 @@ constructor(
mode = mode,
entry = if (forNpmDependencies) null else entry.get().asFile,
output = output,
outputPath = if (forNpmDependencies) null else destinationDirectory,
outputFileName = outputFileName,
outputPath = if (forNpmDependencies) null else outputDirectory.get().asFile,
outputFileName = mainOutputFileName.get(),
configDirectory = configDirectory,
rules = rules,
devServer = devServer,
@@ -298,7 +296,7 @@ constructor(
).execute(services)
val buildMetrics = metrics.get()
destinationDirectory.walkTopDown()
outputDirectory.get().asFile.walkTopDown()
.filter { it.isFile }
.filter { it.extension == "js" }
.map { it.length() }