gmazzo/gradle-buildconfig-plugin

Adding undefined fields to BuildConfig

CodeRedDev opened this issue · 3 comments

I'm currently trying to add a field to BuildConfig that depends on a Gradle project property that will be defined on some extra task.

Unfortunately I can't add my logic to the buildConfig extension as this will be executed at compile time and not on runtime if I understand that right. So my way is to add an extra task like this:

val generateBuildConfig by tasks
task("buildConfigToken") {
    val bConfig = buildConfig.forClass("BuildConfig")

    doFirst {
        println("BuildConfig: Token input!")

        val token =
            if (project.hasProperty("bot_token")) {
                project.property("bot_token")
            } else {
                "RELESE"
            }

        bConfig.buildConfigField("String", "BOT_TOKEN", "\"$token\"")
    }

    generateBuildConfig.dependsOn(this)
}

This leads to a second BuildConfig class in an extra source set.

Is there a way to add fields to the original BuildConfig?

Well I just came to realise that the buildConfig variable where I call forClass() represents the one for the original BuildConfig class. So I got my intended behaviour.

For me the only questions now would be if I am right about that the buildConfig extension block will be executed at compile time and not at runtime?

For me the only questions now would be if I am right about that the buildConfig extension block will be executed at compile time and not at runtime?

It's not about compile/runtime times, but configuration and execution. From the plugin perspective, it's legal to change the DSL (calling forClass for instance) before the generateBuildConfig is executed.

Given task("buildConfigToken") { <block> }, anything in the <block> will be executed at configuration time, expect for those blocks under doFirst/doLast. You can either maniputale the plugin DSL at any of those, just make sure it happens before the generateBuildConfig is executed.

The only issue I see with you code is how you declare dependsOn, and it's a tricky thing from Gradle:

Instead of generateBuildConfig.dependsOn(this) you should do:

def myTask = task("buildConfigToken") { ... }
generateBuildConfig.configure { dependsOn(myTask) }

This setup will ensure a consistent behavior, as doing generateBuildConfig.dependsOn(this) will only setup the dependency if buildConfigToken configured/required elsewhere outside this logic, which is error prone.

And remember you can always use the Provider syntax which is going be lazy until the execution of the task:

 buildConfigField("String", "APP_VERSION", provider { "\"${project.version}\"" })