[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.testbase.*
|
||||||
import org.jetbrains.kotlin.gradle.util.jsCompilerType
|
import org.jetbrains.kotlin.gradle.util.jsCompilerType
|
||||||
import org.jetbrains.kotlin.gradle.util.normalizePath
|
import org.jetbrains.kotlin.gradle.util.normalizePath
|
||||||
import org.junit.jupiter.api.Disabled
|
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.condition.DisabledIf
|
import org.junit.jupiter.api.condition.DisabledIf
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
import kotlin.io.path.*
|
import kotlin.io.path.*
|
||||||
@@ -110,7 +110,6 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GradleTest
|
@GradleTest
|
||||||
@Disabled // Persistent IR is no longer supported
|
|
||||||
fun testJsIrIncrementalInParallel(gradleVersion: GradleVersion) {
|
fun testJsIrIncrementalInParallel(gradleVersion: GradleVersion) {
|
||||||
project("kotlin-js-browser-project", gradleVersion) {
|
project("kotlin-js-browser-project", gradleVersion) {
|
||||||
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
|
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")
|
@DisplayName("falsify kotlin js compiler args")
|
||||||
@GradleTest
|
@GradleTest
|
||||||
fun testFalsifyKotlinJsCompilerArgs(gradleVersion: GradleVersion) {
|
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.NamedDomainObjectContainer
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.tasks.Copy
|
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
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.KotlinJsTarget
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec
|
import org.jetbrains.kotlin.gradle.targets.js.binaryen.BinaryenExec
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.*
|
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.npm.npmProject
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
|
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
|
||||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
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 compilation = binary.compilation
|
||||||
val npmProject = compilation.npmProject
|
val npmProject = compilation.npmProject
|
||||||
return project.registerTask<Copy>(
|
|
||||||
|
return project.registerTask<SyncExecutableTask>(
|
||||||
binary.linkSyncTaskName
|
binary.linkSyncTaskName
|
||||||
) { task ->
|
) { task ->
|
||||||
task.from(
|
task.from(
|
||||||
@@ -145,18 +144,8 @@ constructor(
|
|||||||
|
|
||||||
task.from(project.tasks.named(compilation.processResourcesTaskName))
|
task.from(project.tasks.named(compilation.processResourcesTaskName))
|
||||||
|
|
||||||
// Rewrite relative paths in sourcemaps in the target directory
|
val hashDir = npmProject.dir.resolve("sync-hashes")
|
||||||
task.eachFile {
|
task.hashDir.set(hashDir)
|
||||||
if (it.name.endsWith(".js.map")) {
|
|
||||||
it.filter(
|
|
||||||
mapOf(
|
|
||||||
"srcSourceRoot" to it.file.parentFile,
|
|
||||||
"targetSourceRoot" to npmProject.dist
|
|
||||||
),
|
|
||||||
RewriteSourceMapFilterReader::class.java
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task.into(npmProject.dist)
|
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