[Gradle] Move creation of GranularMetadataTransformation to source set
Now it is encapsulated to DefaultKotlinSourceSet and is lazily created upon demand during project import But metadata configurations still should be created during metadata target configuration. ^KT-56431 Verification Pending
This commit is contained in:
committed by
Space Team
parent
db6c6c736a
commit
737afcb343
+18
-2
@@ -7,14 +7,20 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
|
||||
import org.gradle.api.Project
|
||||
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.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.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.targets.metadata.ALL_COMPILE_METADATA_CONFIGURATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.usageByName
|
||||
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
|
||||
import org.jetbrains.kotlin.gradle.utils.getOrCreate
|
||||
import org.jetbrains.kotlin.gradle.utils.listProperty
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
|
||||
@@ -56,7 +62,7 @@ internal val InternalKotlinSourceSet.resolvableMetadataConfiguration: Configurat
|
||||
}
|
||||
})
|
||||
|
||||
val allCompileMetadataConfiguration = project.configurations.getByName(ALL_COMPILE_METADATA_CONFIGURATION_NAME)
|
||||
val allCompileMetadataConfiguration = project.allCompileMetadataConfiguration
|
||||
|
||||
/* Ensure consistent dependency resolution result within the whole module */
|
||||
configuration.shouldResolveConsistentlyWith(allCompileMetadataConfiguration)
|
||||
@@ -65,6 +71,16 @@ internal val InternalKotlinSourceSet.resolvableMetadataConfiguration: Configurat
|
||||
configuration
|
||||
}
|
||||
|
||||
internal val Project.allCompileMetadataConfiguration get(): Configuration =
|
||||
configurations.getOrCreate("allSourceSetsCompileDependenciesMetadata", invokeWhenCreated = {
|
||||
it.markResolvable()
|
||||
|
||||
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))
|
||||
})
|
||||
|
||||
private inline fun <reified T> Project.listProvider(noinline provider: () -> List<T>): Provider<List<T>> {
|
||||
return project.objects.listProperty<T>().apply {
|
||||
set(project.provider(provider))
|
||||
|
||||
+78
-5
@@ -9,13 +9,16 @@ 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
|
||||
@@ -125,7 +128,9 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
|
||||
* Returns [GranularMetadataTransformation] for all requested compile dependencies
|
||||
* scopes: API, IMPLEMENTATION, COMPILE_ONLY; See [KotlinDependencyScope.compileScopes]
|
||||
*/
|
||||
internal var compileDependenciesTransformation: GranularMetadataTransformation? = null
|
||||
internal val compileDependenciesTransformation: GranularMetadataTransformation? by lazy {
|
||||
createAndConfigureDependencyTransformationForSourceSet()
|
||||
}
|
||||
|
||||
private val _requiresVisibilityOf = mutableSetOf<KotlinSourceSet>()
|
||||
|
||||
@@ -226,7 +231,75 @@ fun KotlinMultiplatformExtension.findSourceSetsDependingOn(sourceSet: KotlinSour
|
||||
return sourceSet.closure { seedSourceSet -> sourceSets.filter { otherSourceSet -> seedSourceSet in otherSourceSet.dependsOn } }
|
||||
}
|
||||
|
||||
internal val DefaultKotlinSourceSet.compileDependenciesTransformationOrFail: GranularMetadataTransformation
|
||||
get() = compileDependenciesTransformation
|
||||
?: error("Accessing Compile Dependencies Transformations that is not yet initialised; " +
|
||||
"Check when compileDependenciesTransformation is set")
|
||||
private fun DefaultKotlinSourceSet.createAndConfigureDependencyTransformationForSourceSet(): GranularMetadataTransformation? {
|
||||
// Create only for source sets in multiplatform plugin
|
||||
project.multiplatformExtensionOrNull ?: return null
|
||||
|
||||
val parentSourceSetVisibilityProvider = ParentSourceSetVisibilityProvider { componentIdentifier ->
|
||||
dependsOnClosureWithInterCompilationDependencies(this).filterIsInstance<DefaultKotlinSourceSet>()
|
||||
.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
|
||||
}
|
||||
+21
-76
@@ -6,8 +6,6 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.metadata
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
|
||||
@@ -21,8 +19,6 @@ import org.gradle.api.tasks.bundling.Zip
|
||||
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.Idea222Api
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.ideaImportDependsOn
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.*
|
||||
@@ -92,7 +88,7 @@ class KotlinMetadataTargetConfigurator :
|
||||
|
||||
configureProjectStructureMetadataGeneration(target.project, allMetadataJar)
|
||||
|
||||
setupDependencyTransformationForCommonSourceSets(target)
|
||||
configureMetadataDependenciesConfigurationsForCommonSourceSets(target)
|
||||
|
||||
target.project.configurations.getByName(target.apiElementsConfigurationName).run {
|
||||
attributes.attribute(USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
|
||||
@@ -166,10 +162,12 @@ class KotlinMetadataTargetConfigurator :
|
||||
return result
|
||||
}
|
||||
|
||||
private fun setupDependencyTransformationForCommonSourceSets(target: KotlinMetadataTarget) {
|
||||
private fun configureMetadataDependenciesConfigurationsForCommonSourceSets(target: KotlinMetadataTarget) {
|
||||
target.project.whenEvaluated {
|
||||
kotlinExtension.sourceSets.all {
|
||||
setupDependencyTransformationForSourceSet(target.project, it)
|
||||
if (it is DefaultKotlinSourceSet) {
|
||||
configureMetadataDependenciesConfigurations(target.project, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -368,79 +366,26 @@ class KotlinMetadataTargetConfigurator :
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupDependencyTransformationForSourceSet(
|
||||
private fun configureMetadataDependenciesConfigurations(
|
||||
project: Project,
|
||||
sourceSet: KotlinSourceSet
|
||||
sourceSet: DefaultKotlinSourceSet
|
||||
) {
|
||||
val parentSourceSetVisibilityProvider = ParentSourceSetVisibilityProvider { componentIdentifier ->
|
||||
dependsOnClosureWithInterCompilationDependencies(sourceSet).filterIsInstance<DefaultKotlinSourceSet>()
|
||||
.flatMap { it.compileDependenciesTransformationOrFail.visibleSourceSetsByComponentId[componentIdentifier].orEmpty() }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
val granularMetadataTransformation = GranularMetadataTransformation(
|
||||
params = GranularMetadataTransformation.Params(project, sourceSet),
|
||||
parentSourceSetVisibilityProvider = parentSourceSetVisibilityProvider
|
||||
)
|
||||
/*
|
||||
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
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
if (sourceSet is DefaultKotlinSourceSet) {
|
||||
sourceSet.compileDependenciesTransformation = granularMetadataTransformation
|
||||
|
||||
/*
|
||||
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(
|
||||
sourceSet.apiMetadataConfigurationName,
|
||||
sourceSet.implementationMetadataConfigurationName,
|
||||
sourceSet.compileOnlyMetadataConfigurationName
|
||||
).forEach { configurationName ->
|
||||
val configuration = project.configurations.getByName(configurationName)
|
||||
configuration.extendsFrom(sourceSet.resolvableMetadataConfiguration)
|
||||
configuration.shouldResolveConsistentlyWith(sourceSet.resolvableMetadataConfiguration)
|
||||
project.applyTransformationToLegacyDependenciesMetadataConfiguration(configuration, 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(this)?.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)
|
||||
}
|
||||
listOf(
|
||||
sourceSet.apiMetadataConfigurationName,
|
||||
sourceSet.implementationMetadataConfigurationName,
|
||||
sourceSet.compileOnlyMetadataConfigurationName
|
||||
).forEach { configurationName ->
|
||||
val configuration = project.configurations.getByName(configurationName)
|
||||
configuration.extendsFrom(sourceSet.resolvableMetadataConfiguration)
|
||||
configuration.shouldResolveConsistentlyWith(sourceSet.resolvableMetadataConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.Choos
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ProjectMetadataProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleIdentifiers
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.compileDependenciesTransformationOrFail
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||
import org.jetbrains.kotlin.gradle.tasks.dependsOn
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||
@@ -156,8 +155,8 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
|
||||
@get:Internal
|
||||
protected val chooseVisibleSourceSets
|
||||
get() = sourceSet
|
||||
.compileDependenciesTransformationOrFail
|
||||
.metadataDependencyResolutions
|
||||
.compileDependenciesTransformation
|
||||
.metadataDependencyResolutionsOrEmpty
|
||||
.resolutionsToTransform()
|
||||
|
||||
@Suppress("unused")
|
||||
|
||||
Reference in New Issue
Block a user