[Gradle, JS] Implement own IncrementalSyncTask
This commit is contained in:
committed by
Space Team
parent
7d2ba28911
commit
63e27a9713
@@ -1484,6 +1484,16 @@ public abstract interface class org/jetbrains/kotlin/gradle/tasks/CompileUsingKo
|
||||
public abstract fun getUseDaemonFallbackStrategy ()Lorg/gradle/api/provider/Property;
|
||||
}
|
||||
|
||||
public abstract interface class org/jetbrains/kotlin/gradle/tasks/IncrementalSyncTask : org/gradle/api/Task {
|
||||
public abstract fun getDestinationDir ()Ljava/io/File;
|
||||
public abstract fun getDestinationDirectory ()Lorg/gradle/api/provider/Property;
|
||||
public abstract fun getFrom ()Lorg/gradle/api/file/ConfigurableFileCollection;
|
||||
}
|
||||
|
||||
public final class org/jetbrains/kotlin/gradle/tasks/IncrementalSyncTask$DefaultImpls {
|
||||
public static fun getDestinationDir (Lorg/jetbrains/kotlin/gradle/tasks/IncrementalSyncTask;)Ljava/io/File;
|
||||
}
|
||||
|
||||
public abstract interface class org/jetbrains/kotlin/gradle/tasks/Kapt : org/jetbrains/kotlin/gradle/tasks/BaseKapt {
|
||||
public abstract fun getAddJdkClassesToClasspath ()Lorg/gradle/api/provider/Property;
|
||||
public abstract fun getKaptJars ()Lorg/gradle/api/file/ConfigurableFileCollection;
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.kotlin.gradle.tasks
|
||||
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.work.NormalizeLineEndings
|
||||
import java.io.File
|
||||
|
||||
interface IncrementalSyncTask : Task {
|
||||
@get:InputFiles
|
||||
@get:NormalizeLineEndings
|
||||
@get:IgnoreEmptyDirectories
|
||||
@get:SkipWhenEmpty
|
||||
val from: ConfigurableFileCollection
|
||||
|
||||
@get:OutputDirectory
|
||||
val destinationDirectory: Property<File>
|
||||
|
||||
@get:Internal
|
||||
@Deprecated("Use destinationDirProperty with Provider API", ReplaceWith("destinationDirProperty.get()"))
|
||||
val destinationDir: File
|
||||
get() = destinationDirectory.get()
|
||||
}
|
||||
-1
@@ -209,7 +209,6 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.CopySpec
|
||||
import org.gradle.api.file.FileSystemOperations
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.work.ChangeType
|
||||
import org.gradle.work.DisableCachingByDefault
|
||||
import org.gradle.work.InputChanges
|
||||
import org.jetbrains.kotlin.gradle.targets.js.internal.RewriteSourceMapFilterReader
|
||||
import org.jetbrains.kotlin.gradle.tasks.IncrementalSyncTask
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
@DisableCachingByDefault
|
||||
abstract class DefaultIncrementalSyncTask : DefaultTask(), IncrementalSyncTask {
|
||||
|
||||
@get:Inject
|
||||
abstract val fs: FileSystemOperations
|
||||
|
||||
@get:Inject
|
||||
abstract val objectFactory: ObjectFactory
|
||||
|
||||
@TaskAction
|
||||
fun doCopy(inputChanges: InputChanges) {
|
||||
val destinationDir = destinationDirectory.get()
|
||||
val commonAction: CopySpec.() -> Unit = {
|
||||
into(destinationDir)
|
||||
// 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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val work = if (!inputChanges.isIncremental) {
|
||||
fs.copy {
|
||||
it.from(from)
|
||||
it.commonAction()
|
||||
}.didWork
|
||||
} else {
|
||||
val changedFiles = inputChanges.getFileChanges(from)
|
||||
|
||||
val modified = changedFiles
|
||||
.filter {
|
||||
it.changeType == ChangeType.ADDED || it.changeType == ChangeType.MODIFIED
|
||||
}
|
||||
.map { it.file }
|
||||
.toSet()
|
||||
|
||||
val forCopy = from.asFileTree
|
||||
.matching { patternFilterable ->
|
||||
patternFilterable.exclude {
|
||||
it.file.isFile && it.file !in modified
|
||||
}
|
||||
}
|
||||
|
||||
val nonRemovingFiles = mutableSetOf<File>()
|
||||
|
||||
from.asFileTree
|
||||
.visit {
|
||||
nonRemovingFiles.add(it.relativePath.getFile(destinationDir))
|
||||
}
|
||||
|
||||
val removingFiles = objectFactory.fileTree()
|
||||
.from(destinationDir)
|
||||
.also { fileTree ->
|
||||
fileTree.exclude {
|
||||
it.file.isFile && it.file in nonRemovingFiles
|
||||
}
|
||||
}
|
||||
|
||||
val deleteWork = fs.delete {
|
||||
it.delete(removingFiles)
|
||||
}
|
||||
|
||||
val copyWork = fs.copy {
|
||||
it.from(forCopy)
|
||||
it.commonAction()
|
||||
}
|
||||
|
||||
deleteWork.didWork || copyWork.didWork
|
||||
}
|
||||
|
||||
didWork = work
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
@@ -14,9 +13,9 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.Distribution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsBinaryContainer.Companion.generateBinaryName
|
||||
import org.jetbrains.kotlin.gradle.targets.js.subtargets.DefaultDistribution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.subtargets.createDefaultDistribution
|
||||
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.IncrementalSyncTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.withType
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
|
||||
@@ -56,9 +55,9 @@ sealed class JsIrBinary(
|
||||
|
||||
val validateGeneratedTsTaskName: String = validateTypeScriptTaskName()
|
||||
|
||||
val linkSyncTask: TaskProvider<Copy>
|
||||
val linkSyncTask: TaskProvider<IncrementalSyncTask>
|
||||
get() = target.project.tasks
|
||||
.withType<Copy>()
|
||||
.withType<IncrementalSyncTask>()
|
||||
.named(linkSyncTaskName)
|
||||
|
||||
private fun linkSyncTaskName(): String =
|
||||
|
||||
+2
-2
@@ -164,7 +164,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
||||
task.commonConfigure(
|
||||
compilation = compilation,
|
||||
mode = mode,
|
||||
inputFilesDirectory = binary.linkSyncTask.map { it.destinationDir },
|
||||
inputFilesDirectory = binary.linkSyncTask.flatMap { it.destinationDirectory },
|
||||
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
|
||||
configurationActions = runTaskConfigurations,
|
||||
nodeJs = nodeJs,
|
||||
@@ -229,7 +229,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
||||
task.commonConfigure(
|
||||
compilation = compilation,
|
||||
mode = mode,
|
||||
inputFilesDirectory = binary.linkSyncTask.map { it.destinationDir },
|
||||
inputFilesDirectory = binary.linkSyncTask.flatMap { it.destinationDirectory },
|
||||
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
|
||||
configurationActions = webpackTaskConfigurations,
|
||||
nodeJs = nodeJs,
|
||||
|
||||
+2
-2
@@ -37,8 +37,8 @@ abstract class KotlinD8Ir @Inject constructor(target: KotlinJsIrTarget) :
|
||||
inputFileProperty.fileProvider(
|
||||
binary.linkSyncTask.flatMap { linkSyncTask ->
|
||||
binary.linkTask.flatMap { linkTask ->
|
||||
linkTask.outputFileProperty.map {
|
||||
linkSyncTask.destinationDir.resolve(it.name)
|
||||
linkTask.outputFileProperty.map { file ->
|
||||
linkSyncTask.destinationDirectory.get().resolve(file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -125,8 +125,8 @@ abstract class KotlinJsIrSubTarget(
|
||||
testJs.inputFileProperty.fileProvider(
|
||||
binary.linkSyncTask.flatMap { linkSyncTask ->
|
||||
binary.linkTask.flatMap { linkTask ->
|
||||
linkTask.outputFileProperty.map {
|
||||
linkSyncTask.destinationDir.resolve(it.name)
|
||||
linkTask.outputFileProperty.map { file ->
|
||||
linkSyncTask.destinationDirectory.get().resolve(file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-8
@@ -131,25 +131,22 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerCompileSync(binary: JsIrBinary): TaskProvider<SyncExecutableTask> {
|
||||
private fun registerCompileSync(binary: JsIrBinary): TaskProvider<DefaultIncrementalSyncTask> {
|
||||
val compilation = binary.compilation
|
||||
val npmProject = compilation.npmProject
|
||||
|
||||
return project.registerTask<SyncExecutableTask>(
|
||||
return project.registerTask<DefaultIncrementalSyncTask>(
|
||||
binary.linkSyncTaskName
|
||||
) { task ->
|
||||
task.from(
|
||||
task.from.from(
|
||||
binary.linkTask.flatMap { linkTask ->
|
||||
linkTask.destinationDirectory.map { it.asFile }
|
||||
}
|
||||
)
|
||||
|
||||
task.from(project.tasks.named(compilation.processResourcesTaskName))
|
||||
task.from.from(project.tasks.named(compilation.processResourcesTaskName))
|
||||
|
||||
val hashDir = npmProject.dir.resolve("sync-hashes")
|
||||
task.hashDir.set(hashDir)
|
||||
|
||||
task.into(npmProject.dist)
|
||||
task.destinationDirectory.set(npmProject.dist)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -40,8 +40,8 @@ abstract class KotlinNodeJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
||||
inputFileProperty.fileProvider(
|
||||
binary.linkSyncTask.flatMap { linkSyncTask ->
|
||||
binary.linkTask.flatMap { linkTask ->
|
||||
linkTask.outputFileProperty.map {
|
||||
linkSyncTask.destinationDir.resolve(it.name)
|
||||
linkTask.outputFileProperty.map { file ->
|
||||
linkSyncTask.destinationDirectory.get().resolve(file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-92
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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