[Gradle, JS] Distinguish cache directories for js ir incremental compilation

[Gradle, JS] Make cleanOutputsAndLocalState as member method

^KT-56765 fixed
This commit is contained in:
Ilya Goncharov
2023-02-21 16:37:37 +00:00
committed by Space Team
parent 81746e5aa1
commit bcb517d66b
6 changed files with 86 additions and 20 deletions
@@ -9,6 +9,7 @@ import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
import java.io.File
import kotlin.io.path.appendText
import kotlin.io.path.readText
import kotlin.io.path.writeText
@@ -34,7 +35,7 @@ class Kotlin2JsIrBeIncrementalCompilationIT : KGPBaseTest() {
project("kotlin-js-ir-ic-rebuild-after-error", gradleVersion) {
fun readCacheFiles(): Map<String, Int> {
val cacheFiles = mutableMapOf<String, Int>()
projectPath.resolve("app/build/klib/cache/").toFile().walk().forEach { cachedFile ->
projectPath.resolve("app/build/klib/cache/js/developmentExecutable").toFile().walk().forEach { cachedFile ->
if (cachedFile.isFile) {
cacheFiles[cachedFile.absolutePath] = cachedFile.readBytes().contentHashCode()
}
@@ -43,7 +44,7 @@ class Kotlin2JsIrBeIncrementalCompilationIT : KGPBaseTest() {
}
val srcFile = projectPath.resolve("app/src/main/kotlin/App.kt").toFile()
val guardFile = projectPath.resolve("app/build/klib/cache/cache.guard").toFile()
val guardFile = projectPath.resolve("app/build/klib/cache/js/developmentExecutable/cache.guard").toFile()
val badCode = srcFile.readText()
var successfulBuildCacheFiles = emptyMap<String, Int>()
@@ -126,7 +127,7 @@ class Kotlin2JsIrBeIncrementalCompilationIT : KGPBaseTest() {
fun testMultipleArtifacts(gradleVersion: GradleVersion) {
project("kotlin-js-ir-ic-multiple-artifacts", gradleVersion) {
build("compileDevelopmentExecutableKotlinJs") {
val cacheDir = projectPath.resolve("app/build/klib/cache/").toFile()
val cacheDir = projectPath.resolve("app/build/klib/cache/js/developmentExecutable").toFile()
val cacheRootDirName = cacheDir.list()?.singleOrNull()
assertTrue("Lib cache root dir should contain 1 element 'version.hash'") {
cacheRootDirName?.startsWith("version.") ?: false
@@ -213,7 +214,7 @@ class Kotlin2JsIrBeIncrementalCompilationIT : KGPBaseTest() {
assertOutputContains(">>> TEST OUT: Hello, Gradle.")
}
val cacheGuard = projectPath.resolve("build/klib/cache/cache.guard").toFile()
val cacheGuard = projectPath.resolve("build/klib/cache/js/developmentExecutable/cache.guard").toFile()
assertFalse(cacheGuard.exists(), "Cache guard file should be removed after successful build")
val srcFile = projectPath.resolve("src/main/kotlin/Main.kt").toFile()
@@ -230,4 +231,52 @@ class Kotlin2JsIrBeIncrementalCompilationIT : KGPBaseTest() {
assertFalse(cacheGuard.exists(), "Cache guard file should be removed after successful build")
}
}
@DisplayName("Separate caches for different binaries")
@GradleTest
fun testSeparateCachesForDifferentBinaries(gradleVersion: GradleVersion) {
project("kotlin-js-ir-ic-multiple-artifacts", gradleVersion) {
val filesToModified = mutableMapOf<File, Long>()
build("compileDevelopmentExecutableKotlinJs") {
val cacheDir = projectPath.resolve("app/build/klib/cache/js/developmentExecutable").toFile()
val cacheRootDirName = cacheDir.list()?.singleOrNull()
val cacheRootDir = cacheDir.resolve(cacheRootDirName!!)
cacheRootDir.listFiles()!!
.forEach {
it.listFiles()!!
.filter { it.isFile }
.filter { it.name == "module.js" }
.forEach {
filesToModified[it] = it.lastModified()
}
}
assertTasksExecuted(":app:compileDevelopmentExecutableKotlinJs")
}
build("compileTestDevelopmentExecutableKotlinJs") {
val cacheDir = projectPath.resolve("app/build/klib/cache/js/developmentExecutable").toFile()
val cacheRootDirName = cacheDir.list()?.singleOrNull()
val cacheRootDir = cacheDir.resolve(cacheRootDirName!!)
val allUpToDate = cacheRootDir.listFiles()!!
.all {
it.listFiles()!!
.filter { it.isFile }
.filter { it.name == "module.js" }
.all {
filesToModified[it] == it.lastModified()
}
}
assertTrue { allUpToDate }
assertTasksExecuted(":app:compileTestDevelopmentExecutableKotlinJs")
}
}
}
}
@@ -4,6 +4,7 @@ plugins {
dependencies {
implementation(project(":lib"))
testImplementation(kotlin("test-js"))
}
kotlin {
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2023 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.
*/
import kotlin.test.Test
import kotlin.test.assertEquals
class MainTest {
@Test
fun testHello() {
assertEquals(true, true)
}
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.DEVELOPMENT
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.PRODUCTION
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
@@ -50,15 +51,6 @@ abstract class KotlinJsIrLink @Inject constructor(
return !entryModule.get().asFile.exists()
}
@get:Internal
val platformType by lazy {
compilation.platformType
}
@Transient
@get:Internal
internal lateinit var compilation: KotlinCompilation<*>
@Transient
@get:Internal
internal val propertiesProvider = PropertiesProvider(project)
@@ -85,8 +77,6 @@ abstract class KotlinJsIrLink @Inject constructor(
@get:Input
internal abstract val modeProperty: Property<KotlinJsBinaryMode>
private val buildDir = project.buildDir
@get:SkipWhenEmpty
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
@@ -95,8 +85,12 @@ abstract class KotlinJsIrLink @Inject constructor(
internal abstract val entryModule: DirectoryProperty
@get:Internal
val rootCacheDirectory by lazy {
buildDir.resolve("klib/cache")
internal abstract val rootCacheDirectory: DirectoryProperty
override fun cleanOutputsAndLocalState(reason: String?) {
if (!usingCacheDirectory()) {
super.cleanOutputsAndLocalState(reason)
}
}
override fun processArgs(args: K2JSCompilerArguments) {
@@ -124,10 +118,13 @@ abstract class KotlinJsIrLink @Inject constructor(
args.includes = entryModule.get().asFile.canonicalPath
if (incrementalJsIr && mode == DEVELOPMENT) {
args.cacheDirectory = rootCacheDirectory.also { it.mkdirs() }.absolutePath
if (usingCacheDirectory()) {
args.cacheDirectory = rootCacheDirectory.get().asFile.also { it.mkdirs() }.absolutePath
}
}
private fun usingCacheDirectory() =
incrementalJsIr && modeProperty.get() == DEVELOPMENT
}
val KotlinPlatformType.fileExtension
@@ -68,6 +68,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast
import java.io.File
import java.nio.file.Files.*
import javax.inject.Inject
import org.jetbrains.kotlin.gradle.tasks.cleanOutputsAndLocalState as cleanOutputsAndLocalStateUtil
const val KOTLIN_BUILD_DIR_NAME = "kotlin"
const val USING_JVM_INCREMENTAL_COMPILATION_MESSAGE = "Using Kotlin/JVM incremental compilation"
@@ -407,6 +408,10 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
buildMetricsService.orNull?.also { it.addTask(path, this.javaClass, buildMetrics) }
}
protected open fun cleanOutputsAndLocalState(reason: String?) {
cleanOutputsAndLocalStateUtil(reason)
}
protected open fun skipCondition(): Boolean = sources.isEmpty
@get:Internal
@@ -34,7 +34,7 @@ internal open class KotlinJsIrLinkConfig(
}
}
).disallowChanges()
task.compilation = compilation
task.rootCacheDirectory.set(project.layout.buildDirectory.map { it.dir("klib/cache/js/${binary.name}") })
task.destinationDirectory.convention(
project.layout.buildDirectory
.dir(COMPILE_SYNC)