Fix failures when a common source set compiled to nothing (KT-36674)

This could happen:
* when a common source set had no sources
* when the compile task of a common source set was disabled

In those cases, there were two subsequent failures:
* the metadata JAR could not interpret the missing klib file as ZIP
* the consumer could not read the empty klib in its dependencies

Issue #KT-36674 Fixed
This commit is contained in:
Sergey Igushkin
2020-03-03 19:08:58 +03:00
parent 066d413fb8
commit ad1a1ac49a
3 changed files with 38 additions and 21 deletions
@@ -30,11 +30,26 @@ class KlibBasedMppIT : BaseGradleIT() {
""".trimIndent())
}
@Test
fun testPublishingAndConsumptionWithEmptySourceSet() = testBuildWithDependency {
// KT-36674
projectDir.resolve("$dependencyModuleName/src/$hostSpecificSourceSet").run {
assertTrue { isDirectory }
deleteRecursively()
}
publishProjectDepAndAddDependency(validateHostSpecificPublication = false)
}
@Test
fun testBuildWithPublishedDependency() = testBuildWithDependency {
publishProjectDepAndAddDependency(validateHostSpecificPublication = true)
}
private fun Project.publishProjectDepAndAddDependency(validateHostSpecificPublication: Boolean) {
build(":$dependencyModuleName:publish") {
assertSuccessful()
checkPublishedHostSpecificMetadata(this@build)
if (validateHostSpecificPublication)
checkPublishedHostSpecificMetadata(this@build)
}
gradleBuildScript().appendText("\n" + """
@@ -371,30 +371,32 @@ private class JarArtifactMppDependencyMetadataExtractor(
artifactBySourceSet.forEach { (sourceSetName, artifact) ->
ZipFile(artifact).use { zip ->
val entries = zip.entries().asSequence().filter { it.name.startsWith("$sourceSetName/") }
val entries = zip.entries().asSequence().filter { it.name.startsWith("$sourceSetName/") }.toList()
// TODO: once IJ supports non-JAR metadata dependencies, extract to a directory, not a JAR
// Also, if both IJ and the CLI compiler can read metadata from a path inside a JAR, then no operations will be needed
val extension =
projectStructureMetadata.sourceSetBinaryLayout[sourceSetName]?.archiveExtension
if (entries.any()) {
val extension = projectStructureMetadata.sourceSetBinaryLayout[sourceSetName]?.archiveExtension
?: SourceSetMetadataLayout.METADATA.archiveExtension
val extractToJarFile = transformedModuleRoot.resolve("$moduleString-$sourceSetName.$extension")
resultFiles[sourceSetName] = project.files(extractToJarFile)
val extractToJarFile = transformedModuleRoot.resolve("$moduleString-$sourceSetName.$extension")
resultFiles[sourceSetName] = project.files(extractToJarFile)
if (doProcessFiles) {
ZipOutputStream(extractToJarFile.outputStream()).use { resultZipOutput ->
for (entry in entries) {
if (entry.isDirectory)
continue
if (doProcessFiles) {
ZipOutputStream(extractToJarFile.outputStream()).use { resultZipOutput ->
for (entry in entries) {
if (entry.isDirectory)
continue
// Drop the source set name from the entry path
val resultEntry = ZipEntry(entry.name.substringAfter("/"))
// Drop the source set name from the entry path
val resultEntry = ZipEntry(entry.name.substringAfter("/"))
zip.getInputStream(entry).use { inputStream ->
resultZipOutput.putNextEntry(resultEntry)
inputStream.copyTo(resultZipOutput)
resultZipOutput.closeEntry()
zip.getInputStream(entry).use { inputStream ->
resultZipOutput.putNextEntry(resultEntry)
inputStream.copyTo(resultZipOutput)
resultZipOutput.closeEntry()
}
}
}
}
@@ -532,9 +532,9 @@ internal fun getPublishedPlatformCompilations(project: Project): Map<KotlinUsage
internal fun Project.filesWithUnpackedArchives(from: FileCollection, extensions: Set<String>): FileCollection =
project.files(project.provider {
from.map {
if (it.extension in extensions)
project.zipTree(it)
else it
from.mapNotNull {
if (it.extension in extensions) {
if (it.exists()) project.zipTree(it) else null
} else it
}
}).builtBy(from)