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