【发布时间】:2016-10-03 04:19:39
【问题描述】:
我想将我的项目的版本号从 1.0.0 增加。每当通过 bash 命令进行新构建时,都会自动升级到 1.0.1。我只需要增加路径数,其他我将在手动构建期间手动增加。
我想改变
这个:
version=1.0.0
到 这个:
version=1.0.1
使用 gradle 任务。 任何帮助我该怎么做。 有没有办法使用正则表达式或使用子字符串函数来更新它。
【问题讨论】:
我想将我的项目的版本号从 1.0.0 增加。每当通过 bash 命令进行新构建时,都会自动升级到 1.0.1。我只需要增加路径数,其他我将在手动构建期间手动增加。
我想改变
这个:
version=1.0.0
到 这个:
version=1.0.1
使用 gradle 任务。 任何帮助我该怎么做。 有没有办法使用正则表达式或使用子字符串函数来更新它。
【问题讨论】:
这是一个示例任务:
version='1.0.0' //version we need to change
task increment<<{
def v=buildFile.getText().find(version) //get this build file's text and extract the version value
String minor=v.substring(v.lastIndexOf('.')+1) //get last digit
int m=minor.toInteger()+1 //increment
String major=v.substring(0,v.length()-1) //get the beginning
//println m
String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+m+"'")
//println s
buildFile.setText(s) //replace the build file's text
}
多次运行此任务,您应该会看到版本更改。
一个变种:
version='1.0.0'
task incrementVersion<<{
String minor=version.substring(version.lastIndexOf('.')+1)
int m=minor.toInteger()+1
String major=version.substring(0,version.length()-1)
String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+m+"'")
buildFile.setText(s)
}
【讨论】:
def v=buildFile.getText().find(version) 有什么用?那不是马上给你version吗?
if(v) check 添加到该任务中。但是如果你做if(version)检查并且没有设置版本,构建会失败。
split 这伤害了我的大脑。还有int m,请不要。
这是 Gradle(Android 项目)中版本升级的自定义任务:
class Version {
private int major
private int minor
private int patch
private int code
Version(int code, String version) {
this.code = code
def (major, minor, patch) = version.tokenize('.')
this.major = major.toInteger()
this.minor = minor.toInteger()
this.patch = patch.toInteger()
}
@SuppressWarnings("unused")
void bumpMajor() {
major += 1
minor = 0
patch = 0
code += 1
}
@SuppressWarnings("unused")
void bumpMinor() {
minor += 1
patch = 0
code += 1
}
@SuppressWarnings("unused")
void bumpPatch() {
patch += 1
code += 1
}
String getName() { "$major.$minor.$patch" }
int getCode() { code }
}
tasks.addRule("Pattern: bump<TYPE>Version") { String taskName ->
if (taskName.matches("bump(Major|Minor|Patch)Version")) {
task(taskName) {
doLast {
String type = (taskName - 'bump' - 'Version')
println "Bumping ${type.toLowerCase()} version…"
int oldVersionCode = android.defaultConfig.versionCode
String oldVersionName = android.defaultConfig.versionName
version = new Version(oldVersionCode, oldVersionName)
version."bump$type"()
String newVersionName = version.getName()
String newVersionCode = version.getCode()
println "$oldVersionName ($oldVersionCode) → $newVersionName ($newVersionCode)"
def updated = buildFile.getText()
updated = updated.replaceFirst("versionName '$oldVersionName'", "versionName '$newVersionName'")
updated = updated.replaceFirst("versionCode $oldVersionCode", "versionCode $newVersionCode")
buildFile.setText(updated)
}
}
}
}
请参阅此Kanji learning Android app 以了解完整性。
需要以下格式(注意单引号):
android {
defaultConfig {
versionCode 3
versionName '0.3.13'
}
}
$ ./gradlew bumpPatchVersion
> Task :app:bumpPatchVersion
Bumping patch version…
0.3.13 (3) → 0.3.14 (4)
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
$ ./gradlew bumpMinorVersion
> Task :app:bumpMinorVersion
Bumping minor version…
0.3.14 (4) → 0.4.0 (5)
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
$ ./gradlew bumpMajorVersion
> Task :app:bumpMajorVersion
Bumping major version…
0.4.0 (5) → 1.0.0 (6)
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
【讨论】:
code 字段的人来说,可能值得链接到Android Versioning doc。但您的代码很容易适应非 Android 项目。
您还可以将 split 与增量矩阵一起使用,可以根据更改的数量进行更改:
def version = '1.0.0'
def incstep = '0.0.1'.split(/\./).collect{it.toInteger()}
def indexedVersionList = version.split(/\./).toList().withIndex()
def updatedVersionList = indexedVersionList.collect{num, idx -> num.toInteger()+incstep[idx]}
def updatedVersion = updatedVersionList.join(".")
【讨论】:
以下解决方案不会在最后一个数字超过 9-10 等时产生问题
version='1.0.11.1001'
task incrementrevsion{
def v = version
println v
String minor=v.substring(v.lastIndexOf('.')+1) //get last digit
int m=minor.toInteger()+1 //increment
println m
String major=v.substring(0,v.lastIndexOf(".")); //get the beginning
println major
String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+ "." +m+"'")
//println s
buildFile.setText(s) //replace the build file's text
}
【讨论】:
这就是我使用 Kotlin DSL (build.gradle.kts) 的方式:
tasks.create("incrementVersion") {
group = "my tasks"
description = "Increments the version in this build file everywhere it is used."
fun generateVersion(): String {
val updateMode = properties["mode"] ?: "minor" // By default, update the minor
val (oldMajor, oldMinor, oldPatch) = version.split(".").map(String::toInt)
var (newMajor, newMinor, newPatch) = arrayOf(oldMajor, oldMinor, 0)
when (updateMode) {
"major" -> newMajor = (oldMajor + 1).also { newMinor = 0 }
"minor" -> newMinor = oldMinor + 1
else -> newPatch = oldPatch + 1
}
return "$newMajor.$newMinor.$newPatch"
}
doLast {
val newVersion = properties["overrideVersion"] as String? ?: generateVersion()
val oldContent = buildFile.readText()
val newContent = oldContent.replace("""= "$version"""", """= "$newVersion"""")
buildFile.writeText(newContent)
}
}
用法:
./gradlew incrementVersion [-P[mode=major|minor|patch]|[overrideVersion=x]]
例子:
./gradlew incrementVersion -Pmode=minor
./gradlew incrementVersion -PoverrideVersion=2.5.11
假设你的构建脚本中有这样的东西:
version = "1.2.3"
...而版本的patch部分只是一个数字(不包含alpha、rc等字母)。
【讨论】:
def patch = version.substring(version.lastIndexOf('.') + 1)
def p = patch.toInteger() + 1
def major = version.substring(0, version.length() - p.toString().length())
def s = buildFile.getText().replaceFirst("version = '$version'", "version = '" + major + p + "'")
buildFile.setText(s)
与 Alexiy 的答案的唯一区别在于第 3 行包含 m.toString().length() 好像次要版本 > 10,即 1.0.12,您将使用该方法将其更改为 1.0.113。我们需要计算次要版本的长度,而不是只砍掉 1 个符号。
还有一件事,通常最后一个数字叫做补丁,小号是中间的:)
【讨论】:
至于我的工作这个解决方案。 您需要将此代码添加到 build.gradle 文件中:
version='1.0.1'
tasks.register("incrementVersion") {
doLast {
def ver = version
println ver
String lastNumber = ver.substring(ver.lastIndexOf('.') + 1)
int increment = lastNumber.toInteger() + 1
println increment
String firstNumber = ver.substring(0, ver.lastIndexOf("."))
println firstNumber
String result = buildFile.getText().replaceFirst("version='$version'","version='" + firstNumber + "." + increment + "'")
buildFile.setText(result)
}
}
【讨论】:
我知道我发布这个很晚,但上面提到的答案在“1.0.99”之前都很好。之后它开始行为不端。
如果有人仍然感兴趣,我找到了另一种方法。
task increment {
def v = buildFile.getText().find(version)
def (major, minor, patch) = v.tokenize('.')
int newPatch = patch.toInteger() + 1
String newVersion = major + "." + minor + "." + newPatch
String updatedVersion = buildFile.getText().replaceFirst("version='"+v+"'","version='"+newVersion+"'")
buildFile.setText(updatedVersion)
}
【讨论】:
这是一个相同想法但使用 KTS(Kotlin 脚本)的示例。
val newVersion: String? by project
tasks.register("bumpVersion") {
this.doFirst {
println("Old version $version")
val newVersion = takeIf { newVersion.isNullOrBlank() }?.let {
val versionArray = version.toString().split(".")
"${versionArray[0]}.${versionArray[1]}.${versionArray.last().toInt().plus(1)}"
} ?: newVersion
buildFile.readText().apply {
println("Bump to $newVersion")
val content = this.replaceFirst("version = \"$version\"", "version = \"$newVersion\"")
buildFile.writeText(content)
}
}
}
自动增加补丁或者可以将新版本作为属性发送。
./gradlew bumpVersion -PnewVersion=0.2.0
【讨论】:
我的解决方案,其中版本将由参数设置。
version = '4.0.0' // I have whitespaces between the equals-sign
task setVersion << {
group = 'Versioning'
description = "Sets the version to the new number specified with -PnewVersion=\'x.x.x\'"
println version
if(project.hasProperty('newVersion')) {
println 'Set Project to new Version '+newVersion
String s=buildFile.getText().replaceFirst("version = '$version'","version = '"+newVersion+"'")
buildFile.setText(s)
}
}
调用 Gradle 任务:
gradle setVersion -PnewVersion='5.1.1'
【讨论】: