2009-09-26 08:18:04 +02:00
|
|
|
package xsbt.boot
|
2009-08-21 14:12:43 +02:00
|
|
|
|
2009-09-26 08:18:04 +02:00
|
|
|
import java.io.File
|
2009-08-21 14:12:43 +02:00
|
|
|
|
2009-09-26 08:18:04 +02:00
|
|
|
object Launch
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
def apply(arguments: Seq[String]): Unit = apply( (new File("")).getAbsoluteFile, arguments )
|
|
|
|
|
def apply(currentDirectory: File, arguments: Seq[String])
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
val (configFile, newArguments) = Configuration.find(arguments, currentDirectory)
|
|
|
|
|
val parsed = Configuration.parse(configFile, currentDirectory)
|
|
|
|
|
val (explicit, finish) = ResolveVersions(parsed)
|
|
|
|
|
val launcher = new Launch(explicit)
|
|
|
|
|
launch(launcher, explicit.getScalaVersion, explicit.app.toID, currentDirectory, newArguments, finish)
|
2009-08-21 14:12:43 +02:00
|
|
|
}
|
2009-09-26 08:18:04 +02:00
|
|
|
final def launch(launcher: xsbti.Launcher, scalaVersion: String, app: xsbti.ApplicationID, workingDirectory: File, arguments: Seq[String], finish: () => Unit)
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
val scalaProvider: xsbti.ScalaProvider = launcher.getScala(scalaVersion)
|
|
|
|
|
val appProvider: xsbti.AppProvider = scalaProvider.app(app)
|
|
|
|
|
val appConfig: xsbti.AppConfiguration = new AppConfiguration(arguments.toArray, workingDirectory, appProvider)
|
2009-08-24 04:21:15 +02:00
|
|
|
|
2009-09-26 08:18:04 +02:00
|
|
|
val main = appProvider.newMain()
|
|
|
|
|
finish()
|
|
|
|
|
main.run(appConfig) match
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
case e: xsbti.Exit => System.exit(e.code)
|
|
|
|
|
case r: xsbti.Reboot => launch(launcher, r.scalaVersion, r.app, r.baseDirectory, r.arguments, () => ())
|
|
|
|
|
case x => throw new BootException("Invalid main result: " + x + (if(x eq null) "" else " (class: " + x.getClass + ")"))
|
2009-08-21 14:12:43 +02:00
|
|
|
}
|
2009-08-24 04:21:15 +02:00
|
|
|
}
|
2009-09-26 08:18:04 +02:00
|
|
|
}
|
2009-09-05 18:19:34 +02:00
|
|
|
|
2009-09-26 08:18:04 +02:00
|
|
|
import BootConfiguration.{appDirectoryName, baseDirectoryName, ScalaDirectoryName, TestLoadScalaClasses}
|
|
|
|
|
class Launch(val configuration: LaunchConfiguration) extends xsbti.Launcher
|
|
|
|
|
{
|
|
|
|
|
import scala.collection.mutable.HashMap
|
|
|
|
|
private val scalaProviders = new HashMap[String, ScalaProvider]
|
|
|
|
|
def getScala(version: String): xsbti.ScalaProvider = scalaProviders.getOrElseUpdate(version, new ScalaProvider(version))
|
|
|
|
|
|
|
|
|
|
class ScalaProvider(val version: String) extends xsbti.ScalaProvider with Provider
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
def launcher: xsbti.Launcher = Launch.this
|
2009-08-24 04:21:15 +02:00
|
|
|
|
2009-09-26 08:18:04 +02:00
|
|
|
lazy val parentLoader = new BootFilteredLoader(getClass.getClassLoader)
|
|
|
|
|
lazy val configuration = Launch.this.configuration.withScalaVersion(version)
|
|
|
|
|
lazy val libDirectory = new File(configuration.boot.directory, baseDirectoryName(version))
|
|
|
|
|
lazy val scalaHome = new File(libDirectory, ScalaDirectoryName)
|
|
|
|
|
def baseDirectories = Seq(scalaHome)
|
|
|
|
|
def testLoadClasses = TestLoadScalaClasses
|
|
|
|
|
def target = UpdateTarget.UpdateScala
|
|
|
|
|
def failLabel = "Scala " + version
|
2009-08-21 14:12:43 +02:00
|
|
|
|
2009-09-26 08:18:04 +02:00
|
|
|
def app(id: xsbti.ApplicationID): xsbti.AppProvider = new AppProvider(id)
|
|
|
|
|
|
|
|
|
|
class AppProvider(val id: xsbti.ApplicationID) extends xsbti.AppProvider with Provider
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
def scalaProvider: xsbti.ScalaProvider = ScalaProvider.this
|
|
|
|
|
lazy val configuration = ScalaProvider.this.configuration.withApp(Application(id))
|
|
|
|
|
lazy val appHome = new File(libDirectory, appDirectoryName(id, File.separator))
|
|
|
|
|
def parentLoader = ScalaProvider.this.loader
|
|
|
|
|
def baseDirectories = id.mainComponents.map(componentLocation) ++ Seq(appHome)
|
|
|
|
|
def testLoadClasses = Seq(id.mainClass)
|
|
|
|
|
def target = UpdateTarget.UpdateApp
|
|
|
|
|
def failLabel = id.name + " " + id.version
|
|
|
|
|
|
|
|
|
|
lazy val mainClass: Class[T] forSome { type T <: xsbti.AppMain } =
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
val c = Class.forName(id.mainClass, true, loader)
|
|
|
|
|
c.asSubclass(classOf[xsbti.AppMain])
|
2009-08-21 14:12:43 +02:00
|
|
|
}
|
2009-09-26 08:18:04 +02:00
|
|
|
def newMain(): xsbti.AppMain = mainClass.newInstance
|
|
|
|
|
|
|
|
|
|
def componentLocation(id: String): File = new File(appHome, id)
|
|
|
|
|
def component(id: String) = GetJars(componentLocation(id) :: Nil)
|
|
|
|
|
def defineComponent(id: String, files: Array[File]) =
|
2009-08-21 14:12:43 +02:00
|
|
|
{
|
2009-09-26 08:18:04 +02:00
|
|
|
val location = componentLocation(id)
|
|
|
|
|
if(location.exists)
|
|
|
|
|
throw new BootException("Cannot redefine component. (id: " + id + ", files: " + files.mkString(","))
|
|
|
|
|
else
|
|
|
|
|
files.foreach(file => Copy(file, location))
|
2009-08-21 14:12:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-09-26 08:18:04 +02:00
|
|
|
}
|