[Gradle] resolvableMetadataConfiguration: Ensure consistent resolution across all compile dependencies

^KT-56461 Verification Pending
^KT-56431 Verification Pending
This commit is contained in:
Sebastian Sellmair
2023-02-07 11:01:13 +01:00
committed by Space Team
parent 5ec153822a
commit 380ca95661
3 changed files with 87 additions and 24 deletions
@@ -10,14 +10,14 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.Usage
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.categoryByName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
import org.jetbrains.kotlin.gradle.utils.markResolvable
import org.jetbrains.kotlin.gradle.plugin.sources.*
import org.jetbrains.kotlin.gradle.plugin.sources.InternalKotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX
import org.jetbrains.kotlin.gradle.plugin.sources.disambiguateName
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
import org.jetbrains.kotlin.gradle.utils.markResolvable
import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
import org.jetbrains.kotlin.gradle.utils.getOrCreate
@@ -71,14 +71,23 @@ internal val InternalKotlinSourceSet.resolvableMetadataConfiguration: Configurat
configuration
}
internal val Project.allCompileMetadataConfiguration get(): Configuration =
configurations.getOrCreate("allSourceSetsCompileDependenciesMetadata", invokeWhenCreated = {
it.markResolvable()
/**
* Configuration containing all compile dependencies from *all* source sets.
* This configuration is used to provide a dependency 'consistency scope' for
* the [InternalKotlinSourceSet.resolvableMetadataConfiguration]
*/
private val Project.allCompileMetadataConfiguration
get(): Configuration = configurations.getOrCreate("allSourceSetsCompileDependenciesMetadata", invokeWhenCreated = { configuration ->
configuration.markResolvable()
configuration.usesPlatformOf(multiplatformExtension.metadata())
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
val metadataTarget = multiplatformExtension.metadata()
it.usesPlatformOf(metadataTarget)
it.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
it.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
kotlinExtension.sourceSets.all { sourceSet ->
configuration.extendsFrom(configurations.getByName(sourceSet.apiConfigurationName))
configuration.extendsFrom(configurations.getByName(sourceSet.implementationConfigurationName))
configuration.extendsFrom(configurations.getByName(sourceSet.compileOnlyConfigurationName))
}
})
private inline fun <reified T> Project.listProvider(noinline provider: () -> List<T>): Provider<List<T>> {
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
internal const val COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME = "commonMainMetadataElements"
internal const val ALL_COMPILE_METADATA_CONFIGURATION_NAME = "allSourceSetsCompileDependenciesMetadata"
internal val Project.isKotlinGranularMetadataEnabled: Boolean
get() = project.pm20ExtensionOrNull != null || with(PropertiesProvider(this)) {
@@ -81,7 +80,6 @@ class KotlinMetadataTargetConfigurator :
compileKotlinTaskProvider.configure { it.onlyIf { isCompatibilityMetadataVariantEnabled } }
}
createAllCompileMetadataConfiguration(target)
val allMetadataJar = target.project.tasks.withType<Jar>().named(ALL_METADATA_JAR_NAME)
createMetadataCompilationsForCommonSourceSets(target, allMetadataJar)
@@ -272,18 +270,6 @@ class KotlinMetadataTargetConfigurator :
}
}
private fun createAllCompileMetadataConfiguration(target: KotlinMetadataTarget) {
val project = target.project
project.configurations.create(ALL_COMPILE_METADATA_CONFIGURATION_NAME).apply {
isCanBeConsumed = false
isCanBeResolved = true
usesPlatformOf(target)
attributes.attribute(USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
attributes.attribute(CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}
}
private fun createMetadataCompilation(
target: KotlinMetadataTarget,
sourceSet: KotlinSourceSet,
@@ -0,0 +1,68 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.dependencyResolutionTests
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.util.applyMultiplatformPlugin
import org.jetbrains.kotlin.gradle.util.buildProject
import org.jetbrains.kotlin.gradle.util.enableDefaultStdlibDependency
import org.jetbrains.kotlin.gradle.util.enableDependencyVerification
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.fail
class ResolvableMetadataConfigurationTest {
@Test
fun `test - resolves consistent in project`() {
val project = buildProject {
enableDefaultStdlibDependency(false)
enableDependencyVerification(false)
applyMultiplatformPlugin()
repositories.mavenCentralCacheRedirector()
}
val kotlin = project.multiplatformExtension
/* Define simple targets */
kotlin.jvm()
kotlin.linuxArm64()
kotlin.linuxX64()
kotlin.targetHierarchy.default()
val commonMain = kotlin.sourceSets.getByName("commonMain")
val nativeMain = kotlin.sourceSets.getByName("nativeMain")
commonMain.dependencies {
implementation("com.squareup.okio:okio:3.2.0")
}
/* nativeMain explicitly using 3.3.0 (higher than 3.2.0 in commonMain) */
nativeMain.dependencies {
implementation("com.squareup.okio:okio:3.3.0")
}
kotlin.sourceSets.forEach { sourceSet ->
sourceSet.internal.resolvableMetadataConfiguration.incoming.resolutionResult.allDependencies
.mapNotNull { result -> if (result is ResolvedDependencyResult) result.selected.id else null }
.filterIsInstance<ModuleComponentIdentifier>()
.filter { id -> id.group == "com.squareup.okio" }
.ifEmpty { fail("Expected at least one okio dependency resolved") }
.forEach { resolvedId ->
assertEquals(
"3.3.0", resolvedId.version,
"SourceSet: ${sourceSet.name} resolved $resolvedId, but expected consistent version 3.3.0"
)
}
}
}
}