[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( checkTaskCompileClasspath(
"compile${hostSpecificSourceSet.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}KotlinMetadata", "compile${hostSpecificSourceSet.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}KotlinMetadata",
listOf( listOf(
"published-producer-1.0-$hostSpecificSourceSet.klib", "published-producer-1.0-$hostSpecificSourceSet-\\w+.klib",
"published-producer-1.0-commonMain.klib", "published-producer-1.0-commonMain-\\w+.klib",
"published-dependency-1.0-$hostSpecificSourceSet.klib", "published-dependency-1.0-$hostSpecificSourceSet-\\w+.klib",
"published-dependency-1.0-commonMain.klib" "published-dependency-1.0-commonMain-\\w+.klib"
) ).map(::Regex)
) )
} }
@@ -326,8 +326,8 @@ class KlibBasedMppIT : BaseGradleIT() {
private fun BaseGradleIT.Project.checkTaskCompileClasspath( private fun BaseGradleIT.Project.checkTaskCompileClasspath(
taskPath: String, taskPath: String,
checkModulesInClasspath: List<String> = emptyList(), checkModulesInClasspath: List<Regex> = emptyList(),
checkModulesNotInClasspath: List<String> = emptyList() checkModulesNotInClasspath: List<Regex> = emptyList()
) { ) {
val subproject = taskPath.substringBeforeLast(":").takeIf { it.isNotEmpty() && it != taskPath } val subproject = taskPath.substringBeforeLast(":").takeIf { it.isNotEmpty() && it != taskPath }
val taskName = taskPath.removePrefix(subproject.orEmpty()) val taskName = taskPath.removePrefix(subproject.orEmpty())
@@ -339,8 +339,8 @@ class KlibBasedMppIT : BaseGradleIT() {
private fun BaseGradleIT.Project.checkPrintedItems( private fun BaseGradleIT.Project.checkPrintedItems(
subproject: String?, subproject: String?,
itemsExpression: String, itemsExpression: String,
checkAnyItemsContains: List<String>, checkAnyItemsContains: List<Regex>,
checkNoItemContains: List<String> checkNoItemContains: List<Regex>
) = with(testCase) { ) = with(testCase) {
setupWorkingDir() setupWorkingDir()
val printingTaskName = "printItems${testBuildRunId++}" val printingTaskName = "printItems${testBuildRunId++}"
@@ -14,6 +14,8 @@ internal interface CompositeMetadataArtifact {
val artifactHandle: ArtifactHandle val artifactHandle: ArtifactHandle
val sourceSet: SourceSet val sourceSet: SourceSet
val archiveExtension: String val archiveExtension: String
val checksum: Int
val checksumString: String
/** /**
* The proposed file-output path. * The proposed file-output path.
@@ -11,6 +11,10 @@ import org.jetbrains.kotlin.gradle.utils.listDescendants
import java.io.Closeable import java.io.Closeable
import java.io.File import java.io.File
import java.io.IOException 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.ZipEntry
import java.util.zip.ZipFile import java.util.zip.ZipFile
@@ -104,9 +108,15 @@ internal class CompositeMetadataArtifactImpl(
get() = kotlinProjectStructureMetadata.sourceSetBinaryLayout[sourceSet.sourceSetName]?.archiveExtension get() = kotlinProjectStructureMetadata.sourceSetBinaryLayout[sourceSet.sourceSetName]?.archiveExtension
?: SourceSetMetadataLayout.METADATA.archiveExtension ?: SourceSetMetadataLayout.METADATA.archiveExtension
override val checksum: Int
get() = artifactFile.checksum
override val checksumString: String
get() = artifactFile.checksumString
/** /**
* Example: * 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 { override val relativeFile: File = File(buildString {
append(artifactHandle.moduleDependencyIdentifier) append(artifactHandle.moduleDependencyIdentifier)
@@ -114,6 +124,8 @@ internal class CompositeMetadataArtifactImpl(
append(artifactHandle.moduleDependencyVersion) append(artifactHandle.moduleDependencyVersion)
append("-") append("-")
append(sourceSet.sourceSetName) append(sourceSet.sourceSetName)
append("-")
append(checksumString)
append(".") append(".")
append(archiveExtension) append(archiveExtension)
}) })
@@ -136,16 +148,22 @@ internal class CompositeMetadataArtifactImpl(
override val artifactHandle: CompositeMetadataArtifact.ArtifactHandle, override val artifactHandle: CompositeMetadataArtifact.ArtifactHandle,
override val sourceSet: CompositeMetadataArtifact.SourceSet, override val sourceSet: CompositeMetadataArtifact.SourceSet,
override val cinteropLibraryName: String, override val cinteropLibraryName: String,
private val artifact: ArtifactFile, private val artifactFile: ArtifactFile,
) : CompositeMetadataArtifact.CInteropMetadataLibrary { ) : CompositeMetadataArtifact.CInteropMetadataLibrary {
override val archiveExtension: String override val archiveExtension: String
get() = SourceSetMetadataLayout.KLIB.archiveExtension get() = SourceSetMetadataLayout.KLIB.archiveExtension
override val checksum: Int
get() = artifactFile.checksum
override val checksumString: String
get() = artifactFile.checksumString
/** /**
* Example: * Example:
* org.jetbrains.sample-sampleLibrary-1.0.0-SNAPSHOT-appleAndLinuxMain-cinterop/ * 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 { override val relativeFile: File = File(buildString {
append(artifactHandle.moduleDependencyIdentifier) append(artifactHandle.moduleDependencyIdentifier)
@@ -154,7 +172,7 @@ internal class CompositeMetadataArtifactImpl(
append("-") append("-")
append(sourceSet.sourceSetName) append(sourceSet.sourceSetName)
append("-cinterop") append("-cinterop")
}).resolve("$cinteropLibraryName.${archiveExtension}") }).resolve("$cinteropLibraryName-${checksumString}.${archiveExtension}")
override fun copyTo(file: File): Boolean { override fun copyTo(file: File): Boolean {
require(file.extension == archiveExtension) { require(file.extension == archiveExtension) {
@@ -167,9 +185,9 @@ internal class CompositeMetadataArtifactImpl(
val cinteropMetadataDirectoryPath = ensureValidZipDirectoryPath(cinteropMetadataDirectory) val cinteropMetadataDirectoryPath = ensureValidZipDirectoryPath(cinteropMetadataDirectory)
val libraryPath = "$cinteropMetadataDirectoryPath$cinteropLibraryName/" val libraryPath = "$cinteropMetadataDirectoryPath$cinteropLibraryName/"
if (!artifact.containsDirectory(libraryPath)) return false if (!artifactFile.containsDirectory(libraryPath)) return false
file.parentFile.mkdirs() file.parentFile.mkdirs()
artifact.zip.copyPartially(file, "$cinteropMetadataDirectoryPath$cinteropLibraryName/") artifactFile.zip.copyPartially(file, "$cinteropMetadataDirectoryPath$cinteropLibraryName/")
return true return true
} }
@@ -181,6 +199,10 @@ internal class CompositeMetadataArtifactImpl(
*/ */
private class ArtifactFile(private val file: File) : Closeable { private class ArtifactFile(private val file: File) : Closeable {
companion object {
val checksumStringEncoder: Encoder = Base64.getUrlEncoder().withoutPadding()
}
private var isClosed = false private var isClosed = false
private val lazyZip = lazy { private val lazyZip = lazy {
@@ -190,7 +212,19 @@ internal class CompositeMetadataArtifactImpl(
val zip: ZipFile get() = lazyZip.value 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 * All potential directory paths, including inferred directory paths when the [zip] file does