[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 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 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 getAddJdkClassesToClasspath ()Lorg/gradle/api/provider/Property;
|
||||||
public abstract fun getKaptJars ()Lorg/gradle/api/file/ConfigurableFileCollection;
|
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")
|
assertTasksExecuted(":app:developmentExecutableCompileSync")
|
||||||
|
|
||||||
assertFileInProjectNotExists("build/js/packages/kotlin-js-browser-app/kotlin/foo/foo.txt")
|
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
|
package org.jetbrains.kotlin.gradle.targets.js.ir
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.tasks.Copy
|
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
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.Distribution
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
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.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.subtargets.createDefaultDistribution
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.typescript.TypeScriptValidationTask
|
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.tasks.withType
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
|
||||||
@@ -56,9 +55,9 @@ sealed class JsIrBinary(
|
|||||||
|
|
||||||
val validateGeneratedTsTaskName: String = validateTypeScriptTaskName()
|
val validateGeneratedTsTaskName: String = validateTypeScriptTaskName()
|
||||||
|
|
||||||
val linkSyncTask: TaskProvider<Copy>
|
val linkSyncTask: TaskProvider<IncrementalSyncTask>
|
||||||
get() = target.project.tasks
|
get() = target.project.tasks
|
||||||
.withType<Copy>()
|
.withType<IncrementalSyncTask>()
|
||||||
.named(linkSyncTaskName)
|
.named(linkSyncTaskName)
|
||||||
|
|
||||||
private fun linkSyncTaskName(): String =
|
private fun linkSyncTaskName(): String =
|
||||||
|
|||||||
+2
-2
@@ -164,7 +164,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
|||||||
task.commonConfigure(
|
task.commonConfigure(
|
||||||
compilation = compilation,
|
compilation = compilation,
|
||||||
mode = mode,
|
mode = mode,
|
||||||
inputFilesDirectory = binary.linkSyncTask.map { it.destinationDir },
|
inputFilesDirectory = binary.linkSyncTask.flatMap { it.destinationDirectory },
|
||||||
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
|
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
|
||||||
configurationActions = runTaskConfigurations,
|
configurationActions = runTaskConfigurations,
|
||||||
nodeJs = nodeJs,
|
nodeJs = nodeJs,
|
||||||
@@ -229,7 +229,7 @@ abstract class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
|||||||
task.commonConfigure(
|
task.commonConfigure(
|
||||||
compilation = compilation,
|
compilation = compilation,
|
||||||
mode = mode,
|
mode = mode,
|
||||||
inputFilesDirectory = binary.linkSyncTask.map { it.destinationDir },
|
inputFilesDirectory = binary.linkSyncTask.flatMap { it.destinationDirectory },
|
||||||
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
|
entryModuleName = binary.linkTask.flatMap { it.compilerOptions.moduleName },
|
||||||
configurationActions = webpackTaskConfigurations,
|
configurationActions = webpackTaskConfigurations,
|
||||||
nodeJs = nodeJs,
|
nodeJs = nodeJs,
|
||||||
|
|||||||
+2
-2
@@ -37,8 +37,8 @@ abstract class KotlinD8Ir @Inject constructor(target: KotlinJsIrTarget) :
|
|||||||
inputFileProperty.fileProvider(
|
inputFileProperty.fileProvider(
|
||||||
binary.linkSyncTask.flatMap { linkSyncTask ->
|
binary.linkSyncTask.flatMap { linkSyncTask ->
|
||||||
binary.linkTask.flatMap { linkTask ->
|
binary.linkTask.flatMap { linkTask ->
|
||||||
linkTask.outputFileProperty.map {
|
linkTask.outputFileProperty.map { file ->
|
||||||
linkSyncTask.destinationDir.resolve(it.name)
|
linkSyncTask.destinationDirectory.get().resolve(file.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -125,8 +125,8 @@ abstract class KotlinJsIrSubTarget(
|
|||||||
testJs.inputFileProperty.fileProvider(
|
testJs.inputFileProperty.fileProvider(
|
||||||
binary.linkSyncTask.flatMap { linkSyncTask ->
|
binary.linkSyncTask.flatMap { linkSyncTask ->
|
||||||
binary.linkTask.flatMap { linkTask ->
|
binary.linkTask.flatMap { linkTask ->
|
||||||
linkTask.outputFileProperty.map {
|
linkTask.outputFileProperty.map { file ->
|
||||||
linkSyncTask.destinationDir.resolve(it.name)
|
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 compilation = binary.compilation
|
||||||
val npmProject = compilation.npmProject
|
val npmProject = compilation.npmProject
|
||||||
|
|
||||||
return project.registerTask<SyncExecutableTask>(
|
return project.registerTask<DefaultIncrementalSyncTask>(
|
||||||
binary.linkSyncTaskName
|
binary.linkSyncTaskName
|
||||||
) { task ->
|
) { task ->
|
||||||
task.from(
|
task.from.from(
|
||||||
binary.linkTask.flatMap { linkTask ->
|
binary.linkTask.flatMap { linkTask ->
|
||||||
linkTask.destinationDirectory.map { it.asFile }
|
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.destinationDirectory.set(npmProject.dist)
|
||||||
task.hashDir.set(hashDir)
|
|
||||||
|
|
||||||
task.into(npmProject.dist)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -40,8 +40,8 @@ abstract class KotlinNodeJsIr @Inject constructor(target: KotlinJsIrTarget) :
|
|||||||
inputFileProperty.fileProvider(
|
inputFileProperty.fileProvider(
|
||||||
binary.linkSyncTask.flatMap { linkSyncTask ->
|
binary.linkSyncTask.flatMap { linkSyncTask ->
|
||||||
binary.linkTask.flatMap { linkTask ->
|
binary.linkTask.flatMap { linkTask ->
|
||||||
linkTask.outputFileProperty.map {
|
linkTask.outputFileProperty.map { file ->
|
||||||
linkSyncTask.destinationDir.resolve(it.name)
|
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