From 251ce101bfa246ae350f966d8004622a793b2f61 Mon Sep 17 00:00:00 2001 From: Pavlo Stavytskyi Date: Sun, 29 Oct 2023 16:20:59 -0700 Subject: [PATCH] implement shared properties mechanism --- .../kotlin/io/morfly/airin/Component.kt | 12 ++++++- .../morfly/airin/DependencyOverridesHolder.kt | 2 ++ .../io/morfly/airin/MigrationProcessor.kt | 5 ++- .../io/morfly/airin/PackageComponent.kt | 5 +++ .../io/morfly/airin/PackageDescriptor.kt | 5 +-- .../io/morfly/airin/SharedPropertiesHolder.kt | 15 +++++++++ .../io/morfly/airin/SharedPropertyDelegate.kt | 32 +++++++++++++++++++ .../io/morfly/airin/StarlarkExtensions.kt | 2 +- 8 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertiesHolder.kt create mode 100644 airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertyDelegate.kt diff --git a/airin-core/src/jvmMain/kotlin/io/morfly/airin/Component.kt b/airin-core/src/jvmMain/kotlin/io/morfly/airin/Component.kt index 4f84941f..dcfe4770 100644 --- a/airin-core/src/jvmMain/kotlin/io/morfly/airin/Component.kt +++ b/airin-core/src/jvmMain/kotlin/io/morfly/airin/Component.kt @@ -1,9 +1,19 @@ package io.morfly.airin -abstract class Component

: HasId, PropertiesHolder { +import io.morfly.airin.label.MavenCoordinates + +abstract class Component

: HasId, PropertiesHolder, SharedPropertiesHolder { final override val properties = mutableMapOf() + final override lateinit var sharedProperties: MutableMap + internal set + + override val sharedPropertiesAvailable + get() = ::sharedProperties.isInitialized + + val allMavenArtifacts: MutableSet by sharedProperty(mutableSetOf()) + override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Component<*>) return false diff --git a/airin-core/src/jvmMain/kotlin/io/morfly/airin/DependencyOverridesHolder.kt b/airin-core/src/jvmMain/kotlin/io/morfly/airin/DependencyOverridesHolder.kt index 6650bac0..28cb9a04 100644 --- a/airin-core/src/jvmMain/kotlin/io/morfly/airin/DependencyOverridesHolder.kt +++ b/airin-core/src/jvmMain/kotlin/io/morfly/airin/DependencyOverridesHolder.kt @@ -45,6 +45,8 @@ class DependencyOverrideContext { } sealed interface DependencyOverride { + data class Override(val label: Label, val configuration: String? = null) : DependencyOverride + data object Ignore : DependencyOverride } diff --git a/airin-core/src/jvmMain/kotlin/io/morfly/airin/MigrationProcessor.kt b/airin-core/src/jvmMain/kotlin/io/morfly/airin/MigrationProcessor.kt index f4d706d8..639b3783 100644 --- a/airin-core/src/jvmMain/kotlin/io/morfly/airin/MigrationProcessor.kt +++ b/airin-core/src/jvmMain/kotlin/io/morfly/airin/MigrationProcessor.kt @@ -25,8 +25,11 @@ class MigrationProcessor

( } traverse(packageDescriptor) - // Processing packages following the order in which components were registered. + // Processing packages, following the order in which components were registered. + val sharedProperties = mutableMapOf() for ((id, component) in components) { + component.sharedProperties = sharedProperties + for (pkg in packages[id].orEmpty()) { val result = component.invoke(pkg) writeGeneratedFiles(pkg.dirPath, result.starlarkFiles) diff --git a/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageComponent.kt b/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageComponent.kt index eb133064..aab5fd9c 100644 --- a/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageComponent.kt +++ b/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageComponent.kt @@ -1,5 +1,6 @@ package io.morfly.airin +import io.morfly.airin.label.MavenCoordinates import io.morfly.pendant.starlark.lang.append abstract class PackageComponent

: Component

(), PropertiesHolder, @@ -20,10 +21,14 @@ abstract class PackageComponent

: Component

(), Propert val features = subcomponents.values.asSequence() .filterIsInstance>() .filter { it.id in packageDescriptor.featureComponentIds } + .onEach { it.sharedProperties = sharedProperties } .map { it.invoke(packageDescriptor) } .toList() packageDescriptor.applyDependencies(packageDescriptor.transformDependencies(features)) + allMavenArtifacts += packageDescriptor.dependencies.values.flatten() + .filterIsInstance() + context.onInvoke(packageDescriptor) for (file in context.starlarkFiles.values.flatten()) { diff --git a/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageDescriptor.kt b/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageDescriptor.kt index 11b75e0c..77e466ff 100644 --- a/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageDescriptor.kt +++ b/airin-core/src/jvmMain/kotlin/io/morfly/airin/PackageDescriptor.kt @@ -32,6 +32,7 @@ fun PackageDescriptor.transformDependencies(features: List): Map val processedDependencies = mutableMapOf>() + // Process dependency overrides for (feature in features) { for ((configuration, labels) in this.originalDependencies) { for (dependency in labels) { @@ -54,6 +55,7 @@ fun PackageDescriptor.transformDependencies(features: List): Map } } + // Process configuration overrides for the remaining dependencies for (feature in features) { for ((configuration, labels) in this.originalDependencies) { for (dependency in labels) { @@ -62,8 +64,7 @@ fun PackageDescriptor.transformDependencies(features: List): Map val configOverride = feature.configurationOverrides[configuration] val config = configOverride?.configuration ?: continue - val dep = dependency.asComparable() - transformedDependencies.getOrPut(config, ::mutableSetOf) += dep + transformedDependencies.getOrPut(config, ::mutableSetOf) += dependency } } } diff --git a/airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertiesHolder.kt b/airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertiesHolder.kt new file mode 100644 index 00000000..b7fa5ba7 --- /dev/null +++ b/airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertiesHolder.kt @@ -0,0 +1,15 @@ +package io.morfly.airin + +interface SharedPropertiesHolder { + + val sharedProperties: MutableMap + + val sharedPropertiesAvailable: Boolean +} + +//@Suppress("UNCHECKED_CAST") +//val MutableMap.allMavenArtifacts: MutableSet +// get() { +// val artifacts = getOrPut("allMavenArtifacts") { mutableSetOf() } +// return artifacts as MutableSet +// } diff --git a/airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertyDelegate.kt b/airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertyDelegate.kt new file mode 100644 index 00000000..e982b201 --- /dev/null +++ b/airin-core/src/jvmMain/kotlin/io/morfly/airin/SharedPropertyDelegate.kt @@ -0,0 +1,32 @@ +package io.morfly.airin + +import java.io.Serializable +import kotlin.reflect.KProperty + +class SharedPropertyDelegate(val defaultValue: V) : Serializable { + + operator fun provideDelegate( + holder: SharedPropertiesHolder, property: KProperty<*> + ): SharedPropertyDelegate = this + + operator fun getValue(holder: SharedPropertiesHolder, property: KProperty<*>): V { + validate(holder, property.name) + @Suppress("UNCHECKED_CAST") + return holder.sharedProperties.getOrPut(property.name) { defaultValue } as V + } + + operator fun setValue(holder: SharedPropertiesHolder, property: KProperty<*>, value: V) { + validate(holder, property.name) + holder.sharedProperties[property.name] = value + } + + private fun validate(holder: SharedPropertiesHolder, property: String) { + require(holder.sharedPropertiesAvailable) { + "Shared property $property is not available during build configuration phase!" + } + } +} + +fun SharedPropertiesHolder.sharedProperty(default: V): SharedPropertyDelegate { + return SharedPropertyDelegate(default) +} diff --git a/airin-gradle-plugin/src/main/kotlin/io/morfly/airin/StarlarkExtensions.kt b/airin-gradle-plugin/src/main/kotlin/io/morfly/airin/StarlarkExtensions.kt index 95f14e2e..dc29ec92 100644 --- a/airin-gradle-plugin/src/main/kotlin/io/morfly/airin/StarlarkExtensions.kt +++ b/airin-gradle-plugin/src/main/kotlin/io/morfly/airin/StarlarkExtensions.kt @@ -8,7 +8,7 @@ fun FunctionCallContext.applyDependenciesFrom(packageDescriptor: GradleProject) for ((configuration, dependencies) in packageDescriptor.dependencies) { configuration `=` dependencies.mapNotNull { when (it) { - is MavenCoordinates -> artifact(it.copy(version = null).toString()) + is MavenCoordinates -> artifact(it.asComparable().toString()) else -> it.asBazelLabel()?.toString() } }