Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ androidx-annotation = "androidx.annotation:annotation:1.7.1"
androidx-lifecycle-common = "androidx.lifecycle:lifecycle-common:2.7.0"
android-build-gradle = "com.android.tools.build:gradle:9.1.0"
android-support-appcompat = "com.android.support:appcompat-v7:28.0.0"
gradle-git = "org.ajoberstar:gradle-git:1.2.0"
groovy-test = "org.apache.groovy:groovy-test:4.0.31"
gson = "com.google.code.gson:gson:2.13.2"
j-ogg-vorbis = "com.github.stephengold:j-ogg-vorbis:1.0.6"
Expand Down
71 changes: 29 additions & 42 deletions version.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@

import java.text.SimpleDateFormat
import org.ajoberstar.grgit.*

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath libs.gradle.git
}
}

ext {
jmeRevision = 0
Expand All @@ -22,8 +12,18 @@ ext {
jmeVersionTag="SNAPSHOT"
}

task configureVersionInfo {
try {
def gitOutput = { List<String> args ->
def output = providers.exec {
commandLine(['git'] + args)
ignoreExitValue = true
}
if (output.result.get().exitValue == 0) {
return output.standardOutput.asText.get().trim()
}
return ""
}

try {
// Users can configure behavior by setting properties on the command
// line:
//
Expand All @@ -39,43 +39,32 @@ task configureVersionInfo {
// Set to true if a non-master branch name should be included in the automatically
// generated version.

def grgit = Grgit.open(project.file('.'))
def head = grgit.head()
jmeRevision = grgit.log(includes: [head]).size()
jmeGitHash = head.id
jmeShortGitHash = head.abbreviatedId
jmeBranchName = grgit.branch.current.name
def revisionOutput = gitOutput(['rev-list', '--count', 'HEAD'])
jmeRevision = revisionOutput ? revisionOutput.toInteger() : 0
jmeGitHash = gitOutput(['rev-parse', 'HEAD'])
jmeShortGitHash = gitOutput(['rev-parse', '--short=7', 'HEAD'])
jmeBranchName = gitOutput(['branch', '--show-current']) ?: gitOutput(['rev-parse', '--abbrev-ref', 'HEAD']) ?: "unknown"

// This code will find an exact-match tag if the current
// commit is the same as the tag commit.
jmeGitTag = grgit.tag.list().find { it.commit == head }
jmeGitTag = gitOutput(['describe', '--tags', '--exact-match', 'HEAD'])
def latestTag;
if( jmeGitTag ) {
// Just use the name. We keep jmeGitTag separate because there
// is some logic that wants to know if this specific commit has
// a tag versus 'whatever tag we are a child of'... which is what
// 'latestTag' will be.
jmeGitTag = jmeGitTag.name
latestTag = jmeGitTag;
} else {
// Use describe to find the most recent tag. Unfortunately,
// in this version of grgit, we don't have the 'always' options
// so we can't make as many assumptions about the format of the
// string.
// If the commit is an exact match then it will return just the
// tag name... else it will be tagName-commitCount-abbreviatedId
// We'll use some groovy regex magic to get the tag either way.
def describe = grgit.describe()
// If the commit is an exact match then this returns just the tag
// name, else it returns tagName-commitCount-abbreviatedId.
def describe = gitOutput(['describe', '--tags', '--abbrev=7', 'HEAD'])
def fullDescribe = (describe =~/(.*?)-(\d+)-g$jmeShortGitHash/)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The regex uses $jmeShortGitHash which is derived from git rev-parse --short=7. However, git describe might use a longer hash if 7 characters are ambiguous in the repository. If describe contains a longer hash than jmeShortGitHash, the regex match might fail because of the implicit anchoring or the specific sequence expected. Consider allowing for additional hex characters after the hash or ensuring the lengths match.

            def fullDescribe = (describe =~ /(.*?)-(\d+)-g${jmeShortGitHash}[0-9a-f]*/)

latestTag = fullDescribe ? fullDescribe[0][1] : describe
println "Latest tag:" + latestTag
}

// We could enhance this with some more regex if we wanted to sanity
// check that it was formatted like our versions.
def tagVersion = (latestTag =~/v?(.*)/)[0][1];
def tagVersion = latestTag ? (latestTag =~/v?(.*)/)[0][1] : jmeVersion;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The regex v?(.*) will always match any non-null string (even an empty one), but accessing [0][1] on the matcher result can be risky if the regex engine behaves unexpectedly or if the Groovy version changes. While latestTag is checked for truthiness, a more robust way to handle the optional 'v' prefix and capture the version part would be using replaceFirst or a more explicit match check.

        def tagVersion = latestTag ? latestTag.replaceFirst(/^v/, "") : jmeVersion;

// If the branch is not master then use the tag.
if( jmeBranchName != "master" ) {
if( jmeBranchName != "master" && latestTag ) {
jmeVersion = tagVersion
}

Expand All @@ -97,9 +86,8 @@ task configureVersionInfo {
// real CI builds should be using non-SNAPSHOT versions so we may
// eventually want to change the script to always use -SNAPSHOT with
// a CI option to turn it off.
// We could also check the grgit.status for unstaged modified/removed files.
// def unstaged = grgit.status().unstaged;
// def modCount = unstaged.modified.size() + unstaged.removed.size()
// We could also check for unstaged modified/removed files.
// def modCount = ...
// ...but that seems like a wasteful check considering only official
// version builds should not have a -SNAPSHOT.

Expand Down Expand Up @@ -137,9 +125,8 @@ task configureVersionInfo {
println("Build Suffix: ${jmeVersionTag}")
println("Build Version: ${jmeFullVersion}")

} catch (ex) {
// Failed to get repo info
logger.warn("Failed to get repository info: " + ex.message + ". " + \
"Only partial build info will be generated.")
}
} catch (ex) {
// Failed to get repo info
logger.warn("Failed to get repository info: " + ex.message + ". " + \
"Only partial build info will be generated.")
}