From 5afc0f0fdfe4500770c000a02fa57c9b46e8de3c Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 12 Dec 2019 19:33:16 -0800 Subject: [PATCH] Don't require newline for load failed commands It's a bit annoying to have to hit enter here. Also, this should fix https://github.com/sbt/sbt/issues/5162 because if there is no System.in attached, the read will return -1 which will cause sbt to quit. --- main/src/main/scala/sbt/Main.scala | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 4e0d31084..1f66e7d0e 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -10,9 +10,9 @@ package sbt import java.io.{ File, IOException } import java.net.URI import java.nio.file.{ FileAlreadyExistsException, FileSystems, Files } +import java.util.Properties import java.util.concurrent.ForkJoinPool import java.util.concurrent.atomic.AtomicBoolean -import java.util.{ Locale, Properties } import sbt.BasicCommandStrings.{ Shell, TemplateCommand } import sbt.Project.LoadAction @@ -764,22 +764,24 @@ object BuiltinCommands { @tailrec private[this] def doLoadFailed(s: State, loadArg: String): State = { - val result = (SimpleReader.readLine( - "Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? (default: r)" - ) getOrElse Quit) - .toLowerCase(Locale.ENGLISH) - def matches(s: String) = !result.isEmpty && (s startsWith result) - def retry = loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog - def ignoreMsg = + s.log.warn("Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? (default: r)") + val result = Terminal.withRawSystemIn { + Terminal.withEcho(toggle = true)(Terminal.wrappedSystemIn.read() match { + case -1 => 'q'.toInt + case b => b + }) + } + def retry: State = loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog + def ignoreMsg: String = if (Project.isProjectLoaded(s)) "using previously loaded project" else "no project loaded" - result match { - case "" => retry - case _ if matches("retry") => retry - case _ if matches(Quit) => s.exit(ok = false) - case _ if matches("ignore") => s.log.warn(s"Ignoring load failure: $ignoreMsg."); s - case _ if matches("last") => LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s - case _ => println("Invalid response."); doLoadFailed(s, loadArg) + result.toChar match { + case '\n' | '\r' => retry + case 'r' => retry + case 'q' => s.exit(ok = false) + case 'i' => s.log.warn(s"Ignoring load failure: $ignoreMsg."); s + case 'l' => LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s + case _ => println("Invalid response."); doLoadFailed(s, loadArg) } }