Better handling of invalid Scala versions

This commit is contained in:
Mark Harrah 2009-12-06 22:58:53 -05:00
parent 4902c3f1b3
commit 9bfc8a8f4a
5 changed files with 65 additions and 21 deletions

View File

@ -1,5 +1,7 @@
#Project properties
#Sun Dec 06 21:31:48 EST 2009
project.organization=org.scala-tools.sbt
project.name=Simple Build Tool
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

View File

@ -4,6 +4,6 @@ import java.net.URL
class Plugins(info: ProjectInfo) extends PluginDefinition(info)
{
val scripted = "org.scala-tools.sbt" % "test" % "0.6.5"
val scripted = "org.scala-tools.sbt" % "test" % "0.6.6"
val technically = Resolver.url("technically.us", new URL("http://databinder.net/repo/"))(Resolver.ivyStylePatterns)
}

View File

@ -3,6 +3,6 @@
project.organization=org.scala-tools.sbt
project.name=test
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
project.initialize=false

View File

@ -155,13 +155,24 @@ class xMain extends xsbti.AppMain
case InteractiveCommand :: _ => continue(project, prompt(baseProject, project) :: arguments, interactiveContinue)
case SpecificBuild(version, action) :: tail =>
if(Some(version) != baseProject.info.buildScalaVersion)
throw new ReloadException(rememberCurrent(action :: tail), Some(version))
{
if(checkVersion(baseProject, version))
throw new ReloadException(rememberCurrent(action :: tail), Some(version))
else
failed(UsageErrorExitCode)
}
else
continue(project, action :: tail, failAction)
case CrossBuild(action) :: tail =>
if(checkAction(project, action))
process(project, CrossBuild(project, action) ::: tail, failAction)
{
CrossBuild(project, action) match
{
case Some(actions) => continue(project, actions ::: tail, failAction)
case None => failed(UsageErrorExitCode)
}
}
else
failed(UsageErrorExitCode)
@ -257,21 +268,35 @@ class xMain extends xsbti.AppMain
None
}
}
def checkVersion(p: Project, version: String) =
{
try { p.getScalaInstance(version); true }
catch { case e: xsbti.RetrieveException => p.log.error(e.getMessage); false }
}
object CrossBuild
{
def unapply(s: String) = if(s.startsWith(CrossBuildPrefix) && !s.startsWith(SpecificBuildPrefix)) Some(s.substring(1)) else None
def apply(project: Project, action: String) =
def apply(project: Project, action: String): Option[List[String]] =
{
val againstScalaVersions = project.crossScalaVersions
if(againstScalaVersions.isEmpty)
{
Console.println("Project does not declare any Scala versions to cross-build against, building against current version...")
action :: Nil
Some(action :: Nil)
}
else
againstScalaVersions.toList.map(SpecificBuildPrefix + _ + " " + action) ::: // build against all versions
(SpecificBuildPrefix + project.buildScalaVersion) :: // reset to the version before the cross-build
Nil
{
if( !againstScalaVersions.forall(v => checkVersion(project, v)) )
None
else
{
val actions =
againstScalaVersions.toList.map(SpecificBuildPrefix + _ + " " + action) ::: // build against all versions
(SpecificBuildPrefix + project.buildScalaVersion) :: // reset to the version before the cross-build
Nil
Some(actions)
}
}
}
}
private def readLines(project: Project, file: File): Option[List[String]] =
@ -382,7 +407,7 @@ class xMain extends xsbti.AppMain
printCmd(ShowActions, "Shows all available actions.")
printCmd(RebootCommand, "Reloads sbt, picking up modifications to sbt.version or scala.version and recompiling modified project definitions.")
printCmd(HelpAction, "Displays this help message.")
printCmd(ShowCurrent, "Shows the current project and logging level of that project.")
printCmd(ShowCurrent, "Shows the current project, Scala version, and logging level.")
printCmd(Level.levels.mkString(", "), "Set logging for the current project to the specified level.")
printCmd(TraceCommand, "Toggles whether logging stack traces is enabled.")
printCmd(ProjectAction + " <project name>", "Sets the currently active project.")
@ -408,6 +433,7 @@ class xMain extends xsbti.AppMain
case ProjectAction => setProjectError(project.log)
case ShowCurrent =>
printProject("Current project is ", project)
Console.println("Current Scala version is " + project.buildScalaVersion)
Console.println("Current log level is " + project.log.getLevel)
printTraceEnabled(project)
true

View File

@ -227,10 +227,24 @@ trait Project extends TaskManager with Dag[Project] with BasicEnvironment
/** The definitive source for the version of Scala being used to *build* the project.*/
def buildScalaVersion = info.buildScalaVersion.getOrElse(crossScalaVersions.first)
def componentManager = new xsbt.ComponentManager(info.launcher.globalLock, info.app.components, log)
def buildScalaInstance =
localScalaInstances.find(_.version == buildScalaVersion) getOrElse
xsbt.ScalaInstance(buildScalaVersion, info.launcher)
def buildScalaInstance = buildScalaInstance0
final def buildScalaInstance0: ScalaInstance =
{
try { getScalaInstance(buildScalaVersion) }
catch { case e: xsbti.RetrieveException if info.buildScalaVersion.isEmpty => // only catch the exception if this is the default Scala version
log.error(e.getMessage)
SimpleReader.readLine("\nProvide a new Scala version or press enter to exit: ") match
{
case Some(v) if v.length > 0=> buildScalaVersions() = v; saveEnvironment(); buildScalaInstance0
case _ => throw e
}
}
}
def getScalaInstance(version: String) =
localScalaInstances.find(_.version == version) getOrElse
xsbt.ScalaInstance(version, info.launcher)
lazy val localScalaInstances: Seq[ScalaInstance] = localScala ++ info.parent.toList.flatMap(_.localScalaInstances)
def localScala: Seq[ScalaInstance] = Nil
def buildCompiler = new AnalyzingCompiler(buildScalaInstance, componentManager)
@ -348,12 +362,14 @@ object Project
case e: Exception => errorLoadingProject(e, log)
}
}
/** Logs the stack trace and returns an error message in Left.*/
private def errorLoadingProject(e: Throwable, log: Logger) =
{
log.trace(e)
new LoadError("Error loading project: " + e.toString)
}
e match
{
case _: xsbti.RetrieveException => LoadSetupDeclined
case _ =>
log.trace(e)
new LoadError("Error loading project: " + e.toString)
}
/** Loads the project for the given `info` and represented by an instance of 'builderClass'.*/
private[sbt] def constructProject[P <: Project](info: ProjectInfo, builderClass: Class[P]): P =
builderClass.getConstructor(classOf[ProjectInfo]).newInstance(info)