Better handling of invalid Scala versions

This commit is contained in:
Mark Harrah 2009-12-06 22:58:05 -05:00
parent 4e0f08d745
commit 41563c59bb
5 changed files with 42 additions and 20 deletions

View File

@ -15,21 +15,32 @@ trait Provider extends NotNull
def parentLoader: ClassLoader def parentLoader: ClassLoader
def lockFile: File 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) val (jars, loader) = Locks(lockFile, new initialize)
private final class initialize extends Callable[(Array[File], ClassLoader)] private final class initialize extends Callable[(Array[File], ClassLoader)]
{ {
def call = def call =
{ {
val (existingJars, existingLoader) = createLoader val (existingJars, existingLoader) = createLoader
if(Provider.needsUpdate(existingLoader, testLoadClasses)) if(Provider.getMissing(existingLoader, testLoadClasses).isEmpty)
{
( new Update(configuration) )(target)
val (newJars, newLoader) = createLoader
Provider.failIfMissing(newLoader, testLoadClasses, failLabel)
(newJars, newLoader)
}
else
(existingJars, existingLoader) (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 = def createLoader =
{ {
@ -48,13 +59,9 @@ object Provider
{ {
def accept(file: File) = !file.isDirectory && file.getName.endsWith(".jar") def accept(file: File) = !file.isDirectory && file.getName.endsWith(".jar")
} }
def failIfMissing(loader: ClassLoader, classes: Iterable[String], label: String) = def getMissing(loader: ClassLoader, classes: Iterable[String]): Iterable[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 classMissing(c: String) = try { Class.forName(c, false, loader); false } catch { case e: ClassNotFoundException => true } def classMissing(c: String) = try { Class.forName(c, false, loader); false } catch { case e: ClassNotFoundException => true }
val missing = classes.toList.filter(classMissing) classes.toList.filter(classMissing)
if(missing.isEmpty) ifSuccess else ifFailure(missing)
} }
} }

View File

@ -51,17 +51,18 @@ final class Update(config: UpdateConfiguration)
private lazy val ivy = Ivy.newInstance(settings) private lazy val ivy = Ivy.newInstance(settings)
/** The main entry point of this class for use by the Update module. It runs Ivy */ /** 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)) Message.setDefaultLogger(new SbtIvyLogger(logWriter))
ivy.pushContext() ivy.pushContext()
try { update(target) } try { update(target); true }
catch catch
{ {
case e: Exception => case e: Exception =>
e.printStackTrace(logWriter) e.printStackTrace(logWriter)
log(e.toString) log(e.toString)
System.out.println(" (see " + logFile + " for complete log)") System.out.println(" (see " + logFile + " for complete log)")
false
} }
finally finally
{ {

View File

@ -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; }
}

View File

@ -31,8 +31,8 @@
project.name: quick=set(test), new=prompt(Name), fill=prompt(Name) project.name: quick=set(test), new=prompt(Name), fill=prompt(Name)
project.organization: new=prompt(Organization) project.organization: new=prompt(Organization)
project.version: quick=set(1.0), new=prompt(Version)[1.0], fill=prompt(Version)[1.0] 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] 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.scratch: quick=set(true)
project.initialize: quick=set(true), new=set(true) project.initialize: quick=set(true), new=set(true)

View File

@ -1,5 +1,7 @@
#Project properties
#Sun Dec 06 21:33:35 EST 2009
project.organization=org.scala-tools.sbt project.organization=org.scala-tools.sbt
project.name=xsbt project.name=xsbt
sbt.version=0.5.6 sbt.version=0.5.6
project.version=0.6.5 project.version=0.6.6
scala.version=2.7.5 scala.version=2.7.7