From 099ad8de1e7266b320adbb9fedc673770a4e2c36 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Fri, 7 Sep 2018 20:59:50 +0300 Subject: [PATCH] Don't set Kotlin platform attribute for the `default` configuration Also, fix empty configurations created for targets that have no runtime outputs (metadata ones, especially), which could get chosen by Gradle during dependency variant-aware resolution of a `project(...)` dependency. See also: d13ca38 With the attribute set, an input configuration that does not require the Gradle's USAGE attribute but requires Kotlin platform metadata, will fail to resolve because the attributes set on the consumable output configurations are not subsets of each other, as follows: > Cannot choose between the following variants of project :lib: - metadataApiElements - metadataDefault - metadataRuntimeElements All of them match the consumer attributes: - Variant 'metadataApiElements': - Found org.gradle.usage 'java-api' but wasn't required. - Required org.jetbrains.kotlin.platform.type 'common' and found compatible value 'common'. - Variant 'metadataDefault': - Required org.jetbrains.kotlin.platform.type 'common' and found compatible value 'common'. - Variant 'metadataRuntimeElements': - Found org.gradle.usage 'java-runtime-jars' but wasn't required. - Required org.jetbrains.kotlin.platform.type 'common' and found compatible value 'common'. Issue #KT-26383 Fixed --- .../kotlin/gradle/NewMultiplatformIT.kt | 33 ++++++++++++++++++- .../gradle/plugin/KotlinTargetConfigurator.kt | 23 ++++++------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index db3e63acedf..ff3c4241ec1 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -2,7 +2,6 @@ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ - package org.jetbrains.kotlin.gradle import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin @@ -399,6 +398,38 @@ class NewMultiplatformIT : BaseGradleIT() { } } + @Test + fun testResolveMppProjectDependencyToMetadata() { + val libProject = Project("sample-lib", gradleVersion, "new-mpp-lib-and-app") + val appProject = Project("sample-app", gradleVersion, "new-mpp-lib-and-app") + + val pathPrefix = "metadataDependency: " + + with(appProject) { + setupWorkingDir() + libProject.setupWorkingDir() + + libProject.projectDir.copyRecursively(projectDir.resolve(libProject.projectDir.name)) + projectDir.resolve("settings.gradle").appendText("\ninclude '${libProject.projectDir.name}'") + gradleBuildScript().modify { + it.replace("'com.example:sample-lib:1.0'", "project(':${libProject.projectDir.name}')") + + "\n" + """ + task('printMetadataFiles') { + doFirst { + configurations.getByName('commonMainImplementation$METADATA_CONFIGURATION_NAME_SUFFIX') + .files.each { println '$pathPrefix' + it.name } + } + } + """.trimIndent() + } + + build("printMetadataFiles") { + assertSuccessful() + assertContains(pathPrefix + "sample-lib-metadata-1.0.jar") + } + } + } + @Test fun testPublishingOnlySupportedNativeTargets() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) { val (publishedVariant, nonPublishedVariant) = when { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt index f969de3e41b..6da3784d499 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt @@ -173,7 +173,7 @@ abstract class AbstractKotlinTargetConfigurator val runtimeOnlyConfiguration = configurations.maybeCreate(mainCompilation.runtimeOnlyConfigurationName) - configurations.maybeCreate(target.apiElementsConfigurationName).apply { + val apiElementsConfiguration = configurations.maybeCreate(target.apiElementsConfigurationName).apply { description = "API elements for main." isVisible = false isCanBeResolved = false @@ -187,21 +187,22 @@ abstract class AbstractKotlinTargetConfigurator usesPlatformOf(target) } - val runtimeElementsConfiguration = configurations.maybeCreate(target.runtimeElementsConfigurationName).apply { - description = "Elements of runtime for main." - isVisible = false - isCanBeConsumed = true - isCanBeResolved = false - attributes.attribute(USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_RUNTIME_JARS)) - if (mainCompilation is KotlinCompilationToRunnableFiles) { + if (mainCompilation is KotlinCompilationToRunnableFiles) { + val runtimeElementsConfiguration = configurations.maybeCreate(target.runtimeElementsConfigurationName).apply { + description = "Elements of runtime for main." + isVisible = false + isCanBeConsumed = true + isCanBeResolved = false + attributes.attribute(USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_RUNTIME_JARS)) val runtimeConfiguration = configurations.maybeCreate(mainCompilation.deprecatedRuntimeConfigurationName) extendsFrom(implementationConfiguration, runtimeOnlyConfiguration, runtimeConfiguration) + usesPlatformOf(target) } - usesPlatformOf(target) + defaultConfiguration.extendsFrom(runtimeElementsConfiguration) + } else { + defaultConfiguration.extendsFrom(apiElementsConfiguration) } - defaultConfiguration.extendsFrom(runtimeElementsConfiguration).usesPlatformOf(target) - if (createTestCompilation) { val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME) val compileTestsConfiguration = configurations.maybeCreate(testCompilation.deprecatedCompileConfigurationName)