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 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]( | def getProperty[A]( | ||||||
|   name: String, |   name: String, | ||||||
|  |  | ||||||
|  | @ -1 +1 @@ | ||||||
| sbt.version=1.9.8 | sbt.version=1.9.9 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,169 @@ | ||||||
| package gs | 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 { | 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." |     "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. |   /** Task which emits the current version at the informational log level. | ||||||
|     */ |     */ | ||||||
|   lazy val calVerInfo = taskKey[Unit]( |   lazy val calVerInfo = taskKey[Unit]( | ||||||
|  |  | ||||||
|  | @ -11,9 +11,22 @@ object CalVerPlugin extends AutoPlugin { | ||||||
| 
 | 
 | ||||||
|   // Perform all version calculations and expose as a variable. |   // Perform all version calculations and expose as a variable. | ||||||
|   lazy val calVerDefaults: Seq[Setting[_]] = { |   lazy val calVerDefaults: Seq[Setting[_]] = { | ||||||
|     // Expose the relevant values as setting keys. |     val isRelease = PluginProperties.isRelease() | ||||||
|     Seq( |     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 := { |     calVerInfo := { | ||||||
|       val log = Keys.streams.value.log |       val log = Keys.streams.value.log | ||||||
|       log.info(s"[CalVer] Version: ${calVer.value}") |       log.info(s"[CalVer] Version: ${calVer.value}") | ||||||
|  |       log.info(s"[CalVer] Pattern: ${calVerPattern.value}") | ||||||
|     } |     } | ||||||
|   ) |   ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,15 +1,16 @@ | ||||||
| package gs | package gs | ||||||
| 
 | 
 | ||||||
| //import java.io.File |  | ||||||
| //import scala.util.Try |  | ||||||
| 
 |  | ||||||
| object Git { | object Git { | ||||||
| 
 |   /** | ||||||
|   /*def getLatestSemVer(): SemVer = { |     * Get the latest SHA. If there are no commits on this branch, the empty | ||||||
|     // Suppress all error output. Suppress exceptions for the failed process. |     * string will be returned. | ||||||
|     // Capture the standard output and parse it if the command succeeds. |     * | ||||||
|  |     * @param length The number of characters to take from the SHA. | ||||||
|  |     * @return The latest SHA. | ||||||
|  |     */ | ||||||
|  |   def getSha(length: Int): String = { | ||||||
|     val result = os |     val result = os | ||||||
|       .proc("git", "describe", "--tags", "--abbrev=0") |       .proc("git", "rev-parse", "HEAD") | ||||||
|       .call( |       .call( | ||||||
|         stderr = os.ProcessOutput( |         stderr = os.ProcessOutput( | ||||||
|           ( |           ( | ||||||
|  | @ -21,9 +22,8 @@ object Git { | ||||||
|       ) |       ) | ||||||
| 
 | 
 | ||||||
|     if (result.exitCode != 0) |     if (result.exitCode != 0) | ||||||
|       SemVer.DefaultVersion |       result.out.text().take(length) | ||||||
|     else |     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: |     /** Use one of the following to calculate an incremented release version: | ||||||
|       * |       * | ||||||
|       *   - `sbt -Drelease=major` |       *   - `sbt -Drelease=true` | ||||||
|       *   - `sbt -Drelease=minor` |       *   - `sbt -Drelease=false` | ||||||
|       *   - `sbt -Drelease=patch` |  | ||||||
|       */ |       */ | ||||||
|     val ReleaseProperty: String = "release" |     val ReleaseProperty: String = "release" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue