[Gradle, JS] Up-to-date checks for Node js and yarn

^KT-47845 fixed
This commit is contained in:
Ilya Goncharov
2021-08-04 18:32:17 +03:00
committed by Space
parent 1a1f6b0c0b
commit 5ec19c2417
4 changed files with 74 additions and 11 deletions
@@ -10,6 +10,7 @@ import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import org.gradle.internal.hash.FileHasher
import org.jetbrains.kotlin.gradle.targets.js.toHex
import java.io.File
/**
@@ -92,17 +93,6 @@ internal open class ProcessedFilesCache(
endObject()
}
fun ByteArray.toHex(): String {
val result = CharArray(size * 2) { ' ' }
var i = 0
forEach {
val n = it.toInt()
result[i++] = Character.forDigit(n shr 4 and 0xF, 16)
result[i++] = Character.forDigit(n and 0xF, 16)
}
return String(result)
}
private fun decodeHexString(hexString: String): ByteArray {
check(hexString.length % 2 == 0)
val bytes = ByteArray(hexString.length / 2)
@@ -7,6 +7,7 @@ import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.targets.js.calculateDirHash
import org.jetbrains.kotlin.gradle.utils.ArchiveOperationsCompat
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
import java.io.File
@@ -36,6 +37,9 @@ abstract class NodeJsSetupTask : DefaultTask() {
val destination: File
@OutputDirectory get() = env.nodeDir
val destinationHashFile: File
@OutputFile get() = destination.parentFile.resolve("${destination.name}.hash")
@Transient
@get:Internal
internal lateinit var configuration: Provider<Configuration>
@@ -78,11 +82,29 @@ abstract class NodeJsSetupTask : DefaultTask() {
fun exec() {
logger.kotlinInfo("Using node distribution from '$nodeJsDist'")
val upToDate = destinationHashFile.let { file ->
if (file.exists()) {
file.useLines {
it.single() == calculateDirHash(destination)
}
} else false
}
if (upToDate) return
if (destination.isDirectory) {
destination.deleteRecursively()
}
unpackNodeArchive(nodeJsDist, destination.parentFile) // parent because archive contains name already
if (!env.isWindows) {
File(env.nodeExecutable).setExecutable(true)
}
destinationHashFile.writeText(
calculateDirHash(destination)!!
)
}
private fun unpackNodeArchive(archive: File, destination: File) {
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.js
import org.jetbrains.kotlin.gradle.utils.appendLine
import java.io.File
import java.security.MessageDigest
fun Appendable.appendConfigsFromDir(confDir: File) {
val files = confDir.listFiles() ?: return
@@ -23,6 +24,34 @@ fun Appendable.appendConfigsFromDir(confDir: File) {
}
}
fun ByteArray.toHex(): String {
val result = CharArray(size * 2) { ' ' }
var i = 0
forEach {
val n = it.toInt()
result[i++] = Character.forDigit(n shr 4 and 0xF, 16)
result[i++] = Character.forDigit(n and 0xF, 16)
}
return String(result)
}
fun calculateDirHash(dir: File): String? {
if (!dir.isDirectory) return null
val md = MessageDigest.getInstance("MD5")
dir.walk()
.forEach { file ->
md.update(file.absolutePath.toByteArray())
if (file.isFile) {
file.inputStream().use {
md.update(it.readBytes())
}
}
}
val digest = md.digest()
return digest.toHex()
}
const val JS = "js"
const val JS_MAP = "js.map"
@@ -12,6 +12,7 @@ import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.logging.kotlinInfo
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
import org.jetbrains.kotlin.gradle.targets.js.calculateDirHash
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.utils.ArchiveOperationsCompat
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
@@ -41,6 +42,9 @@ open class YarnSetupTask : DefaultTask() {
val destination: File
@OutputDirectory get() = env.home
val destinationHashFile: File
@OutputFile get() = destination.parentFile.resolve("${destination.name}.hash")
init {
group = NodeJsRootPlugin.TASKS_GROUP_NAME
description = "Download and install a local yarn version"
@@ -89,7 +93,25 @@ open class YarnSetupTask : DefaultTask() {
fun setup() {
logger.kotlinInfo("Using yarn distribution from '$yarnDist'")
val upToDate = destinationHashFile.let { file ->
if (file.exists()) {
file.useLines {
it.single() == calculateDirHash(destination)
}
} else false
}
if (upToDate) return
if (destination.isDirectory) {
destination.deleteRecursively()
}
extract(yarnDist, destination.parentFile) // parent because archive contains name already
destinationHashFile.writeText(
calculateDirHash(destination)!!
)
}
private fun extract(archive: File, destination: File) {