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
This commit is contained in:
Sergey Igushkin
2018-09-07 20:59:50 +03:00
parent 908be10bf4
commit 099ad8de1e
2 changed files with 44 additions and 12 deletions
@@ -2,7 +2,6 @@
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * 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. * that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin 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 @Test
fun testPublishingOnlySupportedNativeTargets() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) { fun testPublishingOnlySupportedNativeTargets() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
val (publishedVariant, nonPublishedVariant) = when { val (publishedVariant, nonPublishedVariant) = when {
@@ -173,7 +173,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
val runtimeOnlyConfiguration = configurations.maybeCreate(mainCompilation.runtimeOnlyConfigurationName) val runtimeOnlyConfiguration = configurations.maybeCreate(mainCompilation.runtimeOnlyConfigurationName)
configurations.maybeCreate(target.apiElementsConfigurationName).apply { val apiElementsConfiguration = configurations.maybeCreate(target.apiElementsConfigurationName).apply {
description = "API elements for main." description = "API elements for main."
isVisible = false isVisible = false
isCanBeResolved = false isCanBeResolved = false
@@ -187,21 +187,22 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
usesPlatformOf(target) usesPlatformOf(target)
} }
val runtimeElementsConfiguration = configurations.maybeCreate(target.runtimeElementsConfigurationName).apply { if (mainCompilation is KotlinCompilationToRunnableFiles) {
description = "Elements of runtime for main." val runtimeElementsConfiguration = configurations.maybeCreate(target.runtimeElementsConfigurationName).apply {
isVisible = false description = "Elements of runtime for main."
isCanBeConsumed = true isVisible = false
isCanBeResolved = false isCanBeConsumed = true
attributes.attribute<Usage>(USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_RUNTIME_JARS)) isCanBeResolved = false
if (mainCompilation is KotlinCompilationToRunnableFiles) { attributes.attribute<Usage>(USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_RUNTIME_JARS))
val runtimeConfiguration = configurations.maybeCreate(mainCompilation.deprecatedRuntimeConfigurationName) val runtimeConfiguration = configurations.maybeCreate(mainCompilation.deprecatedRuntimeConfigurationName)
extendsFrom(implementationConfiguration, runtimeOnlyConfiguration, runtimeConfiguration) extendsFrom(implementationConfiguration, runtimeOnlyConfiguration, runtimeConfiguration)
usesPlatformOf(target)
} }
usesPlatformOf(target) defaultConfiguration.extendsFrom(runtimeElementsConfiguration)
} else {
defaultConfiguration.extendsFrom(apiElementsConfiguration)
} }
defaultConfiguration.extendsFrom(runtimeElementsConfiguration).usesPlatformOf(target)
if (createTestCompilation) { if (createTestCompilation) {
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME) val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME)
val compileTestsConfiguration = configurations.maybeCreate(testCompilation.deprecatedCompileConfigurationName) val compileTestsConfiguration = configurations.maybeCreate(testCompilation.deprecatedCompileConfigurationName)