From b929d778e9cd36ae1c3c8c1f8d3d22673aaaba2c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 23 Jan 2013 22:16:12 -0500 Subject: [PATCH] adds sbtApiVersion and scalaApiVersion sbtApiVersion and scalaApiVersion each calculates the API version of release builds as well as milestones and RCs. scalaBinaryVersion and sbtBinaryVersion are now aware of scalaApiVersion and sbtApiVersion respectively. For example, sbtBinaryVersion for "0.13.0-SNAPSHOT" now evaluates to "0.13.0-SNAPSHOT" instead of "0.13". --- ivy/src/main/scala/sbt/CrossVersion.scala | 45 ++++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 59b51c795..917f5318f 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -67,9 +67,41 @@ object CrossVersion m } - def isStable(v: String): Boolean = !v.contains("-") + // @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") + def isStable(v: String): Boolean = isScalaApiCompatible(v) + // @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full - + def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined + /** Returns sbt binary interface x.y API compatible with the given version string v. + * RCs for x.y.0 are considered API compatible. + * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). + */ + def sbtApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } + def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined + /** Returns Scala binary interface x.y API compatible with the given version string v. + * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. + */ + def scalaApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r def partialVersion(s: String): Option[(Int,Int)] = s match { @@ -79,12 +111,13 @@ object CrossVersion private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) - def binaryScalaVersion(full: String): String = binaryVersion(full, TransitionScalaVersion) - def binarySbtVersion(full: String): String = binaryVersion(full, TransitionSbtVersion) - def binaryVersion(full: String, cutoff: String): String = + def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) + def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) + private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = { def sub(major: Int, minor: Int) = major + "." + minor - (partialVersion(full), partialVersion(cutoff)) match { + (apiVersion(full), partialVersion(cutoff)) match { case (Some((major, minor)), None) => sub(major, minor) case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) case _ => full