私は広範囲にわたって検索しましたが、Android StudioとGradleの新しさのためと考えられます。これを行う方法の説明は見つかりませんでした。基本的には、 この投稿 、ただしAndroid Eclipse、LinuxではなくStudio、Gradle、Windowsを使用。
最近牽引力を獲得した結果を達成するためのより適切で無駄のない方法は、 Groovy JGitバインディング を介して gradle git integration を使用することです。 JGitを使用しているため、動作するためにgitをインストールする必要さえありません。
同様の(ただしgitVersionName文字列にいくつかの追加情報を含む)ソリューションを示す基本的な例を次に示します。
buildscript {
dependencies {
classpath 'org.ajoberstar:grgit:1.4.+'
}
}
ext {
git = org.ajoberstar.grgit.Grgit.open()
gitVersionCode = git.tag.list().size()
gitVersionName = "${git.describe()}"
}
Android {
defaultConfig {
versionCode gitVersionCode
versionName gitVersionName
}
}
[...]
Grgit APIドキュメント で確認できるように、 describe operation は、履歴で到達可能な最新のタグ以外の追加情報を提供します。
HEADから到達可能な最新のタグを見つけます。タグがコミットを指す場合、タグのみが表示されます。それ以外の場合は、タグ付けされたオブジェクトの上に追加のコミットの数を付けたタグ名と、最新のコミットの省略されたオブジェクト名の接尾辞を付けます。
とにかく、状態が汚れているかどうかはわかりません。この情報は、リポジトリの クリーンステータス を確認し、クリーンでない場合は文字列を追加することで簡単に追加できます。
プロジェクトのbuild.gradleファイルに以下を追加します。マニフェストを直接変更する必要はありません。Googleは構成に必要なフックを提供しました。
def getVersionCode = { ->
try {
def code = new ByteArrayOutputStream()
exec {
commandLine 'git', 'tag', '--list'
standardOutput = code
}
return code.toString().split("\n").size()
}
catch (ignored) {
return -1;
}
}
def getVersionName = { ->
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags', '--dirty'
standardOutput = stdout
}
return stdout.toString().trim()
}
catch (ignored) {
return null;
}
}
Android {
defaultConfig {
versionCode getVersionCode()
versionName getVersionName()
}
}
Gitがマシンにインストールされていない場合、またはバージョン名/コードの取得中に他のエラーが発生した場合は、デフォルトでAndroidマニフェストにあるものになります。
moveaway00の回答 と その回答に関するAvinash Rのコメント を確認した後、私はこれを使用してしまいました。
apply plugin: 'Android'
def getVersionCode = { ->
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-list', '--first-parent', '--count', 'master'
standardOutput = stdout
}
return Integer.parseInt(stdout.toString().trim())
}
catch (ignored) {
return -1;
}
}
def getVersionName = { ->
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags', '--dirty'
standardOutput = stdout
}
return stdout.toString().trim()
}
catch (ignored) {
return null;
}
}
Android {
defaultConfig {
versionCode getVersionCode()
versionName getVersionName()
}
}
Moveaway00のコードを編集して、Avinash Rのコメントも含めました。バージョンコードは、バージョンコードが想定されているものであるため、master
以降のコミット数になりました。
マニフェストでバージョンコードとバージョン名を指定する必要がないことに注意してください。Gradleが処理しました。
さらに別の方法:
https://github.com/gladed/gradle-Android-git-version は、Android対応のバージョン名とバージョンコードを自動的に計算する新しいGradleプラグインです。
承認済みのソリューションでは不可能な多くの特殊なケースを処理します。
免責事項:私はそれを書きました。
コマンドラインにアクセスするには、関数ではなくステートメントを必要とする別のソリューションを次に示します。 警告:* nixのみのソリューション
def gitSha = 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()
// Auto-incrementing commit count based on counting commits to master (Build #543)
def commitCount = Integer.parseInt('git rev-list master --count'.execute([], project.rootDir).text.trim())
// I want to use git tags as my version names (1.2.2)
def gitCurrentTag = 'git describe --tags --abbrev=0'.execute([], project.rootDir).text.trim()
Android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.some.app"
minSdkVersion 16
targetSdkVersion 22
versionCode commitCount
versionName gitCurrentTag
buildConfigField "String", "GIT_SHA", "\"${gitSha}\""
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
}
}
}
Android Studio(Gradle):を使用した別の方法:このブログ投稿を確認してください: http:/ /blog.Android-develop.com/2014/09/automatic-versioning-and-increment.html
これがブログの実装です:
Android {
defaultConfig {
...
// Fetch the version according to git latest tag and "how far are we from last tag"
def longVersionName = "git -C ${rootDir} describe --tags --long".execute().text.trim()
def (fullVersionTag, versionBuild, gitSha) = longVersionName.tokenize('-')
def(versionMajor, versionMinor, versionPatch) = fullVersionTag.tokenize('.')
// Set the version name
versionName "$versionMajor.$versionMinor.$versionPatch($versionBuild)"
// Turn the version name into a version code
versionCode versionMajor.toInteger() * 100000 +
versionMinor.toInteger() * 10000 +
versionPatch.toInteger() * 1000 +
versionBuild.toInteger()
// Friendly print the version output to the Gradle console
printf("\n--------" + "VERSION DATA--------" + "\n" + "- CODE: " + versionCode + "\n" +
"- NAME: " + versionName + "\n----------------------------\n")
...
}
}
それが何らかの助けになれば、GitタグとGit説明を使用してこれを実現するGradleスクリプトの例を設定しました。ここにコードがあります(それを見つけることもできます here )。
1)最初にversioning.gradleファイルを作成します:
import Java.text.SimpleDateFormat
/**
* This Gradle script relies on Git tags to generate versions for your Android app
*
* - The Android version NAME is specified in the tag name and it's 3 digits long (example of a valid tag name: "v1.23.45")
* If the tag name is not in a valid format, then the version name will be 0.0.0 and you should fix the tag.
*
* - The Android version CODE is calculated based on the version name (like this: (major * 1000000) + (minor * 10000) + (patch * 100))
*
* - The 4 digits version name is not "public" and the forth number represents the number of commits from the last tag (example: "1.23.45.178")
*
*/
ext {
getGitSha = {
return 'git rev-parse --short HEAD'.execute().text.trim()
}
getBuildTime = {
def df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'")
df.setTimeZone(TimeZone.getTimeZone("UTC"))
return df.format(new Date())
}
/**
* Git describe returns the following: [GIT_TAG_NAME]-[BUILD_NUMBER]-[GIT_SHA]
*/
getAndroidGitDescribe = {
return "git -C ${rootDir} describe --tags --long".execute().text.trim()
}
/**
* Returns the current Git branch name
*/
getGitBranch = {
return "git rev-parse --abbrev-ref HEAD".execute().text.trim()
}
/**
* Returns the full version name in the format: MM.mm.pp.ccc
*
* The version name is retrieved from the tag name which must be in the format: vMM.mm.pp, example: "v1.23.45"
*/
getFullVersionName = {
def versionName = "0.0.0.0"
def (tag, buildNumber, gitSha) = getAndroidGitDescribe().tokenize('-')
if (tag && tag.startsWith("v")) {
def version = tag.substring(1)
if (version.tokenize('.').size() == 3) {
versionName = version + '.' + buildNumber
}
}
return versionName
}
/**
* Returns the Android version name
*
* Format "X.Y.Z", without commit number
*/
getAndroidVersionName = {
def fullVersionName = getFullVersionName()
return fullVersionName.substring(0, fullVersionName.lastIndexOf('.'))
}
/**
* Returns the Android version code, deducted from the version name
*
* Integer value calculated from the version name
*/
getAndroidVersionCode = {
def (major, minor, patch) = getAndroidVersionName().tokenize('.')
(major, minor, patch) = [major, minor, patch].collect{it.toInteger()}
return (major * 1000000) + (minor * 10000) + (patch * 100)
}
/**
* Return a pretty-printable string containing a summary of the version info
*/
getVersionInfo = {
return "\nVERSION INFO:\n\tFull version name: " + getFullVersionName() +
"\n\tAndroid version name: " + getAndroidVersionName() +
"\n\tAndroid version code: " + getAndroidVersionCode() +
"\n\tAndroid Git branch: " + getGitBranch() +
"\n\tAndroid Git describe: " + getAndroidGitDescribe() +
"\n\tGit SHA: " + getGitSha() +
"\n\tBuild Time: " + getBuildTime() + "\n"
}
// Print version info at build time
println(getVersionInfo());
}
2)次に、app/build.gradleを編集して、次のように使用します。
import groovy.json.StringEscapeUtils;
apply plugin: 'com.Android.application' // << Apply the plugin
Android {
configurations {
// ...
}
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 17
targetSdkVersion 22
applicationId "app.example.com"
versionCode getAndroidVersionCode() // << Use the plugin!
versionName getAndroidVersionName() // << Use the plugin!
// Build config constants
buildConfigField "String", "GIT_SHA", "\"${getGitSha()}\""
buildConfigField "String", "BUILD_TIME", "\"${getBuildTime()}\""
buildConfigField "String", "FULL_VERSION_NAME", "\"${getVersionName()}\""
buildConfigField "String", "VERSION_DESCRIPTION", "\"${StringEscapeUtils.escapeJava(getVersionInfo())}\""
}
signingConfigs {
config {
keyAlias 'MyKeyAlias'
keyPassword 'MyKeyPassword'
storeFile file('my_key_store.keystore')
storePassword 'MyKeyStorePassword'
}
}
buildTypes {
debug {
minifyEnabled false
debuggable true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
debuggable false
}
}
productFlavors {
// ...
}
dependencies {
// ...
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
/**
* Save a build.info file
*/
task saveBuildInfo {
def buildInfo = getVersionInfo()
def assetsDir = Android.sourceSets.main.assets.srcDirs.toArray()[0]
assetsDir.mkdirs()
def buildInfoFile = new File(assetsDir, 'build.info')
buildInfoFile.write(buildInfo)
}
gradle.projectsEvaluated {
assemble.dependsOn(saveBuildInfo)
}
最も重要な部分はプラグインを適用することです
apply plugin: 'com.Android.application'
そして、それをAndroidバージョン名とコードに使用します
versionCode getAndroidVersionCode()
versionName getAndroidVersionName()
LéoLam's answer と以前の explorations に基づいて、antの同じ解決策に基づいて、純粋なクロスプラットフォームjgitを使用したソリューション:
(オリジナル ソース )
ファイル:git-version.gradle
buildscript {
dependencies {
//noinspection GradleDynamicVersion
classpath "org.Eclipse.jgit:org.Eclipse.jgit:4.1.1.+"
}
repositories {
jcenter()
}
}
import org.Eclipse.jgit.api.Git
import org.Eclipse.jgit.revwalk.RevWalk
import org.Eclipse.jgit.storage.file.FileRepositoryBuilder
import static org.Eclipse.jgit.lib.Constants.MASTER
def git = Git.wrap(new FileRepositoryBuilder()
.readEnvironment()
.findGitDir()
.build())
ext.readVersionCode = {
def repo = git.getRepository()
def walk = new RevWalk(repo)
walk.withCloseable {
def head = walk.parseCommit(repo.getRef(MASTER).getObjectId())
def count = 0
while (head != null) {
count++
def parents = head.getParents()
if (parents != null && parents.length > 0) {
head = walk.parseCommit(parents[0])
} else {
head = null
}
}
walk.dispose()
println("using version name: $count")
return count
}
}
ext.readVersionName = {
def tag = git.describe().setLong(false).call()
def clean = git.status().call().isClean()
def version = tag + (clean ? '' : '-dirty')
println("using version code: $version")
return version
}
使用法は次のとおりです。
apply from: 'git-version.gradle'
Android {
...
defaultConfig {
...
versionCode readVersionCode()
versionName readVersionName()
...
}
...
}
これは Diego's answer のわずかに変更されたバージョンであり、バージョン名を次のスタイルにしたいという私の願望を満たしています。
{最新のタグ}-{現在のコミットの短いハッシュ}-{現在のコミットの時間}
import Java.text.SimpleDateFormat
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.ajoberstar.grgit:grgit-core:3.1.1'
}
}
/**
* Version name will be in following format:
*
* "{latest release tag}-{short commit hash of current commit}-{time of current commit}"
*
* Example: 1.6.0-5ae9b86-2019-07-04-13:20
*/
ext {
git = org.ajoberstar.grgit.Grgit.open(currentDir: projectDir)
listOfTags = git.tag.list()
noTags = listOfTags.isEmpty()
head = git.head()
if (noTags) {
gitVersionCode = 0
gitVersionName = "no-tag-${head.abbreviatedId}-${head.time}"
} else {
tagNames = listOfTags.collect { git.describe(commit: it.commit, tags: true) }
mostRecentVersion = mostRecentVersion(tagNames)
def date = new SimpleDateFormat('yyyy-MM-dd-HH:mm').format(new Date(head.time * 1000))
gitVersionCode = listOfTags.size()
gitVersionName = "$mostRecentVersion-${head.abbreviatedId}-${date}"
}
}
/**
* Shamelessly stolen from <a href="https://stackoverflow.com/a/7723766/">StackOverflow</a>.
*/
static String mostRecentVersion(List versions) {
def sorted = versions.sort(false) { a, b ->
List verA = a.tokenize('.')
List verB = b.tokenize('.')
def commonIndices = Math.min(verA.size(), verB.size())
for (int i = 0; i < commonIndices; ++i) {
def numA = verA[i].toInteger()
def numB = verB[i].toInteger()
if (numA != numB) {
return numA <=> numB
}
}
// If we got this far then all the common indices are identical, so whichever version is longer must be more recent
verA.size() <=> verB.size()
}
// println "Sorted versions: $sorted"
sorted[-1]
}
task printVersion() {
println("Version Code: $gitVersionCode")
println("Version Name: $gitVersionName")
}
versionNameSuffix
モジュールのbuild.gradle
でapp
も次のように指定したと仮定します。
Android {
...
productFlavors {
debug {
versionCode gitVersionCode
versionName gitVersionName
versionNameSuffix '-DEBUG'
...
}
// ... other flavors here
}
}
次に、これはバージョン名になります。
Gradleファイルで単純な関数を定義します。
def getVersion(){
def out = new ByteArrayOutputStream();
exec {
executable = 'git'
args = ['describe', '--tags']
standardOutput = out
}
return out.toString().replace('\n','')
}
これを使って:
project.version = getVersion()