[Gradle, JS] Migrate onto usage of layout.buildDir provider in NPM infrastructure.

Api which previously used buildDirectory now migrated to Provider as well, previous properties are deprecated.

^KT-61294 fixed


Co-authored-by: Alexander Likhachev <Alexander.Likhachev@jetbrains.com>
This commit is contained in:
Ilya Goncharov
2023-12-11 10:56:28 +00:00
committed by Space Team
parent ef53bd9548
commit 7b409d0505
27 changed files with 237 additions and 139 deletions
@@ -89,30 +89,7 @@ class BrokenLazyConfigurationIT : KGPBaseTest() {
""".trimIndent() """.trimIndent()
) )
build("build") { build("build") {
try { assertDirectoryInProjectDoesNotExist("build")
assertDirectoryInProjectDoesNotExist("build")
assert(false) // The assertion above now fails. This line is to ensure try-catch is removed after fixing related issues
} catch (e: AssertionError) {
val expectedTopLevelSubdirectoriesMapping = mapOf(
"js" to "KT-61294",
)
val expectedTopLevelSubdirectories = expectedTopLevelSubdirectoriesMapping.keys
val actualTopLevelDirectories =
e.message?.lines()?.filter { it.startsWith(" ") }?.map { it.replace("\\", "").trim() }?.toSet() ?: emptySet()
val fixed = expectedTopLevelSubdirectories - actualTopLevelDirectories
val new = actualTopLevelDirectories - expectedTopLevelSubdirectories
if (fixed.isNotEmpty()) {
throw Exception(
"Please remove the tests workaround for ${
fixed.map(expectedTopLevelSubdirectoriesMapping::get).joinToString(" and ")
} as seems like it's not anymore required", e
)
}
if (new.isNotEmpty()) {
throw Exception("Unexpected new top level files and/or directories are found: ${new.joinToString(",")}", e)
}
}
assertDirectoryInProjectExists("build2") assertDirectoryInProjectExists("build2")
} }
@@ -100,7 +100,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
} }
override fun configureRun( override fun configureRun(
compilation: KotlinJsIrCompilation compilation: KotlinJsIrCompilation,
) { ) {
val commonRunTask = registerSubTargetTask<Task>(disambiguateCamelCased(RUN_TASK_NAME)) {} val commonRunTask = registerSubTargetTask<Task>(disambiguateCamelCased(RUN_TASK_NAME)) {}
@@ -125,18 +125,23 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
task.description = "start ${mode.name.toLowerCaseAsciiOnly()} webpack dev server" task.description = "start ${mode.name.toLowerCaseAsciiOnly()} webpack dev server"
val npmProject = compilation.npmProject val npmProject = compilation.npmProject
task.devServer = KotlinWebpackConfig.DevServer( val resourcesDir = compilation.output.resourcesDir
open = true, task.devServerProperty.convention(
static = mutableListOf( npmProject.dist.zip(npmProject.dir) { distDirectory, dir ->
npmProject.dist.normalize().relativeOrAbsolute(npmProject.dir), KotlinWebpackConfig.DevServer(
compilation.output.resourcesDir.relativeOrAbsolute(npmProject.dir), open = true,
), static = mutableListOf(
client = KotlinWebpackConfig.DevServer.Client( distDirectory.asFile.normalize().relativeOrAbsolute(dir.asFile),
KotlinWebpackConfig.DevServer.Client.Overlay( resourcesDir.relativeOrAbsolute(dir.asFile),
errors = true, ),
warnings = false client = KotlinWebpackConfig.DevServer.Client(
KotlinWebpackConfig.DevServer.Client.Overlay(
errors = true,
warnings = false
)
)
) )
) }
) )
task.watchOptions = KotlinWebpackConfig.WatchOptions( task.watchOptions = KotlinWebpackConfig.WatchOptions(
@@ -167,7 +172,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
} }
override fun configureBuild( override fun configureBuild(
compilation: KotlinJsIrCompilation compilation: KotlinJsIrCompilation,
) { ) {
val project = compilation.target.project val project = compilation.target.project
@@ -302,7 +307,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
private fun <T> getByKind( private fun <T> getByKind(
kind: KotlinJsBinaryMode, kind: KotlinJsBinaryMode,
releaseValue: T, releaseValue: T,
debugValue: T debugValue: T,
): T = when (kind) { ): T = when (kind) {
KotlinJsBinaryMode.PRODUCTION -> releaseValue KotlinJsBinaryMode.PRODUCTION -> releaseValue
KotlinJsBinaryMode.DEVELOPMENT -> debugValue KotlinJsBinaryMode.DEVELOPMENT -> debugValue
@@ -184,7 +184,7 @@ constructor(
task.from.from(project.tasks.named(compilation.processResourcesTaskName)) task.from.from(project.tasks.named(compilation.processResourcesTaskName))
task.destinationDirectory.set(npmProject.dist) task.destinationDirectory.set(npmProject.dist.mapToFile())
} }
} }
@@ -109,7 +109,7 @@ constructor(
it.nodeJs = nodeJs it.nodeJs = nodeJs
it.executable = nodeJs.requireConfigured().nodeExecutable it.executable = nodeJs.requireConfigured().nodeExecutable
if ((compilation.target as? KotlinJsIrTarget)?.wasmTargetType != KotlinWasmTargetType.WASI) { if ((compilation.target as? KotlinJsIrTarget)?.wasmTargetType != KotlinWasmTargetType.WASI) {
it.workingDir = npmProject.dir it.workingDir(npmProject.dir)
it.dependsOn( it.dependsOn(
nodeJsTaskProviders.npmInstallTaskProvider, nodeJsTaskProviders.npmInstallTaskProvider,
nodeJsTaskProviders.storeYarnLockTaskProvider, nodeJsTaskProviders.storeYarnLockTaskProvider,
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.logging.kotlinInfo import org.jetbrains.kotlin.gradle.logging.kotlinInfo
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
@@ -21,6 +23,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask
import org.jetbrains.kotlin.gradle.targets.js.yarn.Yarn import org.jetbrains.kotlin.gradle.targets.js.yarn.Yarn
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockCopyTask
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import org.jetbrains.kotlin.gradle.utils.getFile
import org.jetbrains.kotlin.gradle.utils.property import org.jetbrains.kotlin.gradle.utils.property
import java.io.File import java.io.File
@@ -95,13 +98,34 @@ open class NodeJsRootExtension(
lateinit var resolver: KotlinRootNpmResolver lateinit var resolver: KotlinRootNpmResolver
val rootPackageDir: File = project.buildDir.resolve("js") val rootPackageDirectory: Provider<Directory> = project.layout.buildDirectory.dir("js")
@Deprecated(
"This property is deprecated and will be removed in future. Use rootPackageDirectory instead",
replaceWith = ReplaceWith("rootPackageDirectory")
)
val rootPackageDir: File
get() = rootPackageDirectory.getFile()
val projectPackagesDirectory: Provider<Directory>
get() = rootPackageDirectory.map { it.dir("packages") }
@Deprecated(
"This property is deprecated and will be removed in future. Use projectPackagesDirectory instead",
replaceWith = ReplaceWith("projectPackagesDirectory")
)
val projectPackagesDir: File val projectPackagesDir: File
get() = rootPackageDir.resolve("packages") get() = projectPackagesDirectory.getFile()
val nodeModulesGradleCacheDirectory: Provider<Directory>
get() = rootPackageDirectory.map { it.dir("packages_imported") }
@Deprecated(
"This property is deprecated and will be removed in future. Use nodeModulesGradleCacheDirectory instead",
replaceWith = ReplaceWith("nodeModulesGradleCacheDirectory")
)
val nodeModulesGradleCacheDir: File val nodeModulesGradleCacheDir: File
get() = rootPackageDir.resolve("packages_imported") get() = nodeModulesGradleCacheDirectory.getFile()
internal val platform: org.gradle.api.provider.Property<Platform> = project.objects.property<Platform>() internal val platform: org.gradle.api.provider.Property<Platform> = project.objects.property<Platform>()
@@ -130,7 +154,7 @@ open class NodeJsRootExtension(
return NodeJsEnv( return NodeJsEnv(
download = download, download = download,
cleanableStore = cleanableStore, cleanableStore = cleanableStore,
rootPackageDir = rootPackageDir, rootPackageDir = rootPackageDirectory.getFile(),
dir = nodeDir, dir = nodeDir,
nodeBinDir = nodeBinDir, nodeBinDir = nodeBinDir,
nodeExecutable = getExecutable("node", nodeCommand, "exe"), nodeExecutable = getExecutable("node", nodeCommand, "exe"),
@@ -57,7 +57,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
val gradleNodeModulesProvider: Provider<GradleNodeModulesCache> = GradleNodeModulesCache.registerIfAbsent( val gradleNodeModulesProvider: Provider<GradleNodeModulesCache> = GradleNodeModulesCache.registerIfAbsent(
project, project,
project.projectDir, project.projectDir,
nodeJs.nodeModulesGradleCacheDir nodeJs.nodeModulesGradleCacheDirectory
) )
val setupFileHasherTask = project.registerTask<KotlinNpmCachesSetup>(KotlinNpmCachesSetup.NAME) { val setupFileHasherTask = project.registerTask<KotlinNpmCachesSetup>(KotlinNpmCachesSetup.NAME) {
@@ -80,7 +80,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
} }
npmInstall.outputs.upToDateWhen { npmInstall.outputs.upToDateWhen {
npmInstall.nodeModules.exists() npmInstall.nodeModules.getFile().exists()
} }
} }
@@ -91,7 +91,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
project.version.toString(), project.version.toString(),
TasksRequirements(), TasksRequirements(),
nodeJs.versions, nodeJs.versions,
nodeJs.projectPackagesDir, nodeJs.projectPackagesDirectory,
nodeJs.rootProjectDir, nodeJs.rootProjectDir,
) )
@@ -108,6 +108,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
} }
) )
it.parameters.gradleNodeModulesProvider.set(gradleNodeModulesProvider) it.parameters.gradleNodeModulesProvider.set(gradleNodeModulesProvider)
it.parameters.packagesDir.set(nodeJs.projectPackagesDirectory)
} }
YarnPlugin.apply(project) YarnPlugin.apply(project)
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.file.ArchiveOperations import org.gradle.api.file.ArchiveOperations
import org.gradle.api.file.Directory
import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Internal
@@ -53,7 +55,7 @@ abstract class GradleNodeModulesCache : AbstractNodeModulesCache() {
private fun registerIfAbsentImpl( private fun registerIfAbsentImpl(
project: Project, project: Project,
rootProjectDir: File?, rootProjectDir: File?,
cacheDir: File? cacheDir: Provider<Directory>?
): Provider<GradleNodeModulesCache> { ): Provider<GradleNodeModulesCache> {
project.gradle.sharedServices.registrations.findByName(serviceName)?.let { project.gradle.sharedServices.registrations.findByName(serviceName)?.let {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -76,7 +78,7 @@ abstract class GradleNodeModulesCache : AbstractNodeModulesCache() {
fun registerIfAbsent( fun registerIfAbsent(
project: Project, project: Project,
rootProjectDir: File?, rootProjectDir: File?,
cacheDir: File? cacheDir: Provider<Directory>?
) = registerIfAbsentImpl(project, rootProjectDir, cacheDir).also { serviceProvider -> ) = registerIfAbsentImpl(project, rootProjectDir, cacheDir).also { serviceProvider ->
SingleActionPerProject.run(project, UsesGradleNodeModulesCache::class.java.name) { SingleActionPerProject.run(project, UsesGradleNodeModulesCache::class.java.name) {
project.tasks.withType<UsesGradleNodeModulesCache>().configureEach { task -> project.tasks.withType<UsesGradleNodeModulesCache>().configureEach { task ->
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.npm package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.services.BuildService import org.gradle.api.services.BuildService
@@ -47,11 +49,16 @@ abstract class KotlinNpmResolutionManager : BuildService<KotlinNpmResolutionMana
val resolution: Property<KotlinRootNpmResolution> val resolution: Property<KotlinRootNpmResolution>
val gradleNodeModulesProvider: Property<GradleNodeModulesCache> val gradleNodeModulesProvider: Property<GradleNodeModulesCache>
val packagesDir: DirectoryProperty
} }
val resolution val resolution
get() = parameters.resolution get() = parameters.resolution
val packagesDir
get() = parameters.packagesDir
@Volatile @Volatile
var state: ResolutionState = ResolutionState.Configuring(resolution.get()) var state: ResolutionState = ResolutionState.Configuring(resolution.get())
@@ -6,6 +6,9 @@
package org.jetbrains.kotlin.gradle.targets.js.npm package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.gradle.process.ExecSpec import org.gradle.process.ExecSpec
import org.jetbrains.kotlin.gradle.dsl.JsModuleKind import org.jetbrains.kotlin.gradle.dsl.JsModuleKind
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
@@ -16,6 +19,7 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
import org.jetbrains.kotlin.gradle.utils.getFile
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import java.io.File import java.io.File
import java.io.Serializable import java.io.Serializable
@@ -52,9 +56,7 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
project.rootProject.kotlinNodeJsExtension project.rootProject.kotlinNodeJsExtension
} }
val dir: File by lazy { val dir: Provider<Directory> = nodeJs.projectPackagesDirectory.map { it.dir(name) }
nodeJs.projectPackagesDir.resolve(name)
}
val target: KotlinJsTargetDsl val target: KotlinJsTargetDsl
get() = compilation.target as KotlinJsTargetDsl get() = compilation.target as KotlinJsTargetDsl
@@ -63,10 +65,10 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
get() = target.project get() = target.project
val nodeModulesDir val nodeModulesDir
get() = dir.resolve(NODE_MODULES) get() = dir.map { it.dir(NODE_MODULES) }
val packageJsonFile: File val packageJsonFile: Provider<RegularFile>
get() = dir.resolve(PACKAGE_JSON) get() = dir.map { it.file(PACKAGE_JSON) }
val packageJsonTaskName: String val packageJsonTaskName: String
get() = compilation.disambiguateName("packageJson") get() = compilation.disambiguateName("packageJson")
@@ -78,8 +80,8 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
packageJsonTask.path packageJsonTask.path
} }
val dist: File val dist: Provider<Directory>
get() = dir.resolve(DIST_FOLDER) get() = dir.map { it.dir(DIST_FOLDER) }
val main: String val main: String
get() = "${DIST_FOLDER}/$name$extension" get() = "${DIST_FOLDER}/$name$extension"
@@ -88,7 +90,7 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
get() = compilation.disambiguateName(PublicPackageJsonTask.NAME) get() = compilation.disambiguateName(PublicPackageJsonTask.NAME)
internal val modules by lazy { internal val modules by lazy {
NpmProjectModules(dir) NpmProjectModules(dir.getFile())
} }
private val nodeExecutable by lazy { private val nodeExecutable by lazy {
@@ -101,8 +103,8 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
nodeArgs: List<String> = listOf(), nodeArgs: List<String> = listOf(),
args: List<String> args: List<String>
) { ) {
exec.workingDir = dir exec.workingDir(dir)
exec.executable = nodeExecutable exec.executable(nodeExecutable)
exec.args = nodeArgs + require(tool) + args exec.args = nodeArgs + require(tool) + args
} }
@@ -5,15 +5,18 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.resolved package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
import org.jetbrains.kotlin.gradle.targets.js.npm.* import org.gradle.api.file.Directory
import java.io.File import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.targets.js.npm.GradleNodeModule
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependencyDeclaration
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
import java.io.Serializable import java.io.Serializable
/** /**
* Resolved [NpmProject] * Resolved [NpmProject]
*/ */
class PreparedKotlinCompilationNpmResolution( class PreparedKotlinCompilationNpmResolution(
val npmProjectDir: File, val npmProjectDir: Provider<Directory>,
val externalGradleDependencies: Collection<GradleNodeModule>, val externalGradleDependencies: Collection<GradleNodeModule>,
val externalNpmDependencies: Collection<NpmDependencyDeclaration>, val externalNpmDependencies: Collection<NpmDependencyDeclaration>,
) : Serializable ) : Serializable
@@ -6,12 +6,15 @@
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.Action
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.provider.ListProperty import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Provider
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
import java.io.File import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.Serializable import java.io.Serializable
class KotlinCompilationNpmResolution( class KotlinCompilationNpmResolution(
@@ -21,14 +24,10 @@ class KotlinCompilationNpmResolution(
var externalNpmDependencies: Collection<NpmDependencyDeclaration>, var externalNpmDependencies: Collection<NpmDependencyDeclaration>,
var fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>, var fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>,
val projectPath: String, val projectPath: String,
val projectPackagesDir: File,
val rootDir: File,
val compilationDisambiguatedName: String, val compilationDisambiguatedName: String,
val npmProjectName: String, val npmProjectName: String,
val npmProjectVersion: String, val npmProjectVersion: String,
val npmProjectMain: String, val npmProjectMain: String,
val npmProjectPackageJsonFile: File,
val npmProjectDir: File,
val tasksRequirements: TasksRequirements, val tasksRequirements: TasksRequirements,
) : Serializable { ) : Serializable {
@@ -120,7 +119,7 @@ class KotlinCompilationNpmResolution(
val allNpmDependencies = disambiguateDependencies(externalNpmDependencies, otherNpmDependencies, logger) val allNpmDependencies = disambiguateDependencies(externalNpmDependencies, otherNpmDependencies, logger)
return PreparedKotlinCompilationNpmResolution( return PreparedKotlinCompilationNpmResolution(
npmProjectDir, npmResolutionManager.packagesDir.map { it.dir(npmProjectName) },
importedExternalGradleDependencies, importedExternalGradleDependencies,
allNpmDependencies, allNpmDependencies,
) )
@@ -142,7 +141,7 @@ class KotlinCompilationNpmResolution(
it.execute(packageJson) it.execute(packageJson)
} }
packageJson.saveTo(npmProjectPackageJsonFile) packageJson.saveTo(resolution.npmProjectDir.getFile().resolve(NpmProject.PACKAGE_JSON))
} }
private fun disambiguateDependencies( private fun disambiguateDependencies(
@@ -310,14 +310,10 @@ class KotlinCompilationNpmResolver(
externalNpmDependencies, externalNpmDependencies,
fileCollectionDependencies, fileCollectionDependencies,
projectPath, projectPath,
rootResolver.projectPackagesDir,
rootResolver.rootProjectDir,
compilationDisambiguatedName, compilationDisambiguatedName,
npmProject.name, npmProject.name,
npmVersion, npmVersion,
npmProject.main, npmProject.main,
npmProject.packageJsonFile,
npmProject.dir,
rootResolver.tasksRequirements rootResolver.tasksRequirements
) )
} }
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
@@ -22,7 +24,7 @@ class KotlinRootNpmResolver internal constructor(
val rootProjectVersion: String, val rootProjectVersion: String,
val tasksRequirements: TasksRequirements, val tasksRequirements: TasksRequirements,
val versions: NpmVersions, val versions: NpmVersions,
val projectPackagesDir: File, val projectPackagesDir: Provider<Directory>,
val rootProjectDir: File, val rootProjectDir: File,
) : Serializable { ) : Serializable {
@@ -6,17 +6,30 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.tasks.* import org.gradle.api.file.Directory
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.IgnoreEmptyDirectories
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault import org.gradle.work.DisableCachingByDefault
import org.gradle.work.NormalizeLineEndings import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension
import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager import org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
import org.jetbrains.kotlin.gradle.targets.js.npm.UsesKotlinNpmResolutionManager import org.jetbrains.kotlin.gradle.targets.js.npm.UsesKotlinNpmResolutionManager
import org.jetbrains.kotlin.gradle.targets.js.npm.asNpmEnvironment import org.jetbrains.kotlin.gradle.targets.js.npm.asNpmEnvironment
import org.jetbrains.kotlin.gradle.targets.js.npm.asYarnEnvironment import org.jetbrains.kotlin.gradle.targets.js.npm.asYarnEnvironment
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver
import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn
import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.File import java.io.File
@DisableCachingByDefault @DisableCachingByDefault
@@ -39,6 +52,9 @@ abstract class KotlinNpmInstallTask :
private val rootResolver: KotlinRootNpmResolver private val rootResolver: KotlinRootNpmResolver
get() = nodeJs.resolver get() = nodeJs.resolver
private val packagesDir: Provider<Directory>
get() = nodeJs.projectPackagesDirectory
// ----- // -----
private val npmEnvironment by lazy { private val npmEnvironment by lazy {
@@ -64,24 +80,33 @@ abstract class KotlinNpmInstallTask :
@get:IgnoreEmptyDirectories @get:IgnoreEmptyDirectories
@get:NormalizeLineEndings @get:NormalizeLineEndings
@get:InputFiles @get:InputFiles
val packageJsonFiles: Collection<File> by lazy { val packageJsonFiles: FileCollection = project.objects.fileCollection().from(
rootResolver.projectResolvers.values {
.flatMap { it.compilationResolvers } rootResolver.projectResolvers.values
.map { it.compilationNpmResolution } .flatMap { it.compilationResolvers }
.map { it.npmProjectPackageJsonFile } .map { it.compilationNpmResolution }
} .map { resolution ->
val name = resolution.npmProjectName
packagesDir.map { it.dir(name).file(NpmProject.PACKAGE_JSON) }
}
}
)
@get:OutputFile @get:OutputFile
val yarnLock: File by lazy { val yarnLockFile: Provider<RegularFile> = nodeJs.rootPackageDirectory.map { it.file("yarn.lock") }
nodeJs.rootPackageDir.resolve("yarn.lock")
} @Deprecated(
"This property is deprecated and will be removed in future. Use yarnLockFile instead",
replaceWith = ReplaceWith("yarnLockFile")
)
@get:Internal
val yarnLock: File
get() = yarnLockFile.getFile()
// node_modules as OutputDirectory is performance problematic // node_modules as OutputDirectory is performance problematic
// so input will only be existence of its directory // so input will only be existence of its directory
@get:Internal @get:Internal
val nodeModules: File by lazy { val nodeModules: Provider<Directory> = nodeJs.rootPackageDirectory.map { it.dir("node_modules") }
nodeJs.rootPackageDir.resolve("node_modules")
}
@TaskAction @TaskAction
fun resolve() { fun resolve() {
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.*
import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.CompositeProjectComponentArtifactMetadata import org.jetbrains.kotlin.gradle.utils.CompositeProjectComponentArtifactMetadata
import org.jetbrains.kotlin.gradle.utils.`is` import org.jetbrains.kotlin.gradle.utils.`is`
import org.jetbrains.kotlin.gradle.utils.mapToFile
import java.io.File import java.io.File
@DisableCachingByDefault @DisableCachingByDefault
@@ -146,7 +147,7 @@ abstract class KotlinPackageJsonTask :
task.gradleNodeModules.value(gradleNodeModules) task.gradleNodeModules.value(gradleNodeModules)
.disallowChanges() .disallowChanges()
task.packageJson.set(compilation.npmProject.packageJsonFile) task.packageJson.set(compilation.npmProject.packageJsonFile.mapToFile())
task.onlyIf { task.onlyIf {
it as KotlinPackageJsonTask it as KotlinPackageJsonTask
@@ -6,13 +6,21 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.file.Directory
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFile
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
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension
import org.jetbrains.kotlin.gradle.targets.js.npm.* import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
import org.jetbrains.kotlin.gradle.targets.js.npm.UsesKotlinNpmResolutionManager
import org.jetbrains.kotlin.gradle.targets.js.npm.asNpmEnvironment
import org.jetbrains.kotlin.gradle.targets.js.npm.asYarnEnvironment
import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver import org.jetbrains.kotlin.gradle.targets.js.npm.resolver.KotlinRootNpmResolver
import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn
import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.File import java.io.File
@DisableCachingByDefault @DisableCachingByDefault
@@ -35,6 +43,9 @@ abstract class RootPackageJsonTask :
private val rootResolver: KotlinRootNpmResolver private val rootResolver: KotlinRootNpmResolver
get() = nodeJs.resolver get() = nodeJs.resolver
private val packagesDir: Provider<Directory>
get() = nodeJs.projectPackagesDirectory
// ----- // -----
private val npmEnvironment by lazy { private val npmEnvironment by lazy {
@@ -46,20 +57,33 @@ abstract class RootPackageJsonTask :
} }
@get:OutputFile @get:OutputFile
val rootPackageJson: File by lazy { val rootPackageJsonFile: Provider<RegularFile> =
nodeJs.rootPackageDir.resolve(NpmProject.PACKAGE_JSON) nodeJs.rootPackageDirectory.map { it.file(NpmProject.PACKAGE_JSON) }
}
@Deprecated(
"This property is deprecated and will be removed in future. Use rootPackageJsonFile instead",
replaceWith = ReplaceWith("rootPackageJsonFile")
)
@get:Internal
val rootPackageJson: File
get() = rootPackageJsonFile.getFile()
@get:PathSensitive(PathSensitivity.RELATIVE) @get:PathSensitive(PathSensitivity.RELATIVE)
@get:IgnoreEmptyDirectories @get:IgnoreEmptyDirectories
@get:NormalizeLineEndings @get:NormalizeLineEndings
@get:InputFiles @get:InputFiles
val packageJsonFiles: Collection<File> by lazy { val packageJsonFiles: FileCollection = project.objects.fileCollection().from(
rootResolver.projectResolvers.values {
.flatMap { it.compilationResolvers } rootResolver.projectResolvers.values
.map { it.compilationNpmResolution } .flatMap { it.compilationResolvers }
.map { it.npmProjectPackageJsonFile } .map { it.compilationNpmResolution }
} .map { resolution ->
val name = resolution.npmProjectName
packagesDir.map { it.dir(name).file(NpmProject.PACKAGE_JSON) }
}
}
)
@TaskAction @TaskAction
fun resolve() { fun resolve() {
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma
import org.jetbrains.kotlin.gradle.targets.js.testing.mocha.KotlinMocha import org.jetbrains.kotlin.gradle.targets.js.testing.mocha.KotlinMocha
import org.jetbrains.kotlin.gradle.tasks.KotlinTest import org.jetbrains.kotlin.gradle.tasks.KotlinTest
import org.jetbrains.kotlin.gradle.utils.getFile
import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.newFileProperty import org.jetbrains.kotlin.gradle.utils.newFileProperty
import javax.inject.Inject import javax.inject.Inject
@@ -154,7 +155,7 @@ constructor(
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec { override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
val forkOptions = DefaultProcessForkOptions(fileResolver) val forkOptions = DefaultProcessForkOptions(fileResolver)
forkOptions.workingDir = testFramework!!.workingDir.toFile() forkOptions.workingDir = testFramework!!.workingDir.getFile()
forkOptions.executable = nodeExecutable forkOptions.executable = nodeExecutable
environment.forEach { (key, value) -> environment.forEach { (key, value) ->
@@ -5,10 +5,11 @@
package org.jetbrains.kotlin.gradle.targets.js.testing package org.jetbrains.kotlin.gradle.targets.js.testing
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.process.ProcessForkOptions import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
import java.nio.file.Path
interface KotlinJsTestFramework : RequiresNpmDependencies { interface KotlinJsTestFramework : RequiresNpmDependencies {
val settingsState: String val settingsState: String
@@ -20,5 +21,5 @@ interface KotlinJsTestFramework : RequiresNpmDependencies {
debug: Boolean debug: Boolean
): TCServiceMessagesTestExecutionSpec ): TCServiceMessagesTestExecutionSpec
val workingDir: Path val workingDir: Provider<Directory>
} }
@@ -6,6 +6,9 @@
package org.jetbrains.kotlin.gradle.targets.js.testing package org.jetbrains.kotlin.gradle.targets.js.testing
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Provider
import org.gradle.process.ProcessForkOptions import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
@@ -32,8 +35,8 @@ internal class KotlinWasmD8(private val kotlinJsTest: KotlinJsTest) : KotlinJsTe
private val isTeamCity = project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY) private val isTeamCity = project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY)
private val npmProjectDir by project.provider { compilation.npmProject.dir } private val npmProjectDir by project.provider { compilation.npmProject.dir }
override val workingDir: Path override val workingDir: Provider<Directory>
get() = npmProjectDir.toPath() get() = npmProjectDir
override fun createTestExecutionSpec( override fun createTestExecutionSpec(
task: KotlinJsTest, task: KotlinJsTest,
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.testing package org.jetbrains.kotlin.gradle.targets.js.testing
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.process.ProcessForkOptions import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
@@ -19,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.writeWasmUnitTestRunner import org.jetbrains.kotlin.gradle.targets.js.writeWasmUnitTestRunner
import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
import java.nio.file.Path import java.nio.file.Path
internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJsTestFramework { internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJsTestFramework {
@@ -33,15 +36,17 @@ internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJs
@Transient @Transient
private val project: Project = target.project private val project: Project = target.project
private val projectLayout = project.layout
private val npmProjectDir by project.provider { compilation.npmProject.dir } private val npmProjectDir by project.provider { compilation.npmProject.dir }
private val wasmTargetType: KotlinWasmTargetType? = target.wasmTargetType private val wasmTargetType: KotlinWasmTargetType? = target.wasmTargetType
override val workingDir: Path override val workingDir: Provider<Directory>
get() = if (wasmTargetType != KotlinWasmTargetType.WASI) { get() = if (wasmTargetType != KotlinWasmTargetType.WASI) {
npmProjectDir.toPath() npmProjectDir
} else { } else {
kotlinJsTest.inputFileProperty.get().asFile.toPath().parent projectLayout.dir(kotlinJsTest.inputFileProperty.asFile.map { it.parentFile })
} }
override fun createTestExecutionSpec( override fun createTestExecutionSpec(
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle.targets.js.testing.karma
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import jetbrains.buildServer.messages.serviceMessages.BaseTestSuiteMessage import jetbrains.buildServer.messages.serviceMessages.BaseTestSuiteMessage
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.internal.tasks.testing.TestResultProcessor import org.gradle.api.internal.tasks.testing.TestResultProcessor
import org.gradle.api.provider.Provider
import org.gradle.internal.logging.progress.ProgressLogger import org.gradle.internal.logging.progress.ProgressLogger
import org.gradle.internal.service.ServiceRegistry import org.gradle.internal.service.ServiceRegistry
import org.gradle.process.ProcessForkOptions import org.gradle.process.ProcessForkOptions
@@ -36,12 +38,12 @@ import org.jetbrains.kotlin.gradle.targets.js.testing.*
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
import org.jetbrains.kotlin.gradle.tasks.KotlinTest import org.jetbrains.kotlin.gradle.tasks.KotlinTest
import org.jetbrains.kotlin.gradle.utils.appendLine import org.jetbrains.kotlin.gradle.utils.appendLine
import org.jetbrains.kotlin.gradle.utils.getFile
import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.property import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.slf4j.Logger import org.slf4j.Logger
import java.io.File import java.io.File
import java.nio.file.Path
class KotlinKarma( class KotlinKarma(
@Transient override val compilation: KotlinJsIrCompilation, @Transient override val compilation: KotlinJsIrCompilation,
@@ -56,7 +58,7 @@ class KotlinKarma(
@Transient @Transient
private val nodeJs = project.rootProject.kotlinNodeJsExtension private val nodeJs = project.rootProject.kotlinNodeJsExtension
private val nodeRootPackageDir by lazy { nodeJs.rootPackageDir } private val nodeRootPackageDir by lazy { nodeJs.rootPackageDirectory }
private val versions = nodeJs.versions private val versions = nodeJs.versions
private val config: KarmaConfig = KarmaConfig() private val config: KarmaConfig = KarmaConfig()
@@ -77,8 +79,8 @@ class KotlinKarma(
override val requiredNpmDependencies: Set<RequiredKotlinJsDependency> override val requiredNpmDependencies: Set<RequiredKotlinJsDependency>
get() = requiredDependencies + webpackConfig.getRequiredDependencies(versions) get() = requiredDependencies + webpackConfig.getRequiredDependencies(versions)
override val workingDir: Path override val workingDir: Provider<Directory>
get() = npmProjectDir.toPath() get() = npmProjectDir
override fun getPath() = "$basePath:kotlinKarma" override fun getPath() = "$basePath:kotlinKarma"
@@ -95,7 +97,7 @@ class KotlinKarma(
devtool = null, devtool = null,
export = false, export = false,
progressReporter = true, progressReporter = true,
progressReporterPathFilter = nodeRootPackageDir, progressReporterPathFilter = nodeRootPackageDir.getFile(),
rules = project.objects.webpackRulesContainer(), rules = project.objects.webpackRulesContainer(),
experiments = mutableSetOf("topLevelAwait") experiments = mutableSetOf("topLevelAwait")
) )
@@ -335,7 +337,7 @@ class KotlinKarma(
nodeJsArgs: MutableList<String>, nodeJsArgs: MutableList<String>,
debug: Boolean, debug: Boolean,
): TCServiceMessagesTestExecutionSpec { ): TCServiceMessagesTestExecutionSpec {
val file = task.inputFileProperty.get().asFile val file = task.inputFileProperty.getFile()
val fileString = file.toString() val fileString = file.toString()
config.files.add(npmProject.require("kotlin-test-js-runner/kotlin-test-karma-runner.js")) config.files.add(npmProject.require("kotlin-test-js-runner/kotlin-test-karma-runner.js"))
@@ -352,10 +354,10 @@ class KotlinKarma(
) )
) )
config.files.add( config.files.add(
createLoadWasm(npmProject.dir, file).normalize().absolutePath createLoadWasm(npmProject.dir.getFile(), file).normalize().absolutePath
) )
config.proxies["/${wasmFile.name}"] = basify(npmProjectDir, wasmFile) config.proxies["/${wasmFile.name}"] = basify(npmProjectDir.getFile(), wasmFile)
config.customContextFile = npmProject.require("kotlin-test-js-runner/static/context.html") config.customContextFile = npmProject.require("kotlin-test-js-runner/static/context.html")
config.customDebugFile = npmProject.require("kotlin-test-js-runner/static/debug.html") config.customDebugFile = npmProject.require("kotlin-test-js-runner/static/debug.html")
@@ -397,7 +399,7 @@ class KotlinKarma(
escapeTCMessagesInLog = isTeamCity.isPresent escapeTCMessagesInLog = isTeamCity.isPresent
) )
config.basePath = npmProjectDir.absolutePath config.basePath = npmProjectDir.getFile().absolutePath
configurators.forEach { configurators.forEach {
it(task) it(task)
@@ -410,7 +412,7 @@ class KotlinKarma(
config.client.args.addAll(cliArgs.toList()) config.client.args.addAll(cliArgs.toList())
val karmaConfJs = npmProject.dir.resolve("karma.conf.js") val karmaConfJs = npmProject.dir.getFile().resolve("karma.conf.js")
karmaConfJs.printWriter().use { confWriter -> karmaConfJs.printWriter().use { confWriter ->
envJsCollector.forEach { (envVar, value) -> envJsCollector.forEach { (envVar, value) ->
//language=JavaScript 1.8 //language=JavaScript 1.8
@@ -585,7 +587,7 @@ class KotlinKarma(
private fun createDebuggerJs( private fun createDebuggerJs(
file: String, file: String,
): File { ): File {
val adapterJs = npmProject.dir.resolve("debugger.js") val adapterJs = npmProject.dir.getFile().resolve("debugger.js")
adapterJs.printWriter().use { writer -> adapterJs.printWriter().use { writer ->
// It is necessary for debugger attaching (--inspect-brk analogue) // It is necessary for debugger attaching (--inspect-brk analogue)
writer.println("debugger;") writer.println("debugger;")
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.testing.mocha package org.jetbrains.kotlin.gradle.targets.js.testing.mocha
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.process.ProcessForkOptions import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
@@ -19,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTestFramework
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinTestRunnerCliArgs import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinTestRunnerCliArgs
import org.jetbrains.kotlin.gradle.utils.getFile
import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.utils.getValue
import java.nio.file.Path import java.nio.file.Path
@@ -31,8 +34,8 @@ class KotlinMocha(@Transient override val compilation: KotlinJsIrCompilation, pr
private val isTeamCity = project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY) private val isTeamCity = project.providers.gradleProperty(TCServiceMessagesTestExecutor.TC_PROJECT_PROPERTY)
private val npmProjectDir by project.provider { npmProject.dir } private val npmProjectDir by project.provider { npmProject.dir }
override val workingDir: Path override val workingDir: Provider<Directory>
get() = npmProjectDir.toPath() get() = npmProjectDir
override val settingsState: String override val settingsState: String
get() = "mocha" get() = "mocha"
@@ -72,7 +75,7 @@ class KotlinMocha(@Transient override val compilation: KotlinJsIrCompilation, pr
val mocha = npmProject.require("mocha/bin/mocha") val mocha = npmProject.require("mocha/bin/mocha")
val file = task.inputFileProperty.get().asFile.toString() val file = task.inputFileProperty.getFile().toString()
val args = nodeJsArgs + mutableListOf( val args = nodeJsArgs + mutableListOf(
"--require", "--require",
@@ -22,9 +22,11 @@ import org.gradle.deployment.internal.DeploymentRegistry
import org.gradle.process.internal.ExecHandle import org.gradle.process.internal.ExecHandle
import org.gradle.process.internal.ExecHandleFactory import org.gradle.process.internal.ExecHandleFactory
import org.gradle.work.NormalizeLineEndings import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.build.report.metrics.* import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl
import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.utils.archivesName
import org.jetbrains.kotlin.gradle.report.UsesBuildMetricsService import org.jetbrains.kotlin.gradle.report.UsesBuildMetricsService
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWebpackRulesContainer import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWebpackRulesContainer
@@ -35,7 +37,8 @@ import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode
import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.archivesName
import org.jetbrains.kotlin.gradle.utils.injected import org.jetbrains.kotlin.gradle.utils.injected
import org.jetbrains.kotlin.gradle.utils.property import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
@@ -49,12 +52,12 @@ constructor(
@Internal @Internal
@Transient @Transient
override val compilation: KotlinJsIrCompilation, override val compilation: KotlinJsIrCompilation,
private val objects: ObjectFactory private val objects: ObjectFactory,
) : DefaultTask(), RequiresNpmDependencies, WebpackRulesDsl, UsesBuildMetricsService { ) : DefaultTask(), RequiresNpmDependencies, WebpackRulesDsl, UsesBuildMetricsService {
@Transient @Transient
private val nodeJs = project.rootProject.kotlinNodeJsExtension private val nodeJs = project.rootProject.kotlinNodeJsExtension
private val versions = nodeJs.versions private val versions = nodeJs.versions
private val rootPackageDir by lazy { nodeJs.rootPackageDir } private val rootPackageDir by lazy { nodeJs.rootPackageDirectory }
private val npmProject = compilation.npmProject private val npmProject = compilation.npmProject
@@ -167,7 +170,8 @@ constructor(
get() = mainOutputFile.get().asFile get() = mainOutputFile.get().asFile
@get:Internal @get:Internal
val mainOutputFile: Provider<RegularFile> = objects.providerWithLazyConvention { outputDirectory.file(mainOutputFileName) }.flatMap { it } val mainOutputFile: Provider<RegularFile> =
objects.providerWithLazyConvention { outputDirectory.file(mainOutputFileName) }.flatMap { it }
private val projectDir = project.projectDir private val projectDir = project.projectDir
@@ -193,7 +197,16 @@ constructor(
@Input @Input
@Optional @Optional
var devServer: KotlinWebpackConfig.DevServer? = null val devServerProperty: Property<KotlinWebpackConfig.DevServer> = project.objects.property(KotlinWebpackConfig.DevServer::class.java)
@get:Internal
@Deprecated(
"This property is deprecated and will be removed in future. Use devServerProperty instead",
replaceWith = ReplaceWith("devServerProperty")
)
var devServer: KotlinWebpackConfig.DevServer
get() = devServerProperty.get()
set(value) = devServerProperty.set(value)
@Input @Input
@Optional @Optional
@@ -231,7 +244,7 @@ constructor(
outputFileName = mainOutputFileName.get(), outputFileName = mainOutputFileName.get(),
configDirectory = configDirectory, configDirectory = configDirectory,
rules = rules, rules = rules,
devServer = devServer, devServer = devServerProperty,
devtool = devtool, devtool = devtool,
sourceMaps = sourceMaps, sourceMaps = sourceMaps,
resolveFromModulesFirst = resolveFromModulesFirst, resolveFromModulesFirst = resolveFromModulesFirst,
@@ -286,7 +299,7 @@ constructor(
runner.copy( runner.copy(
config = runner.config.copy( config = runner.config.copy(
progressReporter = true, progressReporter = true,
progressReporterPathFilter = rootPackageDir progressReporterPathFilter = rootPackageDir.getFile()
) )
).execute(services) ).execute(services)
@@ -31,7 +31,7 @@ data class KotlinWebpackConfig(
var outputFileName: String? = entry?.name, var outputFileName: String? = entry?.name,
var configDirectory: File? = null, var configDirectory: File? = null,
var reportEvaluatedConfigFile: File? = null, var reportEvaluatedConfigFile: File? = null,
var devServer: DevServer? = null, var devServer: Provider<DevServer>? = null,
var watchOptions: WatchOptions? = null, var watchOptions: WatchOptions? = null,
var experiments: MutableSet<String> = mutableSetOf(), var experiments: MutableSet<String> = mutableSetOf(),
override val rules: KotlinWebpackRulesContainer, override val rules: KotlinWebpackRulesContainer,
@@ -69,7 +69,7 @@ data class KotlinWebpackConfig(
) )
} }
if (devServer != null) { if (devServer != null && devServer!!.isPresent) {
it.add( it.add(
versions.webpackDevServer versions.webpackDevServer
) )
@@ -176,10 +176,10 @@ data class KotlinWebpackConfig(
} }
private fun Appendable.appendDevServer() { private fun Appendable.appendDevServer() {
if (devServer != null) { if (devServer != null && devServer!!.isPresent) {
appendLine("// dev server") appendLine("// dev server")
appendLine("config.devServer = ${json(devServer!!)};") appendLine("config.devServer = ${json(devServer!!.get())};")
appendLine() appendLine()
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.GradleException import org.gradle.api.GradleException
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
@@ -27,7 +28,7 @@ abstract class YarnLockCopyTask : DefaultTask() {
abstract val inputFile: RegularFileProperty abstract val inputFile: RegularFileProperty
@get:Internal @get:Internal
abstract val outputDirectory: RegularFileProperty abstract val outputDirectory: DirectoryProperty
@get:Internal @get:Internal
abstract val fileName: Property<String> abstract val fileName: Property<String>
@@ -91,7 +91,7 @@ open class YarnPlugin : Plugin<Project> {
tasks.register(STORE_YARN_LOCK_NAME, YarnLockStoreTask::class.java) { task -> tasks.register(STORE_YARN_LOCK_NAME, YarnLockStoreTask::class.java) { task ->
task.dependsOn(kotlinNpmInstall) task.dependsOn(kotlinNpmInstall)
task.inputFile.set(nodeJs.rootPackageDir.resolve("yarn.lock")) task.inputFile.set(nodeJs.rootPackageDirectory.map { it.file("yarn.lock") })
task.outputDirectory.set(yarnRootExtension.lockFileDirectory) task.outputDirectory.set(yarnRootExtension.lockFileDirectory)
task.fileName.set(yarnRootExtension.lockFileName) task.fileName.set(yarnRootExtension.lockFileName)
@@ -102,7 +102,7 @@ open class YarnPlugin : Plugin<Project> {
tasks.register(UPGRADE_YARN_LOCK, YarnLockCopyTask::class.java) { task -> tasks.register(UPGRADE_YARN_LOCK, YarnLockCopyTask::class.java) { task ->
task.dependsOn(kotlinNpmInstall) task.dependsOn(kotlinNpmInstall)
task.inputFile.set(nodeJs.rootPackageDir.resolve("yarn.lock")) task.inputFile.set(nodeJs.rootPackageDirectory.map { it.file("yarn.lock") })
task.outputDirectory.set(yarnRootExtension.lockFileDirectory) task.outputDirectory.set(yarnRootExtension.lockFileDirectory)
task.fileName.set(yarnRootExtension.lockFileName) task.fileName.set(yarnRootExtension.lockFileName)
} }
@@ -110,7 +110,7 @@ open class YarnPlugin : Plugin<Project> {
val restoreYarnLock = tasks.register(RESTORE_YARN_LOCK_NAME, YarnLockCopyTask::class.java) { val restoreYarnLock = tasks.register(RESTORE_YARN_LOCK_NAME, YarnLockCopyTask::class.java) {
val lockFile = yarnRootExtension.lockFileDirectory.resolve(yarnRootExtension.lockFileName) val lockFile = yarnRootExtension.lockFileDirectory.resolve(yarnRootExtension.lockFileName)
it.inputFile.set(yarnRootExtension.lockFileDirectory.resolve(yarnRootExtension.lockFileName)) it.inputFile.set(yarnRootExtension.lockFileDirectory.resolve(yarnRootExtension.lockFileName))
it.outputDirectory.set(nodeJs.rootPackageDir) it.outputDirectory.set(nodeJs.rootPackageDirectory)
it.fileName.set("yarn.lock") it.fileName.set("yarn.lock")
it.onlyIf { it.onlyIf {
lockFile.exists() lockFile.exists()
@@ -9,6 +9,7 @@ import org.gradle.api.logging.Logger
import org.gradle.internal.service.ServiceRegistry import org.gradle.internal.service.ServiceRegistry
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
import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.File import java.io.File
class YarnWorkspaces : YarnBasics() { class YarnWorkspaces : YarnBasics() {
@@ -91,7 +92,7 @@ class YarnWorkspaces : YarnBasics() {
val rootPackageJson = PackageJson(rootProjectName, rootProjectVersion) val rootPackageJson = PackageJson(rootProjectName, rootProjectVersion)
rootPackageJson.private = true rootPackageJson.private = true
val npmProjectWorkspaces = npmProjects.map { it.npmProjectDir.relativeTo(nodeJsWorldDir).path } val npmProjectWorkspaces = npmProjects.map { it.npmProjectDir.getFile().relativeTo(nodeJsWorldDir).path }
val importedProjectWorkspaces = val importedProjectWorkspaces =
YarnImportedPackagesVersionResolver(logger, npmProjects, nodeJsWorldDir).resolveAndUpdatePackages() YarnImportedPackagesVersionResolver(logger, npmProjects, nodeJsWorldDir).resolveAndUpdatePackages()