Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Versioning my own Android Libraries

I'm currently developing a custom library for Android.

My idea is to have a version for the app (I'm currently setting it in de build.gradle file and it works fine), and a different version for the library.

Is there a best practice in order to achieve this without having the two build.gradle files merged together?

I found a couple of similar questions on SO but they were 4 years old and not very helpful.

like image 994
arlistan Avatar asked Aug 13 '14 15:08

arlistan


1 Answers

The solution for this is not Git as you probably already figured out. OP wants to externally version a library, potentially as a means to provide an API to a third-party without providing the source code.

This is not trivial with Gradle but it is doable.

You can do this at different levels, I'll explain the easiest and most straight-forward.

Setting the version number

First you need to add a version variable to your gradle.properties file. You can set this variable with a simple one-liner:

version=0.1.0-SNAPSHOT

Building a version string

In your project create a file called versioning.gradle and paste the following code inside (I found this online a long time ago, I don't have the source anymore):

ext {
    /**
      * Builds an Android version code from the version of the project.
      * This is designed to handle the -SNAPSHOT and -RC format.
      *
      * I.e. during development the version ends with -SNAPSHOT. As the code stabilizes and release nears
      * one or many Release Candidates are tagged. These all end with "-RC1", "-RC2" etc.
      * And the final release is without any suffix.
      * @return
      */
    buildVersionCode = {
        //The rules is as follows:
        //-SNAPSHOT counts as 0
        //-RC* counts as the RC number, i.e. 1 to 98
        //final release counts as 99.
        //Thus you can only have 98 Release Candidates, which ought to be enough for everyone

        def candidate = "99"
        def (major, minor, patch) = version.toLowerCase().replaceAll('-', '').tokenize('.')
        if (patch.endsWith("snapshot")) {
            candidate = "0"
            patch = patch.replaceAll("[^0-9]","")
        } else {
            def rc
            (patch, rc) = patch.tokenize("rc")
            if (rc) {
                candidate = rc
            }
        }

        (major, minor, patch, candidate) = [major, minor, patch, candidate].collect{it.toInteger()}

        (major * 1000000) + (minor * 10000) + (patch * 100) + candidate;
    }
}

Once you've done this, be sure to include the versioning.gradle file from your main build.gradle file by adding apply from: '../versioning.gradle' near where the Android plugin is loaded.

Then, in your defaultConfig block, you want to change the default version variables to the following values:

versionCode buildVersionCode()
versionName version

Version number in the filename of the library

If you're truly building an Android library, then the expected output is an .aar file.

Therefore, add the following gradle code to your build.gradle file:

libraryVariants.all {
    variant -> variant.outputs.each {
        output -> output.outputFile = new File(
                output.outputFile.parent,
                output.outputFile.name.replace(".aar", "-${defaultConfig.versionName}.aar")
        )
    }
}

And that's it! Your output file will have a name with the version number you specify in the gradle.proprties file.

Caveats

This will version your library and/or API in a very static manner. Meaning that there's no way for a developer to dynamically get the version number through a method call.

Be sure to also have a method available that supplies client developers with the version number AND be sure to keep the two in sync. Only then you have a properly versioned library.

like image 66
Tiago Espinha Avatar answered Oct 19 '22 19:10

Tiago Espinha