First complete plugin implementation.
This commit is contained in:
parent
2c7ceabe7a
commit
73f35a406d
7 changed files with 221 additions and 20 deletions
|
@ -8,7 +8,7 @@ externalResolvers := Seq(
|
|||
)
|
||||
|
||||
val ProjectName: String = "sbt-gs-calver"
|
||||
val Description: String = "SBT 1.9.0+ plugin for Git-based semantic versioning."
|
||||
val Description: String = "SBT 1.9.0+ plugin for calendar versioning."
|
||||
|
||||
def getProperty[A](
|
||||
name: String,
|
||||
|
|
|
@ -1 +1 @@
|
|||
sbt.version=1.9.8
|
||||
sbt.version=1.9.9
|
||||
|
|
|
@ -1,6 +1,169 @@
|
|||
package gs
|
||||
|
||||
case class CalVer(value: String)
|
||||
import java.time.LocalDate
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
||||
/**
|
||||
* Representation of a rendered Calendar Version.
|
||||
*
|
||||
* @param value The version string.
|
||||
* @param pattern The pattern which rendered the version string.
|
||||
*/
|
||||
case class CalVer(
|
||||
value: String,
|
||||
pattern: CalVer.Pattern
|
||||
)
|
||||
|
||||
object CalVer {
|
||||
/**
|
||||
* Render the given pattern to a Calendar Version.
|
||||
*
|
||||
* @param pattern The pattern to render.
|
||||
* @return The rendered CalVer value.
|
||||
*/
|
||||
def render(pattern: Pattern): CalVer = {
|
||||
val today = LocalDate.now()
|
||||
CalVer(
|
||||
value = pattern.items.map {
|
||||
case Left(component) =>
|
||||
component match {
|
||||
case Component.YYYY => today.getYear().toString()
|
||||
case Component.MM => today.getMonthValue().toString()
|
||||
case Component.DD => today.getDayOfMonth().toString()
|
||||
case Component.Label(label) => label
|
||||
case Component.GitSha(length) => Git.getSha(length)
|
||||
}
|
||||
case Right(delimiter) => Delimiter.render(delimiter)
|
||||
}.mkString,
|
||||
pattern = pattern
|
||||
)
|
||||
}
|
||||
|
||||
object Defaults {
|
||||
/**
|
||||
* Default pattern for release versions.
|
||||
*/
|
||||
val ReleasePattern: Pattern =
|
||||
Pattern
|
||||
.builder(Component.YYYY)
|
||||
.addDelimiter(Delimiter.Dot)
|
||||
.addComponent(Component.MM)
|
||||
.addDelimiter(Delimiter.Dot)
|
||||
.addComponent(Component.DD)
|
||||
.addDelimiter(Delimiter.Hyphen)
|
||||
.addComponent(Component.GitSha(7))
|
||||
.build()
|
||||
|
||||
/**
|
||||
* Default pattern for pre-release versions.
|
||||
*/
|
||||
val PreReleasePattern: Pattern =
|
||||
Pattern
|
||||
.builder(Component.YYYY)
|
||||
.addDelimiter(Delimiter.Dot)
|
||||
.addComponent(Component.MM)
|
||||
.addDelimiter(Delimiter.Dot)
|
||||
.addComponent(Component.DD)
|
||||
.addDelimiter(Delimiter.Hyphen)
|
||||
.addComponent(Component.Label("SNAPSHOT"))
|
||||
.build()
|
||||
}
|
||||
|
||||
sealed trait Component
|
||||
|
||||
object Component {
|
||||
/**
|
||||
* CalVer Component: Year.
|
||||
*/
|
||||
case object YYYY extends Component
|
||||
|
||||
/**
|
||||
* CalVer Component: Month (1-12), without a leading zero.
|
||||
*/
|
||||
case object MM extends Component
|
||||
|
||||
/**
|
||||
* CalVer Component: Day of Month, without a leading zero.
|
||||
*/
|
||||
case object DD extends Component
|
||||
|
||||
/**
|
||||
* CalVer Component: Label.
|
||||
*
|
||||
* This component contains an arbitrary string value.
|
||||
*
|
||||
* @param value The value of the label.
|
||||
*/
|
||||
case class Label(value: String) extends Component
|
||||
|
||||
/**
|
||||
* CalVer Component. Git SHA.
|
||||
*
|
||||
* This component defines the length (first N characters) of the Git SHA to
|
||||
* take from the current branch of the current repository. An empty string
|
||||
* is used if lookup fails or no commits exist.
|
||||
*
|
||||
* @param length The number of characters of the Git SHA to use.
|
||||
*/
|
||||
case class GitSha(length: Int) extends Component
|
||||
|
||||
def describe(component: Component): String = component match {
|
||||
case YYYY => "YYYY"
|
||||
case MM => "MM"
|
||||
case DD => "DD"
|
||||
case Label(value) => value
|
||||
case GitSha(length) => s"SHA($length)"
|
||||
}
|
||||
}
|
||||
|
||||
sealed abstract class Delimiter(val value: String)
|
||||
|
||||
object Delimiter {
|
||||
case object Dot extends Delimiter(".")
|
||||
case object Hyphen extends Delimiter("-")
|
||||
case object Plus extends Delimiter("+")
|
||||
case object Underscore extends Delimiter("_")
|
||||
|
||||
def render(delimiter: Delimiter): String = delimiter.value
|
||||
}
|
||||
|
||||
final class Pattern private (val items: List[Pattern.Item]) {
|
||||
lazy val str: String =
|
||||
items.map {
|
||||
case Left(component) => Component.describe(component)
|
||||
case Right(delimiter) => Delimiter.render(delimiter)
|
||||
}.mkString
|
||||
|
||||
override def toString(): String = str
|
||||
}
|
||||
|
||||
object Pattern {
|
||||
private type Item = Either[Component, Delimiter]
|
||||
|
||||
def builder(component: Component): Builder = Builder(component)
|
||||
|
||||
final class Builder private () {
|
||||
private val buffer: ListBuffer[Item] = new ListBuffer()
|
||||
|
||||
def addComponent(component: Component): Builder = {
|
||||
val _ = buffer.append(Left(component))
|
||||
this
|
||||
}
|
||||
|
||||
def addDelimiter(delimiter: Delimiter): Builder = {
|
||||
val _ = buffer.append(Right(delimiter))
|
||||
this
|
||||
}
|
||||
|
||||
def build(): Pattern = new Pattern(buffer.toList)
|
||||
}
|
||||
|
||||
object Builder {
|
||||
def apply(component: Component): Builder = {
|
||||
val b = new Builder()
|
||||
b.addComponent(component)
|
||||
b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,31 @@ object CalVerKeys {
|
|||
"Calculated CalVer."
|
||||
)
|
||||
|
||||
/**
|
||||
* SBT setting which defines the CalVer pattern used to calculate the final
|
||||
* version. This should not be set manually, please use
|
||||
* `calVerReleasePattern` and `calVerPreReleasePattern`.
|
||||
*/
|
||||
lazy val calVerPattern = settingKey[CalVer.Pattern](
|
||||
"Selected CalVer pattern."
|
||||
)
|
||||
|
||||
/**
|
||||
* User-defined SBT setting which defines the CalVer pattern to use for a
|
||||
* release build.
|
||||
*/
|
||||
lazy val calVerReleasePattern = settingKey[Option[CalVer.Pattern]](
|
||||
"Pattern to use for calculating CalVer for release builds."
|
||||
)
|
||||
|
||||
/**
|
||||
* User-defined SBT setting which defines the CalVer pattern to use for a
|
||||
* pre-release build.
|
||||
*/
|
||||
lazy val calVerPreReleasePattern = settingKey[Option[CalVer.Pattern]](
|
||||
"Pattern to use for calculating CalVer for pre-release builds."
|
||||
)
|
||||
|
||||
/** Task which emits the current version at the informational log level.
|
||||
*/
|
||||
lazy val calVerInfo = taskKey[Unit](
|
||||
|
|
|
@ -11,9 +11,22 @@ object CalVerPlugin extends AutoPlugin {
|
|||
|
||||
// Perform all version calculations and expose as a variable.
|
||||
lazy val calVerDefaults: Seq[Setting[_]] = {
|
||||
// Expose the relevant values as setting keys.
|
||||
val isRelease = PluginProperties.isRelease()
|
||||
Seq(
|
||||
calVer := ""
|
||||
calVerReleasePattern := calVerReleasePattern.value.orElse(
|
||||
Some(CalVer.Defaults.ReleasePattern)
|
||||
),
|
||||
calVerPreReleasePattern := calVerPreReleasePattern.value.orElse(
|
||||
Some(CalVer.Defaults.PreReleasePattern)
|
||||
),
|
||||
calVerPattern := {
|
||||
if (isRelease) {
|
||||
calVerReleasePattern.value.getOrElse(CalVer.Defaults.ReleasePattern)
|
||||
} else {
|
||||
calVerPreReleasePattern.value.getOrElse(CalVer.Defaults.PreReleasePattern)
|
||||
}
|
||||
} ,
|
||||
calVer := CalVer.render(calVerPattern.value).value
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -25,6 +38,7 @@ object CalVerPlugin extends AutoPlugin {
|
|||
calVerInfo := {
|
||||
val log = Keys.streams.value.log
|
||||
log.info(s"[CalVer] Version: ${calVer.value}")
|
||||
log.info(s"[CalVer] Pattern: ${calVerPattern.value}")
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package gs
|
||||
|
||||
//import java.io.File
|
||||
//import scala.util.Try
|
||||
|
||||
object Git {
|
||||
|
||||
/*def getLatestSemVer(): SemVer = {
|
||||
// Suppress all error output. Suppress exceptions for the failed process.
|
||||
// Capture the standard output and parse it if the command succeeds.
|
||||
/**
|
||||
* Get the latest SHA. If there are no commits on this branch, the empty
|
||||
* string will be returned.
|
||||
*
|
||||
* @param length The number of characters to take from the SHA.
|
||||
* @return The latest SHA.
|
||||
*/
|
||||
def getSha(length: Int): String = {
|
||||
val result = os
|
||||
.proc("git", "describe", "--tags", "--abbrev=0")
|
||||
.proc("git", "rev-parse", "HEAD")
|
||||
.call(
|
||||
stderr = os.ProcessOutput(
|
||||
(
|
||||
|
@ -21,9 +22,8 @@ object Git {
|
|||
)
|
||||
|
||||
if (result.exitCode != 0)
|
||||
SemVer.DefaultVersion
|
||||
result.out.text().take(length)
|
||||
else
|
||||
SemVer.parse(result.out.text()).getOrElse(SemVer.DefaultVersion)
|
||||
}*/
|
||||
|
||||
""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,8 @@ object PluginProperties {
|
|||
|
||||
/** Use one of the following to calculate an incremented release version:
|
||||
*
|
||||
* - `sbt -Drelease=major`
|
||||
* - `sbt -Drelease=minor`
|
||||
* - `sbt -Drelease=patch`
|
||||
* - `sbt -Drelease=true`
|
||||
* - `sbt -Drelease=false`
|
||||
*/
|
||||
val ReleaseProperty: String = "release"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue