mirror of https://github.com/sbt/sbt.git
Fix #8344: Skip interactive prompt in batch mode when project loading fails
When project loading fails in batch mode, sbt was showing an interactive prompt asking the user to choose between retry, quit, last, or ignore. However, in batch mode there is no interactive terminal, causing the process to hang waiting for input that will never come. This fix checks if we're in batch mode (Prompt.Batch) and automatically exits with failure (equivalent to 'q' quit option) without prompting the user. This prevents infinite retry loops on persistent errors and allows batch mode scripts to fail fast, which is appropriate for CI/CD environments. The interactive behavior remains unchanged for non-batch mode.
This commit is contained in:
parent
a4ad73ddf6
commit
4976ec7dc7
|
|
@ -869,25 +869,30 @@ object BuiltinCommands {
|
|||
|
||||
@tailrec
|
||||
private def doLoadFailed(s: State, loadArg: String): State = {
|
||||
s.log.warn("Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? (default: r)")
|
||||
val result: Int =
|
||||
try
|
||||
ITerminal.get.withRawInput(System.in.read) match {
|
||||
case -1 => 'q'.toInt
|
||||
case b => b
|
||||
}
|
||||
catch { case _: ClosedChannelException => 'q' }
|
||||
def retry: State = loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog
|
||||
def ignoreMsg: String =
|
||||
if (Project.isProjectLoaded(s)) "using previously loaded project" else "no project loaded"
|
||||
// In batch mode, exit with failure to avoid infinite retry loops on persistent errors
|
||||
if (ITerminal.console.prompt == Prompt.Batch) {
|
||||
s.exit(ok = false)
|
||||
} else {
|
||||
s.log.warn("Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? (default: r)")
|
||||
val result: Int =
|
||||
try
|
||||
ITerminal.get.withRawInput(System.in.read) match {
|
||||
case -1 => 'q'.toInt
|
||||
case b => b
|
||||
}
|
||||
catch { case _: ClosedChannelException => 'q' }
|
||||
def retry: State = loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog
|
||||
def ignoreMsg: String =
|
||||
if (Project.isProjectLoaded(s)) "using previously loaded project" else "no project loaded"
|
||||
|
||||
result.toChar match {
|
||||
case '\n' | '\r' => retry
|
||||
case 'r' | 'R' => retry
|
||||
case 'q' | 'Q' => s.exit(ok = false)
|
||||
case 'i' | 'I' => s.log.warn(s"Ignoring load failure: $ignoreMsg."); s
|
||||
case 'l' | 'L' => LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s
|
||||
case c => println(s"Invalid response: '$c'"); doLoadFailed(s, loadArg)
|
||||
result.toChar match {
|
||||
case '\n' | '\r' => retry
|
||||
case 'r' | 'R' => retry
|
||||
case 'q' | 'Q' => s.exit(ok = false)
|
||||
case 'i' | 'I' => s.log.warn(s"Ignoring load failure: $ignoreMsg."); s
|
||||
case 'l' | 'L' => LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s
|
||||
case c => println(s"Invalid response: '$c'"); doLoadFailed(s, loadArg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue