From 8f4dd867883a0d2795351e519939d2ab6bd61689 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Tue, 7 Feb 2023 13:31:35 +0100 Subject: [PATCH] [Gradle] Move KotlinSourceSet metadata configuration into separate source file ^KT-56431 Verification Pending --- .../plugin/ide/dependencyResolvers/utils.kt | 6 +- .../plugin/sources/DefaultKotlinSourceSet.kt | 86 +---------------- .../KotlinSourceSetMetadataTransformation.kt | 96 +++++++++++++++++++ .../KotlinMetadataTargetConfigurator.kt | 11 +-- .../CInteropMetadataDependencyClasspath.kt | 3 +- ...ropMetadataDependencyTransformationTask.kt | 3 +- 6 files changed, 107 insertions(+), 98 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetMetadataTransformation.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/utils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/utils.kt index ee1aecd1471..3db1054e009 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/utils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/utils.kt @@ -8,9 +8,9 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution import org.jetbrains.kotlin.gradle.plugin.mpp.metadataDependencyResolutionsOrEmpty -import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.sources.internal +import org.jetbrains.kotlin.gradle.plugin.sources.metadataTransformation internal inline fun KotlinSourceSet.resolveMetadata(): List { - if (this !is DefaultKotlinSourceSet) return emptyList() - return compileDependenciesTransformation.metadataDependencyResolutionsOrEmpty.filterIsInstance() + return internal.metadataTransformation.metadataDependencyResolutionsOrEmpty.filterIsInstance() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt index 48f58dc9f91..209aa92f95e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultKotlinSourceSet.kt @@ -9,16 +9,13 @@ package org.jetbrains.kotlin.gradle.plugin.sources import org.gradle.api.Action import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration import org.gradle.api.file.SourceDirectorySet import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.mpp.* -import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.tooling.core.MutableExtras import org.jetbrains.kotlin.tooling.core.closure @@ -124,13 +121,6 @@ abstract class DefaultKotlinSourceSet @Inject constructor( explicitlyAddedCustomSourceFilesExtensions.addAll(extensions) } - /** - * Returns [GranularMetadataTransformation] for all requested compile dependencies - * scopes: API, IMPLEMENTATION, COMPILE_ONLY; See [KotlinDependencyScope.compileScopes] - */ - internal val compileDependenciesTransformation: GranularMetadataTransformation? by lazy { - createAndConfigureDependencyTransformationForSourceSet() - } private val _requiresVisibilityOf = mutableSetOf() @@ -163,7 +153,7 @@ abstract class DefaultKotlinSourceSet @Inject constructor( internal fun getDependenciesTransformation(): Iterable { val metadataDependencyResolutionByModule = - compileDependenciesTransformation.metadataDependencyResolutionsOrEmpty + metadataTransformation.metadataDependencyResolutionsOrEmpty .associateBy { ModuleIds.fromComponent(project, it.dependency) } return metadataDependencyResolutionByModule.mapNotNull { (groupAndName, resolution) -> @@ -193,7 +183,6 @@ abstract class DefaultKotlinSourceSet @Inject constructor( //endregion } - internal val defaultSourceSetLanguageSettingsChecker = FragmentConsistencyChecker( unitsName = "source sets", @@ -230,76 +219,3 @@ val Iterable.withDependsOnClosure: Set fun KotlinMultiplatformExtension.findSourceSetsDependingOn(sourceSet: KotlinSourceSet): Set { return sourceSet.closure { seedSourceSet -> sourceSets.filter { otherSourceSet -> seedSourceSet in otherSourceSet.dependsOn } } } - -private fun DefaultKotlinSourceSet.createAndConfigureDependencyTransformationForSourceSet(): GranularMetadataTransformation? { - // Create only for source sets in multiplatform plugin - project.multiplatformExtensionOrNull ?: return null - - val parentSourceSetVisibilityProvider = ParentSourceSetVisibilityProvider { componentIdentifier -> - dependsOnClosureWithInterCompilationDependencies(this).filterIsInstance() - .mapNotNull { it.compileDependenciesTransformation } - .flatMap { it.visibleSourceSetsByComponentId[componentIdentifier].orEmpty() } - .toSet() - } - - val granularMetadataTransformation = GranularMetadataTransformation( - params = GranularMetadataTransformation.Params(project, this), - parentSourceSetVisibilityProvider = parentSourceSetVisibilityProvider - ) - - /** - * - * This method is only intended to be called on deprecated DependenciesMetadata configurations to ensure - * correct behaviour in import. - * - * KGP based dependency resolution is therefore unaffected. - * - * Ensure that the [configuration] excludes the dependencies that are classified by this [GranularMetadataTransformation] as - * [MetadataDependencyResolution.Exclude], and uses exactly the same versions as were resolved for the requested - * dependencies during the transformation. - */ - fun applyTransformationToLegacyDependenciesMetadataConfiguration( - configuration: Configuration, - transformation: GranularMetadataTransformation - ) { - // Run this action immediately before the configuration first takes part in dependency resolution: - configuration.withDependencies { - val (unrequested, requested) = transformation.metadataDependencyResolutions - .partition { it is MetadataDependencyResolution.Exclude } - - unrequested.forEach { - val (group, name) = it.projectDependency(project)?.run { - /** Note: the project dependency notation here should be exactly this, group:name, - * not from [ModuleIds.fromProjectPathDependency], as `exclude` checks it against the project's group:name */ - ModuleDependencyIdentifier(group.toString(), name) - } ?: ModuleIds.fromComponent(project, it.dependency) - configuration.exclude(mapOf("group" to group, "module" to name)) - } - - requested.filter { it.dependency.currentBuildProjectIdOrNull == null }.forEach { - val (group, name) = ModuleIds.fromComponent(project, it.dependency) - val notation = listOfNotNull(group.orEmpty(), name, it.dependency.moduleVersion?.version).joinToString(":") - configuration.resolutionStrategy.force(notation) - } - } - } - - @Suppress("DEPRECATION") - /* - Older IDEs still rely on resolving the metadata configurations explicitly. - Dependencies will be coming from extending the newer 'resolvableMetadataConfiguration'. - - the intransitiveMetadataConfigurationName will not extend this mechanism, since it only - relies on dependencies being added explicitly by the Kotlin Gradle Plugin - */ - listOf( - apiMetadataConfigurationName, - implementationMetadataConfigurationName, - compileOnlyMetadataConfigurationName - ).forEach { configurationName -> - val configuration = project.configurations.getByName(configurationName) - applyTransformationToLegacyDependenciesMetadataConfiguration(configuration, granularMetadataTransformation) - } - - return granularMetadataTransformation -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetMetadataTransformation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetMetadataTransformation.kt new file mode 100644 index 00000000000..ab09834d64b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinSourceSetMetadataTransformation.kt @@ -0,0 +1,96 @@ +/* + * 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. + */ + +package org.jetbrains.kotlin.gradle.plugin.sources + +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull +import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.GranularMetadataTransformation +import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution +import org.jetbrains.kotlin.gradle.plugin.mpp.ModuleIds +import org.jetbrains.kotlin.gradle.plugin.mpp.projectDependency +import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies +import org.jetbrains.kotlin.tooling.core.extrasNullableLazyProperty + +/** + * Returns [GranularMetadataTransformation] for all requested compile dependencies + * scopes: API, IMPLEMENTATION, COMPILE_ONLY; See [KotlinDependencyScope.compileScopes] + * + * Used only for IDE import (w/o KGP based dependency resolution). + * Scheduled for removal after 1.9.20 + */ +internal val InternalKotlinSourceSet.metadataTransformation: GranularMetadataTransformation? by extrasNullableLazyProperty lazy@{ + // Create only for source sets in multiplatform plugin + project.multiplatformExtensionOrNull ?: return@lazy null + + val parentSourceSetVisibilityProvider = ParentSourceSetVisibilityProvider { componentIdentifier -> + dependsOnClosureWithInterCompilationDependencies(this).filterIsInstance() + .mapNotNull { it.metadataTransformation } + .flatMap { it.visibleSourceSetsByComponentId[componentIdentifier].orEmpty() } + .toSet() + } + + val granularMetadataTransformation = GranularMetadataTransformation( + params = GranularMetadataTransformation.Params(project, this), + parentSourceSetVisibilityProvider = parentSourceSetVisibilityProvider + ) + + @Suppress("DEPRECATION") + /* + Older IDEs still rely on resolving the metadata configurations explicitly. + Dependencies will be coming from extending the newer 'resolvableMetadataConfiguration'. + + the intransitiveMetadataConfigurationName will not extend this mechanism, since it only + relies on dependencies being added explicitly by the Kotlin Gradle Plugin + */ + listOf( + apiMetadataConfigurationName, + implementationMetadataConfigurationName, + compileOnlyMetadataConfigurationName + ).forEach { configurationName -> + val configuration = project.configurations.getByName(configurationName) + project.applyTransformationToLegacyDependenciesMetadataConfiguration(configuration, granularMetadataTransformation) + } + + granularMetadataTransformation +} + +/** + * + * This method is only intended to be called on deprecated DependenciesMetadata configurations to ensure + * correct behaviour in import. + * + * KGP based dependency resolution is therefore unaffected. + * + * Ensure that the [configuration] excludes the dependencies that are classified by this [GranularMetadataTransformation] as + * [MetadataDependencyResolution.Exclude], and uses exactly the same versions as were resolved for the requested + * dependencies during the transformation. + */ +private fun Project.applyTransformationToLegacyDependenciesMetadataConfiguration( + configuration: Configuration, transformation: GranularMetadataTransformation +) { + // Run this action immediately before the configuration first takes part in dependency resolution: + configuration.withDependencies { + val (unrequested, requested) = transformation.metadataDependencyResolutions + .partition { it is MetadataDependencyResolution.Exclude } + + unrequested.forEach { + val (group, name) = it.projectDependency(project)?.run { + /** Note: the project dependency notation here should be exactly this, group:name, + * not from [ModuleIds.fromProjectPathDependency], as `exclude` checks it against the project's group:name */ + ModuleDependencyIdentifier(group.toString(), name) + } ?: ModuleIds.fromComponent(project, it.dependency) + configuration.exclude(mapOf("group" to group, "module" to name)) + } + + requested.filter { it.dependency.currentBuildProjectIdOrNull == null }.forEach { + val (group, name) = ModuleIds.fromComponent(project, it.dependency) + val notation = listOfNotNull(group.orEmpty(), name, it.dependency.moduleVersion?.version).joinToString(":") + configuration.resolutionStrategy.force(notation) + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index 06708c0094c..febc94881ee 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -162,10 +162,8 @@ class KotlinMetadataTargetConfigurator : private fun configureMetadataDependenciesConfigurationsForCommonSourceSets(target: KotlinMetadataTarget) { target.project.whenEvaluated { - kotlinExtension.sourceSets.all { - if (it is DefaultKotlinSourceSet) { - configureMetadataDependenciesConfigurations(target.project, it) - } + kotlinExtension.sourceSets.all { sourceSet -> + configureMetadataDependenciesConfigurations(target.project, sourceSet.internal) } } } @@ -352,10 +350,7 @@ class KotlinMetadataTargetConfigurator : } } - private fun configureMetadataDependenciesConfigurations( - project: Project, - sourceSet: DefaultKotlinSourceSet - ) { + private fun configureMetadataDependenciesConfigurations(project: Project, sourceSet: InternalKotlinSourceSet) { /* Older IDEs still rely on resolving the metadata configurations explicitly. Dependencies will be coming from extending the newer 'resolvableMetadataConfiguration'. diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt index 0cd2de1a4dd..a43c1290d77 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.Choos import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ProjectMetadataProvider.MetadataConsumer.Ide import org.jetbrains.kotlin.gradle.plugin.mpp.metadataDependencyResolutionsOrEmpty import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.sources.metadataTransformation import org.jetbrains.kotlin.gradle.utils.filesProvider import java.io.File @@ -51,7 +52,7 @@ private fun Project.createCInteropMetadataDependencyClasspathFromProjectDependen forIde: Boolean ): FileCollection { return filesProvider { - sourceSet.compileDependenciesTransformation + sourceSet.metadataTransformation .metadataDependencyResolutionsOrEmpty .filterIsInstance() .flatMap { chooseVisibleSourceSets -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt index 0021b896fac..f6b5a0a5e83 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.Choos import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleIdentifiers import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.sources.internal +import org.jetbrains.kotlin.gradle.plugin.sources.metadataTransformation import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.withType @@ -155,7 +156,7 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru @get:Internal protected val chooseVisibleSourceSets get() = sourceSet - .compileDependenciesTransformation + .metadataTransformation .metadataDependencyResolutionsOrEmpty .resolutionsToTransform()