[Gradle, JS] Consider potential hash of nodejs and yarn

^KT-47845 fixed
This commit is contained in:
Ilya Goncharov
2021-08-04 20:56:05 +03:00
committed by Space
parent 5ec19c2417
commit b8330deefa
3 changed files with 38 additions and 28 deletions
@@ -2,7 +2,9 @@ package org.jetbrains.kotlin.gradle.targets.js.nodejs
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileTree
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.logging.kotlinInfo import org.jetbrains.kotlin.gradle.logging.kotlinInfo
@@ -44,10 +46,6 @@ abstract class NodeJsSetupTask : DefaultTask() {
@get:Internal @get:Internal
internal lateinit var configuration: Provider<Configuration> internal lateinit var configuration: Provider<Configuration>
private val _nodeJsDist by lazy {
configuration.get().files.single()
}
@get:Classpath @get:Classpath
val nodeJsDist: File by lazy { val nodeJsDist: File by lazy {
val repo = project.repositories.ivy { repo -> val repo = project.repositories.ivy { repo ->
@@ -61,7 +59,7 @@ abstract class NodeJsSetupTask : DefaultTask() {
repo.content { it.includeModule("org.nodejs", "node") } repo.content { it.includeModule("org.nodejs", "node") }
} }
val startDownloadTime = System.currentTimeMillis() val startDownloadTime = System.currentTimeMillis()
val dist = _nodeJsDist val dist = configuration.get().files.single()
val downloadDuration = System.currentTimeMillis() - startDownloadTime val downloadDuration = System.currentTimeMillis() - startDownloadTime
if (downloadDuration > 0) { if (downloadDuration > 0) {
KotlinBuildStatsService.getInstance() KotlinBuildStatsService.getInstance()
@@ -82,21 +80,30 @@ abstract class NodeJsSetupTask : DefaultTask() {
fun exec() { fun exec() {
logger.kotlinInfo("Using node distribution from '$nodeJsDist'") logger.kotlinInfo("Using node distribution from '$nodeJsDist'")
var dirHash: String? = null
val upToDate = destinationHashFile.let { file -> val upToDate = destinationHashFile.let { file ->
if (file.exists()) { if (file.exists()) {
file.useLines { file.useLines {
it.single() == calculateDirHash(destination) it.single() == (calculateDirHash(destination).also { dirHash = it })
} }
} else false } else false
} }
if (upToDate) return val tmpDir = temporaryDir
unpackNodeArchive(nodeJsDist, tmpDir)
if (upToDate && calculateDirHash(tmpDir.resolve(destination.name))!! == dirHash) return
if (destination.isDirectory) { if (destination.isDirectory) {
destination.deleteRecursively() destination.deleteRecursively()
} }
unpackNodeArchive(nodeJsDist, destination.parentFile) // parent because archive contains name already fs.copy {
it.from(tmpDir)
it.into(destination.parentFile)
}
tmpDir.deleteRecursively()
if (!env.isWindows) { if (!env.isWindows) {
File(env.nodeExecutable).setExecutable(true) File(env.nodeExecutable).setExecutable(true)
@@ -110,20 +117,18 @@ abstract class NodeJsSetupTask : DefaultTask() {
private fun unpackNodeArchive(archive: File, destination: File) { private fun unpackNodeArchive(archive: File, destination: File) {
logger.kotlinInfo("Unpacking $archive to $destination") logger.kotlinInfo("Unpacking $archive to $destination")
when { fs.copy {
archive.name.endsWith("zip") -> fs.copy { it.from(fileTree(archive))
it.from(archiveOperations.zipTree(archive)) it.into(destination)
it.into(destination)
}
else -> {
fs.copy {
it.from(archiveOperations.tarTree(archive))
it.into(destination)
}
}
} }
} }
private fun fileTree(archive: File): FileTree =
when {
archive.name.endsWith("zip") -> archiveOperations.zipTree(archive)
else -> archiveOperations.tarTree(archive)
}
companion object { companion object {
const val NAME: String = "kotlinNodeJsSetup" const val NAME: String = "kotlinNodeJsSetup"
} }
@@ -40,7 +40,7 @@ fun calculateDirHash(dir: File): String? {
val md = MessageDigest.getInstance("MD5") val md = MessageDigest.getInstance("MD5")
dir.walk() dir.walk()
.forEach { file -> .forEach { file ->
md.update(file.absolutePath.toByteArray()) md.update(file.toRelativeString(dir).toByteArray())
if (file.isFile) { if (file.isFile) {
file.inputStream().use { file.inputStream().use {
md.update(it.readBytes()) md.update(it.readBytes())
@@ -57,10 +57,6 @@ open class YarnSetupTask : DefaultTask() {
@get:Internal @get:Internal
internal lateinit var configuration: Provider<Configuration> internal lateinit var configuration: Provider<Configuration>
private val _yarnDist by lazy {
configuration.get().files.single()
}
@get:Classpath @get:Classpath
val yarnDist: File by lazy { val yarnDist: File by lazy {
val repo = project.repositories.ivy { repo -> val repo = project.repositories.ivy { repo ->
@@ -73,7 +69,7 @@ open class YarnSetupTask : DefaultTask() {
repo.content { it.includeModule("com.yarnpkg", "yarn") } repo.content { it.includeModule("com.yarnpkg", "yarn") }
} }
val startDownloadTime = System.currentTimeMillis() val startDownloadTime = System.currentTimeMillis()
val dist = _yarnDist val dist = configuration.get().files.single()
val downloadDuration = System.currentTimeMillis() - startDownloadTime val downloadDuration = System.currentTimeMillis() - startDownloadTime
if (downloadDuration > 0) { if (downloadDuration > 0) {
KotlinBuildStatsService.getInstance() KotlinBuildStatsService.getInstance()
@@ -93,21 +89,30 @@ open class YarnSetupTask : DefaultTask() {
fun setup() { fun setup() {
logger.kotlinInfo("Using yarn distribution from '$yarnDist'") logger.kotlinInfo("Using yarn distribution from '$yarnDist'")
var dirHash: String? = null
val upToDate = destinationHashFile.let { file -> val upToDate = destinationHashFile.let { file ->
if (file.exists()) { if (file.exists()) {
file.useLines { file.useLines {
it.single() == calculateDirHash(destination) it.single() == (calculateDirHash(destination).also { dirHash = it })
} }
} else false } else false
} }
if (upToDate) return val tmpDir = temporaryDir
extract(yarnDist, tmpDir) // parent because archive contains name already
if (upToDate && calculateDirHash(tmpDir.resolve(destination.name))!! == dirHash) return
if (destination.isDirectory) { if (destination.isDirectory) {
destination.deleteRecursively() destination.deleteRecursively()
} }
extract(yarnDist, destination.parentFile) // parent because archive contains name already fs.copy {
it.from(tmpDir)
it.into(destination.parentFile)
}
tmpDir.deleteRecursively()
destinationHashFile.writeText( destinationHashFile.writeText(
calculateDirHash(destination)!! calculateDirHash(destination)!!