[Gradle, JS] Fix K/JS project build with configuration cache (part 3)
Now configuration cache enabled builds with JS tasks does not fails but prints warning and skips execution on subsequent builds. Relates to KT-42494
This commit is contained in:
+1
-1
@@ -140,8 +140,8 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
||||
|
||||
project.locateOrRegisterTask<ProcessResources>(compilation.processResourcesTaskName) { resourcesTask ->
|
||||
resourcesTask.description = "Processes $resourceSet."
|
||||
DslObject(resourcesTask).conventionMapping.map("destinationDir") { project.file(compilation.output.resourcesDir) }
|
||||
resourcesTask.from(resourceSet)
|
||||
resourcesTask.into(project.file(compilation.output.resourcesDir))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
||||
import org.jetbrains.kotlin.gradle.utils.disableTaskOnConfigurationCacheBuild
|
||||
import java.io.File
|
||||
|
||||
abstract class DukatTask(
|
||||
@@ -21,6 +22,11 @@ abstract class DukatTask(
|
||||
@get:Internal
|
||||
protected val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
|
||||
init {
|
||||
// TODO: temporary workaround for configuration cache enabled builds
|
||||
disableTaskOnConfigurationCacheBuild { nodeJs.npmResolutionManager.toString() }
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
override val nodeModulesRequired: Boolean
|
||||
get() = true
|
||||
|
||||
+3
-2
@@ -21,8 +21,9 @@ constructor(
|
||||
override val considerGeneratingFlag: Boolean = true
|
||||
|
||||
@get:OutputDirectory
|
||||
override val destinationDir: File
|
||||
get() = compilation.npmProject.externalsDir
|
||||
override val destinationDir: File by lazy {
|
||||
compilation.npmProject.externalsDir
|
||||
}
|
||||
|
||||
@delegate:Transient
|
||||
private val executor by lazy {
|
||||
|
||||
+3
-2
@@ -66,8 +66,9 @@ open class NodeJsRootExtension(@Transient val rootProject: Project) : Configurat
|
||||
val rootPackageJsonTaskProvider: TaskProvider<RootPackageJsonTask>
|
||||
get() = rootProject.tasks.withType(RootPackageJsonTask::class.java).named(RootPackageJsonTask.NAME)
|
||||
|
||||
val rootPackageDir: File
|
||||
get() = rootProject.buildDir.resolve("js")
|
||||
val rootPackageDir: File by lazy {
|
||||
rootProject.buildDir.resolve("js")
|
||||
}
|
||||
|
||||
internal val rootNodeModulesStateFile: File
|
||||
get() = rootPackageDir.resolve("node_modules.state")
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import java.net.URI
|
||||
|
||||
@CacheableTask
|
||||
open class NodeJsSetupTask : DefaultTask() {
|
||||
private val settings get() = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val settings = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val env by lazy { settings.requireConfigured() }
|
||||
|
||||
val ivyDependency: String
|
||||
|
||||
+1
-1
@@ -16,12 +16,12 @@ import org.gradle.api.internal.artifacts.dependencies.SelfResolvingDependencyInt
|
||||
import org.gradle.api.tasks.TaskDependency
|
||||
import org.gradle.internal.component.local.model.DefaultLibraryBinaryIdentifier
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency.Scope.DEV
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject.Companion.PACKAGE_JSON
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.resolved.KotlinCompilationNpmResolution
|
||||
import java.io.File
|
||||
|
||||
data class NpmDependency(
|
||||
@Transient
|
||||
internal val project: Project,
|
||||
private val name: String,
|
||||
private val version: String,
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ val KotlinJsCompilation.npmProject: NpmProject
|
||||
*
|
||||
* More info can be obtained from [KotlinCompilationNpmResolution], which is available after project resolution (after [KotlinNpmInstallTask] execution).
|
||||
*/
|
||||
open class NpmProject(val compilation: KotlinJsCompilation) {
|
||||
open class NpmProject(@Transient val compilation: KotlinJsCompilation) {
|
||||
val name: String
|
||||
get() = buildNpmProjectName()
|
||||
|
||||
|
||||
+9
-2
@@ -13,6 +13,7 @@ import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject.Companion.PACKAGE_JSON
|
||||
import org.jetbrains.kotlin.gradle.utils.disableTaskOnConfigurationCacheBuild
|
||||
import org.jetbrains.kotlin.gradle.utils.property
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
@@ -23,13 +24,17 @@ constructor(
|
||||
@Transient
|
||||
private val compilation: KotlinJsCompilation
|
||||
) : DefaultTask() {
|
||||
@Transient
|
||||
private val npmProject = compilation.npmProject
|
||||
private val nodeJs = npmProject.nodeJs
|
||||
|
||||
private val compilationResolution
|
||||
get() = nodeJs.npmResolutionManager.requireInstalled()[project][npmProject.compilation]
|
||||
|
||||
init {
|
||||
// TODO: temporary workaround for configuration cache enabled builds
|
||||
disableTaskOnConfigurationCacheBuild { nodeJs.npmResolutionManager.toString() }
|
||||
}
|
||||
|
||||
@get:Input
|
||||
val packageJsonCustomFields: Map<String, Any?>
|
||||
get() = PackageJson(fakePackageJsonValue, fakePackageJsonValue)
|
||||
@@ -51,11 +56,13 @@ constructor(
|
||||
private val realExternalDependencies: Collection<NpmDependency>
|
||||
get() = compilationResolution.externalNpmDependencies
|
||||
|
||||
private val publicPackageJsonTaskName = npmProject.publicPackageJsonTaskName
|
||||
|
||||
@get:OutputFile
|
||||
var packageJsonFile: File by property {
|
||||
project.buildDir
|
||||
.resolve("tmp")
|
||||
.resolve(npmProject.publicPackageJsonTaskName)
|
||||
.resolve(publicPackageJsonTaskName)
|
||||
.resolve(PACKAGE_JSON)
|
||||
}
|
||||
|
||||
|
||||
+12
-4
@@ -11,6 +11,7 @@ import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.utils.disableTaskOnConfigurationCacheBuild
|
||||
import java.io.File
|
||||
|
||||
open class KotlinNpmInstallTask : DefaultTask() {
|
||||
@@ -27,17 +28,24 @@ open class KotlinNpmInstallTask : DefaultTask() {
|
||||
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val resolutionManager get() = nodeJs.npmResolutionManager
|
||||
|
||||
init {
|
||||
// TODO: temporary workaround for configuration cache enabled builds
|
||||
disableTaskOnConfigurationCacheBuild { resolutionManager.toString() }
|
||||
}
|
||||
|
||||
@Input
|
||||
val args: MutableList<String> = mutableListOf()
|
||||
|
||||
@Suppress("unused")
|
||||
@get:InputFiles
|
||||
val packageJsonFiles: Collection<File>
|
||||
get() = resolutionManager.packageJsonFiles
|
||||
val packageJsonFiles: Collection<File> by lazy {
|
||||
resolutionManager.packageJsonFiles
|
||||
}
|
||||
|
||||
@get:InputFiles
|
||||
val preparedFiles: Collection<File>
|
||||
get() = nodeJs.packageManager.preparedFiles(project)
|
||||
val preparedFiles: Collection<File> by lazy {
|
||||
nodeJs.packageManager.preparedFiles(project)
|
||||
}
|
||||
|
||||
// avoid using node_modules as output directory, as it is significantly slows down build
|
||||
@get:OutputFile
|
||||
|
||||
+12
-8
@@ -33,11 +33,12 @@ open class KotlinPackageJsonTask : DefaultTask() {
|
||||
get() = compilationResolver.packageJsonProducer
|
||||
|
||||
@get:Input
|
||||
val packageJsonCustomFields: Map<String, Any?>
|
||||
get() = PackageJson(fakePackageJsonValue, fakePackageJsonValue)
|
||||
val packageJsonCustomFields: Map<String, Any?> by lazy {
|
||||
PackageJson(fakePackageJsonValue, fakePackageJsonValue)
|
||||
.apply {
|
||||
compilation.packageJsonHandlers.forEach { it() }
|
||||
}.customFields
|
||||
}
|
||||
|
||||
private fun findDependentTasks(): Collection<Any> =
|
||||
producer.internalDependencies.map { dependentResolver ->
|
||||
@@ -47,18 +48,21 @@ open class KotlinPackageJsonTask : DefaultTask() {
|
||||
}
|
||||
|
||||
@get:Input
|
||||
internal val toolsNpmDependencies: List<String>
|
||||
get() = nodeJs.taskRequirements
|
||||
internal val toolsNpmDependencies: List<String> by lazy {
|
||||
nodeJs.taskRequirements
|
||||
.getCompilationNpmRequirements(compilation)
|
||||
.map { it.uniqueRepresentation() }
|
||||
}
|
||||
|
||||
@get:Nested
|
||||
internal val producerInputs: KotlinCompilationNpmResolver.PackageJsonProducerInputs
|
||||
get() = producer.inputs
|
||||
internal val producerInputs: KotlinCompilationNpmResolver.PackageJsonProducerInputs by lazy {
|
||||
producer.inputs
|
||||
}
|
||||
|
||||
@get:OutputFile
|
||||
val packageJson: File
|
||||
get() = compilationResolver.npmProject.prePackageJsonFile
|
||||
val packageJson: File by lazy {
|
||||
compilationResolver.npmProject.prePackageJsonFile
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun resolve() {
|
||||
|
||||
+6
@@ -10,6 +10,7 @@ import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject
|
||||
import org.jetbrains.kotlin.gradle.utils.disableTaskOnConfigurationCacheBuild
|
||||
import java.io.File
|
||||
|
||||
open class RootPackageJsonTask : DefaultTask() {
|
||||
@@ -24,6 +25,11 @@ open class RootPackageJsonTask : DefaultTask() {
|
||||
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val resolutionManager get() = nodeJs.npmResolutionManager
|
||||
|
||||
init {
|
||||
// TODO: temporary workaround for configuration cache enabled builds
|
||||
disableTaskOnConfigurationCacheBuild { resolutionManager.toString() }
|
||||
}
|
||||
|
||||
@get:OutputFile
|
||||
val rootPackageJson: File
|
||||
get() = nodeJs.rootPackageDir.resolve(NpmProject.PACKAGE_JSON)
|
||||
|
||||
+24
-12
@@ -25,6 +25,7 @@ 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.testing.internal.reportsDir
|
||||
import org.jetbrains.kotlin.gradle.utils.disableTaskOnConfigurationCacheBuild
|
||||
import org.jetbrains.kotlin.gradle.utils.injected
|
||||
import org.jetbrains.kotlin.gradle.utils.newFileProperty
|
||||
import org.jetbrains.kotlin.gradle.utils.property
|
||||
@@ -41,6 +42,11 @@ constructor(
|
||||
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val versions = nodeJs.versions
|
||||
|
||||
init {
|
||||
// TODO: temporary workaround for configuration cache enabled builds
|
||||
disableTaskOnConfigurationCacheBuild { nodeJs.npmResolutionManager.toString() }
|
||||
}
|
||||
|
||||
@get:Inject
|
||||
open val fileResolver: FileResolver
|
||||
get() = injected
|
||||
@@ -50,11 +56,13 @@ constructor(
|
||||
get() = injected
|
||||
|
||||
@Suppress("unused")
|
||||
val compilationId: String
|
||||
@Input get() = compilation.let {
|
||||
@get:Input
|
||||
val compilationId: String by lazy {
|
||||
compilation.let {
|
||||
val target = it.target
|
||||
target.project.path + "@" + target.name + ":" + it.compilationName
|
||||
}
|
||||
}
|
||||
|
||||
@Input
|
||||
var mode: Mode = Mode.DEVELOPMENT
|
||||
@@ -82,11 +90,15 @@ constructor(
|
||||
internal var resolveFromModulesFirst: Boolean = false
|
||||
|
||||
@Suppress("unused")
|
||||
val runtimeClasspath: FileCollection
|
||||
@InputFiles get() = compilation.compileDependencyFiles
|
||||
@get:InputFiles
|
||||
val runtimeClasspath: FileCollection by lazy {
|
||||
compilation.compileDependencyFiles
|
||||
}
|
||||
|
||||
open val configFile: File
|
||||
@OutputFile get() = compilation.npmProject.dir.resolve("webpack.config.js")
|
||||
@get:OutputFile
|
||||
open val configFile: File by lazy {
|
||||
compilation.npmProject.dir.resolve("webpack.config.js")
|
||||
}
|
||||
|
||||
@Input
|
||||
var saveEvaluatedConfigFile: Boolean = true
|
||||
@@ -134,12 +146,12 @@ constructor(
|
||||
open val reportDir: File
|
||||
@Internal get() = reportDirProvider.get()
|
||||
|
||||
open val reportDirProvider: Provider<File>
|
||||
@OutputDirectory get() = entryProperty
|
||||
.map { it.asFile.nameWithoutExtension }
|
||||
.map {
|
||||
project.reportsDir.resolve("webpack").resolve(it)
|
||||
}
|
||||
@OutputDirectory
|
||||
open val reportDirProvider: Provider<File> = entryProperty
|
||||
.map { it.asFile.nameWithoutExtension }
|
||||
.map {
|
||||
project.reportsDir.resolve("webpack").resolve(it)
|
||||
}
|
||||
|
||||
open val evaluatedConfigFile: File
|
||||
@Internal get() = evaluatedConfigFileProvider.get()
|
||||
|
||||
-8
@@ -58,11 +58,3 @@ internal data class ParsedGradleVersion(val major: Int, val minor: Int) : Compar
|
||||
fun isGradleVersionAtLeast(major: Int, minor: Int) =
|
||||
ParsedGradleVersion.parse(GradleVersion.current().version)
|
||||
?.let { it >= ParsedGradleVersion(major, minor) } ?: false
|
||||
|
||||
fun isConfigurationCacheAvailable(gradle: Gradle) =
|
||||
try {
|
||||
val startParameters = gradle.startParameter
|
||||
startParameters.javaClass.getMethod("isConfigurationCache").invoke(startParameters) as? Boolean
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
} ?: false
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.utils
|
||||
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.invocation.Gradle
|
||||
|
||||
internal fun isConfigurationCacheAvailable(gradle: Gradle) =
|
||||
try {
|
||||
val startParameters = gradle.startParameter
|
||||
startParameters.javaClass.getMethod("isConfigurationCache").invoke(startParameters) as? Boolean
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
} ?: false
|
||||
|
||||
internal fun Task.disableTaskOnConfigurationCacheBuild(transientFieldAccessor: () -> Unit) {
|
||||
if (isConfigurationCacheAvailable(project.gradle)) {
|
||||
onlyIf {
|
||||
logger.warn("Configuration cache is not yet fully supported: use it at your own risk.")
|
||||
try {
|
||||
// transientFieldAccessor() will throw an exception after loading task from configuration cache
|
||||
transientFieldAccessor()
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Task cannot be executed because of corrupted state after loading from configuration cache.")
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user