[Gradle] Changed the way of unpacking k/n dependencies
Creating `tar` process is not supported by configuration cache. Inner Gradle copy and archive operations don't work well with symlinks. That is why we are using utils from org.apache.commons:commons-compress. ^KT-66422 Fixed
This commit is contained in:
committed by
Space Team
parent
fb3c1f1a2f
commit
f18d00e6f0
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.konan.properties
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.Configurables
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.util.ArchiveType
|
||||
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
||||
import org.jetbrains.kotlin.konan.util.ProgressCallback
|
||||
import org.jetbrains.kotlin.konan.util.*
|
||||
import java.io.File
|
||||
|
||||
interface TargetableExternalStorage {
|
||||
@@ -76,6 +74,10 @@ abstract class KonanPropertiesLoader(
|
||||
dependencyProcessor!!.run()
|
||||
}
|
||||
|
||||
fun downloadDependencies(archiveExtractor: ArchiveExtractor) {
|
||||
dependencyProcessor!!.run(archiveExtractor)
|
||||
}
|
||||
|
||||
// TODO: We may want to add caching to avoid repeated resolve.
|
||||
override fun targetString(key: String): String? = properties.targetString(key, target)
|
||||
override fun targetList(key: String): List<String> = properties.targetList(key, target)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.konan.util
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* An interface for extracting archive files.
|
||||
*/
|
||||
interface ArchiveExtractor {
|
||||
|
||||
/**
|
||||
* Extracts the contents of the specified archive file to the target directory.
|
||||
*
|
||||
* @param archive The archive file to extract.
|
||||
* @param targetDirectory The directory where the contents of the archive will be extracted to.
|
||||
* @param archiveType The type of the archive file.
|
||||
*/
|
||||
fun extract(archive: File, targetDirectory: File, archiveType: ArchiveType)
|
||||
}
|
||||
@@ -33,9 +33,8 @@ enum class ArchiveType(val fileExtension: String) {
|
||||
}
|
||||
}
|
||||
|
||||
class DependencyExtractor(
|
||||
private val archiveType: ArchiveType
|
||||
) {
|
||||
class DependencyExtractor : ArchiveExtractor {
|
||||
|
||||
private fun extractTarGz(tarGz: File, targetDirectory: File) {
|
||||
val tarProcess = ProcessBuilder().apply {
|
||||
command("tar", "-xzf", tarGz.canonicalPath)
|
||||
@@ -47,18 +46,19 @@ class DependencyExtractor(
|
||||
finished && tarProcess.exitValue() != 0 ->
|
||||
throw RuntimeException(
|
||||
"Cannot extract archive with dependency: ${tarGz.canonicalPath}.\n" +
|
||||
"Tar exit code: ${tarProcess.exitValue()}."
|
||||
"Tar exit code: ${tarProcess.exitValue()}."
|
||||
)
|
||||
!finished -> {
|
||||
tarProcess.destroy()
|
||||
throw RuntimeException(
|
||||
"Cannot extract archive with dependency: ${tarGz.canonicalPath}.\n" +
|
||||
"Tar process hasn't finished in ${extractionTimeoutUntis.toSeconds(extractionTimeout)} sec.")
|
||||
"Tar process hasn't finished in ${extractionTimeoutUntis.toSeconds(extractionTimeout)} sec."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun extract(archive: File, targetDirectory: File) {
|
||||
override fun extract(archive: File, targetDirectory: File, archiveType: ArchiveType) {
|
||||
when (archiveType) {
|
||||
ArchiveType.ZIP -> archive.toPath().unzipTo(targetDirectory.toPath())
|
||||
ArchiveType.TAR_GZ -> extractTarGz(archive, targetDirectory)
|
||||
|
||||
@@ -109,7 +109,6 @@ class DependencyProcessor(
|
||||
private var isInfoShown = false
|
||||
|
||||
private val downloader = DependencyDownloader(maxAttempts, attemptIntervalMs, customProgressCallback)
|
||||
private val extractor = DependencyExtractor(archiveType)
|
||||
|
||||
constructor(dependenciesRoot: File,
|
||||
properties: KonanPropertiesLoader,
|
||||
@@ -172,7 +171,7 @@ class DependencyProcessor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadDependency(dependency: String, baseUrl: String) {
|
||||
private fun downloadDependency(dependency: String, baseUrl: String, archiveExtractor: ArchiveExtractor) {
|
||||
val depDir = File(dependenciesDirectory, dependency)
|
||||
val depName = depDir.name
|
||||
|
||||
@@ -211,7 +210,7 @@ class DependencyProcessor(
|
||||
downloader.download(url, archive)
|
||||
}
|
||||
println("Extracting dependency: $archive into $dependenciesDirectory")
|
||||
extractor.extract(archive, dependenciesDirectory)
|
||||
archiveExtractor.extract(archive, dependenciesDirectory, archiveType)
|
||||
if (deleteArchives) {
|
||||
archive.delete()
|
||||
}
|
||||
@@ -275,7 +274,7 @@ class DependencyProcessor(
|
||||
}
|
||||
}
|
||||
|
||||
fun run() {
|
||||
fun run(archiveExtractor: ArchiveExtractor = DependencyExtractor()) {
|
||||
// We need a lock that can be shared between different classloaders (KT-39781).
|
||||
// TODO: Rework dependencies downloading to avoid storing the lock in the system properties.
|
||||
val lock = System.getProperties().computeIfAbsent("kotlin.native.dependencies.lock") {
|
||||
@@ -300,7 +299,7 @@ class DependencyProcessor(
|
||||
DependencySource.Remote.Internal -> InternalServer.url
|
||||
}
|
||||
// TODO: consider using different caches for different remotes.
|
||||
downloadDependency(dependency, baseUrl)
|
||||
downloadDependency(dependency, baseUrl, archiveExtractor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user