From ab65f33ae5d173dc4e02b3d5e61b2757f23e76fa Mon Sep 17 00:00:00 2001 From: Pat Garrity Date: Thu, 11 Jan 2024 22:43:53 -0600 Subject: [PATCH] Minor updates and heavy documentation. --- README.md | 167 +++++++++++++++++++++++++++ src/main/scala/gs/SemVer.scala | 13 ++- src/main/scala/gs/SemVerKeys.scala | 15 ++- src/main/scala/gs/SemVerPlugin.scala | 3 +- 4 files changed, 191 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1746921..0eb638a 100644 --- a/README.md +++ b/README.md @@ -1 +1,168 @@ # gs-semver-sbt-plugin + +SemVer plugin for Garrity Software projects. Typically used for library +development. + +- [Usage](#usage) + - [Adding the Plugin](#adding-the-plugin) + - [Updating the Build File](#updating-the-build-file) + - [Publishing a Release](#publishing-a-release) +- [Supported Setting Keys](#supported-setting-keys) + - [`semVerSelected`](#semverselected) + - [`semVerMajor`](#semvermajor) + - [`semVerCurrent`](#semvercurrent) +- [Supported Command Line Properties](#supported-command-line-properties) + - [The `release` Property](#the-release-property) + - [The `snapshot` Property](#the-snapshot-property) +- [Supported Tasks](#supported-tasks) + - [`semVerInfo`](#semverinfo) +- [Complete Example](#complete-example) + +## Usage + +This is an auto plugin that provides setting keys for version values. + +1. Add the plugin to your build. +2. Update your build file to leverage the calculated SemVer values. +3. Build releases using the `-Drelease` parameter. + +### Adding the Plugin + +**File: project/plugins.sbt** +```scala +resolvers += "Garrity Software Releases" at "https://maven.garrity.co/gs" + +addSbtPlugin("gs" % "gs-semver-sbt-plugin" % "0.1.0") +``` + +### Updating the Build File + +On any project within the build: + +``` +.settings(version := semVerSelected.value) +.settings(name := s"$ProjectName-v${semVerMajor.value}") +``` + +### Publishing a Release + +``` +sbt -Drelease=minor publish +``` + +## Supported Setting Keys + +These are available in `build.sbt` once the plugin is added. + +### `semVerSelected` + +This setting should be used as the project version. Assign the value of this +setting to the `version` setting: + +```scala +lazy val `example` = project + .in(file(".")) + .settings(version := semVerSelected.value) +``` + +### `semVerMajor` + +This setting should be used to calculate library names that are version-aware. +This practice helps protect against binary compatibility issues stemming from +different library versions existing as transitive dependencies. + +```scala +lazy val `example` = project + .in(file(".")) + .settings(version := semVerSelected.value) +``` + +### `semVerCurrent` + +## Supported Command Line Properties + +Properties are provided via `-D` parameters: `-D=`. + +### The `release` Property + +Value may be any of: `major`, `minor`, `patch`. If this property is set, the +build will calculate a semantic version by incrementing the selected version +component. If this property is not defined, a pre-release build is assumed and +the patch version is incremented. + +### The `snapshot` Property + +Used to force a pre-release build. If `-Dsnapshot=true` is specified, the +`-SNAPSHOT` suffix will be appended to the version. + +### Command Line Examples + +Assume that the current version of the project is `1.2.3`. + +| Release | Snapshot | `semVerSelected` | `semVerMajor` | +| --------- | --------- | ---------------- | ------------- | +| | | `1.2.4-SNAPSHOT` | `1` | +| | `true` | `1.2.4-SNAPSHOT` | `1` | +| `patch` | | `1.2.4` | `1` | +| `patch` | `true` | `1.2.4-SNAPSHOT` | `1` | +| `minor` | | `1.3.0` | `1` | +| `minor` | `true` | `1.3.0-SNAPSHOT` | `1` | +| `major` | | `2.0.0` | `2` | +| `major` | `true` | `2.0.0-SNAPSHOT` | `2` | + +## Supported Tasks + +### `semVerInfo` + +Invoking `sbt semVerInfo` will emit diagnostic version information at the `info` +log level via the SBT logger. + +``` +sbt -Drelease=minor -Dsnapshot=true semVerInfo +... +[info] [SemVer] Current: 0.1.0 +[info] [SemVer] Selected: 0.2.0-SNAPSHOT +... +``` + +## Complete Example + +### `plugins.sbt` + +```scala +resolvers += "Garrity Software Releases" at "https://maven.garrity.co/gs" + +addSbtPlugin("gs" % "gs-semver-sbt-plugin" % "0.1.0") +``` + +### `build.sbt` + +```scala +val scala3: String = "3.3.1" + +ThisBuild / organizationName := "garrity software" +ThisBuild / organization := "gs" +ThisBuild / scalaVersion := scala3 +ThisBuild / versionScheme := Some("semver-spec") + +lazy val sharedSettings = Seq( + scalaVersion := scala3, + version := semVerSelected.value +) + +lazy val publishSettings = Seq( + publishTo := { + val repo = "https://maven.garrity.co/" + if (semVerSnapshot.value) + Some("Garrity Software Maven" at repo + "snapshots") + else + Some("Garrity Software Maven" at repo + "releases") + } +) + +lazy val `gs-example` = project + .in(file(".")) + .settings(sharedSettings) + .settings(publishSettings) + .settings(name := s"example-v${semVerMajor.value}") +``` diff --git a/src/main/scala/gs/SemVer.scala b/src/main/scala/gs/SemVer.scala index 5a1ae44..ae3a87b 100644 --- a/src/main/scala/gs/SemVer.scala +++ b/src/main/scala/gs/SemVer.scala @@ -43,12 +43,21 @@ case class SemVer( /** @return * Copy of this SemVer with the major version incremented by 1. */ - def incrementMajor(): SemVer = copy(major = this.major + 1) + def incrementMajor(): SemVer = + copy( + major = this.major + 1, + minor = 0, + patch = 0 + ) /** @return * Copy of this SemVer with the minor version incremented by 1. */ - def incrementMinor(): SemVer = copy(minor = this.minor + 1) + def incrementMinor(): SemVer = + copy( + minor = this.minor + 1, + patch = 0 + ) /** @return * Copy of this SemVer with the patch version incremented by 1. diff --git a/src/main/scala/gs/SemVerKeys.scala b/src/main/scala/gs/SemVerKeys.scala index 41cc77d..6c57c24 100644 --- a/src/main/scala/gs/SemVerKeys.scala +++ b/src/main/scala/gs/SemVerKeys.scala @@ -31,12 +31,12 @@ object SemVerKeys { * * Consider the example current version of `1.2.3`: * - * - `-Drelease=major`: `semVerSelected = 2.2.3` + * - `-Drelease=major`: `semVerSelected = 2.0.0` * - `-Drelease=major`, `-Dsnapshot=true`: `semVerSelected = - * 2.2.3-SNAPSHOT` - * - `-Drelease=minor`: `semVerSelected = 1.3.3` + * 2.0.0-SNAPSHOT` + * - `-Drelease=minor`: `semVerSelected = 1.3.0` * - `-Drelease=minor`, `-Dsnapshot=true`: `semVerSelected = - * 1.3.3-SNAPSHOT` + * 1.3.0-SNAPSHOT` * - `-Drelease=patch`: `semVerSelected = 1.2.4` * - `-Drelease=patch`, `-Dsnapshot=true`: `semVerSelected = * 1.2.4-SNAPSHOT` @@ -53,6 +53,13 @@ object SemVerKeys { "Major version selected for the current build. Depends on the release type and current version." ) + /** SBT Setting for whether the current build is a pre-release (snapshot) + * build. + */ + lazy val semVerSnapshot = settingKey[Boolean]( + "True or false depending on whether the current build is a pre-release (snapshot) build." + ) + /** Task which emits the current and selected versions at the informational * log level. */ diff --git a/src/main/scala/gs/SemVerPlugin.scala b/src/main/scala/gs/SemVerPlugin.scala index 40ca08c..d685f03 100644 --- a/src/main/scala/gs/SemVerPlugin.scala +++ b/src/main/scala/gs/SemVerPlugin.scala @@ -45,7 +45,8 @@ object SemVerPlugin extends AutoPlugin { Seq( semVerCurrent := latestSemVer.toString(), semVerSelected := selectedSemVer.render(isSnapshot), - semVerMajor := selectedSemVer.major + semVerMajor := selectedSemVer.major, + semVerSnapshot := isSnapshot ) }