ReactiveCircus / app-versioning

A Gradle Plugin for lazily generating Android app's versionCode & versionName from Git tags.
Apache License 2.0
205 stars 3 forks source link

Impossible to address global variables from lambda in .gradle.kts file #34

Closed VitaSokolova closed 10 months ago

VitaSokolova commented 10 months ago

We use app-versioning for long time to bump up version code and adding branch name to the version name. When we had gradle scripts on Groovy everything worked fine. We had read latest values from gradle.properties and modified them if needed.

gradle.properties:

appVersionCode=12999
appVersionName=3.36.0

Our app module build.gradle

def props = getVersionProps()

def getVersionProps() {
    def versionPropsFile = file('gradle.properties')
    if (!versionPropsFile.exists()) {
        versionPropsFile.createNewFile()
    }
    def versionProps = new Properties()
    versionProps.load(new FileInputStream(versionPropsFile))
    return versionProps
}

appVersioning {
    overrideVersionName { gitTag, providers, variantInfo ->
        switch (variantInfo.buildType) {
            case "beta":
                def branchName = providers
                        .environmentVariable("BRANCH_NAME")
                        .getOrElse("")
                        .toString()
                        .replaceAll("/", "-")
                        .replaceAll("\\*", "-")
                if (branchName) {
                    props['appVersionName'] + "-" + branchName
                } else {
                    props['appVersionName'].toString()
                }
                break
            default:
                props['appVersionName'].toString()
                break
        }
    }

    overrideVersionCode { gitTag, providers, variantInfo ->
        props['appVersionCode'].toInteger()
    }
}

Now we are in process of migration to .gradle.kts files and we ran into an issue:

Cannot fingerprint input property 'kotlinVersionCodeCustomizer': value '(io.github.reactivecircus.appversioning.GitTag, org.gradle.api.provider.ProviderFactory, io.github.reactivecircus.appversioning.VariantInfo) -> kotlin.Int' cannot be serialized.

The code we have:

import java.io.FileInputStream
import java.util.Properties

val props = getVersionProps()

fun getVersionProps(): Properties {
    val versionPropsFile = file("gradle.properties")
    if (!versionPropsFile.exists()) {
        versionPropsFile.createNewFile()
    }
    val versionProps = Properties()
    versionProps.load(FileInputStream(versionPropsFile))
    return versionProps
}

appVersioning {
    overrideVersionName { gitTag, providers, variantInfo ->
        props.get("appVersionName").toString()
    }

    overrideVersionCode { gitTag, providers, variantInfo->
        props.get("appVersionCode") as Int
    }
}

Can you, please, explain how we can fetch current versionCode and versionName without addressing global variables? I saw similar issue opened, but our case seems to be much simpler and I assume many other developers can struggle with the same problem.

ychescale9 commented 10 months ago

Does this work?

appVersioning {
    overrideVersionName { _, providers, _ ->
        providers.gradleProperty("appVersionName").get()
    }
    overrideVersionCode { _, providers, _ ->
        providers.gradleProperty("appVersionCode").get().toInt()
    }
}
VitaSokolova commented 10 months ago

It was the first thing I tried, tbh, but it fails with error 😔

Execution failed for task ':app:generateAppVersionInfoForDebug'.
> A failure occurred while executing io.github.reactivecircus.appversioning.tasks.GenerateAppVersionInfoWorkAction
> Cannot query the value of this provider because it has no value available.
ychescale9 commented 10 months ago

It works for me🤔 do the file and properties exist?

VitaSokolova commented 10 months ago

I found out, why it didn't work in my project. If I put my values at global gradle.properties, everything works, but if I put them inside the app module's gradle.properties, I receive the error above. In my repository we have two application modules, so using global gradle.properties is not a good solution for us.

You can check on that test project if you run :freeflex:generateAppVersionInfoForDebug --rerun https://github.com/VitaSokolova/AppVersioningSample

ychescale9 commented 10 months ago

Project level gradle.properties won't work: https://github.com/gradle/gradle/issues/13302

Maybe just put the version info in a regular file?

VitaSokolova commented 10 months ago

Seem like it's the simplest solution. Thanks for your help!