Created
February 8, 2017 14:51
-
-
Save dos65/898f3c8a09b1a7178cfbb683b8141a87 to your computer and use it in GitHub Desktop.
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
import sbt._ | |
import sbt.Keys._ | |
import complete.DefaultParsers._ | |
import ComponentVersionsKeys._ | |
object ComponentVersionsKeys { | |
lazy val versionFile = settingKey[File]("Version file") | |
lazy val projectTagName = settingKey[String]("Project name for tag naming") | |
lazy val latestRelease = settingKey[Semver]("Latest project release") | |
lazy val latestTagName = settingKey[String]("Latest tag name for project") | |
lazy val release = inputKey[Unit]("Release task") | |
} | |
object ComponentVersions { | |
val DefaultVersion = Semver("0.0.1") | |
lazy val settings = Seq( | |
versionFile <<= baseDirectory( _ / "version" ), | |
latestRelease <<= Def.setting({ | |
val f = versionFile.value | |
IO.touch(f, false) | |
val content = IO.readLines(f) | |
content.headOption.map(Semver(_)) | |
.getOrElse({ | |
IO.write(f, DefaultVersion.toString) | |
DefaultVersion | |
}) | |
}), | |
latestTagName := projectTagName.value + "_" + latestRelease.value.toString, | |
version <<= Def.setting({ | |
val v = latestRelease.value.toString | |
val expected = latestTagName.value | |
val isTag = Git.pointsAtTags.contains(expected) | |
if (isTag) { | |
v | |
} else { | |
val sha = Git.head.substring(0, 9) | |
s"$v-$sha" | |
} | |
}), | |
release := { | |
val log = streams.value.log | |
val args = spaceDelimited("<arg>").parsed | |
val number = args.headOption match { | |
case Some("major") => Major | |
case Some("minor") => Minor | |
case Some("patch") => Patch | |
case _ => sys.error("You must specify number to bump. Possible values: major, minor, patch") | |
} | |
val next = latestRelease.value.bump(number).toString | |
log.info(s"Next version: $next") | |
val f = versionFile.value | |
IO.write(f, next) | |
Git.add() | |
Git.commit(s"Release $next for ${projectTagName.value}") | |
Git.push(Git.currentBranch) | |
val tagName = projectTagName.value + "_" + next | |
Git.tag(tagName) | |
Git.push(tagName) | |
} | |
) | |
} | |
object Git { | |
def add(): Unit = | |
Seq("git", "add", ".") ! | |
def commit(description: String): Unit = | |
Seq("git", "commit", "-n" , "-m", description) ! | |
def tag(name: String): Unit = | |
Seq("git", "tag", name) ! | |
def push(ref: String): Unit = | |
Seq("git", "push", "origin", ref) ! | |
def head: String = | |
(Seq("git", "rev-parse", "HEAD") !!).trim | |
def pointsAtTags: List[String] = | |
(Seq("git", "tag", "-l", "--points-at", "HEAD") !!).split("\n").toList | |
def currentBranch: String = | |
(Seq("git", "rev-parse", "--abbrev-ref", "HEAD")!!).trim | |
} | |
sealed trait VersionNumber | |
case object Major extends VersionNumber | |
case object Minor extends VersionNumber | |
case object Patch extends VersionNumber | |
case class Semver( | |
major: Int, | |
minor: Int, | |
patch: Int) { | |
def bump(n: VersionNumber): Semver = n match { | |
case Major => copy(major = major + 1, minor = 0, patch = 0) | |
case Minor => copy(minor = minor + 1, patch = 0) | |
case Patch => copy(patch = patch + 1) | |
} | |
override def toString: String = s"$major.$minor.$patch" | |
} | |
object Semver { | |
import scala.util.matching.Regex | |
private val pattern = ("\\s*[v=]*\\s*(\\d+)" // major | |
+ "\\.(\\d+)" // minor | |
+ "\\.(\\d+)" // patch | |
+ "(-\\d+-?)?" // build | |
+ "([a-zA-Z-+][a-zA-Z0-9-\\.:]*)?")r // tag | |
def apply(s: String): Semver = pattern.findFirstMatchIn(s) match { | |
case Some(m) => toSemver(m) | |
case None => throw new IllegalArgumentException(s"Invalid semver string:$version") | |
} | |
private def toSemver(m: Regex.Match): Semver = { | |
val groups = m.subgroups | |
Semver( | |
groups(0).toInt, | |
groups(1).toInt, | |
groups(2).toInt | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment