diff --git a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala index 233ca0526..ea42ec597 100644 --- a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala +++ b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala @@ -166,6 +166,8 @@ class NetworkClient( console.appendLog(Level.Error, "sbt server disconnected") exitClean.set(false) } + } else { + console.appendLog(Level.Info, "sbt server disconnected") } stdinBytes.offer(-1) Option(inputThread.get).foreach(_.close()) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index a4e048edc..aa35b0cf6 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -422,9 +422,14 @@ private[sbt] final class CommandExchange { case _ => mt.channel.prompt(ConsolePromptEvent(lastState.get)) } commandQueue.add(Exec(t, None, None)) - case "exit" => exit(mt) - case "shutdown" => shutdown(mt.channel.name) - case _ => + case "exit" => exit(mt) + case "shutdown" => + channels.find(_.name == mt.channel.name) match { + case Some(c: NetworkChannel) => c.shutdown(false) + case _ => + } + shutdown(mt.channel.name) + case _ => } } if (!isStopped.get) impl() diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index 7259478ef..4fa5a37a5 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -549,6 +549,15 @@ final class NetworkChannel( shutdown(true) } import sjsonnew.BasicJsonProtocol.BooleanJsonFormat + + /** + * Closes down the channel. Before closing the socket, it sends a notification to + * the client to shutdown. If the client initiated the shutdown, we don't want the + * client to display an error or return a non-zero exit code so we send it a + * notification that tells it whether or not to log the shutdown. This can't + * easily be done client side because when the client is in interactive session, + * it doesn't know commands it has sent to the server. + */ override def shutdown(logShutdown: Boolean): Unit = { terminal.close() StandardMain.exchange.removeChannel(this)