[Gradle] Don't use whole Project in MetadataDependencyResolution's

Instead, derive Project info from Resolved Component.
This commit is contained in:
Anton Lakotka
2022-12-12 09:11:09 +01:00
committed by Space Team
parent 35b2672436
commit 0690613082
8 changed files with 38 additions and 40 deletions
@@ -18,10 +18,12 @@ import org.jetbrains.kotlin.gradle.plugin.ide.IdeaKotlinSourceCoordinates
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.projectDependency
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType
import org.jetbrains.kotlin.gradle.plugin.sources.android.type
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.plugin.sources.project
internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
@@ -29,7 +31,8 @@ internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
return sourceSet.resolveMetadata<MetadataDependencyResolution.ChooseVisibleSourceSets>()
.flatMap { chooseVisibleSourceSets ->
val projectDependency = chooseVisibleSourceSets.projectDependency ?: return@flatMap emptyList<IdeaKotlinDependency>()
val projectDependency = chooseVisibleSourceSets.projectDependency(sourceSet.project)
?: return@flatMap emptyList<IdeaKotlinDependency>()
val kotlin = projectDependency.multiplatformExtensionOrNull ?: return@flatMap emptyList<IdeaKotlinDependency>()
kotlin.sourceSets
.filter { sourceSet -> isJvmAndAndroidMain(sourceSet) }
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.ide.IdeaKotlinProjectCoordinates
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
import org.jetbrains.kotlin.gradle.plugin.mpp.projectIdOrNull
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
internal object IdeVisibleMultiplatformSourceDependencyResolver : IdeDependencyResolver {
@@ -24,9 +25,9 @@ internal object IdeVisibleMultiplatformSourceDependencyResolver : IdeDependencyR
}
private fun resolveSourceDependencies(
resolution: MetadataDependencyResolution.ChooseVisibleSourceSets
resolution: MetadataDependencyResolution.ChooseVisibleSourceSets,
): Iterable<IdeaKotlinDependency> {
val projectComponentIdentifier = resolution.dependency.id as? ProjectComponentIdentifier ?: return emptyList()
val projectComponentIdentifier = resolution.dependency.projectIdOrNull ?: return emptyList()
return resolution.allVisibleSourceSetNames.map { visibleSourceSetName ->
IdeaKotlinSourceDependency(
type = IdeaKotlinSourceDependency.Type.Regular,
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.internal
import java.util.*
internal sealed class MetadataDependencyResolution(
@field:Transient // can't be used with Gradle Instant Execution, but fortunately not needed when deserialized
val dependency: ResolvedComponentResult,
@field:Transient
val projectDependency: Project?
) {
/** Evaluate and store the value, as the [dependency] will be lost during Gradle instant execution */
// val originalArtifactFiles: List<File> = dependency.dependents.flatMap { it.allModuleArtifacts } .map { it.file }
@@ -39,19 +36,16 @@ internal sealed class MetadataDependencyResolution(
}
class KeepOriginalDependency(
dependency: ResolvedComponentResult,
projectDependency: Project?
) : MetadataDependencyResolution(dependency, projectDependency)
dependency: ResolvedComponentResult
) : MetadataDependencyResolution(dependency)
sealed class Exclude(
dependency: ResolvedComponentResult,
projectDependency: Project?
) : MetadataDependencyResolution(dependency, projectDependency) {
dependency: ResolvedComponentResult
) : MetadataDependencyResolution(dependency) {
class Unrequested(
dependency: ResolvedComponentResult,
projectDependency: Project?
) : Exclude(dependency, projectDependency)
dependency: ResolvedComponentResult
) : Exclude(dependency)
/**
* Resolution for metadata dependencies of leaf platform source sets.
@@ -62,18 +56,17 @@ internal sealed class MetadataDependencyResolution(
class PublishedPlatformSourceSetDependency(
dependency: ResolvedComponentResult,
val visibleTransitiveDependencies: Set<ResolvedDependencyResult>,
) : Exclude(dependency, null)
) : Exclude(dependency)
}
class ChooseVisibleSourceSets internal constructor(
dependency: ResolvedComponentResult,
projectDependency: Project?,
val projectStructureMetadata: KotlinProjectStructureMetadata,
val allVisibleSourceSetNames: Set<String>,
val visibleSourceSetNamesExcludingDependsOn: Set<String>,
val visibleTransitiveDependencies: Set<ResolvedDependencyResult>,
internal val metadataProvider: MetadataProvider
) : MetadataDependencyResolution(dependency, projectDependency) {
) : MetadataDependencyResolution(dependency) {
internal sealed class MetadataProvider {
class ArtifactMetadataProvider(private val compositeMetadataArtifact: CompositeMetadataArtifact) :
@@ -181,9 +174,6 @@ internal class GranularMetadataTransformation(
result.add(
MetadataDependencyResolution.Exclude.Unrequested(
resolvedDependency.selected,
(resolvedDependency.selected.id as? ProjectComponentIdentifier)
?.takeIf { it.build.isCurrentBuild() }
?.let { project.project(it.projectPath) }
)
)
}
@@ -219,14 +209,14 @@ internal class GranularMetadataTransformation(
val resolvedToProject: Project? = module.toProjectOrNull(project)
val projectStructureMetadata = mppDependencyMetadataExtractor?.getProjectStructureMetadata()
?: return MetadataDependencyResolution.KeepOriginalDependency(module, resolvedToProject)
?: return MetadataDependencyResolution.KeepOriginalDependency(module)
val sourceSetVisibility =
SourceSetVisibilityProvider(project).getVisibleSourceSets(
kotlinSourceSet,
if (projectStructureMetadata.isPublishedAsRoot) module else parent, module,
projectStructureMetadata,
resolvedToProject
resolvedToProject != null
)
val allVisibleSourceSets = sourceSetVisibility.visibleSourceSetNames
@@ -275,7 +265,6 @@ internal class GranularMetadataTransformation(
return MetadataDependencyResolution.ChooseVisibleSourceSets(
dependency = module,
projectDependency = resolvedToProject,
projectStructureMetadata = projectStructureMetadata,
allVisibleSourceSetNames = allVisibleSourceSets,
visibleSourceSetNamesExcludingDependsOn = visibleSourceSetsExcludingDependsOn,
@@ -285,14 +274,22 @@ internal class GranularMetadataTransformation(
}
}
internal fun ResolvedComponentResult.toProjectOrNull(currentProject: Project): Project? {
internal val ResolvedComponentResult.projectIdOrNull get(): ProjectComponentIdentifier? {
val identifier = id
return when {
identifier is ProjectComponentIdentifier && identifier.build.isCurrentBuild -> currentProject.project(identifier.projectPath)
identifier is ProjectComponentIdentifier && identifier.build.isCurrentBuild -> identifier
else -> null
}
}
internal fun MetadataDependencyResolution.projectDependency(currentProject: Project): Project? =
dependency.toProjectOrNull(currentProject)
internal fun ResolvedComponentResult.toProjectOrNull(currentProject: Project): Project? {
val projectId = projectIdOrNull ?: return null
return currentProject.project(projectId.projectPath)
}
private val KotlinMultiplatformExtension.platformCompilationSourceSets: Set<KotlinSourceSet>
get() = targets.filterNot { it is KotlinMetadataTarget }
.flatMap { target -> target.compilations }
@@ -48,6 +48,7 @@ open class MetadataDependencyTransformationTask
project.kotlinTransformedMetadataLibraryDirectoryForBuild(kotlinSourceSet.name)
}
// TODO: Repalce with sourceSet metadata
@Suppress("unused") // Gradle input
@get:IgnoreEmptyDirectories
@get:NormalizeLineEndings
@@ -83,9 +84,7 @@ open class MetadataDependencyTransformationTask
}
}
@get:Internal
@delegate:Transient
internal val transformation: GranularMetadataTransformation by lazy {
private val transformation: GranularMetadataTransformation by lazy {
GranularMetadataTransformation(
project,
kotlinSourceSet,
@@ -52,7 +52,7 @@ internal class SourceSetVisibilityProvider(
resolvedRootMppDependency: ResolvedComponentResult?,
resolvedMetadataDependency: ResolvedComponentResult,
dependencyProjectStructureMetadata: KotlinProjectStructureMetadata,
resolvedToOtherProject: Project?
resolvedToOtherProject: Boolean
): SourceSetVisibilityResult {
val compilations = visibleFrom.internal.compilations
@@ -83,7 +83,7 @@ internal class SourceSetVisibilityProvider(
.values.let { if (it.isEmpty()) emptySet() else it.reduce { acc, item -> acc intersect item } }
val hostSpecificArtifactBySourceSet: Map<String, File> =
if (resolvedToOtherProject != null) {
if (resolvedToOtherProject) {
/**
* When a dependency resolves to a project, we don't need any artifacts from it, we can
* instead use the compilation outputs directly:
@@ -74,10 +74,9 @@ internal class GradleKpmFragmentGranularMetadataResolver(
fragmentResolutionQueue.addAll(visibleTransitiveDependencies.filter { it !in visited })
val resolvedComponentResult = dependencyNode.selectedComponent
val isResolvedAsProject = resolvedComponentResult.toProjectOrNull(project)
val result = when (dependencyModule) {
is GradleKpmExternalPlainModule -> {
MetadataDependencyResolution.KeepOriginalDependency(resolvedComponentResult, isResolvedAsProject)
MetadataDependencyResolution.KeepOriginalDependency(resolvedComponentResult)
}
else -> run {
@@ -124,7 +123,6 @@ internal class GradleKpmFragmentGranularMetadataResolver(
MetadataDependencyResolution.ChooseVisibleSourceSets(
dependency = metadataSourceComponent,
projectDependency = isResolvedAsProject,
projectStructureMetadata = projectStructureMetadata,
allVisibleSourceSetNames = visibleFragmentNames,
visibleSourceSetNamesExcludingDependsOn = visibleFragmentNamesExcludingVisibleByParents,
@@ -140,7 +138,7 @@ internal class GradleKpmFragmentGranularMetadataResolver(
// FIXME this code is based on whole components; use module IDs with classifiers instead
val resultSourceComponents = results.mapTo(mutableSetOf()) { it.dependency }
resolvedComponentsByModuleId.values.minus(resultSourceComponents).forEach {
results.add(MetadataDependencyResolution.Exclude.Unrequested(it, it.toProjectOrNull(project)))
results.add(MetadataDependencyResolution.Exclude.Unrequested(it))
}
return results
@@ -46,7 +46,7 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
get() = disambiguateName(RUNTIME_ONLY)
override val metadataLibrariesConfigurationName: String
get() = disambiguateName(lowerCamelCaseName("compile", METADATA_CONFIGURATION_NAME_SUFFIX))
get() = disambiguateName(METADATA_CONFIGURATION_NAME_SUFFIX)
@Deprecated("KT-55312")
override val apiMetadataConfigurationName: String
@@ -166,7 +166,7 @@ abstract class DefaultKotlinSourceSet @Inject constructor(
return metadataDependencyResolutionByModule.mapNotNull { (groupAndName, resolution) ->
val (group, name) = groupAndName
val projectPath = resolution.projectDependency?.path
val projectPath = resolution.dependency.projectIdOrNull?.projectPath
when (resolution) {
// No metadata transformation leads to original dependency being used during import
is MetadataDependencyResolution.KeepOriginalDependency -> null
@@ -345,7 +345,7 @@ class KotlinMetadataTargetConfigurator :
}
compilation.compileDependencyFiles += createMetadataDependencyTransformationClasspath(
project.configurations.getByName(compilation.defaultSourceSet.metadataLibrariesConfigurationName),
project.configurations.getByName(sourceSet.metadataLibrariesConfigurationName),
compilation
)
@@ -411,7 +411,7 @@ class KotlinMetadataTargetConfigurator :
.partition { it is MetadataDependencyResolution.Exclude }
unrequested.forEach {
val (group, name) = it.projectDependency?.run {
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)
@@ -419,7 +419,7 @@ class KotlinMetadataTargetConfigurator :
configuration.exclude(mapOf("group" to group, "module" to name))
}
requested.filter { it.projectDependency == null }.forEach {
requested.filter { it.dependency.projectIdOrNull == 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)