[Gradle] Add MppDependency[PSM]Factory
Since ProjectMppDependency[PMS]Extractor is decoupled from Project it is possible to create MppDependency[PSM]Extractor just from `ResolvedArtifactResult` using its ComponentIdentifier and file. ^KT-49933
This commit is contained in:
committed by
Space Team
parent
ceefc4f1ee
commit
84d7139a12
+50
@@ -8,11 +8,61 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
import org.gradle.api.artifacts.result.ResolvedArtifactResult
|
||||
import org.gradle.api.artifacts.result.ResolvedComponentResult
|
||||
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.addExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.findExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toSingleKpmModuleIdentifier
|
||||
import org.jetbrains.kotlin.project.model.KpmModuleIdentifier
|
||||
|
||||
class MppDependencyProjectStructureMetadataExtractorFactory(
|
||||
private val projectStructureMetadataByProjectPath: Map<String, Provider<KotlinProjectStructureMetadata?>>
|
||||
) {
|
||||
fun create(
|
||||
metadataArtifact: ResolvedArtifactResult
|
||||
): MppDependencyProjectStructureMetadataExtractor {
|
||||
val moduleId = metadataArtifact.variant.owner
|
||||
|
||||
if (moduleId is ProjectComponentIdentifier && moduleId.build.isCurrentBuild) {
|
||||
val psm = projectStructureMetadataByProjectPath[moduleId.projectPath]
|
||||
?: error("Project structure metadata not found for project ${moduleId.projectPath}")
|
||||
return ProjectMppDependencyProjectStructureMetadataExtractor(
|
||||
moduleIdentifier = metadataArtifact.variant.toSingleKpmModuleIdentifier(),
|
||||
projectPath = moduleId.projectPath,
|
||||
projectStructureMetadataProvider = psm::get
|
||||
)
|
||||
}
|
||||
|
||||
return JarMppDependencyProjectStructureMetadataExtractor(metadataArtifact.file)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val extensionName = MppDependencyProjectStructureMetadataExtractorFactory::class.java.simpleName
|
||||
fun getOrCreate(project: Project): MppDependencyProjectStructureMetadataExtractorFactory {
|
||||
val existing = project.findExtension<MppDependencyProjectStructureMetadataExtractorFactory>(extensionName)
|
||||
if (existing != null) return existing
|
||||
|
||||
val projectStructureMetadataByProjectPath = collectProjectStructureMetadataFromAllProjects(project)
|
||||
val newFactory = MppDependencyProjectStructureMetadataExtractorFactory(projectStructureMetadataByProjectPath)
|
||||
project.addExtension(extensionName, newFactory)
|
||||
return newFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect Kotlin Project StructureMetadata only for TCS model.
|
||||
* TODO: Add support for KPM and auxiliary modules
|
||||
*/
|
||||
private fun collectProjectStructureMetadataFromAllProjects(project: Project): Map<String, Provider<KotlinProjectStructureMetadata?>> {
|
||||
return project.rootProject.allprojects.associateBy { it.path }.mapValues { (_, subProject) ->
|
||||
project.provider { subProject.multiplatformExtensionOrNull?.kotlinProjectStructureMetadata }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun MppDependencyProjectStructureMetadataExtractor.Factory.create(
|
||||
project: Project,
|
||||
resolvedComponentResult: ResolvedComponentResult,
|
||||
|
||||
+16
@@ -10,6 +10,7 @@ import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.component.*
|
||||
import org.gradle.api.artifacts.result.ResolvedComponentResult
|
||||
import org.gradle.api.artifacts.result.ResolvedDependencyResult
|
||||
import org.gradle.api.artifacts.result.ResolvedVariantResult
|
||||
import org.gradle.api.capabilities.Capability
|
||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
@@ -115,6 +116,11 @@ internal fun ResolvedComponentResult.toKpmModuleIdentifiers(): List<KpmModuleIde
|
||||
return classifiers.map { moduleClassifier -> toKpmModuleIdentifier(moduleClassifier) }
|
||||
}
|
||||
|
||||
internal fun ResolvedVariantResult.toKpmModuleIdentifiers(): List<KpmModuleIdentifier> {
|
||||
val classifiers = moduleClassifiersFromCapabilities(capabilities)
|
||||
return classifiers.map { moduleClassifier -> toKpmModuleIdentifier(moduleClassifier) }
|
||||
}
|
||||
|
||||
// FIXME this mapping doesn't have enough information to choose auxiliary modules
|
||||
internal fun ResolvedComponentResult.toSingleKpmModuleIdentifier(): KpmModuleIdentifier {
|
||||
val classifiers = moduleClassifiersFromCapabilities(variants.flatMap { it.capabilities })
|
||||
@@ -122,6 +128,8 @@ internal fun ResolvedComponentResult.toSingleKpmModuleIdentifier(): KpmModuleIde
|
||||
return toKpmModuleIdentifier(moduleClassifier)
|
||||
}
|
||||
|
||||
internal fun ResolvedVariantResult.toSingleKpmModuleIdentifier(): KpmModuleIdentifier = toKpmModuleIdentifiers().single()
|
||||
|
||||
private fun ResolvedComponentResult.toKpmModuleIdentifier(moduleClassifier: String?): KpmModuleIdentifier {
|
||||
return when (val id = id) {
|
||||
is ProjectComponentIdentifier -> KpmLocalModuleIdentifier(id.build.name, id.projectPath, moduleClassifier)
|
||||
@@ -130,6 +138,14 @@ private fun ResolvedComponentResult.toKpmModuleIdentifier(moduleClassifier: Stri
|
||||
}
|
||||
}
|
||||
|
||||
private fun ResolvedVariantResult.toKpmModuleIdentifier(moduleClassifier: String?): KpmModuleIdentifier {
|
||||
return when (val id = owner) {
|
||||
is ProjectComponentIdentifier -> KpmLocalModuleIdentifier(id.build.name, id.projectPath, moduleClassifier)
|
||||
is ModuleComponentIdentifier -> id.toSingleKpmModuleIdentifier()
|
||||
else -> error("Unexpected component identifier '$id' of type ${id.javaClass}")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun moduleClassifiersFromCapabilities(capabilities: Iterable<Capability>): Iterable<String?> {
|
||||
val classifierCapabilities = capabilities.filter { it.name.contains("..") }
|
||||
return if (classifierCapabilities.none()) listOf(null) else classifierCapabilities.map { it.name.substringAfterLast("..") /*FIXME invent a more stable scheme*/ }
|
||||
|
||||
Reference in New Issue
Block a user