Get versionCode and versionName from Manifest - android

I have a script that automatically increases versionName and versionCode in the Manifest.xml. Android studio uses the versionName and versionCode from build.gradle.
build.gradle:
task('increaseVersionCode') << {
def manifestFile = file("src/main/AndroidManifest.xml")
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
manifestFile.write(manifestContent)
}
task('incrementVersionName') << {
def manifestFile = file("src/main/AndroidManifest.xml")
def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
manifestFile.write(manifestContent)
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
task.dependsOn 'increaseVersionCode'
task.dependsOn 'incrementVersionName'
}
}
How do i get the versionCode from manifest into build.gradle?

Related

Increase versionCode by one Automatically after executing packageReleaseJar

I have following in android tag of build.gradle in order to increase versionCode:
apply plugin: 'com.android.library'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
List<String> runTasks = gradle.startParameter.getTaskNames();
def value = 0
for (String item : runTasks)
if (item.contains("packageReleaseJar")) {
value = 1;
}
def code = versionProps['VERSION_CODE'].toInteger() + value
versionProps['VERSION_CODE'] = code.toString()
versionProps.store(versionPropsFile.newWriter(), null)
defaultConfig {
minSdkVersion 8
targetSdkVersion 22
versionCode code
versionName version
testApplicationId 'se.android.instrumenttest'
testInstrumentationRunner 'se.android.Runner'
printf("\n--------" + "VERSION DATA--------"
+ "\n" + "- CODE: " + versionCode + "\n" +
"- NAME: " + versionName + "\n----------------------------\n")
}
} else {
throw new GradleException("Could not read version.properties!")
}
The idea taken from commonsguy sample.
I expect that when I execute packageReleaseJar task using Gradle wrapper, versionCode increased by one. But it is not working as expected.
I guess it could be related to generateReleaseBuildConfig task.
What could be the reason and what is solution for that?
Addenda
def getVersionCode() {
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def code = versionProps['VERSION_CODE'].toInteger()
} else {
throw new GradleException("Could not read version.properties!")
}
return code
}
This method is not working as expected, but when use the logic of method in the android tag, problem will be solved:
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def code = versionProps['VERSION_CODE'].toInteger()
defaultConfig {
minSdkVersion 8
targetSdkVersion 22
versionCode code
versionName version
testApplicationId 'se.android.instrumenttest'
testInstrumentationRunner 'se.android.Runner'
printf("\n--------" + "VERSION DATA--------\n" +
"- CODE: " + versionCode + "\n" +
"- NAME: " + versionName +
"\n----------------------------\n")
}
} else {
throw new GradleException("Could not read version.properties!")
}

How to automatically increase and release signed apk in Android Studio using Gradle script

I'm trying to automatically update the versionName and VersionCode parameters in Android Manifest and use them in the output file name instead of "app-release.apk".
From this site I added this code in my build.gradle file:
import java.util.regex.Pattern
import com.android.builder.core.DefaultManifestParser
def mVersionCode
def mNextVersionName
def newName
task ('increaseVersionCode') << {
def manifestFile = file("src/main/AndroidManifest.xml")
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
mVersionCode = Integer.parseInt(matcher.group(1))
def manifestContent = matcher.replaceAll("versionCode=\"" + ++mVersionCode + "\"")
manifestFile.write(manifestContent)
}
task ('incrementVersionName') << {
def manifestFile = file("src/main/AndroidManifest.xml")
def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
manifestFile.write(manifestContent)
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig') {
task.dependsOn 'increaseVersionCode'
task.dependsOn 'incrementVersionName'
}
}
this code works perfectly, the 2 tasks run and correctly update the manifest file.
Now I want to use the 2 variables mVersionCode and mNextVersionName in the release block inside the buildTypes like this:
newName = defaultConfig.applicationId + "-" + mNextVersionName + " (" + mVersionCode + ").apk"
applicationVariants.all { variant ->
variant.outputs.each {output ->
def file = output.outputFile
output.outputFile = new File(file.parent, file.name.replace("app-release.apk", newName))
}
}
but the returned value of the 2 is null.
I also tried setting properties and extra properties:
task.setProperty("vName", mNextVersionName)
ext.vName = mNextVersionName
extensions.extraProperties.set("vName", mNextVersionName)
in the 2 tasks and getting them in the release block without luck.
Does someone has ideas on how to accomplish this?
No one answered, but I found a working solution. I don't like it, it can be done in a better way, but for now is the only workaround I found.
I'm still looking for a better solution, if you have one, I'll be happy to read and use it instead of mine.
So, I added a new task in the gradle.build file, it just do a copy of the 'app-release.apk' file and rename it using the values in the manifest file:
task copia{
dependsOn('assembleRelease')
def manifestFile = file("src/main/AndroidManifest.xml")
def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
def mVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion)
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def matcher = pattern.matcher(manifestText)
matcher.find()
def myVersionCode = Integer.parseInt(matcher.group(1))
copy {
from 'app-release.apk'
rename { String fileName ->
fileName.replace('app-release.apk', 'com.walker93.catpadova-' + mVersionName + ' (' + myVersionCode + ').apk')
}
into 'apk_outputs'
}
}
As you can see it's just a copy and edited version of the code in the 2 previous tasks with a copy {} function (here the docs), it reads the versionName and versionCode values without increment them, then it put them in the new filename i'm going to replace.
This task still requires the 2 other task to be there, so finally you will have 3 tasks.
In the first line of this task there is dependsOn(assembleRelease). This is very important, it will run all the others default release build tasks (included our 2 tasks that increment and write in the manifest) that generate the updated and signed apk.
Now if you try to run the "generate signed APK..." you will notice that this task will not run. Instead you will have to manually launch it:
Add your task in the "run configurations" like this and then you should be able to run the task from here or here when you want to publish the signed apk with the custom name. If you want to generate a signed apk with default name (and still increment versionName and versionCode) just use the "generate signed APK..." option like before.
Using this method there is no need to add code in the buildTypes part of the file.
Allright, here is my code of build.gradle of application module :
apply plugin: 'com.android.application'
apply from: 'versionalization.gradle'
def genVersionName = VersionInfo.versionName
def genVersionCode = VersionInfo.versionCode
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.vincestyling.exerciseapk"
minSdkVersion 10
targetSdkVersion 22
versionName genVersionName
versionCode genVersionCode
}
}
android.applicationVariants.all { variant ->
def taskSuffix = variant.name.capitalize()
def assembleTaskName = "assemble${taskSuffix}"
if (tasks.findByName(assembleTaskName)) {
def processAPKTask = tasks.create(name: "process${taskSuffix}Apk", type: Copy) {
variant.outputs.each { output ->
from output.outputFile
into output.outputFile.parent
def newApkName = android.defaultConfig.applicationId + "-" + variant.buildType.name + "-" + genVersionName + " (" + genVersionCode + ").apk"
rename ~/(.+)/, newApkName
}
}
tasks[assembleTaskName].finalizedBy processAPKTask
}
}
the versionalization.gradle which applied at head is what I use to increase the VersionInfo, then return two values to use.
task VersionInfo {
String FACTOR_KEY = "BUILD_NUMBER_FACTOR"
File buildDir = file("build")
buildDir.mkdir()
File factorPropFile = new File(buildDir, "kbuildfactor.prop")
Properties props = new Properties()
if (factorPropFile.exists()) {
props.load(new FileInputStream(factorPropFile))
}
int buildNumberFactor = props.get(FACTOR_KEY) as Integer ?: 0
buildNumberFactor += 1
props.put(FACTOR_KEY, buildNumberFactor as String)
props.store(new FileOutputStream(factorPropFile), null)
String BASE_VERSION_NAME = "BASE_VERSION_NAME"
String BASE_VERSION_CODE = "BASE_VERSION_CODE"
File versionPropFile = file("versioning.properties")
props.load(new FileInputStream(versionPropFile))
String baseVersionName = props.get(BASE_VERSION_NAME) as String
Integer baseVersionCode = props.get(BASE_VERSION_CODE) as Integer
ext.versionName = baseVersionName + "." + buildNumberFactor
ext.versionCode = baseVersionCode * 1000 + buildNumberFactor
}
it's quite straightforward, read two files to take the necessary fields to constructing the version informations.
we copy/rename the final APK at last.
besides, I achieved the copy/rename part as below first, but it won't work when you have any product flavors, I paste here as another choice.
android.applicationVariants.all { variant ->
variant.outputs.each {output ->
def newApkName = android.defaultConfig.applicationId + "-" + variant.buildType.name + "-" + genVersionName + " (" + genVersionCode + ").apk"
def oldApkName = "app-${variant.buildType.name}.apk"
def file = output.outputFile
output.outputFile = new File(file.parent, file.name.replace(oldApkName, newApkName))
}
}
To use extra properties extensions, you need to define them like this:
ext {
mVersionCode = 0
mNextVersionName = ""
}
Then you'll be able access them freely in your buildscript just by using them exactly as you used them in your tasks above.

Gradle Autoincrement and Rename APK I/O Error

I'm trying to do an auto increment for the build number in Android Studio. Followed this link, and it worksfine.
Now I want to rename the apk using the versionName. I also did that successfully, as I can see in my app\build\outputs\apk directory, that the file is there.
The problem The generated apk and the part where Android Studio you see the "local path" don't have the same file name.
The generated apk's name: MyAppsName-v1.0-64-debug.apk
The "local path" it's looking for: ..\app\build\outputs\apk\MyAppsName-v1.0-60-debug.apk
So it makes sense to see an error saying "Local path doesn't exist." Because the "MyAppsName-v1.0-60-debug.apk" does not exist.
Here's the snippet of my build.gradle:
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def value = 0
def runTasks = gradle.startParameter.taskNames
if ('assemble' in runTasks || 'assembleRelease' in runTasks || 'aR' in runTasks) {
value = 1;
}
def versionMajor = 1
def versionMinor = 0
def versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1
def version_Code = versionProps['VERSION_CODE'].toInteger() + value
versionProps['VERSION_BUILD'] = versionBuild.toString()
versionProps['VERSION_CODE'] = version_Code.toString()
versionProps.store(versionPropsFile.newWriter(), null)
defaultConfig {
versionCode version_Code
versionName "v${versionMajor}.${versionMinor}-${versionBuild}"
minSdkVersion 15
targetSdkVersion 21
}
archivesBaseName = "MyAppsName" + "-" + defaultConfig.versionName;
} else {
throw new GradleException("Could not read version.properties!")
}

Update Android Application version (stored in build.gradle) with gradle

It is possible to update the Android or library version versionCode and versionName when executing some task in gradle ? The versionCode/Name is placed in my android/build.gradle
I'm searching for a complete gradle script, not a shell one.
It's different from How to autoincrement versionCode in Android Gradle because the versionCode and versioName is stored in the build.gradle not in the manifest
In your build.gradle you want to update, I've changed a script to edit the current build.gradle and incrementing the versionCode and versionName.
Add this task to your gradle :
task incrementVersionCode << {
println("Incrementing Version Code...")
def manifestFile = file("build.gradle")
def patternVersionCode = Pattern.compile("versionCode (\\d+)")
def manifestText = manifestFile.getText()
def matcherVersionCode = patternVersionCode.matcher(manifestText)
matcherVersionCode.find()
def mVersionCode = Integer.parseInt(matcherVersionCode.group(1))
def mNextVersionCode = mVersionCode + 1
def manifestContent = matcherVersionCode.replaceAll("versionCode " + mNextVersionCode)
println("> Set versionCode(" + mVersionCode + ") to " + mNextVersionCode);
manifestFile.write(manifestContent)
}
task incrementVersionName << {
println("Incrementing Version Name...")
def manifestFile = file("build.gradle")
def patternVersionNumber = Pattern.compile("versionName \"(\\d+)\\.(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
def mVersionName = majorVersion + "." + minorVersion + "." + pointVersion
def mNextVersionName = majorVersion + "." + minorVersion + "." + (pointVersion + 1)
def manifestContent = matcherVersionNumber.replaceAll("versionName \"" + mNextVersionName + "\"")
println("> Set versionName(" + mVersionName + ") to " + mNextVersionName);
manifestFile.write(manifestContent)
}
Usage
If you want to update version when running ./gradlew bintrayUpload (for eg, mut it can be the task you want) add this :
bintrayUpload.dependsOn incrementVersionCode
bintrayUpload.dependsOn incrementVersionName

How to autoincrement versionCode in Android Gradle

I'm experimenting with new Android build system based on Gradle and I'm thinking, what is the best way to autoincrease versionCode with it. I am thinking about two options
create versionCode file, read number from it, increase it and write it back to the file
parse AndroidManifest.xml, read versionCode from it, increase it and write it back to the AndroidManifest.xml
Is there any more simple or suitable solution?
Has anyone used one of mentiod options and could share it with me?
I have decided for second option - to parse AndroidManifest.xml. Here is working snippet.
task('increaseVersionCode') << {
def manifestFile = file("AndroidManifest.xml")
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
manifestFile.write(manifestContent)
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig') {
task.dependsOn 'increaseVersionCode'
}
}
versionCode is released for release builds in this case. To increase it for debug builds change task.name equation in task.whenTaskAdded callback.
I'm using this code to update both versionCode and versionName, using a "major.minor.patch.build" scheme.
import java.util.regex.Pattern
task('increaseVersionCode') << {
def manifestFile = file("src/main/AndroidManifest.xml")
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
manifestFile.write(manifestContent)
}
task('incrementVersionName') << {
def manifestFile = file("src/main/AndroidManifest.xml")
def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
manifestFile.write(manifestContent)
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
task.dependsOn 'increaseVersionCode'
task.dependsOn 'incrementVersionName'
}
}
it doesn't seem to be the exact setup you're using, but in my case the builds are being run by jenkins and i wanted to use its $BUILD_NUMBER as the app's versionCode. the following did the trick for me there.
defaultConfig {
...
versionCode System.getenv("BUILD_NUMBER") as Integer ?: 9999
...
}
UPDATE
As google play warning:
The greatest value Google Play allows for versionCode is 2100000000.
We might change the format as below to reduce the risk of reaching limit:
def formattedDate = date.format('yyMMddHH')
ORIGINAL
I am using time stamp for the version code:
def date = new Date()
def formattedDate = date.format('yyMMddHHmm')
def code = formattedDate.toInteger()
defaultConfig {
minSdkVersion 10
targetSdkVersion 21
versionCode code
}
If you are holding the version code in the build.gradle file use the next snippet:
import java.util.regex.Pattern
task('increaseVersionCode') << {
def buildFile = file("build.gradle")
def pattern = Pattern.compile("versionCode\\s+(\\d+)")
def manifestText = buildFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
def manifestContent = matcher.replaceAll("versionCode " + ++versionCode)
buildFile.write(manifestContent)
}
Gradle Advanced Build Version is a plugin for Android that makes generating versionCode and versionName automatically. there are lots of customization. here you can find more info about it
https://github.com/moallemi/gradle-advanced-build-version
To take both product flavors and build types into account and using #sealskej's logic for parsing manifest:
android.applicationVariants.all { variant ->
/* Generate task to increment version code for release */
if (variant.name.contains("Release")) {
def incrementVersionCodeTaskName = "increment${variant.name}VersionCode"
task(incrementVersionCodeTaskName) << {
if (android.defaultConfig.versionCode == -1) {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def versionCode = Integer.parseInt(matcher.group(1))
android.defaultConfig.versionCode = versionCode + 1
def manifestContent = matcher.replaceAll("versionCode=\"" + android.defaultConfig.versionCode + "\"")
manifestFile.write(manifestContent)
}
}
def hookTask = variant.generateBuildConfig
hookTask.dependsOn(incrementVersionCodeTaskName)
}
}
Increment VersionCode Task(Integer):
This works by incrementing the Version Code by 1, for example:
android:versionCode="1"
1 + 1 = 2
import java.util.regex.Pattern
task incrementVersionCode << {
def manifestFile = file('AndroidManifest.xml')
def matcher = Pattern.compile('versionCode=\"(\\d+)\"')
.matcher(manifestFile.getText())
matcher.find()
def manifestContent = matcher.replaceAll('versionCode=\"' +
++Integer.parseInt(matcher.group(1)) + '\"')
manifestFile.write(manifestContent)
}
Increment VersionName Task(String):
Warning: Must contain 1 period for Regex
This works by incrementing the Version Name by 0.01, for example:
You can easily modify and change your increment or add more digits.
android:versionName="1.0"
1.00 + 0.01 -> 1.01
1.01 + 0.01 -> 1.02
1.10 + 0.01 -> 1.11
1.99 + 0.01 -> 2.0
1.90 + 0.01 -> 1.91
import java.util.regex.Pattern
task incrementVersionName << {
def manifestFile = file('AndroidManifest.xml')
def matcher = Pattern.compile('versionName=\"(\\d+)\\.(\\d+)\"')
.matcher(manifestFile.getText())
matcher.find()
def versionName = String.format("%.2f", Integer
.parseInt(matcher.group(1)) + Double.parseDouble("." + matcher
.group(2)) + 0.01)
def manifestContent = matcher.replaceAll('versionName=\"' +
versionName + '\"')
manifestFile.write(manifestContent)
}
Before:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exmaple.test"
android:installLocation="auto"
android:versionCode="1"
android:versionName="1.0" >
After:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exmaple.test"
android:installLocation="auto"
android:versionCode="2"
android:versionName="1.01" >
If you write your versionCode in gradle.build file(most case currently), here is a workaround. A little bit stupid(update "self"), but it works!
import java.util.regex.Pattern
task('increaseVersionCode') << {
def buildFile = file("build.gradle")
def pattern = Pattern.compile("versionCode(\\s+\\d+)")
def buildText = buildFile.getText()
def matcher = pattern.matcher(buildText)
matcher.find()
def versionCode = android.defaultConfig.versionCode
def buildContent = matcher.replaceAll("versionCode " + ++versionCode)
buildFile.write(buildContent)
System.out.println("Incrementing Version Code ===> " + versionCode)
}
tasks.whenTaskAdded { task ->
if (task.name == 'generateReleaseBuildConfig') {
task.dependsOn 'increaseVersionCode'
}
}
To add on to #sealskej's post, this is how you can update both your version code and version name (Here I'm assuming your major and minor version are both 0):
task('increaseVersion') << {
def manifestFile = file("AndroidManifest.xml")
def patternVersionCode = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionCode = patternVersionCode.matcher(manifestText)
matcherVersionCode.find()
def versionCode = Integer.parseInt(matcherVersionCode.group(1))
def manifestContent = matcherVersionCode.replaceAll("versionCode=\"" + ++versionCode + "\"")
manifestFile.write(manifestContent)
def patternVersionNumber = Pattern.compile("versionName=\"0.0.(\\d+)\"")
manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def versionNumber = Integer.parseInt(matcherVersionNumber.group(1))
manifestContent = matcherVersionNumber.replaceAll("versionName=\"0.0." + ++versionNumber + "\"")
manifestFile.write(manifestContent)
}
what about this ?
add to build.gradle (app module)
def getBuildVersionCode() {
def date = new Date()
def formattedDate = date.format('yyyyMMdd')
def formattedSeconds = date.format('HHmmssSSS')
def formatInt = formattedDate as int;
def SecondsInt = formattedSeconds as int;
return (formatInt + SecondsInt) as int
}
defaultConfig {
applicationId "com.app"
minSdkVersion 17
targetSdkVersion 22
versionCode getBuildVersionCode()
versionName "1.0"
}
So as I was looking into most of the solution, they were nice but not enough so I wrote this, one increment per multi-deploy:
This will increment the build when compiling debug versions, and increment the point and version code when deploying.
import java.util.regex.Pattern
def incrementVersionName(int length, int index) {
def gradleFile = file("build.gradle")
def versionNamePattern = Pattern.compile("versionName\\s*\"(.*?)\"")
def gradleText = gradleFile.getText()
def matcher = versionNamePattern.matcher(gradleText)
matcher.find()
def originalVersion = matcher.group(1)
def originalVersionArray = originalVersion.split("\\.")
def versionKeys = [0, 0, 0, 0]
for (int i = 0; i < originalVersionArray.length; i++) {
versionKeys[i] = Integer.parseInt(originalVersionArray[i])
}
def finalVersion = ""
versionKeys[index]++;
for (int i = 0; i < length; i++) {
finalVersion += "" + versionKeys[i]
if (i < length - 1)
finalVersion += "."
}
System.out.println("Incrementing Version Name: " + originalVersion + " ==> " + finalVersion)
def newGradleContent = gradleText.replaceAll("versionName\\s*\"(.*?)\"", "versionName \"" + finalVersion + "\"")
gradleFile.write(newGradleContent)
}
def incrementVersionCode() {
def gradleFile = file("build.gradle")
def versionCodePattern = Pattern.compile("versionCode\\s*(\\d+)")
def gradleText = gradleFile.getText()
def matcher = versionCodePattern.matcher(gradleText)
matcher.find()
def originalVersionCode = Integer.parseInt(matcher.group(1) + "")
def finalVersionCode = originalVersionCode + 1;
System.out.println("Incrementing Version Code: " + originalVersionCode + " ==> " + finalVersionCode)
def newGradleContent = gradleText.replaceAll("versionCode\\s*(\\d+)", "versionCode " + finalVersionCode)
gradleFile.write(newGradleContent)
}
task('incrementVersionNameBuild') << {
incrementVersionName(4, 3)
}
task('incrementVersionNamePoint') << {
incrementVersionName(3, 2)
}
task('incrementVersionCode') << {
incrementVersionCode()
}
def incrementedBuild = false
def incrementedRelease = false
tasks.whenTaskAdded { task ->
System.out.println("incrementedRelease: " + incrementedRelease)
System.out.println("incrementedBuild: " + incrementedBuild)
System.out.println("task.name: " + task.name)
if (!incrementedBuild && task.name.matches('generate.*?DebugBuildConfig')) {
task.dependsOn 'incrementVersionNameBuild'
incrementedBuild = true
return
}
if (!incrementedRelease && task.name.matches('generate.*?ReleaseBuildConfig')) {
task.dependsOn 'incrementVersionCode'
task.dependsOn 'incrementVersionNamePoint'
incrementedRelease = true
return
}
}
My approach is to read manifest file from build folder and get buildVersion out of there, than I delete a folder. When task creates new manifest, my incremented buildVersion variable is already there.
def versionPattern = "Implementation-Version=(\\d+.\\d+.\\d+.\\d+\\w+)"
task generateVersion (dependsOn : 'start') {
// read build version from previous manifest
def file = file("build/libs/MANIFEST.MF")
if (file.exists()) {
def pattern = Pattern.compile(versionPattern)
def text = file.getText()
def matcher = pattern.matcher(text)
matcher.find()
buildNumber = Integer.parseInt(matcher.group(1))
// increment build version
version = "${majorVer}.${minorVer}.${patchVer}.${++buildNumber}${classifier}_${access}"
}
else
version = "${majorVer}.${minorVer}.${patchVer}.1${classifier}_${access}"
}
task specifyOutputDir (dependsOn : 'generateVersion', type : JavaCompile) {
// create a folder for new build
destinationDir = file("build/${version}/")
}
task clean (dependsOn : 'generateVersion', type : Delete) {
doLast {
delete "build/${version}"
println 'Build directory is deleted'
}
}
task configureJar (dependsOn : 'generateVersion', type : Jar) {
baseName = applicationName
version = project.version
archiveName = "${applicationName}_ver${version}.${extension}"
manifest {[
"Main-Class" : mainClassName,
"Implementation-Title" : name,
"Implementation-Version" : version,
"Access" : access,
"Developer" : developer
]}
}

Categories

Resources