[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()
)
build("build") {
try {
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)
}
}
assertDirectoryInProjectDoesNotExist("build")
assertDirectoryInProjectExists("build2")
}
@@ -100,7 +100,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
}
override fun configureRun(
compilation: KotlinJsIrCompilation
compilation: KotlinJsIrCompilation,
) {
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"
val npmProject = compilation.npmProject
task.devServer = KotlinWebpackConfig.DevServer(
open = true,
static = mutableListOf(
npmProject.dist.normalize().relativeOrAbsolute(npmProject.dir),
compilation.output.resourcesDir.relativeOrAbsolute(npmProject.dir),
),
client = KotlinWebpackConfig.DevServer.Client(
KotlinWebpackConfig.DevServer.Client.Overlay(
errors = true,
warnings = false
val resourcesDir = compilation.output.resourcesDir
task.devServerProperty.convention(
npmProject.dist.zip(npmProject.dir) { distDirectory, dir ->
KotlinWebpackConfig.DevServer(
open = true,
static = mutableListOf(
distDirectory.asFile.normalize().relativeOrAbsolute(dir.asFile),
resourcesDir.relativeOrAbsolute(dir.asFile),
),
client = KotlinWebpackConfig.DevServer.Client(
KotlinWebpackConfig.DevServer.Client.Overlay(
errors = true,
warnings = false
)
)
)
)
}
)
task.watchOptions = KotlinWebpackConfig.WatchOptions(
@@ -167,7 +172,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
}
override fun configureBuild(
compilation: KotlinJsIrCompilation
compilation: KotlinJsIrCompilation,
) {
val project = compilation.target.project
@@ -302,7 +307,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
private fun <T> getByKind(
kind: KotlinJsBinaryMode,
releaseValue: T,
debugValue: T
debugValue: T,
): T = when (kind) {
KotlinJsBinaryMode.PRODUCTION -> releaseValue
KotlinJsBinaryMode.DEVELOPMENT -> debugValue
@@ -184,7 +184,7 @@ constructor(
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.executable = nodeJs.requireConfigured().nodeExecutable
if ((compilation.target as? KotlinJsIrTarget)?.wasmTargetType != KotlinWasmTargetType.WASI) {
it.workingDir = npmProject.dir
it.workingDir(npmProject.dir)
it.dependsOn(
nodeJsTaskProviders.npmInstallTaskProvider,
nodeJsTaskProviders.storeYarnLockTaskProvider,
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs
import org.gradle.api.Project
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.jetbrains.kotlin.gradle.logging.kotlinInfo
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.YarnLockCopyTask
import org.jetbrains.kotlin.gradle.tasks.internal.CleanableStore
import org.jetbrains.kotlin.gradle.utils.getFile
import org.jetbrains.kotlin.gradle.utils.property
import java.io.File
@@ -95,13 +98,34 @@ open class NodeJsRootExtension(
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
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
get() = rootPackageDir.resolve("packages_imported")
get() = nodeModulesGradleCacheDirectory.getFile()
internal val platform: org.gradle.api.provider.Property<Platform> = project.objects.property<Platform>()
@@ -130,7 +154,7 @@ open class NodeJsRootExtension(
return NodeJsEnv(
download = download,
cleanableStore = cleanableStore,
rootPackageDir = rootPackageDir,
rootPackageDir = rootPackageDirectory.getFile(),
dir = nodeDir,
nodeBinDir = nodeBinDir,
nodeExecutable = getExecutable("node", nodeCommand, "exe"),
@@ -57,7 +57,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
val gradleNodeModulesProvider: Provider<GradleNodeModulesCache> = GradleNodeModulesCache.registerIfAbsent(
project,
project.projectDir,
nodeJs.nodeModulesGradleCacheDir
nodeJs.nodeModulesGradleCacheDirectory
)
val setupFileHasherTask = project.registerTask<KotlinNpmCachesSetup>(KotlinNpmCachesSetup.NAME) {
@@ -80,7 +80,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
}
npmInstall.outputs.upToDateWhen {
npmInstall.nodeModules.exists()
npmInstall.nodeModules.getFile().exists()
}
}
@@ -91,7 +91,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
project.version.toString(),
TasksRequirements(),
nodeJs.versions,
nodeJs.projectPackagesDir,
nodeJs.projectPackagesDirectory,
nodeJs.rootProjectDir,
)
@@ -108,6 +108,7 @@ open class NodeJsRootPlugin : Plugin<Project> {
}
)
it.parameters.gradleNodeModulesProvider.set(gradleNodeModulesProvider)
it.parameters.packagesDir.set(nodeJs.projectPackagesDirectory)
}
YarnPlugin.apply(project)
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle.targets.js.npm
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.ArchiveOperations
import org.gradle.api.file.Directory
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Internal
@@ -53,7 +55,7 @@ abstract class GradleNodeModulesCache : AbstractNodeModulesCache() {
private fun registerIfAbsentImpl(
project: Project,
rootProjectDir: File?,
cacheDir: File?
cacheDir: Provider<Directory>?
): Provider<GradleNodeModulesCache> {
project.gradle.sharedServices.registrations.findByName(serviceName)?.let {
@Suppress("UNCHECKED_CAST")
@@ -76,7 +78,7 @@ abstract class GradleNodeModulesCache : AbstractNodeModulesCache() {
fun registerIfAbsent(
project: Project,
rootProjectDir: File?,
cacheDir: File?
cacheDir: Provider<Directory>?
) = registerIfAbsentImpl(project, rootProjectDir, cacheDir).also { serviceProvider ->
SingleActionPerProject.run(project, UsesGradleNodeModulesCache::class.java.name) {
project.tasks.withType<UsesGradleNodeModulesCache>().configureEach { task ->
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.npm
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.provider.Property
import org.gradle.api.services.BuildService
@@ -47,11 +49,16 @@ abstract class KotlinNpmResolutionManager : BuildService<KotlinNpmResolutionMana
val resolution: Property<KotlinRootNpmResolution>
val gradleNodeModulesProvider: Property<GradleNodeModulesCache>
val packagesDir: DirectoryProperty
}
val resolution
get() = parameters.resolution
val packagesDir
get() = parameters.packagesDir
@Volatile
var state: ResolutionState = ResolutionState.Configuring(resolution.get())
@@ -6,6 +6,9 @@
package org.jetbrains.kotlin.gradle.targets.js.npm
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.jetbrains.kotlin.gradle.dsl.JsModuleKind
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.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension
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 java.io.File
import java.io.Serializable
@@ -52,9 +56,7 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
project.rootProject.kotlinNodeJsExtension
}
val dir: File by lazy {
nodeJs.projectPackagesDir.resolve(name)
}
val dir: Provider<Directory> = nodeJs.projectPackagesDirectory.map { it.dir(name) }
val target: KotlinJsTargetDsl
get() = compilation.target as KotlinJsTargetDsl
@@ -63,10 +65,10 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
get() = target.project
val nodeModulesDir
get() = dir.resolve(NODE_MODULES)
get() = dir.map { it.dir(NODE_MODULES) }
val packageJsonFile: File
get() = dir.resolve(PACKAGE_JSON)
val packageJsonFile: Provider<RegularFile>
get() = dir.map { it.file(PACKAGE_JSON) }
val packageJsonTaskName: String
get() = compilation.disambiguateName("packageJson")
@@ -78,8 +80,8 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
packageJsonTask.path
}
val dist: File
get() = dir.resolve(DIST_FOLDER)
val dist: Provider<Directory>
get() = dir.map { it.dir(DIST_FOLDER) }
val main: String
get() = "${DIST_FOLDER}/$name$extension"
@@ -88,7 +90,7 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
get() = compilation.disambiguateName(PublicPackageJsonTask.NAME)
internal val modules by lazy {
NpmProjectModules(dir)
NpmProjectModules(dir.getFile())
}
private val nodeExecutable by lazy {
@@ -101,8 +103,8 @@ open class NpmProject(@Transient val compilation: KotlinJsIrCompilation) : Seria
nodeArgs: List<String> = listOf(),
args: List<String>
) {
exec.workingDir = dir
exec.executable = nodeExecutable
exec.workingDir(dir)
exec.executable(nodeExecutable)
exec.args = nodeArgs + require(tool) + args
}
@@ -5,15 +5,18 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.resolved
import org.jetbrains.kotlin.gradle.targets.js.npm.*
import java.io.File
import org.gradle.api.file.Directory
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
/**
* Resolved [NpmProject]
*/
class PreparedKotlinCompilationNpmResolution(
val npmProjectDir: File,
val npmProjectDir: Provider<Directory>,
val externalGradleDependencies: Collection<GradleNodeModule>,
val externalNpmDependencies: Collection<NpmDependencyDeclaration>,
) : Serializable
@@ -6,12 +6,15 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
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.provider.ListProperty
import org.gradle.api.provider.Provider
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.resolved.PreparedKotlinCompilationNpmResolution
import java.io.File
import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.Serializable
class KotlinCompilationNpmResolution(
@@ -21,14 +24,10 @@ class KotlinCompilationNpmResolution(
var externalNpmDependencies: Collection<NpmDependencyDeclaration>,
var fileCollectionDependencies: Collection<FileCollectionExternalGradleDependency>,
val projectPath: String,
val projectPackagesDir: File,
val rootDir: File,
val compilationDisambiguatedName: String,
val npmProjectName: String,
val npmProjectVersion: String,
val npmProjectMain: String,
val npmProjectPackageJsonFile: File,
val npmProjectDir: File,
val tasksRequirements: TasksRequirements,
) : Serializable {
@@ -120,7 +119,7 @@ class KotlinCompilationNpmResolution(
val allNpmDependencies = disambiguateDependencies(externalNpmDependencies, otherNpmDependencies, logger)
return PreparedKotlinCompilationNpmResolution(
npmProjectDir,
npmResolutionManager.packagesDir.map { it.dir(npmProjectName) },
importedExternalGradleDependencies,
allNpmDependencies,
)
@@ -142,7 +141,7 @@ class KotlinCompilationNpmResolution(
it.execute(packageJson)
}
packageJson.saveTo(npmProjectPackageJsonFile)
packageJson.saveTo(resolution.npmProjectDir.getFile().resolve(NpmProject.PACKAGE_JSON))
}
private fun disambiguateDependencies(
@@ -310,14 +310,10 @@ class KotlinCompilationNpmResolver(
externalNpmDependencies,
fileCollectionDependencies,
projectPath,
rootResolver.projectPackagesDir,
rootResolver.rootProjectDir,
compilationDisambiguatedName,
npmProject.name,
npmVersion,
npmProject.main,
npmProject.packageJsonFile,
npmProject.dir,
rootResolver.tasksRequirements
)
}
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.resolver
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.mpp.isMain
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType
@@ -22,7 +24,7 @@ class KotlinRootNpmResolver internal constructor(
val rootProjectVersion: String,
val tasksRequirements: TasksRequirements,
val versions: NpmVersions,
val projectPackagesDir: File,
val projectPackagesDir: Provider<Directory>,
val rootProjectDir: File,
) : Serializable {
@@ -6,17 +6,30 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
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.NormalizeLineEndings
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.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.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.yarn.yarn
import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.File
@DisableCachingByDefault
@@ -39,6 +52,9 @@ abstract class KotlinNpmInstallTask :
private val rootResolver: KotlinRootNpmResolver
get() = nodeJs.resolver
private val packagesDir: Provider<Directory>
get() = nodeJs.projectPackagesDirectory
// -----
private val npmEnvironment by lazy {
@@ -64,24 +80,33 @@ abstract class KotlinNpmInstallTask :
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
@get:InputFiles
val packageJsonFiles: Collection<File> by lazy {
rootResolver.projectResolvers.values
.flatMap { it.compilationResolvers }
.map { it.compilationNpmResolution }
.map { it.npmProjectPackageJsonFile }
}
val packageJsonFiles: FileCollection = project.objects.fileCollection().from(
{
rootResolver.projectResolvers.values
.flatMap { it.compilationResolvers }
.map { it.compilationNpmResolution }
.map { resolution ->
val name = resolution.npmProjectName
packagesDir.map { it.dir(name).file(NpmProject.PACKAGE_JSON) }
}
}
)
@get:OutputFile
val yarnLock: File by lazy {
nodeJs.rootPackageDir.resolve("yarn.lock")
}
val yarnLockFile: Provider<RegularFile> = nodeJs.rootPackageDirectory.map { it.file("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
// so input will only be existence of its directory
@get:Internal
val nodeModules: File by lazy {
nodeJs.rootPackageDir.resolve("node_modules")
}
val nodeModules: Provider<Directory> = nodeJs.rootPackageDirectory.map { it.dir("node_modules") }
@TaskAction
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.utils.CompositeProjectComponentArtifactMetadata
import org.jetbrains.kotlin.gradle.utils.`is`
import org.jetbrains.kotlin.gradle.utils.mapToFile
import java.io.File
@DisableCachingByDefault
@@ -146,7 +147,7 @@ abstract class KotlinPackageJsonTask :
task.gradleNodeModules.value(gradleNodeModules)
.disallowChanges()
task.packageJson.set(compilation.npmProject.packageJsonFile)
task.packageJson.set(compilation.npmProject.packageJsonFile.mapToFile())
task.onlyIf {
it as KotlinPackageJsonTask
@@ -6,13 +6,21 @@
package org.jetbrains.kotlin.gradle.targets.js.npm.tasks
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.work.DisableCachingByDefault
import org.gradle.work.NormalizeLineEndings
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.yarn.yarn
import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.File
@DisableCachingByDefault
@@ -35,6 +43,9 @@ abstract class RootPackageJsonTask :
private val rootResolver: KotlinRootNpmResolver
get() = nodeJs.resolver
private val packagesDir: Provider<Directory>
get() = nodeJs.projectPackagesDirectory
// -----
private val npmEnvironment by lazy {
@@ -46,20 +57,33 @@ abstract class RootPackageJsonTask :
}
@get:OutputFile
val rootPackageJson: File by lazy {
nodeJs.rootPackageDir.resolve(NpmProject.PACKAGE_JSON)
}
val rootPackageJsonFile: Provider<RegularFile> =
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:IgnoreEmptyDirectories
@get:NormalizeLineEndings
@get:InputFiles
val packageJsonFiles: Collection<File> by lazy {
rootResolver.projectResolvers.values
.flatMap { it.compilationResolvers }
.map { it.compilationNpmResolution }
.map { it.npmProjectPackageJsonFile }
}
val packageJsonFiles: FileCollection = project.objects.fileCollection().from(
{
rootResolver.projectResolvers.values
.flatMap { it.compilationResolvers }
.map { it.compilationNpmResolution }
.map { resolution ->
val name = resolution.npmProjectName
packagesDir.map { it.dir(name).file(NpmProject.PACKAGE_JSON) }
}
}
)
@TaskAction
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.mocha.KotlinMocha
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.newFileProperty
import javax.inject.Inject
@@ -154,7 +155,7 @@ constructor(
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
val forkOptions = DefaultProcessForkOptions(fileResolver)
forkOptions.workingDir = testFramework!!.workingDir.toFile()
forkOptions.workingDir = testFramework!!.workingDir.getFile()
forkOptions.executable = nodeExecutable
environment.forEach { (key, value) ->
@@ -5,10 +5,11 @@
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.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
import java.nio.file.Path
interface KotlinJsTestFramework : RequiresNpmDependencies {
val settingsState: String
@@ -20,5 +21,5 @@ interface KotlinJsTestFramework : RequiresNpmDependencies {
debug: Boolean
): TCServiceMessagesTestExecutionSpec
val workingDir: Path
val workingDir: Provider<Directory>
}
@@ -6,6 +6,9 @@
package org.jetbrains.kotlin.gradle.targets.js.testing
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.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
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 npmProjectDir by project.provider { compilation.npmProject.dir }
override val workingDir: Path
get() = npmProjectDir.toPath()
override val workingDir: Provider<Directory>
get() = npmProjectDir
override fun createTestExecutionSpec(
task: KotlinJsTest,
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.testing
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
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.writeWasmUnitTestRunner
import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
import java.nio.file.Path
internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJsTestFramework {
@@ -33,15 +36,17 @@ internal class KotlinWasmNode(private val kotlinJsTest: KotlinJsTest) : KotlinJs
@Transient
private val project: Project = target.project
private val projectLayout = project.layout
private val npmProjectDir by project.provider { compilation.npmProject.dir }
private val wasmTargetType: KotlinWasmTargetType? = target.wasmTargetType
override val workingDir: Path
override val workingDir: Provider<Directory>
get() = if (wasmTargetType != KotlinWasmTargetType.WASI) {
npmProjectDir.toPath()
npmProjectDir
} else {
kotlinJsTest.inputFileProperty.get().asFile.toPath().parent
projectLayout.dir(kotlinJsTest.inputFileProperty.asFile.map { it.parentFile })
}
override fun createTestExecutionSpec(
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle.targets.js.testing.karma
import com.google.gson.GsonBuilder
import jetbrains.buildServer.messages.serviceMessages.BaseTestSuiteMessage
import org.gradle.api.Project
import org.gradle.api.file.Directory
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.service.ServiceRegistry
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.tasks.KotlinTest
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.property
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.slf4j.Logger
import java.io.File
import java.nio.file.Path
class KotlinKarma(
@Transient override val compilation: KotlinJsIrCompilation,
@@ -56,7 +58,7 @@ class KotlinKarma(
@Transient
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 config: KarmaConfig = KarmaConfig()
@@ -77,8 +79,8 @@ class KotlinKarma(
override val requiredNpmDependencies: Set<RequiredKotlinJsDependency>
get() = requiredDependencies + webpackConfig.getRequiredDependencies(versions)
override val workingDir: Path
get() = npmProjectDir.toPath()
override val workingDir: Provider<Directory>
get() = npmProjectDir
override fun getPath() = "$basePath:kotlinKarma"
@@ -95,7 +97,7 @@ class KotlinKarma(
devtool = null,
export = false,
progressReporter = true,
progressReporterPathFilter = nodeRootPackageDir,
progressReporterPathFilter = nodeRootPackageDir.getFile(),
rules = project.objects.webpackRulesContainer(),
experiments = mutableSetOf("topLevelAwait")
)
@@ -335,7 +337,7 @@ class KotlinKarma(
nodeJsArgs: MutableList<String>,
debug: Boolean,
): TCServiceMessagesTestExecutionSpec {
val file = task.inputFileProperty.get().asFile
val file = task.inputFileProperty.getFile()
val fileString = file.toString()
config.files.add(npmProject.require("kotlin-test-js-runner/kotlin-test-karma-runner.js"))
@@ -352,10 +354,10 @@ class KotlinKarma(
)
)
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.customDebugFile = npmProject.require("kotlin-test-js-runner/static/debug.html")
@@ -397,7 +399,7 @@ class KotlinKarma(
escapeTCMessagesInLog = isTeamCity.isPresent
)
config.basePath = npmProjectDir.absolutePath
config.basePath = npmProjectDir.getFile().absolutePath
configurators.forEach {
it(task)
@@ -410,7 +412,7 @@ class KotlinKarma(
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 ->
envJsCollector.forEach { (envVar, value) ->
//language=JavaScript 1.8
@@ -585,7 +587,7 @@ class KotlinKarma(
private fun createDebuggerJs(
file: String,
): File {
val adapterJs = npmProject.dir.resolve("debugger.js")
val adapterJs = npmProject.dir.getFile().resolve("debugger.js")
adapterJs.printWriter().use { writer ->
// It is necessary for debugger attaching (--inspect-brk analogue)
writer.println("debugger;")
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.targets.js.testing.mocha
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.process.ProcessForkOptions
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings
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.KotlinJsTestFramework
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinTestRunnerCliArgs
import org.jetbrains.kotlin.gradle.utils.getFile
import org.jetbrains.kotlin.gradle.utils.getValue
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 npmProjectDir by project.provider { npmProject.dir }
override val workingDir: Path
get() = npmProjectDir.toPath()
override val workingDir: Provider<Directory>
get() = npmProjectDir
override val settingsState: String
get() = "mocha"
@@ -72,7 +75,7 @@ class KotlinMocha(@Transient override val compilation: KotlinJsIrCompilation, pr
val mocha = npmProject.require("mocha/bin/mocha")
val file = task.inputFileProperty.get().asFile.toString()
val file = task.inputFileProperty.getFile().toString()
val args = nodeJsArgs + mutableListOf(
"--require",
@@ -22,9 +22,11 @@ import org.gradle.deployment.internal.DeploymentRegistry
import org.gradle.process.internal.ExecHandle
import org.gradle.process.internal.ExecHandleFactory
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.utils.archivesName
import org.jetbrains.kotlin.gradle.report.UsesBuildMetricsService
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
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.npmProject
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.property
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
@@ -49,12 +52,12 @@ constructor(
@Internal
@Transient
override val compilation: KotlinJsIrCompilation,
private val objects: ObjectFactory
private val objects: ObjectFactory,
) : DefaultTask(), RequiresNpmDependencies, WebpackRulesDsl, UsesBuildMetricsService {
@Transient
private val nodeJs = project.rootProject.kotlinNodeJsExtension
private val versions = nodeJs.versions
private val rootPackageDir by lazy { nodeJs.rootPackageDir }
private val rootPackageDir by lazy { nodeJs.rootPackageDirectory }
private val npmProject = compilation.npmProject
@@ -167,7 +170,8 @@ constructor(
get() = mainOutputFile.get().asFile
@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
@@ -193,7 +197,16 @@ constructor(
@Input
@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
@Optional
@@ -231,7 +244,7 @@ constructor(
outputFileName = mainOutputFileName.get(),
configDirectory = configDirectory,
rules = rules,
devServer = devServer,
devServer = devServerProperty,
devtool = devtool,
sourceMaps = sourceMaps,
resolveFromModulesFirst = resolveFromModulesFirst,
@@ -286,7 +299,7 @@ constructor(
runner.copy(
config = runner.config.copy(
progressReporter = true,
progressReporterPathFilter = rootPackageDir
progressReporterPathFilter = rootPackageDir.getFile()
)
).execute(services)
@@ -31,7 +31,7 @@ data class KotlinWebpackConfig(
var outputFileName: String? = entry?.name,
var configDirectory: File? = null,
var reportEvaluatedConfigFile: File? = null,
var devServer: DevServer? = null,
var devServer: Provider<DevServer>? = null,
var watchOptions: WatchOptions? = null,
var experiments: MutableSet<String> = mutableSetOf(),
override val rules: KotlinWebpackRulesContainer,
@@ -69,7 +69,7 @@ data class KotlinWebpackConfig(
)
}
if (devServer != null) {
if (devServer != null && devServer!!.isPresent) {
it.add(
versions.webpackDevServer
)
@@ -176,10 +176,10 @@ data class KotlinWebpackConfig(
}
private fun Appendable.appendDevServer() {
if (devServer != null) {
if (devServer != null && devServer!!.isPresent) {
appendLine("// dev server")
appendLine("config.devServer = ${json(devServer!!)};")
appendLine("config.devServer = ${json(devServer!!.get())};")
appendLine()
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js.yarn
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
@@ -27,7 +28,7 @@ abstract class YarnLockCopyTask : DefaultTask() {
abstract val inputFile: RegularFileProperty
@get:Internal
abstract val outputDirectory: RegularFileProperty
abstract val outputDirectory: DirectoryProperty
@get:Internal
abstract val fileName: Property<String>
@@ -91,7 +91,7 @@ open class YarnPlugin : Plugin<Project> {
tasks.register(STORE_YARN_LOCK_NAME, YarnLockStoreTask::class.java) { task ->
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.fileName.set(yarnRootExtension.lockFileName)
@@ -102,7 +102,7 @@ open class YarnPlugin : Plugin<Project> {
tasks.register(UPGRADE_YARN_LOCK, YarnLockCopyTask::class.java) { task ->
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.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 lockFile = 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.onlyIf {
lockFile.exists()
@@ -9,6 +9,7 @@ import org.gradle.api.logging.Logger
import org.gradle.internal.service.ServiceRegistry
import org.jetbrains.kotlin.gradle.targets.js.npm.*
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.PreparedKotlinCompilationNpmResolution
import org.jetbrains.kotlin.gradle.utils.getFile
import java.io.File
class YarnWorkspaces : YarnBasics() {
@@ -91,7 +92,7 @@ class YarnWorkspaces : YarnBasics() {
val rootPackageJson = PackageJson(rootProjectName, rootProjectVersion)
rootPackageJson.private = true
val npmProjectWorkspaces = npmProjects.map { it.npmProjectDir.relativeTo(nodeJsWorldDir).path }
val npmProjectWorkspaces = npmProjects.map { it.npmProjectDir.getFile().relativeTo(nodeJsWorldDir).path }
val importedProjectWorkspaces =
YarnImportedPackagesVersionResolver(logger, npmProjects, nodeJsWorldDir).resolveAndUpdatePackages()