Resolve java-runtime everywhere Gradle synthesises classified dependencies as java-runtime and now we support these in lenient resolution ^KT-81467
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt index 61048af..d0f8d4b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/uklibs/consumption/UklibConsumptionSetupAction.kt
@@ -348,6 +348,10 @@ */ JAVA_API, /** + * Classified JVM POM dependencies are synthesized as "java-runtime": KT-81467 + */ + JAVA_RUNTIME, + /** * Fallback to metadata variant to inherit dependencies for lenient interlibrary dependencies. Platform configurations * throw away metadata jars in [ThrowAwayMetadataJarsTransform]. GMT now always resolves and special-handles the case * when platform configurations resolved into metadata jar. @@ -423,6 +427,10 @@ * Compatibility with all the Maven POM-only and Gradle JVM producers for dependency inheritance */ JAVA_API, + /** + * Classified JVM POM dependencies are synthesized as "java-runtime": KT-81467 + */ + JAVA_RUNTIME, KOTLIN_UKLIB_FALLBACK_VARIANT, ), )[consumerUsage]?.contains(producerUsage) == true
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTestingAttributes.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTestingAttributes.kt index 886093f..967e187 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTestingAttributes.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/ResolutionTestingAttributes.kt
@@ -56,6 +56,10 @@ "org.gradle.libraryelements" to "jar", "org.gradle.usage" to "java-api", ) +val jvmRuntimeClassifiedAttributes = mapOf( + "org.gradle.libraryelements" to "jar", + "org.gradle.usage" to "java-runtime", +) val kmpJvmRuntimeVariantAttributes = mapOf( "org.gradle.category" to "library",
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWithMockComponents.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWithMockComponents.kt index 7c617a1..65332ae 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWithMockComponents.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/UklibResolutionWithMockComponents.kt
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.gradle.testing.runtimeResolution import org.jetbrains.kotlin.gradle.unitTests.uklibs.GradleMetadataComponent.MockVariantType import org.jetbrains.kotlin.gradle.unitTests.uklibs.GradleMetadataComponent.Variant +import org.jetbrains.kotlin.gradle.unitTests.uklibs.MavenComponent.MockArtifactType import org.jetbrains.kotlin.gradle.util.* import org.jetbrains.kotlin.incremental.createDirectory import org.junit.Rule @@ -780,6 +781,87 @@ } @Test + fun `uklib resolution - all configurations can resolve classified POM dependencies - KT-81467`() { + val repo = generateMockRepository( + tmpDir, + mavenComponents = listOf( + directMavenComponent( + mocks = listOf( + MockArtifactType.EmptyJar(), + MockArtifactType.EmptyJar(classifier = "foo"), + ) + ) + ) + ) + + val consumer = uklibConsumer { + repositories.maven(repo) + kotlin { + iosArm64() + iosX64() + jvm() + js() + sourceSets.commonMain.dependencies { implementation("foo:direct:1.0:foo") } + } + } + + listOf( + consumer.multiplatformExtension.iosArm64(), + consumer.multiplatformExtension.jvm(), + consumer.multiplatformExtension.js(), + ).forEach { + assertEquals( + mapOf<String, ResolvedComponentWithArtifacts>( + "foo:direct:1.0" to ResolvedComponentWithArtifacts( + configuration = "compile", + artifacts = mutableListOf( + jvmRuntimeClassifiedAttributes + jarArtifact, + ) + ) + ).prettyPrinted, + it.compilationResolution().prettyPrinted, + message = it.name + ) + } + + listOf( + consumer.multiplatformExtension.sourceSets.iosMain.get().internal.resolvableMetadataConfiguration, + consumer.multiplatformExtension.sourceSets.commonMain.get().internal.resolvableMetadataConfiguration, + ).forEach { + assertEquals( + mapOf<String, ResolvedComponentWithArtifacts>( + "foo:direct:1.0" to ResolvedComponentWithArtifacts( + configuration = "compile", + artifacts = mutableListOf( + jvmRuntimeClassifiedAttributes + jarArtifact, + ) + ) + ).prettyPrinted, + it.resolveProjectDependencyComponentsWithArtifacts().prettyPrinted, + message = it.name, + ) + } + + listOf( + consumer.multiplatformExtension.jvm(), + consumer.multiplatformExtension.js(), + ).forEach { + assertEquals( + mapOf<String, ResolvedComponentWithArtifacts>( + "foo:direct:1.0" to ResolvedComponentWithArtifacts( + configuration = "runtime", + artifacts = mutableListOf( + jvmRuntimeClassifiedAttributes + jarArtifact, + ) + ) + ).prettyPrinted, + it.runtimeResolution().prettyPrinted, + message = it.name, + ) + } + } + + @Test fun `uklib resolution - resolution with annotations`() { val consumer = uklibConsumer { repositories.mavenCentral() @@ -1542,11 +1624,15 @@ version = "1.0", ) - private fun directMavenComponent(packaging: String? = null) = MavenComponent( + private fun directMavenComponent( + packaging: String? = null, + mocks: List<MockArtifactType> = listOf(MockArtifactType.EmptyJar()) + ) = MavenComponent( directGradleComponent.group, directGradleComponent.module, directGradleComponent.version, packaging = packaging, dependencies = listOf(), true, + mocks = mocks, ) private val uklibMock = GradleMetadataComponent.MockVariantFile( @@ -1727,4 +1813,4 @@ files = listOf(kmpJvmMock), dependencies = listOf() ) -} \ No newline at end of file +}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/generateMockRepository.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/generateMockRepository.kt index 61f12cb..e093d9c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/generateMockRepository.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/uklibs/generateMockRepository.kt
@@ -121,6 +121,7 @@ val packaging: String?, val dependencies: List<Dependency>, val gradleMetadataMarker: Boolean, + val mocks: List<MockArtifactType> = listOf(MockArtifactType.EmptyJar()), ) { class Dependency( val groupId: String?, @@ -128,6 +129,12 @@ val version: String?, val scope: String?, ) + + sealed class MockArtifactType( + val classifier: String? + ) { + class EmptyJar(classifier: String? = null) : MockArtifactType(classifier) + } } fun generateMockRepository( @@ -204,10 +211,17 @@ componentRoot.resolve("${mavenComponent.artifactId}-${mavenComponent.version}.pom").writeText( generatePom(mavenComponent) ) - componentRoot.resolve("${mavenComponent.artifactId}-${mavenComponent.version}.jar").also { - // Avoid overwriting Gradle variant - if (!it.exists()) { - ZipOutputStream(FileOutputStream(it)).use {} + mavenComponent.mocks.forEach { mock -> + val coordinate = listOfNotNull( + mavenComponent.artifactId, + mavenComponent.version, + mock.classifier + ).joinToString("-") + componentRoot.resolve("${coordinate}.jar").also { + // Avoid overwriting Gradle variant + if (!it.exists()) { + ZipOutputStream(FileOutputStream(it)).use {} + } } } }