Skip to content

Instantly share code, notes, and snippets.

@davideicardi
Last active August 31, 2020 10:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davideicardi/694c4fc92dbe42b34ebd752139dc9bc1 to your computer and use it in GitHub Desktop.
Save davideicardi/694c4fc92dbe42b34ebd752139dc9bc1 to your computer and use it in GitHub Desktop.
Calculate version for an SBT project
/*
Calculate project's version using GIT tags and commits.
Main idea is to avoid having a version written in the source code but instead link it to the GIT repository.
It is similar to sbt-git plugin but increment the PATCH part when there are additional commits.
The version is calculated using the last tag and the last commit (using `git describe` output).
If there is at least one commit after the last tag the PATCH part is incremented by 1
and `-SNAPSHOT` is added as a suffix.
Otherwise the tag is used as is.
Also add as a last version part a BUILD_NUMBER environment variable or 0.
Requirements:
- tag should be in the format `vMAJOR.MINOR.PATCH` following semantic versioning
Usage:
Copy the content of this file inside `./project/AutoVersion.scala`
Put the following code inside `build.sbt` or in a dedicated version.sbt file:
```
import AutoVersion._
version in ThisBuild := autoVersion()
```
To check how version is calculated in your project you can use `sbt "show version"`
Possible improvements:
- Check if GIT is installed, if not return a default version
- If there are changes or untracked or unstaged files and in this case consider it a snapshot and increment always PATCH (plus adding a warning?)
- Conside BUILD_NUMBER optional
- Check if "git describe" commands works always as expected, in all cases.
*/
object AutoVersion {
def autoVersion(): String = {
val gitVersionPattern = "^v([0-9]+\\.[0-9]+\\.[0-9]+)(-.+)?$".r
getGitVersion() match {
case gitVersionPattern(tagVersion, null) => // example: v0.2.4
s"${tagVersion}.${getCIBuildNumber}"
case gitVersionPattern(tagVersion, suffix) => // example: v0.2.4-2-g009ed65 or v0.2.4-beta
if (isSnapshot) {
val newVersion = incrementVersion(tagVersion)
s"${newVersion}.${getCIBuildNumber}${suffix}-SNAPSHOT"
} else {
s"${tagVersion}.${getCIBuildNumber}${suffix}"
}
}
}
def incrementVersion(version: String): String = {
val versionPattern = "^([0-9]+).([0-9]+).([0-9]+)$".r
val versionPattern(major, minor, patch) = version
val nextPatch = (patch.toInt + 1).toString
s"${major}.${minor}.${nextPatch}"
}
def getGitVersion(): String = {
import scala.sys.process.Process
val process = Process("git describe")
process.lineStream.head
}
def getGitVersionTag(): String = {
import scala.sys.process.Process
val process = Process("git describe --abbrev=0")
process.lineStream.head
}
def isSnapshot(): Boolean = {
getGitVersionTag() != getGitVersion()
}
def getCIBuildNumber(): Int = Option(System.getenv("BUILD_NUMBER")) match {
case Some(ref) => ref.toInt
case None => 0
}
}
import AutoVersion._
version in ThisBuild := autoVersion()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment