From cf2c686630ad3e9eaf6c960b9dd44fc4d34c1a5c Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Mon, 21 Jun 2021 17:37:01 +0300 Subject: [PATCH] Fix kotlin-test variants for correct resolution in *DependenciesMetadata Make Gradle choose the `commonVariant` when a capability-less dependency on kotlin-test is resolved for configurations requesting the common artifacts. Issue #KTIJ-6098 Fixed --- libraries/kotlin.test/build.gradle.kts | 19 ++++++++++++++++++- .../gradle/KotlinSpecificDependenciesIT.kt | 15 +++++++++++++++ .../mpp-single-jvm-target/build.gradle.kts | 12 ++++++++++++ .../mpp-single-jvm-target/gradle.properties | 1 + .../mpp-single-jvm-target/settings.gradle.kts | 10 ++++++++++ .../src/commonMain/kotlin/ThirdParty.kt | 5 +++++ .../src/jvmMain/kotlin/ThirdPartyJvm.kt | 5 +++++ 7 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/build.gradle.kts create mode 100755 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/gradle.properties create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/settings.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/commonMain/kotlin/ThirdParty.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/jvmMain/kotlin/ThirdPartyJvm.kt diff --git a/libraries/kotlin.test/build.gradle.kts b/libraries/kotlin.test/build.gradle.kts index 74545518343..fc7659823e8 100644 --- a/libraries/kotlin.test/build.gradle.kts +++ b/libraries/kotlin.test/build.gradle.kts @@ -119,11 +119,14 @@ val rootComponent = componentFactory.adhoc("root").apply { } +val kotlinTestCapability = "$group:kotlin-test:$version" // add to variants with explicit capabilities when the default one is needed, too val baseCapability = "$group:kotlin-test-framework:$version" val implCapability = "$group:kotlin-test-framework-impl:$version" val jvmTestFrameworks = listOf("junit", "junit5", "testng") +val frameworkCapabilities = mutableSetOf() + jvmTestFrameworks.forEach { framework -> val (apiVariant, runtimeVariant) = listOf("api", "runtime").map { usage -> configurations.create("${framework}${usage.capitalize()}Variant") { @@ -134,7 +137,9 @@ jvmTestFrameworks.forEach { framework -> attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm) } outgoing.capability(baseCapability) // C0 - outgoing.capability("$group:kotlin-test-framework-$framework:$version") // C0 + outgoing.capability( + "$group:kotlin-test-framework-$framework:$version".also { frameworkCapabilities.add(it) } + ) // C0 } } runtimeVariant.extendsFrom(apiVariant) @@ -188,6 +193,18 @@ jvmTestFrameworks.forEach { framework -> }.let { components.add(it) } } +/** + * When a consumer's dependency requires a specific test framework (like with auto framework selection), their configurations requesting + * "common" artifacts (such as `*DependenciesMetadata` in MPP) should choose this variant anyway. Otherwise, choosing this variant + * (from a "pure", capability-less dependency on `kotlin-test` appearing transitively in the dependency graph) along with some + * capability-providing *platform* variant leads to incompatible variants being chosen together, causing dependency resolution errors, + * see KTIJ-6098 + */ +commonVariant.apply { + frameworkCapabilities.forEach(outgoing::capability) + outgoing.capability(kotlinTestCapability) +} + val (jsApi, jsRuntime) = listOf("api", "runtime").map { usage -> configurations.create("js${usage.capitalize()}") { isCanBeConsumed = true diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinSpecificDependenciesIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinSpecificDependenciesIT.kt index e52c6caf889..210edf35cb5 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinSpecificDependenciesIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinSpecificDependenciesIT.kt @@ -163,6 +163,21 @@ class KotlinSpecificDependenciesIT : BaseGradleIT() { "jvmAndJsTestCompileOnlyDependenciesMetadata" to listOf("kotlin-test-common"), "jvmAndJsTestImplementationDependenciesMetadata" to listOf("!kotlin-test-common"), ) + ), + TestCase( + /** + * Check that in a single-platform project the common metadata configurations resolve the + * framework-specific dependency (inferred as JUnit) correctly to the common artifact + * KTIJ-6098 + */ + Project("mpp-single-jvm-target"), + listOf("commonTestImplementation"), + mapOf( + "compileTestKotlinJvm" to listOf("kotlin-test-junit"), + ), + mapOf( + "commonTestImplementationDependenciesMetadata" to listOf("kotlin-test-common", "kotlin-test-annotations-common") + ) ) ).forEach { testCase -> with(testCase) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/build.gradle.kts new file mode 100644 index 00000000000..abce9c1c157 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + kotlin("multiplatform") +} + +repositories { + mavenLocal() + mavenCentral() +} + +kotlin { + jvm() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/gradle.properties b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/gradle.properties new file mode 100755 index 00000000000..2a391fe78b0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/gradle.properties @@ -0,0 +1 @@ +kotlin.mpp.enableGranularSourceSetsMetadata=true \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/settings.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/settings.gradle.kts new file mode 100644 index 00000000000..92e9d3068fc --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/settings.gradle.kts @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + } + val kotlin_version: String by settings + plugins { + kotlin("multiplatform").version(kotlin_version) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/commonMain/kotlin/ThirdParty.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/commonMain/kotlin/ThirdParty.kt new file mode 100644 index 00000000000..52ee4ee68a6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/commonMain/kotlin/ThirdParty.kt @@ -0,0 +1,5 @@ +package com.example.thirdparty + +expect fun thirdPartyFun(): String + +private fun useStdlibInCommonMain() = listOf(1, 2, 3).joinToString() \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/jvmMain/kotlin/ThirdPartyJvm.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/jvmMain/kotlin/ThirdPartyJvm.kt new file mode 100644 index 00000000000..ad7e11903d8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/mpp-single-jvm-target/src/jvmMain/kotlin/ThirdPartyJvm.kt @@ -0,0 +1,5 @@ +package com.example.thirdparty + +actual fun thirdPartyFun(): String = "thirdPartyFun @ jvm" + +fun thirdPartyJvmFun() { } \ No newline at end of file