From 8137c8078244c6f7e96a23f67f332940c867b685 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Tue, 17 Nov 2020 20:20:14 -0800 Subject: [PATCH] Fix thin client sbt process startup output The boot server socket was not working correctly when the sbt server was started by the thin client. This was because it is necessary for us to create a ConsoleTerminal in order for System.out and System.err to be properly forwarded to the clients connected over the boot server socket. As a result, if you started a server instance of sbt with the thin client, you wouldn't see any output util you connected to the server. The fix is to just make sure that we create a console terminal if sbt is run as a subprocess. --- .../src/main/scala/sbt/internal/util/Terminal.scala | 5 +++-- .../src/main/scala/sbt/internal/client/NetworkClient.scala | 2 +- main/src/main/scala/sbt/Main.scala | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala index 762541cc4..d7cca5535 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala @@ -337,9 +337,10 @@ object Terminal { * @tparam T the result type of the thunk * @return the result of the thunk */ - private[sbt] def withStreams[T](isServer: Boolean)(f: => T): T = { + private[sbt] def withStreams[T](isServer: Boolean, isSubProcess: Boolean)(f: => T): T = { // In ci environments, don't touch the io streams unless run with -Dsbt.io.virtual=true - if (hasConsole && !isDumbTerminal) consoleTerminalHolder.set(newConsoleTerminal()) + if ((hasConsole && !isDumbTerminal) || isSubProcess) + consoleTerminalHolder.set(newConsoleTerminal()) if (hasVirtualIO) { hasProgress.set(isServer && isAnsiSupported) activeTerminal.set(consoleTerminalHolder.get) 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 57ef3ea65..c89715661 100644 --- a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala +++ b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala @@ -1160,7 +1160,7 @@ object NetworkClient { Runtime.getRuntime.addShutdownHook(hook) if (Util.isNonCygwinWindows) sbt.internal.util.JLine3.forceWindowsJansi() val parsed = parseArgs(restOfArgs) - System.exit(Terminal.withStreams(false) { + System.exit(Terminal.withStreams(isServer = false, isSubProcess = false) { val term = Terminal.console try client(base, parsed, term.inputStream, System.err, term, useJNI) catch { case _: AccessDeniedException => 1 } finally { diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 26fa0b00b..d7b857fa4 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -79,13 +79,13 @@ private[sbt] object xMain { BspClient.run(dealiasBaseDirectory(configuration)) } else { bootServerSocket.foreach(l => ITerminal.setBootStreams(l.inputStream, l.outputStream)) - ITerminal.withStreams(true) { + val detachStdio = userCommands.exists(_ == BasicCommandStrings.DashDashDetachStdio) + ITerminal.withStreams(true, isSubProcess = detachStdio) { if (clientModByEnv || userCommands.exists(isClient)) { val args = userCommands.toList.filterNot(isClient) NetworkClient.run(dealiasBaseDirectory(configuration), args) Exit(0) } else { - val detachStdio = userCommands.exists(_ == BasicCommandStrings.DashDashDetachStdio) val state0 = StandardMain .initialState( dealiasBaseDirectory(configuration),