@@ -13,13 +13,15 @@ import org.gradle.api.artifacts.dsl.DependencyHandler
1313import org.gradle.api.model.ObjectFactory
1414import org.gradle.api.provider.Property
1515import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
16+ import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
1617import software.amazon.app.platform.gradle.ModuleStructurePlugin.Companion.testingSourceSets
1718
1819/* *
1920 * The extension to configure the App Platform. Following options are available:
2021 * ```
2122 * appPlatform {
2223 * enableKotlinInject true // false is the default
24+ * enableMetro true // false is the default
2325 *
2426 * enableMoleculePresenters true // false is the default
2527 * enableModuleStructure true // false is the default
@@ -52,6 +54,24 @@ constructor(objects: ObjectFactory, private val project: Project) {
5254
5355 internal fun isKotlinInjectEnabled (): Property <Boolean > = enableKotlinInject
5456
57+ private val enableMetro: Property <Boolean > =
58+ objects.property(Boolean ::class .java).convention(false )
59+
60+ /* * Adds Metro as dependency. */
61+ public fun enableMetro (enabled : Boolean ) {
62+ if (enabled == enableMetro.get()) return
63+
64+ enableMetro.set(enabled)
65+ enableMetro.disallowChanges()
66+
67+ if (enabled) {
68+ addPublicModuleDependencies(true )
69+ project.enableMetro()
70+ }
71+ }
72+
73+ internal fun isMetroEnabled (): Property <Boolean > = enableMetro
74+
5575 private val enableMoleculePresenters: Property <Boolean > =
5676 objects.property(Boolean ::class .java).convention(false )
5777
@@ -185,41 +205,8 @@ private fun Project.enableKotlinInject() {
185205 }
186206
187207 kmpExtension.targets.configureEach { target ->
188- // Skip the metadata, because we want to run KSP only for the concrete platforms.
189- if (target.name != " metadata" ) {
190- target.compilations.configureEach { compilation ->
191- fun configExists (name : String ): Boolean = configurations.any { it.name == name }
192-
193- // The implementationConfigurationName name is
194- // 'iosSimulatorArm64CompilationImplementation', 'wasmJsTestCompileClasspath' or
195- // 'desktopCompileClasspath'.
196- //
197- // E.g. 'desktopCompileClasspath' with give use 'kspDesktop'
198- var configName =
199- " ksp" +
200- compilation.implementationConfigurationName
201- .substringBefore(" Compilation" )
202- .capitalize()
203-
204- if (! configExists(configName) && target.platformType == KotlinPlatformType .androidJvm) {
205- // Android has different naming for some reason.
206- //
207- // E.g. for instrumentation tests 'kspAndroidDebugAndroidTest' should actually be
208- // 'kspAndroidAndroidTestDebug', but we will use 'kspAndroidAndroidTest'.
209- //
210- // For unit tests 'kspAndroidDebugUnitTest' should actually be 'kspAndroidTestDebug',
211- // but we will use 'kspAndroidTest'.
212- when {
213- configName.endsWith(" AndroidTest" ) -> configName = " kspAndroidAndroidTest"
214- configName.endsWith(" UnitTest" ) -> configName = " kspAndroidTest"
215- }
216- }
217-
218- // Check again if the config exists.
219- if (configExists(configName)) {
220- dependencies.addKspProcessorDependencies(configName)
221- }
222- }
208+ addKspDependenciesWhenConfigExists(target) { configName ->
209+ dependencies.addKspProcessorDependencies(configName)
223210 }
224211 }
225212 }
@@ -250,6 +237,41 @@ private fun Project.enableKotlinInject() {
250237 }
251238}
252239
240+ private fun Project.enableMetro () {
241+ plugins.apply (PluginIds .METRO )
242+
243+ // Enable KSP for our custom extensions.
244+ plugins.apply (PluginIds .KSP )
245+
246+ fun DependencyHandler.addKspProcessorDependencies (kspConfigurationName : String ) {
247+ add(
248+ kspConfigurationName,
249+ " $APP_PLATFORM_GROUP :metro-contribute-impl-code-generators:$APP_PLATFORM_VERSION " ,
250+ )
251+ }
252+
253+ plugins.withId(PluginIds .KOTLIN_MULTIPLATFORM ) {
254+ kmpExtension.sourceSets.getByName(" commonMain" ).dependencies {
255+ implementation(" $APP_PLATFORM_GROUP :di-common-public:$APP_PLATFORM_VERSION " )
256+ implementation(" $APP_PLATFORM_GROUP :metro-public:$APP_PLATFORM_VERSION " )
257+
258+ kmpExtension.targets.configureEach { target ->
259+ addKspDependenciesWhenConfigExists(target) { configName ->
260+ dependencies.addKspProcessorDependencies(configName)
261+ }
262+ }
263+ }
264+ }
265+
266+ plugins.withIds(PluginIds .KOTLIN_ANDROID , PluginIds .KOTLIN_JVM ) {
267+ dependencies.add(" implementation" , " $APP_PLATFORM_GROUP :di-common-public:$APP_PLATFORM_VERSION " )
268+
269+ dependencies.add(" implementation" , " $APP_PLATFORM_GROUP :metro-public:$APP_PLATFORM_VERSION " )
270+
271+ dependencies.addKspProcessorDependencies(" ksp" )
272+ }
273+ }
274+
253275private fun Project.enableMoleculePresenters () {
254276 plugins.apply (PluginIds .COMPOSE_COMPILER )
255277
@@ -335,3 +357,42 @@ private fun Project.enableComposeUi() {
335357 }
336358 }
337359}
360+
361+ private fun Project.addKspDependenciesWhenConfigExists (
362+ target : KotlinTarget ,
363+ block : (String ) -> Unit ,
364+ ) {
365+ if (target.name != " metadata" ) {
366+ target.compilations.configureEach { compilation ->
367+ fun configExists (name : String ): Boolean = configurations.any { it.name == name }
368+
369+ // The implementationConfigurationName name is
370+ // 'iosSimulatorArm64CompilationImplementation', 'wasmJsTestCompileClasspath' or
371+ // 'desktopCompileClasspath'.
372+ //
373+ // E.g. 'desktopCompileClasspath' with give use 'kspDesktop'
374+ var configName =
375+ " ksp" +
376+ compilation.implementationConfigurationName.substringBefore(" Compilation" ).capitalize()
377+
378+ if (! configExists(configName) && target.platformType == KotlinPlatformType .androidJvm) {
379+ // Android has different naming for some reason.
380+ //
381+ // E.g. for instrumentation tests 'kspAndroidDebugAndroidTest' should actually be
382+ // 'kspAndroidAndroidTestDebug', but we will use 'kspAndroidAndroidTest'.
383+ //
384+ // For unit tests 'kspAndroidDebugUnitTest' should actually be 'kspAndroidTestDebug',
385+ // but we will use 'kspAndroidTest'.
386+ when {
387+ configName.endsWith(" AndroidTest" ) -> configName = " kspAndroidAndroidTest"
388+ configName.endsWith(" UnitTest" ) -> configName = " kspAndroidTest"
389+ }
390+ }
391+
392+ // Check again if the config exists.
393+ if (configExists(configName)) {
394+ block(configName)
395+ }
396+ }
397+ }
398+ }
0 commit comments