diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 9a984c5c5..3425bb1f5 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -4,29 +4,56 @@ import cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) +/** Configures how a module will be cross-versioned. */ sealed trait CrossVersion + object CrossVersion { + /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion + + /** The first `major.minor` sbt version that the sbt binary version should be used for cross-versioning instead of the full version. */ val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion + /** Disables cross versioning for a module.*/ object Disabled extends CrossVersion { override def toString = "disabled" } + + /** Cross-versions a module using the result of applying `remapVersion` to the binary version. + * For example, if `remapVersion = v => "2.10"` and the binary version is "2.9.2" or "2.10", + * the module is cross-versioned with "2.10". */ final class Binary(val remapVersion: String => String) extends CrossVersion { override def toString = "Binary" } + + /** Cross-versions a module with the result of applying `remapVersion` to the full version. + * For example, if `remapVersion = v => "2.10"` and the full version is "2.9.2" or "2.10.3", + * the module is cross-versioned with "2.10". */ final class Full(val remapVersion: String => String) extends CrossVersion { override def toString = "Full" } + /** Cross-versions a module with the full version (typically the full Scala version). */ def full: CrossVersion = new Full(idFun) + + /** Cross-versions a module with the result of applying `remapVersion` to the full version + * (typically the full Scala version). See also [[sbt.CrossVersion.Full]]. */ def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) + /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = new Binary(idFun) + + /** Cross-versions a module with the result of applying `remapVersion` to the binary version + * (typically the binary Scala version). See also [[sbt.CrossVersion.Binary]]. */ def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) private[this] def idFun[T]: T => T = x => x + + @deprecated("Will be made private.", "0.13.1") def append(s: String): Option[String => String] = Some(x => crossName(x, s)) + /** Construct a cross-versioning function given cross-versioning configuration `cross`, + * full version `fullVersion` and binary version `binaryVersion`. The behavior of the + * constructed function is as documented for the [[sbt.CrossVersion]] datatypes. */ def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = cross match { @@ -35,31 +62,43 @@ object CrossVersion case f: Full => append(f.remapVersion(fullVersion)) } + /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ def apply(module: ModuleID, is: IvyScala): Option[String => String] = CrossVersion(module.crossVersion, is.scalaFullVersion, is.scalaBinaryVersion) + /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = is flatMap { i => apply(module, i) } + /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = cross match { case None => artifacts case Some(is) => substituteCrossA(artifacts, cross) } + @deprecated("Will be made private.", "0.13.1") def applyCross(s: String, fopt: Option[String => String]): String = fopt match { case None => s case Some(fopt) => fopt(s) } + @deprecated("Will be made private.", "0.13.1") def crossName(name: String, cross: String): String = name + "_" + cross + + /** Cross-versions `a` according to cross-version function `cross`. */ def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = a.copy(name = applyCross(a.name, cross)) + + @deprecated("Will be made private.", "0.13.1") def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = as.map(art => substituteCross(art, cross)) + /** Constructs a function that will cross-version a ModuleID + * for the given full and binary Scala versions `scalaFullVersion` and `scalaBinaryVersion` + * according to the ModuleID's cross-versioning setting. */ def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m => { val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) @@ -71,23 +110,38 @@ object CrossVersion @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 = 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)] = 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. - */ + * 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)] = CrossVersionUtil.scalaApiVersion(v) + + /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ val PartialVersion = CrossVersionUtil.PartialVersion + + /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ def partialVersion(s: String): Option[(Int,Int)] = CrossVersionUtil.partialVersion(s) + + /** Computes the binary Scala version from the `full` version. + * Full Scala versions earlier than [[sbt.CrossVersion.TransitionScalaVersion]] are returned as is. */ def binaryScalaVersion(full: String): String = CrossVersionUtil.binaryScalaVersion(full) + + /** Computes the binary sbt version from the `full` version. + * Full sbt versions earlier than [[sbt.CrossVersion.TransitionSbtVersion]] are returned as is. */ 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 = CrossVersionUtil.binaryVersion(full, cutoff)