mirror of https://github.com/sbt/sbt.git
cleanup MainResult handling to enable finer control over reloading
This commit is contained in:
parent
cf17a578a1
commit
8d922b61ab
|
|
@ -29,7 +29,7 @@ final class xMain extends xsbti.AppMain
|
||||||
import CommandSupport.{DefaultsCommand, InitCommand}
|
import CommandSupport.{DefaultsCommand, InitCommand}
|
||||||
val initialCommandDefs = Seq(initialize, defaults)
|
val initialCommandDefs = Seq(initialize, defaults)
|
||||||
val commands = DefaultsCommand +: InitCommand +: (DefaultBootCommands ++ configuration.arguments.map(_.trim))
|
val commands = DefaultsCommand +: InitCommand +: (DefaultBootCommands ++ configuration.arguments.map(_.trim))
|
||||||
val state = State( configuration, initialCommandDefs, Set.empty, None, commands, initialAttributes, Next.Continue )
|
val state = State( configuration, initialCommandDefs, Set.empty, None, commands, initialAttributes, None )
|
||||||
MainLoop.run(state)
|
MainLoop.run(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ final class ScriptMain extends xsbti.AppMain
|
||||||
{
|
{
|
||||||
import BuiltinCommands.{initialAttributes, ScriptCommands}
|
import BuiltinCommands.{initialAttributes, ScriptCommands}
|
||||||
val commands = Script.Name +: configuration.arguments.map(_.trim)
|
val commands = Script.Name +: configuration.arguments.map(_.trim)
|
||||||
val state = State( configuration, ScriptCommands, Set.empty, None, commands, initialAttributes, Next.Continue )
|
val state = State( configuration, ScriptCommands, Set.empty, None, commands, initialAttributes, None )
|
||||||
MainLoop.run(state)
|
MainLoop.run(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,25 +49,19 @@ final class ConsoleMain extends xsbti.AppMain
|
||||||
{
|
{
|
||||||
import BuiltinCommands.{initialAttributes, ConsoleCommands}
|
import BuiltinCommands.{initialAttributes, ConsoleCommands}
|
||||||
val commands = IvyConsole.Name +: configuration.arguments.map(_.trim)
|
val commands = IvyConsole.Name +: configuration.arguments.map(_.trim)
|
||||||
val state = State( configuration, ConsoleCommands, Set.empty, None, commands, initialAttributes, Next.Continue )
|
val state = State( configuration, ConsoleCommands, Set.empty, None, commands, initialAttributes, None )
|
||||||
MainLoop.run(state)
|
MainLoop.run(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object MainLoop
|
object MainLoop
|
||||||
{
|
{
|
||||||
@tailrec final def run(state: State): xsbti.MainResult =
|
@tailrec final def run(state: State): xsbti.MainResult =
|
||||||
{
|
state.result match
|
||||||
import Next._
|
|
||||||
state.next match
|
|
||||||
{
|
{
|
||||||
case Continue => run(next(state))
|
case None => run(next(state))
|
||||||
case Fail => Exit(1)
|
case Some(result) => result
|
||||||
case Done => Exit(0)
|
|
||||||
case Reload =>
|
|
||||||
val app = state.configuration.provider
|
|
||||||
new Reboot(app.scalaProvider.version, state.remainingCommands, app.id, state.configuration.baseDirectory)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
def next(state: State): State =
|
def next(state: State): State =
|
||||||
ErrorHandling.wideConvert { state.process(Command.process) } match
|
ErrorHandling.wideConvert { state.process(Command.process) } match
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,23 @@ package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
private case class Exit(code: Int) extends xsbti.Exit
|
final case class Exit(code: Int) extends xsbti.Exit
|
||||||
{
|
{
|
||||||
require(code >= 0)
|
require(code >= 0)
|
||||||
}
|
}
|
||||||
private class Reboot(val scalaVersion: String, argsList: Seq[String], val app: xsbti.ApplicationID, val baseDirectory: File) extends xsbti.Reboot
|
final case class Reboot(scalaVersion: String, argsList: Seq[String], app: xsbti.ApplicationID, baseDirectory: File) extends xsbti.Reboot
|
||||||
{
|
{
|
||||||
def arguments = argsList.toArray
|
def arguments = argsList.toArray
|
||||||
}
|
}
|
||||||
private class ApplicationID(delegate: xsbti.ApplicationID, newVersion: String) extends xsbti.ApplicationID
|
final case class ApplicationID(groupID: String, name: String, version: String, mainClass: String, components: Seq[String], crossVersioned: Boolean, extra: Seq[File]) extends xsbti.ApplicationID
|
||||||
{
|
{
|
||||||
def groupID = delegate.groupID
|
def mainComponents = components.toArray
|
||||||
def name = delegate.name
|
def classpathExtra = extra.toArray
|
||||||
def version = newVersion
|
}
|
||||||
|
object ApplicationID
|
||||||
def mainClass = delegate.mainClass
|
{
|
||||||
def mainComponents = delegate.mainComponents
|
def apply(delegate: xsbti.ApplicationID, newVersion: String): ApplicationID =
|
||||||
def crossVersioned = delegate.crossVersioned
|
apply(delegate).copy(version = newVersion)
|
||||||
|
def apply(delegate: xsbti.ApplicationID): ApplicationID =
|
||||||
def classpathExtra = delegate.classpathExtra
|
ApplicationID(delegate.groupID, delegate.name, delegate.version, delegate.mainClass, delegate.mainComponents, delegate.crossVersioned, delegate.classpathExtra)
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ final case class State(
|
||||||
onFailure: Option[String],
|
onFailure: Option[String],
|
||||||
remainingCommands: Seq[String],
|
remainingCommands: Seq[String],
|
||||||
attributes: AttributeMap,
|
attributes: AttributeMap,
|
||||||
next: Next.Value
|
result: Option[xsbti.MainResult]
|
||||||
) extends Identity {
|
) extends Identity {
|
||||||
lazy val combinedParser = Command.combine(definedCommands)(this)
|
lazy val combinedParser = Command.combine(definedCommands)(this)
|
||||||
}
|
}
|
||||||
|
|
@ -24,16 +24,13 @@ trait Identity {
|
||||||
override final def toString = super.toString
|
override final def toString = super.toString
|
||||||
}
|
}
|
||||||
|
|
||||||
object Next extends Enumeration {
|
|
||||||
val Reload, Fail, Done, Continue = Value
|
|
||||||
}
|
|
||||||
|
|
||||||
trait StateOps {
|
trait StateOps {
|
||||||
def process(f: (String, State) => State): State
|
def process(f: (String, State) => State): State
|
||||||
def ::: (commands: Seq[String]): State
|
def ::: (commands: Seq[String]): State
|
||||||
def :: (command: String): State
|
def :: (command: String): State
|
||||||
def continue: State
|
def continue: State
|
||||||
def reboot(full: Boolean): State
|
def reboot(full: Boolean): State
|
||||||
|
def setResult(n: Option[xsbti.MainResult]): State
|
||||||
def reload: State
|
def reload: State
|
||||||
def exit(ok: Boolean): State
|
def exit(ok: Boolean): State
|
||||||
def fail: State
|
def fail: State
|
||||||
|
|
@ -48,6 +45,12 @@ trait StateOps {
|
||||||
}
|
}
|
||||||
object State
|
object State
|
||||||
{
|
{
|
||||||
|
def defaultReload(state: State): Reboot =
|
||||||
|
{
|
||||||
|
val app = state.configuration.provider
|
||||||
|
new Reboot(app.scalaProvider.version, state.remainingCommands, app.id, state.configuration.baseDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
implicit def stateOps(s: State): StateOps = new StateOps {
|
implicit def stateOps(s: State): StateOps = new StateOps {
|
||||||
def process(f: (String, State) => State): State =
|
def process(f: (String, State) => State): State =
|
||||||
s.remainingCommands match {
|
s.remainingCommands match {
|
||||||
|
|
@ -60,11 +63,11 @@ object State
|
||||||
def ++ (newCommands: Seq[Command]): State = s.copy(definedCommands = (s.definedCommands ++ newCommands).distinct)
|
def ++ (newCommands: Seq[Command]): State = s.copy(definedCommands = (s.definedCommands ++ newCommands).distinct)
|
||||||
def + (newCommand: Command): State = this ++ (newCommand :: Nil)
|
def + (newCommand: Command): State = this ++ (newCommand :: Nil)
|
||||||
def baseDir: File = s.configuration.baseDirectory
|
def baseDir: File = s.configuration.baseDirectory
|
||||||
def setNext(n: Next.Value) = s.copy(next = n)
|
def setResult(n: Option[xsbti.MainResult]) = s.copy(result = n)
|
||||||
def continue = setNext(Next.Continue)
|
def continue = setResult(None)
|
||||||
def reboot(full: Boolean) = throw new xsbti.FullReload(s.remainingCommands.toArray, full)
|
def reboot(full: Boolean) = throw new xsbti.FullReload(s.remainingCommands.toArray, full)
|
||||||
def reload = setNext(Next.Reload)
|
def reload = setResult(Some(defaultReload(s)))
|
||||||
def exit(ok: Boolean) = setNext(if(ok) Next.Done else Next.Fail)
|
def exit(ok: Boolean) = setResult(Some(Exit(if(ok) 0 else 1)))
|
||||||
def get[T](key: AttributeKey[T]) = s.attributes get key
|
def get[T](key: AttributeKey[T]) = s.attributes get key
|
||||||
def put[T](key: AttributeKey[T], value: T) = s.copy(attributes = s.attributes.put(key, value))
|
def put[T](key: AttributeKey[T], value: T) = s.copy(attributes = s.attributes.put(key, value))
|
||||||
def remove(key: AttributeKey[_]) = s.copy(attributes = s.attributes remove key)
|
def remove(key: AttributeKey[_]) = s.copy(attributes = s.attributes remove key)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue