mirror of https://github.com/sbt/sbt.git
Unprompt channels during project load
In the situation where sbt was started in server mode and a client is running a `~` command and a project reload is triggered by a change to a build source, the console terminal looks like sbt:foo> [info] received remote command: ~compile sbt:foo> [info] welcome to sbt 1.4.0-SNAPSHOT (Azul Systems, Inc. Java 1.8.0_252) sbt:foo> [info] loading global plugins from ~/.sbt/1.0/plugins sbt:foo> [info] loading settings for project foo-build from metals.sbt ... sbt:foo> [info] loading project definition from ~/foo/project sbt:foo> [info] loading settings for project root from build.sbt ... sbt:foo> [info] loading settings for project macros from build.sbt ... sbt:foo> [info] loading settings for project main from build.sbt ... sbt:foo> [info] set current project to foo (in build file:~/foo) sbt:foo> This change fixes that by unprompting all channels during project loading and reprompting them when it completes.
This commit is contained in:
parent
30e4c02c9c
commit
b1dcf031a5
|
|
@ -44,4 +44,5 @@ private[sbt] object Prompt {
|
||||||
private[sbt] case object Running extends NoPrompt
|
private[sbt] case object Running extends NoPrompt
|
||||||
private[sbt] case object Batch extends NoPrompt
|
private[sbt] case object Batch extends NoPrompt
|
||||||
private[sbt] case object Watch extends NoPrompt
|
private[sbt] case object Watch extends NoPrompt
|
||||||
|
private[sbt] case object Loading extends NoPrompt
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -772,7 +772,7 @@ object Terminal {
|
||||||
case s if s.nonEmpty => currentLine.set(new ArrayBuffer[Byte])
|
case s if s.nonEmpty => currentLine.set(new ArrayBuffer[Byte])
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
progressState.reprint(TerminalImpl.this, rawPrintStream)
|
if (prompt != Prompt.Loading) progressState.reprint(TerminalImpl.this, rawPrintStream)
|
||||||
new ArrayBuffer[Byte]
|
new ArrayBuffer[Byte]
|
||||||
} else buf += i
|
} else buf += i
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import java.util.concurrent.Executors
|
||||||
|
|
||||||
import sbt.State
|
import sbt.State
|
||||||
import sbt.internal.util.{ ConsoleAppender, ProgressEvent, ProgressState, Util }
|
import sbt.internal.util.{ ConsoleAppender, ProgressEvent, ProgressState, Util }
|
||||||
import sbt.internal.util.Prompt.{ AskUser, Running }
|
import sbt.internal.util.Prompt.{ AskUser, Loading, Running }
|
||||||
|
|
||||||
private[sbt] class UserThread(val channel: CommandChannel) extends AutoCloseable {
|
private[sbt] class UserThread(val channel: CommandChannel) extends AutoCloseable {
|
||||||
private[this] val uiThread = new AtomicReference[(UITask, Thread)]
|
private[this] val uiThread = new AtomicReference[(UITask, Thread)]
|
||||||
|
|
@ -70,8 +70,9 @@ private[sbt] class UserThread(val channel: CommandChannel) extends AutoCloseable
|
||||||
}
|
}
|
||||||
val state = consolePromptEvent.state
|
val state = consolePromptEvent.state
|
||||||
terminal.prompt match {
|
terminal.prompt match {
|
||||||
case Running => terminal.setPrompt(AskUser(() => UITask.shellPrompt(terminal, state)))
|
case Loading | Running =>
|
||||||
case _ =>
|
terminal.setPrompt(AskUser(() => UITask.shellPrompt(terminal, state)))
|
||||||
|
case _ =>
|
||||||
}
|
}
|
||||||
onProgressEvent(ProgressEvent("Info", Vector(), None, None, None))
|
onProgressEvent(ProgressEvent("Info", Vector(), None, None, None))
|
||||||
reset(state)
|
reset(state)
|
||||||
|
|
|
||||||
|
|
@ -913,6 +913,8 @@ object BuiltinCommands {
|
||||||
}
|
}
|
||||||
|
|
||||||
def doLoadProject(s0: State, action: LoadAction.Value): State = {
|
def doLoadProject(s0: State, action: LoadAction.Value): State = {
|
||||||
|
StandardMain.exchange.unprompt(ConsoleUnpromptEvent(None), force = true)
|
||||||
|
StandardMain.exchange.channels.foreach(_.terminal.setPrompt(Prompt.Loading))
|
||||||
welcomeBanner(s0)
|
welcomeBanner(s0)
|
||||||
checkSBTVersionChanged(s0)
|
checkSBTVersionChanged(s0)
|
||||||
val (s1, base) = Project.loadAction(SessionVar.clear(s0), action)
|
val (s1, base) = Project.loadAction(SessionVar.clear(s0), action)
|
||||||
|
|
@ -933,7 +935,9 @@ object BuiltinCommands {
|
||||||
SessionSettings.checkSession(session, s2)
|
SessionSettings.checkSession(session, s2)
|
||||||
val s3 = addCacheStoreFactoryFactory(Project.setProject(session, structure, s2))
|
val s3 = addCacheStoreFactoryFactory(Project.setProject(session, structure, s2))
|
||||||
val s4 = setupGlobalFileTreeRepository(s3)
|
val s4 = setupGlobalFileTreeRepository(s3)
|
||||||
CheckBuildSources.init(LintUnused.lintUnusedFunc(s4))
|
val s5 = CheckBuildSources.init(LintUnused.lintUnusedFunc(s4))
|
||||||
|
StandardMain.exchange.prompt(ConsolePromptEvent(s5))
|
||||||
|
s5
|
||||||
}
|
}
|
||||||
|
|
||||||
private val setupGlobalFileTreeRepository: State => State = { state =>
|
private val setupGlobalFileTreeRepository: State => State = { state =>
|
||||||
|
|
@ -977,9 +981,11 @@ object BuiltinCommands {
|
||||||
val exchange = StandardMain.exchange
|
val exchange = StandardMain.exchange
|
||||||
if (exchange.channels.exists(ContinuousCommands.isInWatch)) {
|
if (exchange.channels.exists(ContinuousCommands.isInWatch)) {
|
||||||
val s1 = exchange.run(s0)
|
val s1 = exchange.run(s0)
|
||||||
|
def needPrompt(c: CommandChannel) =
|
||||||
|
ContinuousCommands.isInWatch(c) && !ContinuousCommands.isPending(c)
|
||||||
exchange.channels.foreach {
|
exchange.channels.foreach {
|
||||||
case c if ContinuousCommands.isPending(c) =>
|
case c if needPrompt(c) => c.prompt(ConsolePromptEvent(s1))
|
||||||
case c => c.prompt(ConsolePromptEvent(s1))
|
case _ =>
|
||||||
}
|
}
|
||||||
val exec: Exec = getExec(s1, Duration.Inf)
|
val exec: Exec = getExec(s1, Duration.Inf)
|
||||||
val remaining: List[Exec] =
|
val remaining: List[Exec] =
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ object MainLoop {
|
||||||
}
|
}
|
||||||
StandardMain.exchange.setState(progressState)
|
StandardMain.exchange.setState(progressState)
|
||||||
StandardMain.exchange.setExec(Some(exec))
|
StandardMain.exchange.setExec(Some(exec))
|
||||||
StandardMain.exchange.unprompt(ConsoleUnpromptEvent(exec.source))
|
StandardMain.exchange.unprompt(ConsoleUnpromptEvent(exec.source), force = false)
|
||||||
val newState = Command.process(exec.commandLine, progressState)
|
val newState = Command.process(exec.commandLine, progressState)
|
||||||
if (exec.execId.fold(true)(!_.startsWith(networkExecPrefix)) &&
|
if (exec.execId.fold(true)(!_.startsWith(networkExecPrefix)) &&
|
||||||
!exec.commandLine.startsWith(networkExecPrefix)) {
|
!exec.commandLine.startsWith(networkExecPrefix)) {
|
||||||
|
|
|
||||||
|
|
@ -350,7 +350,11 @@ private[sbt] final class CommandExchange {
|
||||||
case c => c.prompt(event)
|
case c => c.prompt(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def unprompt(event: ConsoleUnpromptEvent): Unit = channels.foreach(_.unprompt(event))
|
def unprompt(event: ConsoleUnpromptEvent, force: Boolean): Unit = {
|
||||||
|
if (force)
|
||||||
|
channels.foreach(c => c.unprompt(event.copy(lastSource = Some(CommandSource(c.name)))))
|
||||||
|
else channels.foreach(_.unprompt(event))
|
||||||
|
}
|
||||||
|
|
||||||
def logMessage(event: LogEvent): Unit = {
|
def logMessage(event: LogEvent): Unit = {
|
||||||
channels.foreach {
|
channels.foreach {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue