mirror of https://github.com/sbt/sbt.git
Add shutdown command
Shutdown was being handled as a special case in CommandExchange. This promotes it to a full fledged command. Also replace instance of hard-coded strings with constants.
This commit is contained in:
parent
261084bbb2
commit
77b1e38e41
|
|
@ -14,8 +14,10 @@ object BasicCommandStrings {
|
|||
val HelpCommand: String = "help"
|
||||
val CompletionsCommand: String = "completions"
|
||||
val Exit: String = "exit"
|
||||
val Shutdown: String = "shutdown"
|
||||
val Quit: String = "quit"
|
||||
val TemplateCommand: String = "new"
|
||||
val Cancel: String = "cancel"
|
||||
|
||||
/** The command name to terminate the program.*/
|
||||
val TerminateAction: String = Exit
|
||||
|
|
@ -57,7 +59,8 @@ $HelpCommand <regular expression>
|
|||
def historyHelp =
|
||||
Help(Nil, (HistoryHelpBrief +: HistoryCommands.descriptions).toMap, Set(HistoryCommands.Start))
|
||||
|
||||
def exitBrief: String = "Terminates the build."
|
||||
def exitBrief: String = "Terminates the remote client or the build when called from the console."
|
||||
def shutdownBrief: String = "Terminates the build."
|
||||
|
||||
def logLevelHelp: Help = {
|
||||
val levels = Level.values.toSeq
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ object BasicCommands {
|
|||
call,
|
||||
early,
|
||||
exit,
|
||||
shutdown,
|
||||
history,
|
||||
oldshell,
|
||||
client,
|
||||
|
|
@ -356,6 +357,13 @@ object BasicCommands {
|
|||
case _ => s exit true
|
||||
}
|
||||
}
|
||||
def shutdown: Command = Command.command(Shutdown, shutdownBrief, shutdownBrief) { s =>
|
||||
s.source match {
|
||||
case Some(c) if c.channelName.startsWith("network") =>
|
||||
s"${DisconnectNetworkChannel} ${c.channelName}" :: (Exec(Shutdown, None) +: s)
|
||||
case _ => s exit true
|
||||
}
|
||||
}
|
||||
|
||||
@deprecated("Replaced by BuiltInCommands.continuous", "1.3.0")
|
||||
def continuous: Command =
|
||||
|
|
@ -412,7 +420,7 @@ object BasicCommands {
|
|||
case xs => xs map (_.commandLine)
|
||||
})
|
||||
NetworkClient.run(s0.configuration, arguments)
|
||||
"exit" :: s0.copy(remainingCommands = Nil)
|
||||
TerminateAction :: s0.copy(remainingCommands = Nil)
|
||||
}
|
||||
|
||||
def read: Command =
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import java.util.UUID
|
|||
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
|
||||
import java.util.concurrent.{ ConcurrentHashMap, LinkedBlockingQueue, TimeUnit }
|
||||
|
||||
import sbt.BasicCommandStrings.{ Shutdown, TerminateAction }
|
||||
import sbt.internal.client.NetworkClient.Arguments
|
||||
import sbt.internal.langserver.{ LogMessageParams, MessageType, PublishDiagnosticsParams }
|
||||
import sbt.internal.protocol._
|
||||
|
|
@ -155,13 +156,13 @@ class NetworkClient(
|
|||
val conn = new ServerConnection(sk) {
|
||||
override def onNotification(msg: JsonRpcNotificationMessage): Unit = {
|
||||
msg.method match {
|
||||
case "shutdown" =>
|
||||
case `Shutdown` =>
|
||||
val log = msg.params match {
|
||||
case Some(jvalue) => Converter.fromJson[Boolean](jvalue).getOrElse(true)
|
||||
case _ => false
|
||||
}
|
||||
if (running.compareAndSet(true, false) && log) {
|
||||
if (!arguments.commandArguments.contains("shutdown")) {
|
||||
if (!arguments.commandArguments.contains(Shutdown)) {
|
||||
if (Terminal.console.getLastLine.fold(true)(_.nonEmpty)) errorStream.println()
|
||||
console.appendLog(Level.Error, "sbt server disconnected")
|
||||
exitClean.set(false)
|
||||
|
|
@ -451,7 +452,7 @@ class NetworkClient(
|
|||
case Success(params) => splitDiagnostics(params); Vector()
|
||||
case Failure(_) => Vector()
|
||||
}
|
||||
case ("shutdown", Some(_)) => Vector.empty
|
||||
case (`Shutdown`, Some(_)) => Vector.empty
|
||||
case (msg, _) if msg.startsWith("build/") => Vector.empty
|
||||
case _ =>
|
||||
Vector(
|
||||
|
|
@ -557,7 +558,7 @@ class NetworkClient(
|
|||
withSignalHandler(contHandler, Signals.CONT) {
|
||||
interactiveThread.set(Thread.currentThread)
|
||||
val cleaned = arguments.commandArguments
|
||||
val userCommands = cleaned.takeWhile(_ != "exit")
|
||||
val userCommands = cleaned.takeWhile(_ != TerminateAction)
|
||||
val interactive = cleaned.isEmpty
|
||||
val exit = cleaned.nonEmpty && userCommands.isEmpty
|
||||
attachUUID.set(sendJson(attach, s"""{"interactive": $interactive}"""))
|
||||
|
|
@ -668,8 +669,8 @@ class NetworkClient(
|
|||
case _ => queue.take
|
||||
}
|
||||
} catch {
|
||||
case _: InterruptedException if cmd == "shutdown" => result = 0
|
||||
case _: InterruptedException => result = if (exitClean.get) 0 else 1
|
||||
case _: InterruptedException if cmd == Shutdown => result = 0
|
||||
case _: InterruptedException => result = if (exitClean.get) 0 else 1
|
||||
}
|
||||
}
|
||||
if (result == null) 1 else result
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import java.nio.channels.ClosedChannelException
|
|||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
import jline.console.history.PersistentHistory
|
||||
import sbt.BasicCommandStrings.{ Cancel, TerminateAction, Shutdown }
|
||||
import sbt.BasicKeys.{ historyPath, terminalShellPrompt }
|
||||
import sbt.State
|
||||
import sbt.internal.CommandChannel
|
||||
|
|
@ -54,7 +55,7 @@ private[sbt] object UITask {
|
|||
try {
|
||||
@tailrec def impl(): Either[String, String] = {
|
||||
lineReader.readLine(clear + terminal.prompt.mkPrompt()) match {
|
||||
case null => Left("exit")
|
||||
case null => Left(TerminateAction)
|
||||
case s: String =>
|
||||
lineReader.getHistory match {
|
||||
case p: PersistentHistory =>
|
||||
|
|
@ -63,8 +64,8 @@ private[sbt] object UITask {
|
|||
case _ =>
|
||||
}
|
||||
s match {
|
||||
case "" => impl()
|
||||
case cmd @ ("shutdown" | "exit" | "cancel") => Left(cmd)
|
||||
case "" => impl()
|
||||
case cmd @ (`Shutdown` | `TerminateAction` | `Cancel`) => Left(cmd)
|
||||
case cmd =>
|
||||
if (terminal.prompt != Prompt.Batch) terminal.setPrompt(Prompt.Running)
|
||||
terminal.printStream.write(Int.MinValue)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import java.util.Properties
|
|||
import java.util.concurrent.ForkJoinPool
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
import sbt.BasicCommandStrings.{ SetTerminal, Shell, TemplateCommand, networkExecPrefix }
|
||||
import sbt.BasicCommandStrings.{ SetTerminal, Shell, Shutdown, TemplateCommand, networkExecPrefix }
|
||||
import sbt.Project.LoadAction
|
||||
import sbt.compiler.EvalImports
|
||||
import sbt.internal.Aggregation.AnyKeys
|
||||
|
|
@ -1025,7 +1025,7 @@ object BuiltinCommands {
|
|||
* happen primarily on windows.
|
||||
*/
|
||||
if (Terminal.startedByRemoteClient && !exchange.hasServer) {
|
||||
Exec("shutdown", None) +: s1
|
||||
Exec(Shutdown, None) +: s1
|
||||
} else {
|
||||
exchange prompt ConsolePromptEvent(s0)
|
||||
val minGCInterval = Project
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import java.lang.reflect.InvocationTargetException
|
|||
import java.nio.file.Path
|
||||
import java.io.File
|
||||
|
||||
import sbt.BasicCommandStrings.TerminateAction
|
||||
import sbt.io._, syntax._
|
||||
import sbt.util._
|
||||
import sbt.internal.util.complete.{ DefaultParsers, Parser }, DefaultParsers._
|
||||
|
|
@ -54,7 +55,7 @@ private[sbt] object TemplateCommandUtil {
|
|||
case xs => xs map (_.commandLine)
|
||||
})
|
||||
run(infos, arguments, state.configuration, ivyConf, globalBase, scalaModuleInfo, log)
|
||||
"exit" :: s2.copy(remainingCommands = Nil)
|
||||
TerminateAction :: s2.copy(remainingCommands = Nil)
|
||||
}
|
||||
|
||||
private def run(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import java.net.Socket
|
|||
import java.util.concurrent.atomic._
|
||||
import java.util.concurrent.{ LinkedBlockingQueue, TimeUnit }
|
||||
|
||||
import sbt.BasicCommandStrings.networkExecPrefix
|
||||
import sbt.BasicCommandStrings.{ Cancel, Shutdown, TerminateAction, networkExecPrefix }
|
||||
import sbt.BasicKeys._
|
||||
import sbt.internal.protocol.JsonRpcResponseError
|
||||
import sbt.internal.server._
|
||||
|
|
@ -96,7 +96,7 @@ private[sbt] final class CommandExchange {
|
|||
case _ =>
|
||||
}
|
||||
}
|
||||
Exec("exit", Some(CommandSource(ConsoleChannel.defaultName)))
|
||||
Exec(TerminateAction, Some(CommandSource(ConsoleChannel.defaultName)))
|
||||
case x => x
|
||||
}
|
||||
case _ => commandQueue.take
|
||||
|
|
@ -105,11 +105,8 @@ private[sbt] final class CommandExchange {
|
|||
poll match {
|
||||
case Some(exec) if exec.source.fold(true)(s => channels.exists(_.name == s.channelName)) =>
|
||||
exec.commandLine match {
|
||||
case "shutdown" =>
|
||||
exec
|
||||
.withCommandLine("exit")
|
||||
.withSource(Some(CommandSource(ConsoleChannel.defaultName)))
|
||||
case "exit" if exec.source.fold(false)(_.channelName.startsWith("network")) =>
|
||||
case `TerminateAction`
|
||||
if exec.source.fold(false)(_.channelName.startsWith("network")) =>
|
||||
channels.collectFirst {
|
||||
case c: NetworkChannel if exec.source.fold(false)(_.channelName == c.name) => c
|
||||
} match {
|
||||
|
|
@ -383,8 +380,7 @@ private[sbt] final class CommandExchange {
|
|||
private[sbt] def shutdown(name: String): Unit = {
|
||||
Option(currentExecRef.get).foreach(cancel)
|
||||
commandQueue.clear()
|
||||
val exit =
|
||||
Exec("shutdown", Some(Exec.newExecId), Some(CommandSource(name)))
|
||||
val exit = Exec(Shutdown, Some(Exec.newExecId), Some(CommandSource(name)))
|
||||
commandQueue.add(exit)
|
||||
()
|
||||
}
|
||||
|
|
@ -415,7 +411,7 @@ private[sbt] final class CommandExchange {
|
|||
case mt: FastTrackTask =>
|
||||
mt.task match {
|
||||
case `attach` => mt.channel.prompt(ConsolePromptEvent(lastState.get))
|
||||
case "cancel" => Option(currentExecRef.get).foreach(cancel)
|
||||
case `Cancel` => Option(currentExecRef.get).foreach(cancel)
|
||||
case t if t.startsWith(ContinuousCommands.stopWatch) =>
|
||||
ContinuousCommands.stopWatchImpl(mt.channel.name)
|
||||
mt.channel match {
|
||||
|
|
@ -423,8 +419,8 @@ private[sbt] final class CommandExchange {
|
|||
case _ => mt.channel.prompt(ConsolePromptEvent(lastState.get))
|
||||
}
|
||||
commandQueue.add(Exec(t, None, None))
|
||||
case "exit" => exit(mt)
|
||||
case "shutdown" =>
|
||||
case `TerminateAction` => exit(mt)
|
||||
case `Shutdown` =>
|
||||
channels.find(_.name == mt.channel.name) match {
|
||||
case Some(c: NetworkChannel) => c.shutdown(false)
|
||||
case _ =>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ package internal.nio
|
|||
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
|
||||
import sbt.BasicCommandStrings.{ RebootCommand, TerminateAction }
|
||||
import sbt.BasicCommandStrings.{ RebootCommand, Shutdown, TerminateAction }
|
||||
import sbt.Keys.{ baseDirectory, pollInterval, state }
|
||||
import sbt.Scope.Global
|
||||
import sbt.SlashSyntax0._
|
||||
|
|
@ -90,7 +90,7 @@ private[sbt] class CheckBuildSources extends AutoCloseable {
|
|||
val commands =
|
||||
allCmds.flatMap(_.split(";").flatMap(_.trim.split(" ").headOption).filterNot(_.isEmpty))
|
||||
val filter = (c: String) =>
|
||||
c == LoadProject || c == RebootCommand || c == TerminateAction || c == "shutdown"
|
||||
c == LoadProject || c == RebootCommand || c == TerminateAction || c == Shutdown
|
||||
val res = !commands.exists(filter)
|
||||
if (!res) {
|
||||
previousStamps.set(getStamps(force = true))
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ package server
|
|||
|
||||
import java.net.URI
|
||||
|
||||
import sbt.BasicCommandStrings.Shutdown
|
||||
import sbt.BuildSyntax._
|
||||
import sbt.Def._
|
||||
import sbt.Keys._
|
||||
|
|
@ -153,7 +154,7 @@ object BuildServerProtocol {
|
|||
()
|
||||
|
||||
case r: JsonRpcRequestMessage if r.method == "build/exit" =>
|
||||
val _ = callback.appendExec("shutdown", Some(r.id))
|
||||
val _ = callback.appendExec(Shutdown, Some(r.id))
|
||||
|
||||
case r: JsonRpcRequestMessage if r.method == "buildTarget/sources" =>
|
||||
val param = Converter.fromJson[SourcesParams](json(r)).get
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import java.nio.channels.ClosedChannelException
|
|||
import java.util.concurrent.{ ConcurrentHashMap, LinkedBlockingQueue }
|
||||
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
|
||||
|
||||
import sbt.BasicCommandStrings.{ Shutdown, TerminateAction }
|
||||
import sbt.internal.langserver.{ CancelRequestParams, ErrorCodes, LogMessageParams, MessageType }
|
||||
import sbt.internal.langserver.{ CancelRequestParams, ErrorCodes }
|
||||
import sbt.internal.protocol.{
|
||||
|
|
@ -150,7 +151,7 @@ final class NetworkChannel(
|
|||
override def reader: UITask.Reader = () => {
|
||||
try {
|
||||
this.synchronized(this.wait)
|
||||
Left("exit")
|
||||
Left(TerminateAction)
|
||||
} catch {
|
||||
case _: InterruptedException => Right("")
|
||||
}
|
||||
|
|
@ -564,7 +565,7 @@ final class NetworkChannel(
|
|||
super.shutdown(logShutdown)
|
||||
if (logShutdown) Terminal.consoleLog(s"shutting down client connection $name")
|
||||
VirtualTerminal.cancelRequests(name)
|
||||
try jsonRpcNotify("shutdown", logShutdown)
|
||||
try jsonRpcNotify(Shutdown, logShutdown)
|
||||
catch { case _: IOException => }
|
||||
running.set(false)
|
||||
out.close()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import java.time.{ Instant, ZoneId, ZonedDateTime }
|
|||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import sbt.BasicCommandStrings.ContinuousExecutePrefix
|
||||
import sbt.BasicCommandStrings.{ ContinuousExecutePrefix, TerminateAction }
|
||||
import sbt._
|
||||
import sbt.internal.LabeledFunctions._
|
||||
import sbt.internal.nio.FileEvent
|
||||
|
|
@ -487,7 +487,7 @@ object Watch {
|
|||
Watch.InputOption(4.toChar, "<ctrl-d>", "interrupt (exits sbt in batch mode)", CancelWatch),
|
||||
Watch.InputOption('r', "re-run the command", Trigger),
|
||||
Watch.InputOption('s', "return to shell", Prompt),
|
||||
Watch.InputOption('q', "quit sbt", Run("exit")),
|
||||
Watch.InputOption('q', "quit sbt", Run(TerminateAction)),
|
||||
Watch.InputOption('?', "print options", ShowOptions)
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue