[Gradle, JS] Not sync files which are not changed
[Gradle, JS] Try to fix test in windows [Gradle, JS] Support hierarchical sync compile [Gradle, JS] Add test on syncing only changed files [Gradle, JS] Use relative path instead of just name ^KT-56719 fixed
This commit is contained in:
committed by
Space Team
parent
fbcaf3efeb
commit
a4ce2ced6d
+90
-2
@@ -25,10 +25,10 @@ import org.jetbrains.kotlin.gradle.tasks.USING_JS_IR_BACKEND_MESSAGE
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.util.jsCompilerType
|
||||
import org.jetbrains.kotlin.gradle.util.normalizePath
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.condition.DisabledIf
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.io.path.*
|
||||
@@ -110,7 +110,6 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
||||
}
|
||||
|
||||
@GradleTest
|
||||
@Disabled // Persistent IR is no longer supported
|
||||
fun testJsIrIncrementalInParallel(gradleVersion: GradleVersion) {
|
||||
project("kotlin-js-browser-project", gradleVersion) {
|
||||
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
||||
@@ -126,6 +125,95 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Only changed files synced during JS IR build")
|
||||
@GradleTest
|
||||
fun testJsIrOnlyChangedFilesSynced(gradleVersion: GradleVersion) {
|
||||
project("kotlin-js-browser-project", gradleVersion) {
|
||||
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
||||
|
||||
val filesModified: MutableMap<String, Long> = mutableMapOf()
|
||||
|
||||
build("compileDevelopmentExecutableKotlinJs") {
|
||||
assertTasksExecuted(":app:developmentExecutableCompileSync")
|
||||
|
||||
projectPath.resolve("build/js/packages/kotlin-js-browser-app")
|
||||
.resolve("kotlin")
|
||||
.toFile()
|
||||
.walkTopDown()
|
||||
.associateByTo(filesModified, { it.path }) {
|
||||
it.lastModified()
|
||||
}
|
||||
}
|
||||
|
||||
projectPath.resolve("base/src/main/kotlin/Base.kt").modify {
|
||||
it.replace("73", "37")
|
||||
}
|
||||
|
||||
val fooTxt = projectPath.resolve("app/src/main/resources/foo/foo.txt")
|
||||
fooTxt.parent.toFile().mkdirs()
|
||||
fooTxt.createFile().writeText("foo")
|
||||
|
||||
build("compileDevelopmentExecutableKotlinJs") {
|
||||
assertTasksExecuted(":app:developmentExecutableCompileSync")
|
||||
|
||||
val modified = projectPath.resolve("build/js/packages/kotlin-js-browser-app")
|
||||
.resolve("kotlin")
|
||||
.toFile()
|
||||
.walkTopDown()
|
||||
.filter { it.isFile }
|
||||
.filterNot { filesModified[it.path] == it.lastModified() }
|
||||
.toSet()
|
||||
|
||||
assertEquals(
|
||||
setOf(
|
||||
projectPath.resolve("build/js/packages/kotlin-js-browser-app/kotlin/kotlin-js-browser-base-js-ir.js").toFile(),
|
||||
projectPath.resolve("build/js/packages/kotlin-js-browser-app/kotlin/foo/foo.txt").toFile(),
|
||||
),
|
||||
modified.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
projectPath.resolve("build/js/packages/kotlin-js-browser-app")
|
||||
.resolve("kotlin")
|
||||
.toFile()
|
||||
.walkTopDown()
|
||||
.associateByTo(filesModified, { it.path }) {
|
||||
it.lastModified()
|
||||
}
|
||||
|
||||
fooTxt.writeText("bar")
|
||||
|
||||
build("compileDevelopmentExecutableKotlinJs") {
|
||||
assertTasksExecuted(":app:developmentExecutableCompileSync")
|
||||
|
||||
val modified = projectPath.resolve("build/js/packages/kotlin-js-browser-app")
|
||||
.resolve("kotlin")
|
||||
.toFile()
|
||||
.walkTopDown()
|
||||
.filter { it.isFile }
|
||||
.filterNot { filesModified[it.path] == it.lastModified() }
|
||||
.toSet()
|
||||
|
||||
assertEquals(
|
||||
setOf(
|
||||
projectPath.resolve("build/js/packages/kotlin-js-browser-app/kotlin/foo/foo.txt").toFile(),
|
||||
),
|
||||
modified.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
fooTxt.deleteExisting()
|
||||
|
||||
|
||||
build("compileDevelopmentExecutableKotlinJs") {
|
||||
assertTasksExecuted(":app:developmentExecutableCompileSync")
|
||||
|
||||
assertFileInProjectNotExists("build/js/packages/kotlin-js-browser-app/kotlin/foo/foo.txt")
|
||||
assertFileInProjectNotExists("build/js/packages/kotlin-js-browser-app/sync-hashes/foo/foo.txt.hash")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("falsify kotlin js compiler args")
|
||||
@GradleTest
|
||||
fun testFalsifyKotlinJsCompilerArgs(gradleVersion: GradleVersion) {
|
||||
|
||||
+5
-16
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
@@ -22,7 +21,6 @@ import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.internal.RewriteSourceMapFilterReader
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||
@@ -131,10 +129,11 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerCompileSync(binary: JsIrBinary): TaskProvider<Copy> {
|
||||
private fun registerCompileSync(binary: JsIrBinary): TaskProvider<SyncExecutableTask> {
|
||||
val compilation = binary.compilation
|
||||
val npmProject = compilation.npmProject
|
||||
return project.registerTask<Copy>(
|
||||
|
||||
return project.registerTask<SyncExecutableTask>(
|
||||
binary.linkSyncTaskName
|
||||
) { task ->
|
||||
task.from(
|
||||
@@ -145,18 +144,8 @@ constructor(
|
||||
|
||||
task.from(project.tasks.named(compilation.processResourcesTaskName))
|
||||
|
||||
// Rewrite relative paths in sourcemaps in the target directory
|
||||
task.eachFile {
|
||||
if (it.name.endsWith(".js.map")) {
|
||||
it.filter(
|
||||
mapOf(
|
||||
"srcSourceRoot" to it.file.parentFile,
|
||||
"targetSourceRoot" to npmProject.dist
|
||||
),
|
||||
RewriteSourceMapFilterReader::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
val hashDir = npmProject.dir.resolve("sync-hashes")
|
||||
task.hashDir.set(hashDir)
|
||||
|
||||
task.into(npmProject.dist)
|
||||
}
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.internal.hash.FileHasher
|
||||
import org.jetbrains.kotlin.gradle.targets.js.internal.RewriteSourceMapFilterReader
|
||||
import org.jetbrains.kotlin.gradle.targets.js.toHex
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class SyncExecutableTask : Copy() {
|
||||
|
||||
@get:Inject
|
||||
abstract val fileHasher: FileHasher
|
||||
|
||||
@get:Inject
|
||||
abstract val objects: ObjectFactory
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val hashDir: Property<File>
|
||||
|
||||
override fun copy() {
|
||||
val actualFiles = mutableSetOf<File>()
|
||||
|
||||
val hashDirFile = hashDir.get()
|
||||
eachFile {
|
||||
actualFiles.add(it.relativeSourcePath.getFile(destinationDir))
|
||||
|
||||
val hashFile = hashDirFile.resolve(it.relativeSourcePath.pathString + ".$HASH_EXTENSION")
|
||||
|
||||
val currentHash = fileHasher.hash(it.file)
|
||||
val currentHashHex = currentHash.toByteArray().toHex()
|
||||
|
||||
if (hashFile.exists()) {
|
||||
val previousHash = hashFile.readText()
|
||||
|
||||
if (previousHash == currentHashHex) {
|
||||
it.exclude()
|
||||
return@eachFile
|
||||
}
|
||||
} else {
|
||||
hashFile.parentFile.mkdirs()
|
||||
}
|
||||
|
||||
hashFile.writeText(currentHashHex)
|
||||
}
|
||||
|
||||
// Rewrite relative paths in sourcemaps in the target directory
|
||||
eachFile {
|
||||
if (it.name.endsWith(".js.map")) {
|
||||
it.filter(
|
||||
mapOf(
|
||||
RewriteSourceMapFilterReader::srcSourceRoot.name to it.file.parentFile,
|
||||
RewriteSourceMapFilterReader::targetSourceRoot.name to destinationDir
|
||||
),
|
||||
RewriteSourceMapFilterReader::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
super.copy()
|
||||
|
||||
objects.fileTree()
|
||||
.from(hashDirFile)
|
||||
.files
|
||||
.forEach {
|
||||
if (destinationDir.resolve(it.relativeTo(hashDirFile).path.removeSuffix(".$HASH_EXTENSION")) !in actualFiles) {
|
||||
it.delete()
|
||||
}
|
||||
}
|
||||
|
||||
objects.fileTree()
|
||||
.from(destinationDir)
|
||||
.files
|
||||
.forEach {
|
||||
if (it !in actualFiles) {
|
||||
it.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val HASH_EXTENSION = "hash"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user