Last active
August 2, 2017 19:48
-
-
Save joelanford/5427e54a018171b031ef7fd834f3313b to your computer and use it in GitHub Desktop.
A (not quite working) groovy script to generate a sane version string from a git repository
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env groovy | |
class GitVersion { | |
static String initialVersion = "0.0.1" | |
String repoDir | |
Boolean isGitRepository | |
Boolean hasCommit | |
Boolean isClean | |
String lastTag | |
String lastVersion | |
String lastLabel | |
String nextMajorVersion | |
String nextMinorVersion | |
String nextPatchVersion | |
String branch | |
String commitHash | |
String shortCommitHash | |
Integer commitsSinceLastTag | |
Integer commitsSinceDevelop | |
GitVersion(repoDir) { | |
this.repoDir = repoDir | |
this.isGitRepository = this.initIsGitRepository() | |
if (!this.isGitRepository) { | |
throw new Exception("not a git repository") | |
} | |
this.hasCommit = this.initHasCommit() | |
if (!this.hasCommit) { | |
throw new Exception("repository has no commits") | |
} | |
this.isClean = this.initIsClean() | |
this.lastTag = this.initLastTag() | |
this.lastVersion = this.initLastVersion() | |
this.lastLabel = this.initLastLabel() | |
if (this.lastVersion == "") { | |
this.nextMajorVersion = this.nextMajorVersionFrom(GitVersion.initialVersion) | |
this.nextMinorVersion = this.nextMinorVersionFrom(GitVersion.initialVersion) | |
this.nextPatchVersion = this.nextPatchVersionFrom(GitVersion.initialVersion) | |
} else { | |
this.nextMajorVersion = this.nextMajorVersionFrom(this.lastVersion) | |
this.nextMinorVersion = this.nextMinorVersionFrom(this.lastVersion) | |
this.nextPatchVersion = this.nextPatchVersionFrom(this.lastVersion) | |
} | |
this.branch = this.initBranch() | |
this.commitHash = this.initCommitHash() | |
this.shortCommitHash = this.commitHash[0..Math.min(this.commitHash.length()-1,7)] | |
this.commitsSinceLastTag = this.commitsSince(this.lastTag) | |
this.commitsSinceDevelop = this.commitsSince("develop") | |
} | |
Boolean initIsGitRepository() { | |
def cmd = "git status".execute() | |
cmd.waitFor() | |
return cmd.exitValue() == 0 | |
} | |
Boolean initHasCommit() { | |
return this.initCommitHash() != "HEAD" | |
} | |
Boolean initIsClean() { | |
return "git status --porcelain".execute().text == "" | |
} | |
String initLastTag() { | |
return "git rev-list --tags --no-walk --max-count=1".execute().text.trim() | |
} | |
String initLastVersion() { | |
def lastVersionLabel = "git describe --abbrev=0".execute().text.trim() | |
if (lastVersionLabel == "") { | |
return "" | |
} | |
return lastVersionLabel.tokenize("-")[0] | |
} | |
String initLastLabel() { | |
def lastVersionLabel = "git describe --abbrev=0".execute().text.trim() | |
if (lastVersionLabel == "") { | |
return "" | |
} | |
def lvSplit = lastVersionLabel.tokenize("-") | |
if (lvSplit.size() > 1) { | |
return lvSplit[1..-1].join("-") | |
} else { | |
return "" | |
} | |
} | |
String nextMajorVersionFrom(fromVersion) { | |
def (major, minor, patch) = fromVersion.tokenize(".")*.toInteger() | |
return "${major+1}.0.0" | |
} | |
String nextMinorVersionFrom(fromVersion) { | |
def (major, minor, patch) = fromVersion.tokenize(".")*.toInteger() | |
return "${major}.${minor+1}.0" | |
} | |
String nextPatchVersionFrom(fromVersion) { | |
def (major, minor, patch) = fromVersion.tokenize(".")*.toInteger() | |
return "${major}.${minor}.${patch+1}" | |
} | |
String initBranch() { | |
def branch = "git symbolic-ref HEAD".execute().text.replace("refs/heads/", "").trim() | |
if (branch == "") { | |
branch = "undefined" | |
} | |
return branch | |
} | |
String initCommitHash() { | |
def commitHash = "git rev-parse HEAD".execute().text.trim() | |
if (commitHash == "") { | |
commitHash = "undefined" | |
} | |
return commitHash | |
} | |
Integer commitsSince(rev) { | |
if (rev == "") { | |
return -1 | |
} | |
def commitsSince = "git rev-list ${rev}..HEAD --count".execute().text.trim() | |
if (commitsSince == "") { | |
return -1 | |
} | |
return commitsSince.toInteger() | |
} | |
String masterVersion() { | |
if (this.lastTag == "") { | |
return GitVersion.initialVersion | |
} | |
return this.lastVersion | |
} | |
String masterLabel() { | |
def labelSegments = [this.lastLabel] | |
if (this.commitsSinceLastTag < 0) { | |
labelSegments += this.shortCommitHash | |
} else if (this.commitsSinceLastTag > 0) { | |
labelSegments += "untagged+${this.commitsSinceLastTag}" | |
} | |
return this.joinLabelSegments(labelSegments) | |
} | |
String developVersion() { | |
return this.nextMinorVersion | |
} | |
String developLabel() { | |
def labelSegments = [] | |
if (this.commitsSinceLastTag < 0) { | |
labelSegments += this.shortCommitHash | |
} else if (this.commitsSinceLastTag > 0) { | |
if (lastLabel.startsWith("alpha")) { | |
labelSegments += "${lastLabel}+${this.commitsSinceLastTag}" | |
} else { | |
labelSegments += "alpha0+${this.commitsSinceLastTag}" | |
} | |
} | |
return this.joinLabelSegments(labelSegments) | |
} | |
String releaseCandidateVersion() { | |
return branch - "release/" | |
} | |
String releaseCandidateLabel() { | |
def labelSegments = [] | |
if (this.commitsSinceLastTag < 0) { | |
labelSegments += this.shortCommitHash | |
} else if (this.commitsSinceLastTag > 0) { | |
if (lastLabel.startsWith("beta")) { | |
labelSegments += "${lastLabel}+${this.commitsSinceLastTag}" | |
} else { | |
labelSegments += "beta0+${this.commitsSinceLastTag}" | |
} | |
} | |
return this.joinLabelSegments(labelSegments) | |
} | |
String hotfixVersion() { | |
return branch - "hotfix/" | |
} | |
String hotfixLabel() { | |
return this.releaseCandidateLabel() | |
} | |
String featureVersion() { | |
this.nextMinorVersion | |
} | |
String featureLabel() { | |
def feature = (this.branch - "feature/").toLowerCase().replace("-", "_") | |
return this.joinLabelSegments(["feature-${feature}", this.shortCommitHash]) | |
} | |
String joinLabelSegments(segments) { | |
segments.removeAll([""]) | |
if (segments.size() == 0) { | |
return "" | |
} | |
return "-${segments.join("-")}" | |
} | |
void printInfo() { | |
println "Is Git Repository: ${this.isGitRepository}" | |
println "Has commit: ${this.hasCommit}" | |
println "Last version: ${this.lastVersion}" | |
println "Last label: ${this.lastLabel}" | |
println "Next major version: ${this.nextMajorVersion}" | |
println "Next minor version: ${this.nextMinorVersion}" | |
println "Next patch version: ${this.nextPatchVersion}" | |
println "Branch: ${this.branch}" | |
println "Commit hash: ${this.commitHash}" | |
println "Is Clean: ${this.isClean}" | |
println "Last tag: ${this.lastTag}" | |
println "Commits since last tag: ${this.commitsSinceLastTag}" | |
println "Commits since develop: ${this.commitsSinceDevelop}" | |
} | |
String computedVersionLabel() { | |
def version = "" | |
def label = "" | |
if (commitsSinceLastTag == 0) { | |
version = this.lastVersion | |
label = this.joinLabelSegments([this.lastLabel]) | |
} else if (branch == "master") { | |
version = this.masterVersion() | |
label = this.masterLabel() | |
} else if (branch == "develop") { | |
version = this.developVersion() | |
label = this.developLabel() | |
} else if (branch.startsWith("release/")) { | |
version = this.releaseCandidateVersion() | |
label = this.releaseCandidateLabel() | |
} else if (branch.startsWith("hotfix/")) { | |
version = this.hotfixVersion() | |
label = this.hotfixLabel() | |
} else if (branch.startsWith("feature/")) { | |
version = this.featureVersion() | |
label = this.featureLabel() | |
} else { | |
throw new Exception("unsupported branch name!") | |
} | |
if (!isClean) { | |
label += "-dirty" | |
} | |
return "${version}${label}" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment