[Gradle][MPP] Include artifact checksum string in transformed metadata klib file names

This can be used for locally published snapshot libraries.
Without it, the import will see that there is already
a library with same coordinates in .gradle/kotlin/... and
therefore skip extracting it.

Including the 32 checksum at the end of the file will ensure,
that if a different artifact is the source of the metadata,
then a new file will be created.

This approach is generally more desirable than cleaning the
.gradle/kotlin directory to avoid the IDE of re-indexing
after import.

^KT-48135 Verification Pending
This commit is contained in:
Sebastian Sellmair
2022-09-16 10:14:53 +02:00
committed by Space
parent f1aad4aa4e
commit 75cc378cac
3 changed files with 52 additions and 16 deletions
@@ -92,11 +92,11 @@ class KlibBasedMppIT : BaseGradleIT() {
checkTaskCompileClasspath(
"compile${hostSpecificSourceSet.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}KotlinMetadata",
listOf(
"published-producer-1.0-$hostSpecificSourceSet.klib",
"published-producer-1.0-commonMain.klib",
"published-dependency-1.0-$hostSpecificSourceSet.klib",
"published-dependency-1.0-commonMain.klib"
)
"published-producer-1.0-$hostSpecificSourceSet-\\w+.klib",
"published-producer-1.0-commonMain-\\w+.klib",
"published-dependency-1.0-$hostSpecificSourceSet-\\w+.klib",
"published-dependency-1.0-commonMain-\\w+.klib"
).map(::Regex)
)
}
@@ -326,8 +326,8 @@ class KlibBasedMppIT : BaseGradleIT() {
private fun BaseGradleIT.Project.checkTaskCompileClasspath(
taskPath: String,
checkModulesInClasspath: List<String> = emptyList(),
checkModulesNotInClasspath: List<String> = emptyList()
checkModulesInClasspath: List<Regex> = emptyList(),
checkModulesNotInClasspath: List<Regex> = emptyList()
) {
val subproject = taskPath.substringBeforeLast(":").takeIf { it.isNotEmpty() && it != taskPath }
val taskName = taskPath.removePrefix(subproject.orEmpty())
@@ -339,8 +339,8 @@ class KlibBasedMppIT : BaseGradleIT() {
private fun BaseGradleIT.Project.checkPrintedItems(
subproject: String?,
itemsExpression: String,
checkAnyItemsContains: List<String>,
checkNoItemContains: List<String>
checkAnyItemsContains: List<Regex>,
checkNoItemContains: List<Regex>
) = with(testCase) {
setupWorkingDir()
val printingTaskName = "printItems${testBuildRunId++}"
@@ -14,6 +14,8 @@ internal interface CompositeMetadataArtifact {
val artifactHandle: ArtifactHandle
val sourceSet: SourceSet
val archiveExtension: String
val checksum: Int
val checksumString: String
/**
* The proposed file-output path.
@@ -11,6 +11,10 @@ import org.jetbrains.kotlin.gradle.utils.listDescendants
import java.io.Closeable
import java.io.File
import java.io.IOException
import java.nio.ByteBuffer
import java.util.*
import java.util.Base64.Encoder
import java.util.zip.CRC32
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
@@ -104,9 +108,15 @@ internal class CompositeMetadataArtifactImpl(
get() = kotlinProjectStructureMetadata.sourceSetBinaryLayout[sourceSet.sourceSetName]?.archiveExtension
?: SourceSetMetadataLayout.METADATA.archiveExtension
override val checksum: Int
get() = artifactFile.checksum
override val checksumString: String
get() = artifactFile.checksumString
/**
* Example:
* org.jetbrains.sample-sampleLibrary-1.0.0-SNAPSHOT-appleAndLinuxMain.klib
* org.jetbrains.sample-sampleLibrary-1.0.0-SNAPSHOT-appleAndLinuxMain-Vk5pxQ.klib
*/
override val relativeFile: File = File(buildString {
append(artifactHandle.moduleDependencyIdentifier)
@@ -114,6 +124,8 @@ internal class CompositeMetadataArtifactImpl(
append(artifactHandle.moduleDependencyVersion)
append("-")
append(sourceSet.sourceSetName)
append("-")
append(checksumString)
append(".")
append(archiveExtension)
})
@@ -136,16 +148,22 @@ internal class CompositeMetadataArtifactImpl(
override val artifactHandle: CompositeMetadataArtifact.ArtifactHandle,
override val sourceSet: CompositeMetadataArtifact.SourceSet,
override val cinteropLibraryName: String,
private val artifact: ArtifactFile,
private val artifactFile: ArtifactFile,
) : CompositeMetadataArtifact.CInteropMetadataLibrary {
override val archiveExtension: String
get() = SourceSetMetadataLayout.KLIB.archiveExtension
override val checksum: Int
get() = artifactFile.checksum
override val checksumString: String
get() = artifactFile.checksumString
/**
* Example:
* org.jetbrains.sample-sampleLibrary-1.0.0-SNAPSHOT-appleAndLinuxMain-cinterop/
* org.jetbrains.sample_sampleLibrary-cinterop-simple.klib
* org.jetbrains.sample_sampleLibrary-cinterop-simple-Vk5pxQ.klib
*/
override val relativeFile: File = File(buildString {
append(artifactHandle.moduleDependencyIdentifier)
@@ -154,7 +172,7 @@ internal class CompositeMetadataArtifactImpl(
append("-")
append(sourceSet.sourceSetName)
append("-cinterop")
}).resolve("$cinteropLibraryName.${archiveExtension}")
}).resolve("$cinteropLibraryName-${checksumString}.${archiveExtension}")
override fun copyTo(file: File): Boolean {
require(file.extension == archiveExtension) {
@@ -167,9 +185,9 @@ internal class CompositeMetadataArtifactImpl(
val cinteropMetadataDirectoryPath = ensureValidZipDirectoryPath(cinteropMetadataDirectory)
val libraryPath = "$cinteropMetadataDirectoryPath$cinteropLibraryName/"
if (!artifact.containsDirectory(libraryPath)) return false
if (!artifactFile.containsDirectory(libraryPath)) return false
file.parentFile.mkdirs()
artifact.zip.copyPartially(file, "$cinteropMetadataDirectoryPath$cinteropLibraryName/")
artifactFile.zip.copyPartially(file, "$cinteropMetadataDirectoryPath$cinteropLibraryName/")
return true
}
@@ -181,6 +199,10 @@ internal class CompositeMetadataArtifactImpl(
*/
private class ArtifactFile(private val file: File) : Closeable {
companion object {
val checksumStringEncoder: Encoder = Base64.getUrlEncoder().withoutPadding()
}
private var isClosed = false
private val lazyZip = lazy {
@@ -190,7 +212,19 @@ internal class CompositeMetadataArtifactImpl(
val zip: ZipFile get() = lazyZip.value
val entries: List<ZipEntry> by lazy { zip.entries().toList() }
val entries: List<ZipEntry> by lazy {
zip.entries().toList()
}
val checksum: Int by lazy(LazyThreadSafetyMode.NONE) {
val crc32 = CRC32()
entries.forEach { entry -> crc32.update(entry.crc.toInt()) }
crc32.value.toInt()
}
val checksumString: String by lazy(LazyThreadSafetyMode.NONE) {
checksumStringEncoder.encodeToString(ByteBuffer.allocate(4).putInt(checksum).array())
}
/**
* All potential directory paths, including inferred directory paths when the [zip] file does