Currently migrating to Kotlin 2, and I see I shoul...
# compose
m
Currently migrating to Kotlin 2, and I see I should place
composeCompiler { }
in each appropriate module. My app has over 20 such modules. Is there a way to declare this just once for the project?
s
Make a convention plugin like https://github.com/android/nowinandroid/blob/main/build-logic%2Fconvention%2Fsrc%2Fmain%2Fkotlin%2FAndroidApplicationComposeConventionPlugin.kt But also you can just not add that block if you don't configure anything there.
Just throwing relevant links here to hook all this together 😅
I believe these are the docs for it https://docs.gradle.org/current/samples/sample_convention_plugins.html but honestly when I did it I looked at NiA instead
s
You can also use
subprojects/allprojects
block in the root gradle file
âž• 1
Practically the same place where you configure Kotlin/Android target sdk/etc
m
Thanks I’ll check all that out shortly. Meanwhile, here is my pre Kotlin 2 approach in the project-level gradle script:
Copy code
subprojects {
    project.plugins.applyBaseConfig(project)
}

// <https://www.droidcon.com/2022/03/11/reducing-gradle-boilerplate-in-multi-module-android-projects/>
fun BaseExtension.baseConfig() {
    compileSdkVersion(AndroidSdk.compile)

    defaultConfig.apply {
        minSdk = AndroidSdk.min
        targetSdk = AndroidSdk.target

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

        consumerProguardFiles("<http://proguard-rules.pro|proguard-rules.pro>")
    }

    compileOptions.apply {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}

/**
 * Apply configuration settings that are shared across all modules.
 */
fun PluginContainer.applyBaseConfig(project: Project) {
    whenPluginAdded {
        when (this) {
            is AppPlugin -> {
                project.extensions
                    .getByType<AppExtension>()
                    .apply {
                        baseConfig()
                    }
            }
            is LibraryPlugin -> {
                project.extensions
                    .getByType<LibraryExtension>()
                    .apply {
                        baseConfig()
                    }
            }
        }
    }
}
s
m
My initial attempt was to put `
Copy code
project.composeCompiler { ... }
inside the
baseConfig
extension function, but that doesn’t work. Just seeing if I can get it working with my existing approach before trying something new.
m
Not yet, I was going to try it next if I can’t use my existing approach
s
I meant do this in your existing approach without the convention plugin stuff
m
Currently on slow internet connection, so it’s taking a while to download the terabytes of NIA dependencies 🙂 On another note, it seems if I remove
buildFeatures { compose = true }
the app still builds and runs fine. Is that to be expected? Perhaps something else is setting that implicitly.
If I just blindly use
Copy code
extensions.configure<ComposeCompilerGradlePluginExtension> { ... }
I get:
Copy code
Extension of type 'ComposeCompilerGradlePluginExtension' does not exist
So I guess I need to register it somewhere?
I noticed NIA uses
ApplicationPlugin
&
ApplicationExtension
instead of the
App*
equivalents. Is it safe to just switch to those
Application*
types? This enables using
CommonExtension
as the receiver for the
baseConfig
function.
a
I have had zero problems with Application types
m
If I do this:
Copy code
fun PluginContainer.applyBaseConfig(project: Project) {
    whenPluginAdded {
        when (this) {
            is ApplicationPlugin -> {
                project.extensions
                    .getByType<ApplicationExtension>()
                    .apply {
                        println("found ApplicationExtension")
                        (this as BaseExtension).baseConfig()
                    }
            }
            is LibraryPlugin -> {
                project.extensions
                    .getByType<LibraryExtension>()
                    .apply {
                        println("found LibraryExtension")
                        baseConfig()
                    }
            }
        }
    }
}
then the app modules are not found. I need to use AppPlugin/AppExtension. Oh but this seems to work:
Copy code
is AppPlugin -> {
                project.extensions
                    .getByType<ApplicationExtension>()