From 75cc378cac2b780104cb6c01c7ccf53e72bc50c1 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Fri, 16 Sep 2022 10:14:53 +0200 Subject: [PATCH] [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 --- .../jetbrains/kotlin/gradle/KlibBasedMppIT.kt | 18 +++---- .../plugin/mpp/CompositeMetadataArtifact.kt | 2 + .../mpp/CompositeMetadataArtifactImpl.kt | 48 ++++++++++++++++--- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt index 6ae3c32c834..1397b29096b 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KlibBasedMppIT.kt @@ -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 = emptyList(), - checkModulesNotInClasspath: List = emptyList() + checkModulesInClasspath: List = emptyList(), + checkModulesNotInClasspath: List = 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, - checkNoItemContains: List + checkAnyItemsContains: List, + checkNoItemContains: List ) = with(testCase) { setupWorkingDir() val printingTaskName = "printItems${testBuildRunId++}" diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifact.kt index 62c5deea476..45bbb90cf2c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifact.kt @@ -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. diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt index fccd8826bb1..513275a96f4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompositeMetadataArtifactImpl.kt @@ -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 by lazy { zip.entries().toList() } + val entries: List 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