diff --git a/README.md b/README.md index f1e6bc1..cbd9a2b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ can't trace back to code, then this plugin is for you! Add the plugin the top of your `app/build.gradle` (or equivalent): ```groovy plugins { - id 'com.gladed.androidgitversion' version '0.3.1' + id 'com.gladed.androidgitversion' version '0.3.3' } ``` @@ -91,12 +91,13 @@ gradle task that makes changes to the repo. ## Configuration Properties -An `androidGitVersion` block in your project's `build.gradle` file can supply optional properties -to configure this plugin's behavior, e.g.: +You can configure how names and codes are generated by adding an `androidGitVersion` block +to your project's `build.gradle` file. For example: ```groovy androidGitVersion { - baseCode 2000 + abis = ["armeabi":1, "armeabi-v7a":2 ] + baseCode 200000 codeFormat = 'MNNPPP' format = '%tag%%.count%%%%-branch%%...dirty%' hideBranches = [ 'develop' ] @@ -105,13 +106,20 @@ androidGitVersion { untrackedIsDirty = false } ``` +### abis (map of String:int) +`abis` indicate how [ABI platforms](https://developer.android.com/ndk/guides/abis.html) +are mapped to integer codes. These integer codes are inserted into the `A` place in `codeFormat`. + +The default `abis` are: + + ['armeabi':1, 'armeabi-v7a':2, 'arm64-v8a':3, 'mips':5, 'mips64':6, 'x86':8, 'x86_64':9 ] ### baseCode (int) `baseCode` sets a floor for all generated version codes (that is, it is added to all generated version codes). Use this when you have already released a version with a code, and don't want to go backwards. -The default baseCode is 0. +The default `baseCode` is 0. ### codeFormat (string) `codeFormat` defines a scheme for building the version code. Each character corresponds to a @@ -120,10 +128,22 @@ reserved decimal place in the resulting code: - `M` for the Major version number (1.x.x) - `N` for the Minor version number (x.1.x) - `P` for the Patch version number (x.x.1) -- `B` place for the build number (revisions since last tag) +- `B` for the build number (revisions since last tag) +- `A` for the ABI platform code [1] - `X` for a blank place filled with 0 -Take care; changing the version code scheme for a released Android project can cause problems if +[1] if you use `A` you must call `variants` to tell the plugin about your project's build +variants. For example: + + android { + ... + androidGitVersion { + codeFormat = 'AMNNPPP' + variants applicationVariants + } + } + +Note that changing the version code scheme for a released Android project can cause problems if your new version code does not [increase monotonically](http://developer.android.com/tools/publishing/versioning.html). Consider `baseCode` if you are changing code formats from a prior release. @@ -131,8 +151,8 @@ your new version code does not Android version codes are limited to a maximum version code of 2100000000. As a result, codeFormat only allows you to specify 9 digits. -The default is `codeFormat` is `"MMMNNNPPP"`, leaving 3 digits for each portion of the semantic -version. +The default `codeFormat` is `"MMMNNNPPP"`, leaving 3 digits for each portion of the semantic +version. A shorter code format such as `MNNPPP` is **highly recommended**. ### hideBranches (list of strings) `hideBranches` describes which branches which should *not* be mentioned explicitly when building @@ -163,7 +183,7 @@ entire part will not appear. The default format is `"%tag%%-count%%-commit%%-branch%%-dirty%"` -### Deprecated: multiplier (int) +### ~~multiplier (int)~~ (deprecated) Use `codeFormat` instead. `multiplier` sets the space allowed each part of the version when calculating the version code. @@ -197,7 +217,7 @@ paths (like `my-app/build.gradle` or `my-app/app/src`) will not affect the versi The default onlyIn path is `''`, which includes all paths. -### Deprecated: parts (int) +### ~~parts (int)~~ (deprecated) Use `codeFormat` instead. `parts` sets the number of parts the version number will have. diff --git a/RELEASE.md b/RELEASE.md index 167d11f..5749a72 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -4,4 +4,4 @@ To release: * Update version number in README.md. * Run `gradle test publishPlugins` * Commit any changes and tag the release version number -* Run `git push origin master --tags` to sync with GitHub +* Run `git push origin master --tags` to sync with github.com diff --git a/build.gradle b/build.gradle index 538f142..4b79996 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,7 @@ dependencies { compile gradleApi() compile localGroovy() compile 'org.eclipse.jgit:org.eclipse.jgit:4.1.1.201511131810-r' + compile 'com.android.tools.build:gradle:2.1.3' } repositories { @@ -31,7 +32,7 @@ task wrapper(type: Wrapper) { gradleVersion = '2.4' } -version = '0.3.1' // <-----UPDATE THIS VERSION NUMBER MANUALLY FOR EACH RELEASE +version = '0.3.3' // <-----UPDATE THIS VERSION NUMBER MANUALLY FOR EACH RELEASE group = 'com.gladed.gradle.androidgitversion' pluginBundle { diff --git a/src/main/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersion.groovy b/src/main/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersion.groovy index ce336ea..0a96fb6 100644 --- a/src/main/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersion.groovy +++ b/src/main/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersion.groovy @@ -18,6 +18,8 @@ import org.eclipse.jgit.diff.RawTextComparator import org.eclipse.jgit.util.io.DisabledOutputStream import org.eclipse.jgit.revwalk.RevObject +import com.android.build.OutputFile + class AndroidGitVersion implements Plugin { void apply(Project project) { project.extensions.create("androidGitVersion", AndroidGitVersionExtension, project) @@ -79,16 +81,20 @@ class AndroidGitVersionExtension { String format = '%tag%%-count%%-commit%%-branch%%-dirty%' /** - * Format of version code value: AA = API level, SS = Screen size, M+ = Major version (1.x.x), - * N+ = Minor version (x.2.x), P+ = Patch version (x.x.3), B+ = Build number (commit count - * since last tag). - * - * Default is "MMMNNNPPP", allocating 3 digits each for Major, Minor, Patch. + * Format for versionCode output. null if user is still using deprecated fields. + */ + String codeFormat + + /** + * Map of ABI designators to integers. */ - String codeFormat; + def abis = abis = ['armeabi':1, 'armeabi-v7a':2, 'arm64-v8a':3, 'mips':5, 'mips64':6, + 'x86':8, 'x86_64':9 ] + + def currentAbi = 0 enum CodePart { - EMPTY, MAJOR, MINOR, PATCH, BUILD + EMPTY, MAJOR, MINOR, PATCH, BUILD, ABI } private List codeParts; @@ -137,15 +143,17 @@ class AndroidGitVersionExtension { * Return a version code corresponding to the most recent version */ final int code() { - readCodeFormat(); - if (!results) results = scan(); + readCodeFormat() + if (!results) results = scan() if (codeParts == null) { + // Fallback for case where no codeParts are given def versionParts = results.getVersionParts(parts); return baseCode + versionParts.inject(0) { result, i -> result * multiplier + i.toInteger() }; } else { - def r = results; - return baseCode + - codeParts.inject(0) { code, part -> r.addCodePart(code, part[0], part[1]) } + def r = results // Make available to closure + return baseCode + codeParts.inject(0) { + code, part -> r.addCodePart(code, part[0], part[1]) + } } } @@ -154,6 +162,18 @@ class AndroidGitVersionExtension { results = null } + /** Update the versionCodeOverride for all variant outputs according to ABI */ + final void variants(variants) { + variants.all { variant -> + variant.outputs.each { output -> + currentAbi = abis.get(output.getFilter(OutputFile.ABI), 0) + output.versionCodeOverride = code() + // Don't leave this value dangling, we don't know when this closure will apply + currentAbi = 0; + } + } + } + private Results scan() { Results results = new Results() @@ -236,7 +256,7 @@ class AndroidGitVersionExtension { } if (parts != null || multiplier != null) { - throw new GradleException('cannot use parts/multiplier with codeFormat') + throw new GradleException('cannot use "parts" or "multiplier" with "codeFormat"') } // Parse out code parts @@ -252,6 +272,7 @@ class AndroidGitVersionExtension { case 'N': part = CodePart.MINOR; break; case 'P': part = CodePart.PATCH; break; case 'B': part = CodePart.BUILD; break; + case 'A': part = CodePart.ABI; break; case 'X': part = CodePart.EMPTY; break; default: throw new GradleException("Unrecognized char " + ch + " in codeFormat"); } @@ -361,6 +382,7 @@ class AndroidGitVersionExtension { case CodePart.MINOR: digits = getVersionParts(3)[1]; break; case CodePart.PATCH: digits = getVersionParts(3)[2]; break; case CodePart.BUILD: digits = revCount; break; + case CodePart.ABI: digits = currentAbi; break; case CodePart.EMPTY: digits = 0; break; default: throw new GradleException("Unimplemented part " + part) } diff --git a/src/test/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersionTest.groovy b/src/test/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersionTest.groovy index 84bd07f..0604392 100644 --- a/src/test/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersionTest.groovy +++ b/src/test/groovy/com/gladed/gradle/androidgitversion/AndroidGitVersionTest.groovy @@ -1,5 +1,6 @@ package com.gladed.gradle.androidgitversion +import com.android.build.OutputFile import org.eclipse.jgit.api.Git import org.eclipse.jgit.lib.Repository @@ -355,6 +356,52 @@ class AndroidGitVersionTest extends GroovyTestCase { assertEquals(10203, plugin.code()) } + enum AbiType { ONE, TWO, THREE } + + class SimOutput { + int versionCodeOverride = 0 + AbiType abi + AbiType getFilter(f) { + if (f == OutputFile.ABI) return abi + return null + } + } + + class SimVariants { + def variants + void all(Closure c) { + variants.each { + c it + } + } + } + + class SimVariant { + def outputs + } + + void testVariants() { + plugin.codeFormat = "AMNNPP" + addCommit() + addTag("1.2.3") + + // Configure our own abi map + plugin.abis = [ (AbiType.ONE) : 1, (AbiType.TWO) : 2, (AbiType.THREE) : 3 ] + + // Simulate some variants each with their own set of abi outputs + def simVariants = new SimVariants(variants : [ + new SimVariant(outputs : [new SimOutput()]), + new SimVariant(outputs : [new SimOutput(abi: AbiType.TWO), + new SimOutput(abi: AbiType.THREE)] ) + ]) + + plugin.variants(simVariants) + assertEquals(10203, plugin.code()) + assertEquals(10203, simVariants.variants[0].outputs[0].versionCodeOverride) + assertEquals(210203, simVariants.variants[1].outputs[0].versionCodeOverride) + assertEquals(310203, simVariants.variants[1].outputs[1].versionCodeOverride) + } + void testFlush() { addCommit() addTag("1.2.3")