gmazzo / gradle-buildconfig-plugin

A plugin for generating BuildConstants for any kind of Gradle projects: Java, Kotlin, Groovy, etc. Designed for KTS scripts.
MIT License
644 stars 29 forks source link

will it support with productFlavors ? #68

Closed Egi10 closed 1 year ago

Egi10 commented 1 year ago

Like on Android : https://developer.android.com/build/build-variants#product-flavors

gmazzo commented 1 year ago

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 1 year ago

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 1 year ago

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 8 months ago

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 8 months ago

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 8 months ago

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