add cleanupCommands setting to specify commands to run before interpreter exits. fixes #219

This commit is contained in:
Mark Harrah 2011-10-16 17:27:36 -04:00
parent 16eee17503
commit 1578341a10
6 changed files with 24 additions and 16 deletions

View File

@ -38,15 +38,15 @@ class AnalyzingCompiler(val scalaInstance: ScalaInstance, val manager: Component
call("xsbt.ScaladocInterface", log) (classOf[Array[String]], classOf[xLogger], classOf[Reporter]) (
arguments.toArray[String] : Array[String], log, reporter)
}
def console(classpath: Seq[File], options: Seq[String], initialCommands: String, log: Logger)(loader: Option[ClassLoader] = None, bindings: Seq[(String, Any)] = Nil): Unit =
def console(classpath: Seq[File], options: Seq[String], initialCommands: String, cleanupCommands: String, log: Logger)(loader: Option[ClassLoader] = None, bindings: Seq[(String, Any)] = Nil): Unit =
{
val arguments = new CompilerArguments(scalaInstance, cp)
val classpathString = CompilerArguments.absString(arguments.finishClasspath(classpath))
val bootClasspath = if(cp.autoBoot) arguments.createBootClasspath else ""
val (names, values) = bindings.unzip
call("xsbt.ConsoleInterface", log)(
classOf[Array[String]], classOf[String], classOf[String], classOf[String], classOf[ClassLoader], classOf[Array[String]], classOf[Array[Any]], classOf[xLogger])(
options.toArray[String]: Array[String], bootClasspath, classpathString, initialCommands, loader.orNull, names.toArray[String], values.toArray[Any], log)
classOf[Array[String]], classOf[String], classOf[String], classOf[String], classOf[String], classOf[ClassLoader], classOf[Array[String]], classOf[Array[Any]], classOf[xLogger])(
options.toArray[String]: Array[String], bootClasspath, classpathString, initialCommands, cleanupCommands, loader.orNull, names.toArray[String], values.toArray[Any], log)
}
def force(log: Logger): Unit = getInterfaceJar(log)
private def call(interfaceClassName: String, log: Logger)(argTypes: Class[_]*)(args: AnyRef*)

View File

@ -11,7 +11,7 @@ import scala.tools.nsc.util.ClassPath
class ConsoleInterface
{
def run(args: Array[String], bootClasspathString: String, classpathString: String, initialCommands: String, loader: ClassLoader, bindNames: Array[String], bindValues: Array[Any], log: Logger)
def run(args: Array[String], bootClasspathString: String, classpathString: String, initialCommands: String, cleanupCommands: String, loader: ClassLoader, bindNames: Array[String], bindValues: Array[Any], log: Logger)
{
val options = args.toList
lazy val interpreterSettings = MakeSettings.sync(options, log)
@ -47,6 +47,12 @@ class ConsoleInterface
if(!initialCommands.isEmpty)
interpreter.interpret(initialCommands)
}
override def closeInterpreter()
{
if(!cleanupCommands.isEmpty)
interpreter.interpret(cleanupCommands)
super.closeInterpreter()
}
}
loop.main(if(loader eq null) compilerSettings else interpreterSettings)
}

View File

@ -8,7 +8,7 @@ package sbt
object ConsoleProject
{
def apply(state: State, extra: String, options: Seq[String] = Nil)(implicit log: Logger)
def apply(state: State, extra: String, cleanupCommands: String = "", options: Seq[String] = Nil)(implicit log: Logger)
{
val extracted = Project extract state
val bindings = ("currentState" -> state) :: ("extracted" -> extracted ) :: Nil
@ -17,6 +17,6 @@ object ConsoleProject
val imports = Load.getImports(unit.unit) ++ Load.importAll(bindings.map(_._1))
val importString = imports.mkString("", ";\n", ";\n\n")
val initCommands = importString + extra
(new Console(compiler))(unit.classpath, options, initCommands)(Some(unit.loader), bindings)
(new Console(compiler))(unit.classpath, options, initCommands, cleanupCommands)(Some(unit.loader), bindings)
}
}

View File

@ -191,6 +191,7 @@ object Defaults extends BuildCommon
lazy val configTasks = docSetting(doc) ++ Seq(
initialCommands in GlobalScope :== "",
cleanupCommands in GlobalScope :== "",
compile <<= compileTask,
compileInputs <<= compileInputsTask,
compileIncSetup <<= compileIncSetupTask,
@ -461,9 +462,9 @@ object Defaults extends BuildCommon
def consoleProjectTask = (state, streams, initialCommands in consoleProject) map { (state, s, extra) => ConsoleProject(state, extra)(s.log); println() }
def consoleTask: Initialize[Task[Unit]] = consoleTask(fullClasspath, console)
def consoleQuickTask = consoleTask(externalDependencyClasspath, consoleQuick)
def consoleTask(classpath: TaskKey[Classpath], task: TaskKey[_]): Initialize[Task[Unit]] = (compilers in task, classpath in task, scalacOptions in task, initialCommands in task, streams) map {
(cs, cp, options, initCommands, s) =>
(new Console(cs.scalac))(data(cp), options, initCommands, s.log).foreach(msg => error(msg))
def consoleTask(classpath: TaskKey[Classpath], task: TaskKey[_]): Initialize[Task[Unit]] = (compilers in task, classpath in task, scalacOptions in task, initialCommands in task, cleanupCommands in task, streams) map {
(cs, cp, options, initCommands, cleanup, s) =>
(new Console(cs.scalac))(data(cp), options, initCommands, cleanup, s.log).foreach(msg => error(msg))
println()
}

View File

@ -127,6 +127,7 @@ object Keys
val javacOptions = SettingKey[Seq[String]]("javac-options", "Options for the Java compiler.")
val compileOrder = SettingKey[CompileOrder.Value]("compile-order", "Configures the order in which Java and sources within a single compilation are compiled. Valid values are: JavaThenScala, ScalaThenJava, or Mixed.")
val initialCommands = SettingKey[String]("initial-commands", "Initial commands to execute when starting up the Scala interpreter.")
val cleanupCommands = SettingKey[String]("cleanup-commands", "Commands to execute before the Scala interpreter exits.")
val compileInputs = TaskKey[Compiler.Inputs]("compile-inputs", "Collects all inputs needed for compilation.")
val scalaHome = SettingKey[Option[File]]("scala-home", "If Some, defines the local Scala installation to use for compilation, running, and testing.")
val scalaInstance = TaskKey[ScalaInstance]("scala-instance", "Defines the Scala instance to use for compilation, running, and testing.")

View File

@ -10,17 +10,17 @@ final class Console(compiler: AnalyzingCompiler)
{
/** Starts an interactive scala interpreter session with the given classpath.*/
def apply(classpath: Seq[File], log: Logger): Option[String] =
apply(classpath, Nil, "", log)
apply(classpath, Nil, "", "", log)
def apply(classpath: Seq[File], options: Seq[String], initialCommands: String, log: Logger): Option[String] =
apply(classpath, options, initialCommands)(None, Nil)(log)
def apply(classpath: Seq[File], options: Seq[String], initialCommands: String, cleanupCommands: String, log: Logger): Option[String] =
apply(classpath, options, initialCommands, cleanupCommands)(None, Nil)(log)
def apply(classpath: Seq[File], options: Seq[String], loader: ClassLoader, initialCommands: String)(bindings: (String, Any)*)(implicit log: Logger): Option[String] =
apply(classpath, options, initialCommands)(Some(loader), bindings)
def apply(classpath: Seq[File], options: Seq[String], loader: ClassLoader, initialCommands: String, cleanupCommands: String)(bindings: (String, Any)*)(implicit log: Logger): Option[String] =
apply(classpath, options, initialCommands, cleanupCommands)(Some(loader), bindings)
def apply(classpath: Seq[File], options: Seq[String], initialCommands: String)(loader: Option[ClassLoader], bindings: Seq[(String, Any)])(implicit log: Logger): Option[String] =
def apply(classpath: Seq[File], options: Seq[String], initialCommands: String, cleanupCommands: String)(loader: Option[ClassLoader], bindings: Seq[(String, Any)])(implicit log: Logger): Option[String] =
{
def console0 = compiler.console(classpath, options, initialCommands, log)(loader, bindings)
def console0 = compiler.console(classpath, options, initialCommands, cleanupCommands, log)(loader, bindings)
JLine.withJLine( Run.executeTrapExit(console0, log) )
}
}