[Gradle] Remove metadata dependencies transformation for runtimeOnly

Kotlin Metadata KLIBs cannot be used in runtime thus
we don't have to transform composite JARs that contain
metadata per source set for runtimeOnly dependencies scopes.

^KT-55230 Fixed
This commit is contained in:
Anton Lakotka
2022-12-02 11:37:15 +01:00
committed by Space Team
parent 5db9c2990a
commit 98678bce0a
9 changed files with 48 additions and 82 deletions
@@ -28,6 +28,7 @@ interface KotlinSourceSet : Named, HasKotlinDependencies {
val apiMetadataConfigurationName: String
val implementationMetadataConfigurationName: String
val compileOnlyMetadataConfigurationName: String
@Deprecated(message = "KT-55230: RuntimeOnly scope is not supported for metadata dependency transformation")
val runtimeOnlyMetadataConfigurationName: String
override val relatedConfigurationNames: List<String>
@@ -36,7 +37,6 @@ interface KotlinSourceSet : Named, HasKotlinDependencies {
apiMetadataConfigurationName,
implementationMetadataConfigurationName,
compileOnlyMetadataConfigurationName,
runtimeOnlyMetadataConfigurationName
)
companion object {
@@ -12,12 +12,12 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.ide.IdeaKotlinBinaryCoordinates
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfigurationForSourceSets
import org.jetbrains.kotlin.gradle.plugin.sources.project
object IdeOriginalMetadataDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
val metadataDependenciesConfiguration = resolvableMetadataConfiguration(sourceSet.project, listOf(sourceSet),)
val metadataDependenciesConfiguration = resolvableMetadataConfigurationForSourceSets(sourceSet.project, listOf(sourceSet))
val keptOriginalDependencyResolutionIds = sourceSet.resolveMetadata<MetadataDependencyResolution.KeepOriginalDependency>()
.map { it.dependency.id }.toSet()
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.Choos
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope
import org.jetbrains.kotlin.gradle.targets.metadata.ALL_COMPILE_METADATA_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.targets.metadata.ALL_RUNTIME_METADATA_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies
import java.util.*
@@ -106,6 +105,12 @@ internal class GranularMetadataTransformation(
/** A configuration that holds the dependencies of the appropriate scope for all Kotlin source sets in the project */
private val parentTransformations: Lazy<Iterable<GranularMetadataTransformation>>
) {
init {
require(KotlinDependencyScope.RUNTIME_ONLY_SCOPE !in sourceSetRequestedScopes) {
"KT-55230: RuntimeOnly scope is not supported for metadata dependency transformation"
}
}
val metadataDependencyResolutions: Iterable<MetadataDependencyResolution> by lazy { doTransform() }
// Keep parents of each dependency, too. We need a dependency's parent when it's an MPP's metadata module dependency:
@@ -119,11 +124,8 @@ internal class GranularMetadataTransformation(
requestedDependencies(project, kotlinSourceSet, sourceSetRequestedScopes)
}
private val allSourceSetsConfiguration: Configuration =
commonMetadataDependenciesConfigurationForScopes(project, sourceSetRequestedScopes)
internal val configurationToResolve: Configuration by lazy {
resolvableMetadataConfiguration(project, allSourceSetsConfiguration, requestedDependencies)
resolvableMetadataConfigurationForDependencies(project, requestedDependencies)
}
private fun doTransform(): Iterable<MetadataDependencyResolution> {
@@ -305,18 +307,12 @@ internal fun ResolvedComponentResult.toProjectOrNull(currentProject: Project): P
}
}
internal fun resolvableMetadataConfiguration(
internal fun resolvableMetadataConfigurationForSourceSets(
project: Project,
sourceSets: Iterable<KotlinSourceSet>,
scopes: Iterable<KotlinDependencyScope> = setOf(
KotlinDependencyScope.API_SCOPE,
KotlinDependencyScope.IMPLEMENTATION_SCOPE,
KotlinDependencyScope.COMPILE_ONLY_SCOPE
)
): Configuration = resolvableMetadataConfiguration(
): Configuration = resolvableMetadataConfigurationForDependencies(
project,
commonMetadataDependenciesConfigurationForScopes(project, scopes),
sourceSets.flatMapTo(mutableListOf()) { requestedDependencies(project, it, scopes) }
sourceSets.flatMapTo(mutableListOf()) { requestedDependencies(project, it, KotlinDependencyScope.compileScopes) }
)
/** If a source set is not a published source set, its dependencies are not included in [allSourceSetsConfiguration].
@@ -324,11 +320,12 @@ internal fun resolvableMetadataConfiguration(
* we need to create a new configuration with the dependencies from both [allSourceSetsConfiguration] and the
* other [requestedDependencies] */
// TODO: optimize by caching the resulting configurations?
internal fun resolvableMetadataConfiguration(
internal fun resolvableMetadataConfigurationForDependencies(
project: Project,
allSourceSetsConfiguration: Configuration,
requestedDependencies: Iterable<Dependency>
): Configuration {
val allSourceSetsConfiguration = project.configurations.getByName(ALL_COMPILE_METADATA_CONFIGURATION_NAME)
var modifiedConfiguration: Configuration? = null
val originalDependencies = allSourceSetsConfiguration.allDependencies
@@ -348,20 +345,6 @@ internal fun resolvableMetadataConfiguration(
return modifiedConfiguration ?: allSourceSetsConfiguration
}
/** The configuration that contains the dependencies of the corresponding scopes (and maybe others)
* from all published source sets. */
internal fun commonMetadataDependenciesConfigurationForScopes(
project: Project,
scopes: Iterable<KotlinDependencyScope>
): Configuration {
// TODO: what if 'runtimeOnly' is combined with 'compileOnly'? prohibit this or merge the two? we never do that now, though
val configurationName = if (KotlinDependencyScope.RUNTIME_ONLY_SCOPE in scopes)
ALL_RUNTIME_METADATA_CONFIGURATION_NAME
else
ALL_COMPILE_METADATA_CONFIGURATION_NAME
return project.configurations.getByName(configurationName)
}
internal fun requestedDependencies(
project: Project,
sourceSet: KotlinSourceSet,
@@ -12,6 +12,7 @@ import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.targets.metadata.ALL_COMPILE_METADATA_CONFIGURATION_NAME
@@ -87,7 +88,7 @@ open class MetadataDependencyTransformationTask
GranularMetadataTransformation(
project,
kotlinSourceSet,
listOf(API_SCOPE, IMPLEMENTATION_SCOPE, COMPILE_ONLY_SCOPE),
KotlinDependencyScope.compileScopes,
lazy {
dependsOnClosureWithInterCompilationDependencies(kotlinSourceSet).map {
project.tasks.withType(MetadataDependencyTransformationTask::class.java)
@@ -11,8 +11,7 @@ import org.gradle.api.artifacts.result.ResolvedComponentResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.pm20ExtensionOrNull
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfigurationForSourceSets
import org.jetbrains.kotlin.project.model.*
internal fun resolvableMetadataConfiguration(
@@ -22,10 +21,9 @@ internal fun resolvableMetadataConfiguration(
internal fun configurationToResolveMetadataDependencies(project: Project, requestingModule: KpmModule): Configuration =
when {
project.pm20ExtensionOrNull != null -> resolvableMetadataConfiguration(requestingModule as GradleKpmModule)
else -> resolvableMetadataConfiguration(
else -> resolvableMetadataConfigurationForSourceSets(
project,
project.kotlinExtension.sourceSets, // take dependencies from all source sets; TODO introduce consistency scopes?
KotlinDependencyScope.compileScopes
)
}
@@ -54,6 +54,7 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
override val compileOnlyMetadataConfigurationName: String
get() = lowerCamelCaseName(compileOnlyConfigurationName, METADATA_CONFIGURATION_NAME_SUFFIX)
@Deprecated(message = "KT-55230: RuntimeOnly scope is not supported for metadata dependency transformation")
override val runtimeOnlyMetadataConfigurationName: String
get() = lowerCamelCaseName(runtimeOnlyConfigurationName, METADATA_CONFIGURATION_NAME_SUFFIX)
@@ -143,8 +144,8 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
@Suppress("unused") // Used in IDE import
fun getDependenciesTransformation(configurationName: String): Iterable<MetadataDependencyTransformation> {
val scope = KotlinDependencyScope.values().find {
project.sourceSetMetadataConfigurationByScope(this, it).name == configurationName
val scope = KotlinDependencyScope.compileScopes.find {
project.sourceSetMetadataConfigurationByScope(this, it)?.name == configurationName
} ?: return emptyList()
return getDependenciesTransformation(scope)
@@ -53,12 +53,12 @@ internal fun Project.compilationDependencyConfigurationByScope(
}
)
internal fun Project.sourceSetMetadataConfigurationByScope(sourceSet: KotlinSourceSet, scope: KotlinDependencyScope): Configuration =
project.configurations.getByName(
when (scope) {
API_SCOPE -> sourceSet.apiMetadataConfigurationName
IMPLEMENTATION_SCOPE -> sourceSet.implementationMetadataConfigurationName
COMPILE_ONLY_SCOPE -> sourceSet.compileOnlyMetadataConfigurationName
RUNTIME_ONLY_SCOPE -> sourceSet.runtimeOnlyMetadataConfigurationName
}
)
internal fun Project.sourceSetMetadataConfigurationByScope(sourceSet: KotlinSourceSet, scope: KotlinDependencyScope): Configuration? {
val configurationName = when (scope) {
API_SCOPE -> sourceSet.apiMetadataConfigurationName
IMPLEMENTATION_SCOPE -> sourceSet.implementationMetadataConfigurationName
COMPILE_ONLY_SCOPE -> sourceSet.compileOnlyMetadataConfigurationName
RUNTIME_ONLY_SCOPE -> return null // KT-55230: RuntimeOnly scope is not supported for metadata dependency transformation
}
return project.configurations.getByName(configurationName)
}
@@ -79,7 +79,6 @@ internal class DefaultKotlinSourceSetFactory(
apiConfigurationName to apiMetadataConfigurationName,
implementationConfigurationName to implementationMetadataConfigurationName,
compileOnlyConfigurationName to compileOnlyMetadataConfigurationName,
runtimeOnlyConfigurationName to runtimeOnlyMetadataConfigurationName,
null to intransitiveMetadataConfigurationName
)
}
@@ -32,7 +32,6 @@ import java.util.concurrent.Callable
internal const val COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME = "commonMainMetadataElements"
internal const val ALL_COMPILE_METADATA_CONFIGURATION_NAME = "allSourceSetsCompileDependenciesMetadata"
internal const val ALL_RUNTIME_METADATA_CONFIGURATION_NAME = "allSourceSetsRuntimeDependenciesMetadata"
internal val Project.isKotlinGranularMetadataEnabled: Boolean
get() = project.pm20ExtensionOrNull != null || with(PropertiesProvider(rootProject)) {
@@ -80,7 +79,7 @@ class KotlinMetadataTargetConfigurator :
compileKotlinTaskProvider.configure { it.onlyIf { isCompatibilityMetadataVariantEnabled } }
}
createMergedAllSourceSetsConfigurations(target)
createAllCompileMetadataConfiguration(target)
val allMetadataJar = target.project.tasks.withType<Jar>().named(ALL_METADATA_JAR_NAME)
createMetadataCompilationsForCommonSourceSets(target, allMetadataJar)
@@ -271,16 +270,15 @@ class KotlinMetadataTargetConfigurator :
}
}
private fun createMergedAllSourceSetsConfigurations(target: KotlinMetadataTarget): Unit = with(target.project) {
listOf(ALL_COMPILE_METADATA_CONFIGURATION_NAME, ALL_RUNTIME_METADATA_CONFIGURATION_NAME).forEach { configurationName ->
project.configurations.create(configurationName).apply {
isCanBeConsumed = false
isCanBeResolved = true
private fun createAllCompileMetadataConfiguration(target: KotlinMetadataTarget): Unit {
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))
}
usesPlatformOf(target)
attributes.attribute(USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
attributes.attribute(CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}
}
@@ -361,7 +359,7 @@ class KotlinMetadataTargetConfigurator :
sourceSet: KotlinSourceSet,
isSourceSetPublished: Boolean
) {
KotlinDependencyScope.values().forEach { scope ->
KotlinDependencyScope.compileScopes.forEach { scope ->
val granularMetadataTransformation = GranularMetadataTransformation(
project,
sourceSet,
@@ -378,29 +376,15 @@ class KotlinMetadataTargetConfigurator :
val sourceSetDependencyConfigurationByScope = project.configurations.sourceSetDependencyConfigurationByScope(sourceSet, scope)
if (isSourceSetPublished) {
if (scope != KotlinDependencyScope.COMPILE_ONLY_SCOPE) {
project.addExtendsFromRelation(
ALL_RUNTIME_METADATA_CONFIGURATION_NAME,
sourceSetDependencyConfigurationByScope.name
)
}
if (scope != KotlinDependencyScope.RUNTIME_ONLY_SCOPE) {
project.addExtendsFromRelation(
ALL_COMPILE_METADATA_CONFIGURATION_NAME,
sourceSetDependencyConfigurationByScope.name
)
}
project.addExtendsFromRelation(
ALL_COMPILE_METADATA_CONFIGURATION_NAME,
sourceSetDependencyConfigurationByScope.name
)
}
val sourceSetMetadataConfigurationByScope = project.sourceSetMetadataConfigurationByScope(sourceSet, scope)
granularMetadataTransformation.applyToConfiguration(sourceSetMetadataConfigurationByScope)
if (scope != KotlinDependencyScope.COMPILE_ONLY_SCOPE) {
project.addExtendsFromRelation(
sourceSetMetadataConfigurationByScope.name,
ALL_COMPILE_METADATA_CONFIGURATION_NAME
)
}
if (scope != KotlinDependencyScope.RUNTIME_ONLY_SCOPE) {
if (sourceSetMetadataConfigurationByScope != null) {
granularMetadataTransformation.applyToConfiguration(sourceSetMetadataConfigurationByScope)
project.addExtendsFromRelation(
sourceSetMetadataConfigurationByScope.name,
ALL_COMPILE_METADATA_CONFIGURATION_NAME