-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simplify integration with sbt-release
- Loading branch information
Showing
4 changed files
with
178 additions
and
55 deletions.
There are no files selected for viewing
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
85 changes: 85 additions & 0 deletions
85
sbt-version-policy/src/main/scala/sbtversionpolicy/withsbtrelease/ReleaseVersion.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package sbtversionpolicy.withsbtrelease | ||
|
||
import sbtversionpolicy.Compatibility | ||
import sbtversionpolicy.SbtVersionPolicyPlugin.aggregatedAssessedCompatibilityWithLatestRelease | ||
import sbtversionpolicy.SbtVersionPolicyPlugin.autoImport.versionPolicyAssessCompatibility | ||
import sbt.* | ||
|
||
object ReleaseVersion { | ||
|
||
/** | ||
* @return a [release version function](https://github.com/sbt/sbt-release?tab=readme-ov-file#custom-versioning) | ||
* that bumps the patch, minor, or major version number depending on the provided | ||
* compatibility level. | ||
*/ | ||
def fromCompatibility(compatibility: Compatibility): String => String = { | ||
val maybeBump = | ||
compatibility match { | ||
case Compatibility.None => Some(Version.Bump.Major) | ||
case Compatibility.BinaryCompatible => Some(Version.Bump.Minor) | ||
case Compatibility.BinaryAndSourceCompatible => None // No need to bump the patch version, because it has already been bumped when sbt-release set the next release version | ||
} | ||
{ (currentVersion: String) => | ||
val versionWithoutQualifier = | ||
Version(currentVersion) | ||
.getOrElse(Version.formatError(currentVersion)) | ||
.withoutQualifier | ||
(maybeBump match { | ||
case Some(bump) => versionWithoutQualifier.bump(bump) | ||
case None => versionWithoutQualifier | ||
}).string | ||
} | ||
} | ||
|
||
/** | ||
* Task returning a [release version function](https://github.com/sbt/sbt-release?tab=readme-ov-file#custom-versioning) | ||
* based on the assessed compatibility level of the project. | ||
* | ||
* Use it in your `.sbt` build definition as follows: | ||
* | ||
* {{{ | ||
* import sbtversionpolicy.withsbtrelease.ReleaseVersion | ||
* | ||
* releaseVersion := ReleaseVersion.fromAssessedCompatibilityWithLatestRelease.value | ||
* }}} | ||
*/ | ||
val fromAssessedCompatibilityWithLatestRelease: Def.Initialize[Task[String => String]] = | ||
Def.task { | ||
val compatibilityResults = versionPolicyAssessCompatibility.value | ||
val log = Keys.streams.value.log | ||
val compatibilityWithLatestRelease = | ||
compatibilityResults.headOption | ||
.getOrElse(throw new MessageOnlyException("Unable to assess the compatibility level of this project. Is 'versionPolicyPreviousVersions' defined?")) | ||
val (_, compatibility) = compatibilityWithLatestRelease | ||
log.debug(s"Compatibility level is ${compatibility}") | ||
fromCompatibility(compatibility) | ||
} | ||
|
||
/** | ||
* Task returning a [release version function](https://github.com/sbt/sbt-release?tab=readme-ov-file#custom-versioning) | ||
* based on the assessed compatibility level of the project (ie, the highest level of compatibility | ||
* satisfied by all the sub-projects aggregated by this project). | ||
* | ||
* Use it in the root project of your `.sbt` build definition as follows: | ||
* | ||
* {{{ | ||
* import sbtversionpolicy.withsbtrelease.ReleaseVersion | ||
* | ||
* val `my-project` = | ||
* project | ||
* .in(file(".")) | ||
* .aggregate(mySubproject1, mySubproject2) | ||
* .settings( | ||
* releaseVersion := ReleaseVersion.fromAggregatedAssessedCompatibilityWithLatestRelease.value | ||
* ) | ||
* }}} | ||
*/ | ||
val fromAggregatedAssessedCompatibilityWithLatestRelease: Def.Initialize[Task[String => String]] = | ||
Def.task { | ||
val log = Keys.streams.value.log | ||
val compatibility = aggregatedAssessedCompatibilityWithLatestRelease.value | ||
log.debug(s"Aggregated compatibility level is ${compatibility}") | ||
fromCompatibility(compatibility) | ||
} | ||
|
||
} |
77 changes: 77 additions & 0 deletions
77
sbt-version-policy/src/main/scala/sbtversionpolicy/withsbtrelease/Version.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package sbtversionpolicy.withsbtrelease | ||
|
||
// All the code below has been copied from https://github.com/sbt/sbt-release/blob/master/src/main/scala/Version.scala | ||
|
||
import util.control.Exception._ | ||
|
||
private[withsbtrelease] object Version { | ||
sealed trait Bump { | ||
def bump: Version => Version | ||
} | ||
|
||
object Bump { | ||
case object Major extends Bump { def bump = _.bumpMajor } | ||
case object Minor extends Bump { def bump = _.bumpMinor } | ||
case object Bugfix extends Bump { def bump = _.bumpBugfix } | ||
case object Nano extends Bump { def bump = _.bumpNano } | ||
case object Next extends Bump { def bump = _.bump } | ||
|
||
val default = Next | ||
} | ||
|
||
val VersionR = """([0-9]+)((?:\.[0-9]+)+)?([\.\-0-9a-zA-Z]*)?""".r | ||
val PreReleaseQualifierR = """[\.-](?i:rc|m|alpha|beta)[\.-]?[0-9]*""".r | ||
|
||
def apply(s: String): Option[Version] = { | ||
allCatch opt { | ||
val VersionR(maj, subs, qual) = s | ||
// parse the subversions (if any) to a Seq[Int] | ||
val subSeq: Seq[Int] = Option(subs) map { str => | ||
// split on . and remove empty strings | ||
str.split('.').filterNot(_.trim.isEmpty).map(_.toInt).toSeq | ||
} getOrElse Nil | ||
Version(maj.toInt, subSeq, Option(qual).filterNot(_.isEmpty)) | ||
} | ||
} | ||
|
||
def formatError(version: String) = sys.error(s"Version [$version] format is not compatible with " + Version.VersionR.pattern.toString) | ||
} | ||
|
||
private[withsbtrelease] case class Version(major: Int, subversions: Seq[Int], qualifier: Option[String]) { | ||
def bump = { | ||
val maybeBumpedPrerelease = qualifier.collect { | ||
case Version.PreReleaseQualifierR() => withoutQualifier | ||
} | ||
def maybeBumpedLastSubversion = bumpSubversionOpt(subversions.length-1) | ||
def bumpedMajor = copy(major = major + 1) | ||
|
||
maybeBumpedPrerelease | ||
.orElse(maybeBumpedLastSubversion) | ||
.getOrElse(bumpedMajor) | ||
} | ||
|
||
def bumpMajor = copy(major = major + 1, subversions = Seq.fill(subversions.length)(0)) | ||
def bumpMinor = maybeBumpSubversion(0) | ||
def bumpBugfix = maybeBumpSubversion(1) | ||
def bumpNano = maybeBumpSubversion(2) | ||
|
||
def maybeBumpSubversion(idx: Int) = bumpSubversionOpt(idx) getOrElse this | ||
|
||
private def bumpSubversionOpt(idx: Int) = { | ||
val bumped = subversions.drop(idx) | ||
val reset = bumped.drop(1).length | ||
bumped.headOption map { head => | ||
val patch = (head+1) +: Seq.fill(reset)(0) | ||
copy(subversions = subversions.patch(idx, patch, patch.length)) | ||
} | ||
} | ||
|
||
def bump(bumpType: Version.Bump): Version = bumpType.bump(this) | ||
|
||
def withoutQualifier = copy(qualifier = None) | ||
def asSnapshot = copy(qualifier = Some("-SNAPSHOT")) | ||
|
||
def string = "" + major + mkString(subversions) + qualifier.getOrElse("") | ||
|
||
private def mkString(parts: Seq[Int]) = parts.map("."+_).mkString | ||
} |
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