diff --git a/main/src/main/scala/sbt/MainLoop.scala b/main/src/main/scala/sbt/MainLoop.scala index 9556c0e1d..85893709c 100644 --- a/main/src/main/scala/sbt/MainLoop.scala +++ b/main/src/main/scala/sbt/MainLoop.scala @@ -233,17 +233,16 @@ private[sbt] object MainLoop: exchange.setState(cmdProgressState) exchange.setExec(Some(exec)) - val (restoreTerminal, termState) = channelName.flatMap(exchange.channelForName) match { + val (flushTerminal, termState) = channelName.flatMap(exchange.channelForName) match case Some(c) => val prevTerminal = ITerminal.set(c.terminal) // temporarily set the prompt to running during task evaluation c.terminal.setPrompt(Prompt.Running) - (() => { - ITerminal.set(prevTerminal) - c.terminal.flush() - }) -> cmdProgressState.put(Keys.terminalKey, Terminal(c.terminal)) + (() => c.terminal.flush()) -> cmdProgressState.put( + Keys.terminalKey, + Terminal(c.terminal) + ) case _ => (() => ()) -> cmdProgressState.put(Keys.terminalKey, Terminal(ITerminal.get)) - } val currentCmdProgress = cmdProgressState.get(sbt.Keys.currentCommandProgress) @@ -279,12 +278,10 @@ private[sbt] object MainLoop: currentCmdProgress .foreach(_.afterCommand(exec.commandLine, Left(e))) throw e - } finally { + } finally // Flush the terminal output after command evaluation to ensure that all output - // is displayed in the thin client before we report the command status. Also - // set the prompt to whatever it was before we started evaluating the task. - restoreTerminal() - } + // is displayed in the thin client before we report the command status. + flushTerminal() if ( exec.execId.fold(true)(!_.startsWith(networkExecPrefix)) && !exec.commandLine.startsWith(networkExecPrefix) diff --git a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala index 936fe9c57..0e1821488 100644 --- a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala +++ b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala @@ -28,6 +28,7 @@ import sbt.util.{ Level, Logger } import scala.concurrent.ExecutionContext import scala.concurrent.duration.* import scala.util.Try +import scala.util.control.NonFatal import sbt.util.LoggerContext import java.util.concurrent.TimeoutException import xsbti.FileConverter @@ -308,19 +309,21 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe copyClasspath(products, full, workingDirectory, hashFileContents = true, converter) private[sbt] def pauseChannelDuringJob(state: State, handle: JobHandle): Unit = - currentChannel(state) match - case Some(channel) => - handle match - case t: ThreadJobHandle => - val level = channel.logLevel - channel.setLevel(Level.Error) - channel.pause() - t.job.onStop: () => - channel.setLevel(level) - channel.resume() - channel.prompt(ConsolePromptEvent(state)) - case _ => () - case _ => () + if !jobs.contains(handle) then () + else + currentChannel(state) match + case Some(channel) => + handle match + case t: ThreadJobHandle => + val level = channel.logLevel + channel.setLevel(Level.Error) + channel.pause() + t.job.onStop: () => + channel.setLevel(level) + channel.resume() + channel.prompt(ConsolePromptEvent(state)) + case _ => () + case _ => () private[sbt] def currentChannel(state: State): Option[CommandChannel] = state.currentCommand match @@ -424,7 +427,8 @@ private[sbt] class BackgroundThreadPool extends java.io.Closeable { list } listeners.foreach { l => - l.executionContext.execute(() => l.callback()) + try l.executionContext.execute(() => l.callback()) + catch case NonFatal(_) => () } } }