From 4823fc3c64de9a1c9d9a240f4c2bbd648c00b2e4 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Tue, 20 Jun 2023 10:59:37 +0200 Subject: [PATCH] [Gradle] GranularMetadataTransformation: Collect moduleIds in ProjectData for non Kotlin Projects ^KT-59446 Verification Pending (cherry picked from commit 685eee38ac6aa08a10fa428e238e8c2573c91030) --- .../mpp/GranularMetadataTransformation.kt | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt index d8d6777356c7f..b26976b979017 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GranularMetadataTransformation.kt @@ -13,6 +13,7 @@ import org.gradle.api.attributes.AttributeContainer import org.gradle.api.file.FileCollection import org.gradle.api.logging.Logging import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.dsl.kotlinExtensionOrNull import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ArtifactMetadataProvider @@ -36,15 +37,15 @@ internal sealed class MetadataDependencyResolution( } class KeepOriginalDependency( - dependency: ResolvedComponentResult + dependency: ResolvedComponentResult, ) : MetadataDependencyResolution(dependency) sealed class Exclude( - dependency: ResolvedComponentResult + dependency: ResolvedComponentResult, ) : MetadataDependencyResolution(dependency) { class Unrequested( - dependency: ResolvedComponentResult + dependency: ResolvedComponentResult, ) : Exclude(dependency) /** @@ -65,7 +66,7 @@ internal sealed class MetadataDependencyResolution( val allVisibleSourceSetNames: Set, val visibleSourceSetNamesExcludingDependsOn: Set, val visibleTransitiveDependencies: Set, - internal val metadataProvider: MetadataProvider + internal val metadataProvider: MetadataProvider, ) : MetadataDependencyResolution(dependency) { internal sealed class MetadataProvider { @@ -89,7 +90,7 @@ internal sealed class MetadataDependencyResolution( internal class GranularMetadataTransformation( val params: Params, - val parentSourceSetVisibilityProvider: ParentSourceSetVisibilityProvider + val parentSourceSetVisibilityProvider: ParentSourceSetVisibilityProvider, ) { private val logger = Logging.getLogger("GranularMetadataTransformation[${params.sourceSetName}]") @@ -114,7 +115,7 @@ internal class GranularMetadataTransformation( class ProjectData( val path: String, val sourceSetMetadataOutputs: LenientFuture>, - val moduleId: LenientFuture + val moduleId: LenientFuture, ) { override fun toString(): String = "ProjectData[path='$path']" } @@ -334,13 +335,33 @@ private val Project.allProjectsData: Map { return rootProject.allprojects.associateBy { it.path }.mapValues { (path, currentProject) -> + + /* + We're calling into various different projects (Note: This implementation will change with Project Isolation) + Since not all projects might have the Kotlin Gradle Plugin applied we do call into 'idOfRootModule' in two different ways: + + 1) If KGP is applied, we use the lifecycle APIs to safely get a value after the DSL was finalised. + 2) If KGP was *not* applied, we create a Future which + - creates a lazy once the project is evaluated + - only evaluates the lazy once the moduleId is actually accessed + + This double deferral ensures that the value indeed is accessed as late as possible. + Unwrapping the lazy before the buildscript is evaluated will fail with 'future not completed' + */ + val moduleId = if (currentProject.kotlinExtensionOrNull != null) currentProject.future { + KotlinPluginLifecycle.Stage.AfterFinaliseDsl.await() + ModuleIds.idOfRootModule(currentProject) + }.lenient else CompletableFuture>().apply { + currentProject.whenEvaluated { + complete(lazy { ModuleIds.idOfRootModule(currentProject) }) + } + }.map { it.value }.lenient + + GranularMetadataTransformation.ProjectData( path = path, sourceSetMetadataOutputs = currentProject.future { currentProject.collectSourceSetMetadataOutputs() }.lenient, - moduleId = currentProject.future { - KotlinPluginLifecycle.Stage.AfterFinaliseDsl.await() - ModuleIds.idOfRootModule(currentProject) - }.lenient + moduleId = moduleId ) } }