[Gradle][MPP] CompositeMetadataJar: Support omitted directory entries

^KT-46198
This commit is contained in:
sebastian.sellmair
2021-10-21 16:37:22 +02:00
committed by Space
parent 05364fa958
commit dea434b6d5
2 changed files with 27 additions and 16 deletions
@@ -71,20 +71,17 @@ private class CompositeMetadataJarImpl(
val artifactFile = getArtifactFile(sourceSetName)
val moduleOutputDirectory = outputDirectory.resolve(moduleIdentifier).also(File::mkdirs)
ZipFile(getArtifactFile(sourceSetName)).use { compoundMetadataArtifactZipFile ->
val cinteropRootDirectory = compoundMetadataArtifactZipFile.entries().asSequence()
.firstOrNull { zipEntry -> zipEntry.name == "$sourceSetName-cinterop/" && zipEntry.isDirectory }
?: return emptySet()
val cinterops = compoundMetadataArtifactZipFile.listChildren(cinteropRootDirectory)
val cinteropsByOutputFile = cinterops.associateBy { cinteropZipEntry ->
moduleOutputDirectory.resolve("${cinteropZipEntry.name.removePrefix(cinteropRootDirectory.name).removeSuffix("/")}.klib")
}
ZipFile(getArtifactFile(sourceSetName)).use { artifactZipFile ->
val cinteropRootPath = "$sourceSetName-cinterop/"
val cinteropEntries = artifactZipFile.listChildren(cinteropRootPath)
val cinteropNames = cinteropEntries.map { entry ->
entry.name.removePrefix(cinteropRootPath).split("/", limit = 2).first()
}.toSet()
val cinteropsByOutputFile = cinteropNames.associateBy { cinteropName -> moduleOutputDirectory.resolve("$cinteropName.klib") }
if (materializeFiles) {
cinteropsByOutputFile.forEach { (cinteropOutputFile, cinteropZipEntry) ->
copyZipFilePartially(artifactFile, cinteropOutputFile, cinteropZipEntry.name)
cinteropsByOutputFile.forEach { (cinteropOutputFile, cinteropName) ->
copyZipFilePartially(artifactFile, cinteropOutputFile, "$cinteropRootPath$cinteropName/")
}
}
@@ -11,7 +11,7 @@ import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
internal fun copyZipFilePartially(sourceZipFile: File, destinationZipFile: File, path: String) {
require(path.endsWith("/")) { "Expected path to end with '/', found '$path'" }
requireValidZipPath(path)
ZipFile(sourceZipFile).use { zip ->
val entries = zip.entries().asSequence()
@@ -35,11 +35,23 @@ internal fun copyZipFilePartially(sourceZipFile: File, destinationZipFile: File,
}
}
internal fun ZipFile.listDescendants(path: String): Sequence<ZipEntry> {
requireValidZipPath(path)
return entries().asSequence().filter { entry ->
entry.name != path && entry.name.startsWith(path)
}
}
internal fun ZipFile.listChildren(path: String): Sequence<ZipEntry> {
requireValidZipPath(path)
return listDescendants(path).filter { entry ->
entry.name.removePrefix(path).count { it == '/' } == 1
}
}
internal fun ZipFile.listDescendants(zipEntry: ZipEntry): Sequence<ZipEntry> {
require(zipEntry.isDirectory)
return entries().asSequence().filter { entry ->
entry.name != zipEntry.name && entry.name.startsWith(zipEntry.name)
}
return listDescendants(zipEntry.name)
}
internal fun ZipFile.listChildren(zipEntry: ZipEntry): Sequence<ZipEntry> {
@@ -47,3 +59,5 @@ internal fun ZipFile.listChildren(zipEntry: ZipEntry): Sequence<ZipEntry> {
entry.name.removePrefix(zipEntry.name).count { it == '/' } == 1
}
}
private fun requireValidZipPath(path: String) = require(path.endsWith("/")) { "Expected path to end with '/', found '$path'" }