[Gradle] Test for KLIB manifest in CompositeMetadataArtifactImpl
This should protect from cases when CompositeMetadataArtifact got polluted due to some bugs or user misconfiguration. One of the cases is when resource file is added to common source set. In this case due to KT-66563 bug, resources will be mixed in to the KLIB content. But if for some source set there is no sources. Then in composite metadata artifact will be only the resources. And previous implementation of CompositeMetadataArtifactImpl treated that content as Metadata KLIB, however the metadata compiler didn't. And thus it was failing with. This change makes it stricter. Now it checks for `default/manifest` entry. This entry is considered a sane check for KLIB content. ^KT-65315 Verification Pending
This commit is contained in:
committed by
Space Team
parent
322940f228
commit
2880082c9a
+15
-47
@@ -73,7 +73,7 @@ internal class CompositeMetadataArtifactImpl(
|
||||
|
||||
In this case, return null
|
||||
*/
|
||||
if (artifactFile.containsDirectory(sourceSetName)) MetadataBinaryImpl(this, artifactFile) else null
|
||||
if (artifactFile.containsKlibDirectory(sourceSetName)) MetadataBinaryImpl(this, artifactFile) else null
|
||||
}
|
||||
|
||||
override val cinteropMetadataBinaries: List<CompositeMetadataArtifactContent.CInteropMetadataBinary> by lazy {
|
||||
@@ -131,7 +131,7 @@ internal class CompositeMetadataArtifactImpl(
|
||||
}
|
||||
|
||||
val libraryPath = "${containingSourceSetContent.sourceSetName}/"
|
||||
if (!artifactFile.containsDirectory(libraryPath)) return false
|
||||
if (!artifactFile.containsKlibDirectory(libraryPath)) return false
|
||||
file.parentFile.mkdirs()
|
||||
artifactFile.zip.copyPartially(file, libraryPath)
|
||||
|
||||
@@ -176,7 +176,7 @@ internal class CompositeMetadataArtifactImpl(
|
||||
val cinteropMetadataDirectoryPath = ensureValidZipDirectoryPath(cinteropMetadataDirectory)
|
||||
|
||||
val libraryPath = "$cinteropMetadataDirectoryPath$cinteropLibraryName/"
|
||||
if (!artifactFile.containsDirectory(libraryPath)) return false
|
||||
if (!artifactFile.containsKlibDirectory(libraryPath)) return false
|
||||
file.parentFile.mkdirs()
|
||||
artifactFile.zip.copyPartially(file, "$cinteropMetadataDirectoryPath$cinteropLibraryName/")
|
||||
|
||||
@@ -186,7 +186,7 @@ internal class CompositeMetadataArtifactImpl(
|
||||
|
||||
/**
|
||||
* Interface to the underlying [zip][file] that only opens the file lazily and keeps references to
|
||||
* all [entries] and infers all potential directory paths (see [directoryPaths] and [containsDirectory])
|
||||
* all [entries] and infers all potential directory paths (see [directoryPaths] and [containsKlibDirectory])
|
||||
*/
|
||||
private class ArtifactFile(private val file: File) : Closeable {
|
||||
|
||||
@@ -210,21 +210,18 @@ internal class CompositeMetadataArtifactImpl(
|
||||
}
|
||||
|
||||
/**
|
||||
* All potential directory paths, including inferred directory paths when the [zip] file does
|
||||
* not include directory entries.
|
||||
* @see collectAllDirectoryPaths
|
||||
*/
|
||||
val directoryPaths: Set<String> by lazy { collectAllDirectoryPaths(entries) }
|
||||
|
||||
/**
|
||||
* Check if the underlying [zip] file contains this directory.
|
||||
* Note: This check also works for zip files that did not include directory entries.
|
||||
* Check if the underlying [zip] file contains klib at [path].
|
||||
* Note: This check also works for zip files that did not include any klibs.
|
||||
* This will return true, if any other zip-entry is placed inside this directory [path]
|
||||
*/
|
||||
fun containsDirectory(path: String): Boolean {
|
||||
val validPath = ensureValidZipDirectoryPath(path)
|
||||
if (zip.getEntry(validPath) != null) return true
|
||||
return validPath in directoryPaths
|
||||
fun containsKlibDirectory(path: String): Boolean {
|
||||
// Checking for manifest file in "default" folder is considered "good enough" to say that it is a KLIB
|
||||
// There are three possible states of content in the subdirectory of Composite Metadata Artifact
|
||||
// 1. Klib
|
||||
// 2. resources or mix klib + resources (FIXME: KT-66563)
|
||||
// 3. empty directory. In case if something went wrong with publication. Like Task was skipped for some reason.
|
||||
val pathToTheManifestFile = ensureValidZipDirectoryPath(path) + "default/manifest"
|
||||
return zip.getEntry(pathToTheManifestFile) != null
|
||||
}
|
||||
|
||||
private fun ensureNotClosed() {
|
||||
@@ -238,33 +235,4 @@ internal class CompositeMetadataArtifactImpl(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip files are not **forced** to include entries for directories.
|
||||
* In order to do preliminary checks, if some directory is present in Zip Files it is
|
||||
* often useful to infer the directories included in any Zip File by looking into file entries
|
||||
* and inferring their directories.
|
||||
*/
|
||||
private fun collectAllDirectoryPaths(entries: List<ZipEntry>): Set<String> {
|
||||
/*
|
||||
The 'root' directory is represented as empty String in ZipFile
|
||||
*/
|
||||
val set = hashSetOf("")
|
||||
|
||||
entries.forEach { entry ->
|
||||
if (entry.isDirectory) {
|
||||
set.add(entry.name)
|
||||
return@forEach
|
||||
}
|
||||
|
||||
/* Collect all 'intermediate' directories found by looking at the files path */
|
||||
val pathParts = entry.name.split("/")
|
||||
pathParts.runningReduce { currentPath, nextPart ->
|
||||
set.add("$currentPath/")
|
||||
"$currentPath/$nextPart"
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
}
|
||||
+21
-14
@@ -20,6 +20,8 @@ class CompositeMetadataArtifactTest {
|
||||
@get:Rule
|
||||
val temporaryFolder = TemporaryFolder()
|
||||
|
||||
private val KLIB_MANIFEST_PATH = "default/manifest"
|
||||
|
||||
@Test
|
||||
fun `empty jar - contains no metadataBinary and no cinteropMetadataBinaries`() {
|
||||
val primaryArtifactContent = temporaryFolder.newFolder()
|
||||
@@ -59,7 +61,7 @@ class CompositeMetadataArtifactTest {
|
||||
fun `stub metadata library - can be unzipped`() {
|
||||
val testSourceSetName = "testSourceSetName"
|
||||
val primaryArtifactContent = temporaryFolder.newFolder()
|
||||
val stubFile = primaryArtifactContent.resolve(testSourceSetName).resolve("stub.txt")
|
||||
val stubFile = primaryArtifactContent.resolve(testSourceSetName).resolve(KLIB_MANIFEST_PATH)
|
||||
stubFile.parentFile.mkdirs()
|
||||
stubFile.writeText("stub!")
|
||||
|
||||
@@ -93,8 +95,9 @@ class CompositeMetadataArtifactTest {
|
||||
val unzippedMetadataFile = metadataOutputDirectory.resolve("unzipped")
|
||||
unzipTo(unzippedMetadataFile, metadataFile)
|
||||
|
||||
assertEquals(setOf(unzippedMetadataFile.resolve("stub.txt")), unzippedMetadataFile.listFiles().orEmpty().toSet())
|
||||
assertEquals("stub!", unzippedMetadataFile.resolve("stub.txt").readText())
|
||||
val actualUnzippedFiles = unzippedMetadataFile.walkTopDown().filter { it.isFile }.toSet()
|
||||
assertEquals(setOf(unzippedMetadataFile.resolve(KLIB_MANIFEST_PATH)), actualUnzippedFiles)
|
||||
assertEquals("stub!", unzippedMetadataFile.resolve(KLIB_MANIFEST_PATH).readText())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,21 +131,21 @@ class CompositeMetadataArtifactTest {
|
||||
/* Setup Artifact content */
|
||||
val primaryArtifactContent = temporaryFolder.newFolder()
|
||||
|
||||
primaryArtifactContent.resolve("sourceSetA/sourceSetAStub1.txt")
|
||||
primaryArtifactContent.resolve("sourceSetA/$KLIB_MANIFEST_PATH")
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("Content of sourceSetA stub1")
|
||||
.writeText("Content of sourceSetA Metadata KLIB")
|
||||
|
||||
primaryArtifactContent.resolve("sourceSetA/nested/sourceSetAStub2.txt")
|
||||
primaryArtifactContent.resolve("sourceSetA/sourceSetAStub.txt")
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("Content of sourceSetB stub2")
|
||||
.writeText("Resource file mixed with sourceSetA Metadata KLIB")
|
||||
|
||||
primaryArtifactContent.resolve("sourceSetB/sourceSetBStub1.txt")
|
||||
primaryArtifactContent.resolve("sourceSetB/$KLIB_MANIFEST_PATH")
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("Content of sourceSetB stub1")
|
||||
|
||||
primaryArtifactContent.resolve("sourceSetB/nested/sourceSetBStub2.txt")
|
||||
primaryArtifactContent.resolve("sourceSetWithResourcesOnly/stub.txt")
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("Content of sourceSetB stub2")
|
||||
.writeText("Resource file with klib content")
|
||||
|
||||
/* Create metadata jar */
|
||||
val primaryArtifactFile = temporaryFolder.newFile("metadata.jar")
|
||||
@@ -154,7 +157,8 @@ class CompositeMetadataArtifactTest {
|
||||
kotlinProjectStructureMetadata = createProjectStructureMetadata(
|
||||
sourceSetBinaryLayout = mapOf(
|
||||
"sourceSetA" to SourceSetMetadataLayout.KLIB,
|
||||
"sourceSetB" to SourceSetMetadataLayout.METADATA
|
||||
"sourceSetB" to SourceSetMetadataLayout.METADATA,
|
||||
"sourceSetWithResourcesOnly" to SourceSetMetadataLayout.KLIB,
|
||||
)
|
||||
),
|
||||
primaryArtifactFile = primaryArtifactFile,
|
||||
@@ -195,6 +199,9 @@ class CompositeMetadataArtifactTest {
|
||||
"Expected correct content of extracted 'sourceSetA'"
|
||||
)
|
||||
}
|
||||
|
||||
/* even though there is sourceSetWithResourcesOnly directory, there is no metadata KLIB in it */
|
||||
assertNull(artifactContent.getSourceSet("sourceSetWithResourcesOnly").metadataBinary)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +210,7 @@ class CompositeMetadataArtifactTest {
|
||||
/* Setup Artifact content */
|
||||
val primaryArtifactContent = temporaryFolder.newFolder()
|
||||
|
||||
primaryArtifactContent.resolve("sourceSetA-cinterop/interopA0/stub0")
|
||||
primaryArtifactContent.resolve("sourceSetA-cinterop/interopA0/$KLIB_MANIFEST_PATH")
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("stub0 content")
|
||||
|
||||
@@ -211,11 +218,11 @@ class CompositeMetadataArtifactTest {
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("stub1 content")
|
||||
|
||||
primaryArtifactContent.resolve("sourceSetA-cinterop/interopA1/stub2")
|
||||
primaryArtifactContent.resolve("sourceSetA-cinterop/interopA1/$KLIB_MANIFEST_PATH")
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("stub2 content")
|
||||
|
||||
primaryArtifactContent.resolve("nested/sourceSetB/interops/interopB0/stub3")
|
||||
primaryArtifactContent.resolve("nested/sourceSetB/interops/interopB0/$KLIB_MANIFEST_PATH")
|
||||
.withParentDirectoriesCreated()
|
||||
.writeText("stub3 content")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user