alexfu
11/9/2015 - 7:34 PM

An auto-versioning Gradle plugin for Android. http://alexfu.github.io/2015/11/09/Android-Auto-Versioning/

An auto-versioning Gradle plugin for Android. http://alexfu.github.io/2015/11/09/Android-Auto-Versioning/

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

ext.VersioningPlugin = VersioningPlugin

class VersioningPlugin implements Plugin<Project> {
  @Override
  void apply(Project project) {
    project.extensions.create("versioning", VersioningPluginExtension)

    applyVersion(project);

    makeTask(project, 'prepareBuildRelease', { versionJSON ->
      versionJSON.buildNumber += 1
    })

    makeTask(project, 'preparePatchRelease', { versionJSON ->
      versionJSON.patch += 1
    }).dependsOn('prepareBuildRelease');

    makeTask(project, 'prepareMinorRelease', { versionJSON ->
      versionJSON.patch = 0
      versionJSON.minor += 1
    }).dependsOn('prepareBuildRelease');

    makeTask(project, 'prepareMajorRelease', { versionJSON ->
      versionJSON.patch = 0
      versionJSON.minor = 0
      versionJSON.major += 1
    }).dependsOn('prepareBuildRelease');
  }

  private def makeTask(project, name, increment) {
    return project.task(name) << {
      // Update version
      def versionJSON = project.versioning.getVersionJSON();
      increment(versionJSON);

      // Save version file
      def contents = new JsonBuilder(versionJSON).toPrettyString();
      project.versioning.versionFile.write(contents);

      applyVersion(project);
    }
  }

  private def applyVersion(project) {
    // Apply current version to all flavors
    project.android.applicationVariants.all { variant ->
      def versionCode = project.versioning.getVersionCode()
      def versionName = project.versioning.getVersionName()
      variant.mergedFlavor.versionCode = versionCode
      variant.mergedFlavor.versionName = versionName
    }
  }
}

class VersioningPluginExtension {
  File versionFile
  private Object versionJSON

  def getVersionCode() {
    sanityCheck();
    return versionJSON.buildNumber;
  }

  def getVersionName() {
    sanityCheck();
    return "${versionJSON.major}.${versionJSON.minor}.${versionJSON.patch}";
  }

  def getVersionJSON() {
    sanityCheck();
    return versionJSON;
  }

  private def sanityCheck() {
    if (!versionJSON) {
      versionJSON = new JsonSlurper().parseText(versionFile.text)
    }
  }
}