gmazzo/gradle-buildconfig-plugin

will it support with productFlavors ?

Egi10 opened this issue · 6 comments

gmazzo commented

Hi @Egi10 , can you elaborate a use case for this? This plugin was never meant to be a replacement of Android's buildConfigField which is already flavor-awre.

This plugin was meant to port this feature back to any Kotlin (mainly non-Android) project.

Egi10 commented

I have a case where I need several configurations, such as staging, UAT, and production. Each configuration has a different base URL, and in Android, I usually use Product Flavors.

Example :

productFlavors {
        create("staging") {
            buildConfigField "String", "BASE_URL", "\"https://api.uat.example.com/\"" // Define specific base URL for UAT
        }
        create("prod") {
            buildConfigField "String", "BASE_URL", "\"https://api.example.com/\"" // Define specific base URL for production
        }
    }

For now, in KMM, I'm using the BuildKonfig library to manage this.

gmazzo commented

This plugin works from SourceSet based approach. By default, applying the java or kotlin plugin, it binds to the JVM source sets, and creates an ad-hoc BuildConfigSourceSet per each.

Android Flavors (variants actually: buildType-flavors) are built upon SourceSets as well.

If what you want is to mimic Android's BuildConfig (having all fields from default, buildType and flavors merged into a single class), you should add something like this to the DSL:

    // mimics the variant-aware buildConfigField behavior from Android, by declaring fields on the final variant sourceSet
    applicationVariants.all variant@ { // per each variant (buildType-flavor)
        buildConfig.sourceSets.named(this@variant.name) { // access the sources for the variant. i.e.: `debugFoo`
            className.set("BuildConfig") // forces the class name to be the same on all, as defaults to `DebugFooBuildConfig`

            // static constants, what would you have in the `defaultConfig` on Android DSL
            buildConfigField("String", "APP_NAME", "\"${project.name}\"")
            buildConfigField("String", "APP_SECRET", "\"Z3JhZGxlLWphdmEtYnVpbGRjb25maWctcGx1Z2lu\"")
            buildConfigField("long", "BUILD_TIME", "${System.currentTimeMillis()}L")
            buildConfigField("boolean", "FEATURE_ENABLED", "${true}")
            buildConfigField("kotlin.IntArray", "MAGIC_NUMBERS", "intArrayOf(1, 2, 3, 4)")

            // and declares "flavored" constants
            buildConfigField("boolean", "IS_DEBUG", "${this@variant.buildType.isDebuggable}") 
            buildConfigField("String", "BRAND", "\"${this@variant.productFlavors.single().name}\"")
        }
    }

https://github.com/gmazzo/gradle-buildconfig-plugin/blob/main/demo-project/kts-android/build.gradle.kts

In case you want to be explicit on the "flavor-specific" value, you can also do this:

buildConfig.sourceSets.named(`debugFoo`) {
    buildConfigField("boolean", "IS_DEBUG", "${true}") 
}
buildConfig.sourceSets.named(`releaseFoo`) {
    buildConfigField("boolean", "IS_DEBUG", "${false}") 
}
gmazzo commented

Can you elaborate yours needs? May be a sample project would help to understand.

Basically, this project supports kotlin multiplatform, as you can register a BuildConfig class per source set.

What is not supported is generating expect/actual definitions, but may still create a class on each final target: jvmMain, iosMain etc

gmazzo commented

Is it an Android project, a multiplatform one, it both? What are your target platforms?

I'd create for each platform leaf source set, and add the constants the.

gmazzo commented

It's doable, but I can't write that piece of course for you sorry.

If you understand the basics of Kotlin Multiplatform and it's source sets, it will be easy to do