mirror of https://github.com/sbt/sbt.git
Cleanup SbtHandler
This commit is contained in:
parent
4debec0053
commit
89e501443c
|
|
@ -22,41 +22,40 @@ final case class SbtInstance(process: Process, server: IPC.Server)
|
|||
final class SbtHandler(remoteSbtCreator: RemoteSbtCreator) extends StatementHandler {
|
||||
|
||||
type State = Option[SbtInstance]
|
||||
|
||||
def initialState = None
|
||||
|
||||
def apply(command: String, arguments: List[String], i: Option[SbtInstance]): Option[SbtInstance] =
|
||||
onSbtInstance(i) { (process, server) =>
|
||||
onSbtInstance(i) { (_, server) =>
|
||||
send((command :: arguments.map(escape)).mkString(" "), server)
|
||||
receive(command + " failed", server)
|
||||
receive(s"$command failed", server)
|
||||
}
|
||||
|
||||
def onSbtInstance(i: Option[SbtInstance])(f: (Process, IPC.Server) => Unit): Option[SbtInstance] =
|
||||
i match {
|
||||
case Some(SbtInstance(_, server)) if server.isClosed =>
|
||||
finish(i)
|
||||
onNewSbtInstance(f)
|
||||
case Some(SbtInstance(process, server)) =>
|
||||
f(process, server)
|
||||
i
|
||||
case None =>
|
||||
onNewSbtInstance(f)
|
||||
case Some(SbtInstance(_, server)) if server.isClosed => finish(i); onNewSbtInstance(f)
|
||||
case Some(SbtInstance(process, server)) => f(process, server); i
|
||||
case None => onNewSbtInstance(f)
|
||||
}
|
||||
|
||||
private[this] def onNewSbtInstance(f: (Process, IPC.Server) => Unit): Option[SbtInstance] = {
|
||||
val server = IPC.unmanagedServer
|
||||
val p = try newRemote(server)
|
||||
catch { case e: Throwable => server.close(); throw e }
|
||||
val ai = Some(SbtInstance(p, server))
|
||||
val p =
|
||||
try newRemote(server)
|
||||
catch { case e: Throwable => server.close(); throw e }
|
||||
val i = Some(SbtInstance(p, server))
|
||||
try f(p, server)
|
||||
catch {
|
||||
case e: Throwable =>
|
||||
// TODO: closing is necessary only because StatementHandler uses exceptions for signaling errors
|
||||
finish(ai); throw e
|
||||
finish(i)
|
||||
throw e
|
||||
}
|
||||
ai
|
||||
i
|
||||
}
|
||||
|
||||
def finish(state: Option[SbtInstance]) = state match {
|
||||
def finish(state: State) = state match {
|
||||
case None =>
|
||||
case Some(SbtInstance(process, server)) =>
|
||||
try {
|
||||
send("exit", server)
|
||||
|
|
@ -65,24 +64,28 @@ final class SbtHandler(remoteSbtCreator: RemoteSbtCreator) extends StatementHand
|
|||
} catch {
|
||||
case _: IOException => process.destroy()
|
||||
}
|
||||
case None =>
|
||||
}
|
||||
def send(message: String, server: IPC.Server) = server.connection { _.send(message) }
|
||||
|
||||
def send(message: String, server: IPC.Server) = server.connection(_.send(message))
|
||||
|
||||
def receive(errorMessage: String, server: IPC.Server) =
|
||||
server.connection { ipc =>
|
||||
val resultMessage = ipc.receive
|
||||
if (!resultMessage.toBoolean) throw new TestFailed(errorMessage)
|
||||
}
|
||||
|
||||
def newRemote(server: IPC.Server): Process = {
|
||||
val p = remoteSbtCreator.newRemote(server)
|
||||
try receive("Remote sbt initialization failed", server)
|
||||
catch { case _: SocketException => throw new TestFailed("Remote sbt initialization failed") }
|
||||
p
|
||||
}
|
||||
import java.util.regex.Pattern.{ quote => q }
|
||||
|
||||
// if the argument contains spaces, enclose it in quotes, quoting backslashes and quotes
|
||||
def escape(argument: String) =
|
||||
def escape(argument: String) = {
|
||||
import java.util.regex.Pattern.{ quote => q }
|
||||
if (argument.contains(" "))
|
||||
"\"" + argument.replaceAll(q("""\"""), """\\""").replaceAll(q("\""), "\\\"") + "\""
|
||||
else argument
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue