diff --git a/launch/Provider.scala b/launch/Provider.scala index 69d93f751..365c2b2d4 100644 --- a/launch/Provider.scala +++ b/launch/Provider.scala @@ -15,21 +15,32 @@ trait Provider extends NotNull def parentLoader: ClassLoader def lockFile: File + def retrieveFailed: Nothing = fail("") + def retrieveCorrupt(missing: Iterable[String]): Nothing = fail(": missing " + missing.mkString(", ")) + private def fail(extra: String) = + throw new xsbti.RetrieveException(versionString, "Could not retrieve " + failLabel + extra) + private def versionString: String = target match { case UpdateScala => configuration.scalaVersion; case a: UpdateApp => Version.get(a.id.version) } + val (jars, loader) = Locks(lockFile, new initialize) private final class initialize extends Callable[(Array[File], ClassLoader)] { def call = { val (existingJars, existingLoader) = createLoader - if(Provider.needsUpdate(existingLoader, testLoadClasses)) - { - ( new Update(configuration) )(target) - val (newJars, newLoader) = createLoader - Provider.failIfMissing(newLoader, testLoadClasses, failLabel) - (newJars, newLoader) - } - else + if(Provider.getMissing(existingLoader, testLoadClasses).isEmpty) (existingJars, existingLoader) + else + { + val retrieveSuccess = ( new Update(configuration) )(target) + if(retrieveSuccess) + { + val (newJars, newLoader) = createLoader + val missing = Provider.getMissing(newLoader, testLoadClasses) + if(missing.isEmpty) (newJars, newLoader) else retrieveCorrupt(missing) + } + else + retrieveFailed + } } def createLoader = { @@ -48,13 +59,9 @@ object Provider { def accept(file: File) = !file.isDirectory && file.getName.endsWith(".jar") } - def failIfMissing(loader: ClassLoader, classes: Iterable[String], label: String) = - checkTarget(loader, classes, (), missing => error("Could not retrieve " + label + ": missing " + missing.mkString(", "))) - def needsUpdate(loader: ClassLoader, classes: Iterable[String]) = checkTarget(loader, classes, false, x => true) - def checkTarget[T](loader: ClassLoader, classes: Iterable[String], ifSuccess: => T, ifFailure: Iterable[String] => T): T = + def getMissing(loader: ClassLoader, classes: Iterable[String]): Iterable[String] = { def classMissing(c: String) = try { Class.forName(c, false, loader); false } catch { case e: ClassNotFoundException => true } - val missing = classes.toList.filter(classMissing) - if(missing.isEmpty) ifSuccess else ifFailure(missing) + classes.toList.filter(classMissing) } } \ No newline at end of file diff --git a/launch/Update.scala b/launch/Update.scala index 7857b107a..30a70ecd2 100644 --- a/launch/Update.scala +++ b/launch/Update.scala @@ -51,17 +51,18 @@ final class Update(config: UpdateConfiguration) private lazy val ivy = Ivy.newInstance(settings) /** The main entry point of this class for use by the Update module. It runs Ivy */ - def apply(target: UpdateTarget) + def apply(target: UpdateTarget): Boolean = { Message.setDefaultLogger(new SbtIvyLogger(logWriter)) ivy.pushContext() - try { update(target) } + try { update(target); true } catch { case e: Exception => e.printStackTrace(logWriter) log(e.toString) System.out.println(" (see " + logFile + " for complete log)") + false } finally { diff --git a/launch/interface/src/main/java/xsbti/RetrieveException.java b/launch/interface/src/main/java/xsbti/RetrieveException.java new file mode 100644 index 000000000..f9975b809 --- /dev/null +++ b/launch/interface/src/main/java/xsbti/RetrieveException.java @@ -0,0 +1,12 @@ +package xsbti; + +public final class RetrieveException extends RuntimeException +{ + private final String version; + public RetrieveException(String version, String msg) + { + super(msg); + this.version = version; + } + public String version() { return version; } +} \ No newline at end of file diff --git a/launch/src/main/resources/sbt/sbt.boot.properties b/launch/src/main/resources/sbt/sbt.boot.properties index 561d0f76c..e43653655 100644 --- a/launch/src/main/resources/sbt/sbt.boot.properties +++ b/launch/src/main/resources/sbt/sbt.boot.properties @@ -31,8 +31,8 @@ project.name: quick=set(test), new=prompt(Name), fill=prompt(Name) project.organization: new=prompt(Organization) project.version: quick=set(1.0), new=prompt(Version)[1.0], fill=prompt(Version)[1.0] - def.scala.version: quick=set(2.7.5), new=set(2.7.5), fill=set(2.7.5) + def.scala.version: quick=set(2.7.7), new=set(2.7.7), fill=set(2.7.7) build.scala.versions: quick=set(2.7.7), new=prompt(Scala version)[2.7.7], fill=prompt(Scala version)[2.7.7] - sbt.version: quick=set(0.6.3), new=prompt(sbt version)[0.6.3], fill=prompt(sbt version)[0.6.3] + sbt.version: quick=set(0.6.6), new=prompt(sbt version)[0.6.6], fill=prompt(sbt version)[0.6.6] project.scratch: quick=set(true) project.initialize: quick=set(true), new=set(true) \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index 3a7ca66b1..4a35c1583 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1,5 +1,7 @@ +#Project properties +#Sun Dec 06 21:33:35 EST 2009 project.organization=org.scala-tools.sbt project.name=xsbt sbt.version=0.5.6 -project.version=0.6.5 -scala.version=2.7.5 +project.version=0.6.6 +scala.version=2.7.7