diff --git a/ivy/src/main/scala/sbt/ComponentManager.scala b/ivy/src/main/scala/sbt/ComponentManager.scala index 2d6c5a447..bdf78b9ec 100644 --- a/ivy/src/main/scala/sbt/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/ComponentManager.scala @@ -39,6 +39,8 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr d() if (d.cache) cache(id) getOrElse(notFound) + case f: IfMissing.Fallback => + f() } lockLocalCache { getOrElse(fromGlobal) } @@ -73,6 +75,7 @@ sealed trait IfMissing extends NotNull object IfMissing { object Fail extends IfMissing final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } + final class Fallback(f: => Iterable[File]) extends IfMissing { def apply() = f } } object ComponentManager { lazy val (version, timestamp) = @@ -86,4 +89,4 @@ object ComponentManager { import java.net.URL private def versionResource: URL = getClass.getResource("/xsbt.version.properties") -} \ No newline at end of file +} diff --git a/ivy/src/main/scala/sbt/Configuration.scala b/ivy/src/main/scala/sbt/Configuration.scala index d666b32bc..d2307b89d 100644 --- a/ivy/src/main/scala/sbt/Configuration.scala +++ b/ivy/src/main/scala/sbt/Configuration.scala @@ -44,6 +44,7 @@ object Configurations { lazy val ScalaTool = config("scala-tool") hide lazy val CompilerPlugin = config("plugin") hide + lazy val Component = config("component") hide private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) diff --git a/ivy/src/main/scala/sbt/VersionNumber.scala b/ivy/src/main/scala/sbt/VersionNumber.scala index 182d44edc..a5d1d494b 100644 --- a/ivy/src/main/scala/sbt/VersionNumber.scala +++ b/ivy/src/main/scala/sbt/VersionNumber.scala @@ -13,6 +13,11 @@ final class VersionNumber private[sbt] ( else Some(numbers(idx)) def size: Int = numbers.size + /** The vector of version numbers from more to less specific from this version number. */ + lazy val cascadingVersions: Vector[VersionNumber] = + (Vector(this) ++ + (numbers.inits filter (_.length >= 2) map (VersionNumber(_, Nil, Nil)))).distinct + private[this] val versionStr: String = numbers.mkString(".") + (tags match { diff --git a/ivy/src/test/scala/VersionNumberSpec.scala b/ivy/src/test/scala/VersionNumberSpec.scala index 7b836050f..68bc2ad6e 100644 --- a/ivy/src/test/scala/VersionNumberSpec.scala +++ b/ivy/src/test/scala/VersionNumberSpec.scala @@ -10,15 +10,18 @@ class VersionNumberSpec extends Specification { 1 should ${beParsedAs("1", Seq(1), Seq(), Seq())} ${breakDownTo("1", Some(1))} + ${generateCorrectCascadingNumbers("1", Seq("1"))} 1.0 should ${beParsedAs("1.0", Seq(1, 0), Seq(), Seq())} ${breakDownTo("1.0", Some(1), Some(0))} + ${generateCorrectCascadingNumbers("1.0", Seq("1.0"))} 1.0.0 should ${beParsedAs("1.0.0", Seq(1, 0, 0), Seq(), Seq())} ${breakDownTo("1.0.0", Some(1), Some(0), Some(0))} - + ${generateCorrectCascadingNumbers("1.0.0", Seq("1.0.0", "1.0"))} + ${beSemVerCompatWith("1.0.0", "1.0.1")} ${beSemVerCompatWith("1.0.0", "1.1.1")} ${notBeSemVerCompatWith("1.0.0", "2.0.0")} @@ -32,10 +35,12 @@ class VersionNumberSpec extends Specification { 1.0.0.0 should ${beParsedAs("1.0.0.0", Seq(1, 0, 0, 0), Seq(), Seq())} ${breakDownTo("1.0.0.0", Some(1), Some(0), Some(0), Some(0))} + ${generateCorrectCascadingNumbers("1.0.0.0", Seq("1.0.0.0", "1.0.0", "1.0"))} 0.12.0 should ${beParsedAs("0.12.0", Seq(0, 12, 0), Seq(), Seq())} ${breakDownTo("0.12.0", Some(0), Some(12), Some(0))} + ${generateCorrectCascadingNumbers("0.12.0", Seq("0.12.0", "0.12"))} ${notBeSemVerCompatWith("0.12.0", "0.12.0-RC1")} ${notBeSemVerCompatWith("0.12.0", "0.12.1")} @@ -47,6 +52,7 @@ class VersionNumberSpec extends Specification { 0.1.0-SNAPSHOT should ${beParsedAs("0.1.0-SNAPSHOT", Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-SNAPSHOT", Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))} ${beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT")} ${notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0")} @@ -58,15 +64,20 @@ class VersionNumberSpec extends Specification { 0.1.0-M1 should ${beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-M1", Seq("0.1.0-M1", "0.1.0", "0.1"))} 0.1.0-RC1 should ${beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-RC1", Seq("0.1.0-RC1", "0.1.0", "0.1"))} 0.1.0-MSERVER-1 should ${beParsedAs("0.1.0-MSERVER-1", Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-MSERVER-1", Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))} + 2.10.4-20140115-000117-b3a-sources should ${beParsedAs("2.10.4-20140115-000117-b3a-sources", Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())} + ${generateCorrectCascadingNumbers("2.10.4-20140115-000117-b3a-sources", Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))} ${beSemVerCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0")} @@ -74,12 +85,15 @@ class VersionNumberSpec extends Specification { 20140115000117-b3a-sources should ${beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq())} + ${generateCorrectCascadingNumbers("20140115000117-b3a-sources", Seq("20140115000117-b3a-sources"))} 1.0.0-alpha+001+002 should ${beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))} + ${generateCorrectCascadingNumbers("1.0.0-alpha+001+002", Seq("1.0.0-alpha+001+002", "1.0.0", "1.0"))} non.space.!?string should ${beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string"))} + ${generateCorrectCascadingNumbers("non.space.!?string", Seq("non.space.!?string"))} space !?string should ${beParsedAsError("space !?string")} @@ -119,4 +133,8 @@ class VersionNumberSpec extends Specification { VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== true def notBeSecSegCompatWith(v1: String, v2: String) = VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== false + def generateCorrectCascadingNumbers(s: String, ns: Seq[String]) = { + val versionNumbers = ns.toVector map VersionNumber.apply + VersionNumber(s).cascadingVersions must_== versionNumbers + } }