|
4 | 4 |
|
5 | 5 | package dev.icerock.gradle.data |
6 | 6 |
|
7 | | -import org.jetbrains.kotlin.konan.file.File |
8 | | -import org.jetbrains.kotlin.konan.file.file |
9 | | -import org.jetbrains.kotlin.konan.file.unzipTo |
10 | | -import org.jetbrains.kotlin.konan.file.withZipFileSystem |
11 | | -import org.jetbrains.kotlin.library.KotlinLibraryLayout |
12 | | -import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutImpl |
| 7 | +import java.io.File |
| 8 | +import java.nio.file.Files |
| 9 | +import java.util.zip.ZipEntry |
| 10 | +import java.util.zip.ZipFile |
| 11 | + |
| 12 | +private const val DEFAULT_COMPONENT = "default" |
| 13 | +private const val RESOURCES_DIR_NAME = "resources" |
| 14 | +private const val RESOURCES_PREFIX = "$DEFAULT_COMPONENT/$RESOURCES_DIR_NAME/" |
13 | 15 |
|
14 | 16 | /** |
15 | | - * The code in this file is pulled from a previous version of Kotlin to replicate |
16 | | - * removed functionality that MR relies on for extracting klibs. |
17 | | - * https://github.com/JetBrains/kotlin/blob/00984f32ac1ebc2e7fb71b440c282be2a8b05f36/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryLayoutImpl.kt |
| 17 | + * Gets the resources directory from a klib file (packed or unpacked). |
| 18 | + * |
| 19 | + * For a packed (zipped) klib (single .klib file), extracts the resources |
| 20 | + * directory to a temporary location and returns it. Returns null if the |
| 21 | + * klib does not contain a resources directory. |
| 22 | + * |
| 23 | + * For an unpacked klib (directory), returns the direct path to the |
| 24 | + * resources directory (which may not exist if the klib has no resources). |
| 25 | + * |
| 26 | + * The structure of a klib is: |
| 27 | + * - Packed: a .klib zip containing `default/resources/` |
| 28 | + * - Unpacked: a directory with `default/resources/` subdirectory |
18 | 29 | */ |
19 | | - |
20 | | -internal open class ExtractingKotlinLibraryLayout(zipped: KotlinLibraryLayoutImpl) : KotlinLibraryLayout { |
21 | | - override val libFile: File get() = error("Extracting layout doesn't extract its own root") |
22 | | - override val libraryName = zipped.libraryName |
23 | | - override val component = zipped.component |
| 30 | +internal fun getKlibResourcesDir(klibFile: File): File? { |
| 31 | + return if (klibFile.isFile) { |
| 32 | + // Packed (zipped) klib - extract resources to temp if present |
| 33 | + extractResourcesFromPackedKlib(klibFile) |
| 34 | + } else { |
| 35 | + // Unpacked klib directory - navigate to resources (may not exist) |
| 36 | + File(klibFile, "$DEFAULT_COMPONENT/$RESOURCES_DIR_NAME") |
| 37 | + } |
24 | 38 | } |
25 | 39 |
|
26 | | -internal class ExtractingBaseLibraryImpl(zipped: KotlinLibraryLayoutImpl) : ExtractingKotlinLibraryLayout(zipped) { |
27 | | - override val manifestFile: File by lazy { zipped.extract(zipped.manifestFile) } |
28 | | - override val resourcesDir: File by lazy { zipped.extractDir(zipped.resourcesDir) } |
29 | | -} |
| 40 | +private fun extractResourcesFromPackedKlib(klibFile: File): File? { |
| 41 | + ZipFile(klibFile).use { zip -> |
| 42 | + val hasResources = zip.entries().asSequence().any { it.name.startsWith(RESOURCES_PREFIX) } |
| 43 | + if (!hasResources) return null |
30 | 44 |
|
31 | | -private fun KotlinLibraryLayoutImpl.extract(file: File): File = extract(this.klib, file) |
32 | | - |
33 | | -private fun extract(zipFile: File, file: File) = zipFile.withZipFileSystem { zipFileSystem -> |
34 | | - val temporary = org.jetbrains.kotlin.konan.file.createTempFile(file.name) |
35 | | - zipFileSystem.file(file).copyTo(temporary) |
36 | | - temporary.deleteOnExit() |
37 | | - temporary |
| 45 | + val temporary = Files.createTempDirectory(RESOURCES_DIR_NAME).toFile().also { |
| 46 | + it.deleteOnExit() |
| 47 | + } |
| 48 | + zip.entries().asSequence() |
| 49 | + .filter { it.name.startsWith(RESOURCES_PREFIX) } |
| 50 | + .forEach { entry -> |
| 51 | + val relativeName = entry.name.removePrefix(RESOURCES_PREFIX) |
| 52 | + if (relativeName.isNotEmpty()) { |
| 53 | + extractZipEntry(zip, entry, File(temporary, relativeName)) |
| 54 | + } |
| 55 | + } |
| 56 | + return temporary |
| 57 | + } |
38 | 58 | } |
39 | 59 |
|
40 | | -private fun KotlinLibraryLayoutImpl.extractDir(directory: File): File = extractDir(this.klib, directory) |
41 | | - |
42 | | -private fun extractDir(zipFile: File, directory: File): File { |
43 | | - val temporary = org.jetbrains.kotlin.konan.file.createTempDir(directory.name) |
44 | | - temporary.deleteOnExitRecursively() |
45 | | - zipFile.unzipTo(temporary, fromSubdirectory = directory) |
46 | | - return temporary |
| 60 | +private fun extractZipEntry(zip: ZipFile, entry: ZipEntry, output: File) { |
| 61 | + if (entry.isDirectory) { |
| 62 | + output.mkdirs() |
| 63 | + } else { |
| 64 | + output.parentFile?.mkdirs() |
| 65 | + zip.getInputStream(entry).use { it.copyTo(output.outputStream()) } |
| 66 | + } |
47 | 67 | } |
0 commit comments