diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index ed5533a44..6e5df8197 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -1,12 +1,14 @@ package sbt +import cross.CrossVersionUtil + final case class ScalaVersion(full: String, binary: String) sealed trait CrossVersion object CrossVersion { - val TransitionScalaVersion = "2.10" - val TransitionSbtVersion = "0.12" + val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion + val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion object Disabled extends CrossVersion { override def toString = "disabled" } final class Binary(val remapVersion: String => String) extends CrossVersion { @@ -71,58 +73,22 @@ object CrossVersion 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 + def isSbtApiCompatible(v: String): Boolean = CrossVersionUtil.isSbtApiCompatible(v) /** 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 + def sbtApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.sbtApiVersion(v) + def isScalaApiCompatible(v: String): Boolean = CrossVersionUtil.isScalaApiCompatible(v) /** 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 { - case PartialVersion(major, minor) => Some(major.toInt, minor.toInt) - case _ => None - } - private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = - major > minMajor || (major == minMajor && minor >= minMinor) - - def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) - def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + def scalaApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.scalaApiVersion(v) + val PartialVersion = CrossVersionUtil.PartialVersion + def partialVersion(s: String): Option[(Int,Int)] = CrossVersionUtil.partialVersion(s) + def binaryScalaVersion(full: String): String = CrossVersionUtil.binaryScalaVersion(full) + def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") - 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 - (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 - } - } -} + def binaryVersion(full: String, cutoff: String): String = CrossVersionUtil.binaryVersion(full, cutoff) +} diff --git a/util/cross/src/main/input_sources/CrossVersionUtil.scala b/util/cross/src/main/input_sources/CrossVersionUtil.scala new file mode 100644 index 000000000..c22106b2e --- /dev/null +++ b/util/cross/src/main/input_sources/CrossVersionUtil.scala @@ -0,0 +1,69 @@ +package ${{cross.package0}}.${{cross.package1}} + +object CrossVersionUtil +{ + val trueString = "true" + val falseString = "false" + val fullString = "full" + val noneString = "none" + val disabledString = "disabled" + val binaryString = "binary" + val TransitionScalaVersion = "2.10" + val TransitionSbtVersion = "0.12" + + def isFull(s: String): Boolean = (s == trueString) || (s == fullString) + def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) + def isBinary(s: String): Boolean = (s == binaryString) + + private[${{cross.package0}}] 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). + */ + private[${{cross.package0}}] 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 + } + } + private[${{cross.package0}}] 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. + */ + private[${{cross.package0}}] 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 + } + } + private[${{cross.package0}}] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r + private[${{cross.package0}}] def partialVersion(s: String): Option[(Int,Int)] = + s match { + case PartialVersion(major, minor) => Some(major.toInt, minor.toInt) + case _ => None + } + def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) + def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + private[${{cross.package0}}] def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) + private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = + major > minMajor || (major == minMajor && minor >= minMinor) + private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = + { + def sub(major: Int, minor: Int) = major + "." + minor + (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 + } + } +}