From b70bdce683feba375eba00237b8ed2bcc03ed6d2 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Fri, 27 Nov 2020 12:12:15 -0800 Subject: [PATCH 1/2] Set the exit value when sbt is started with -client --- main/src/main/scala/sbt/Main.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index f2e7a2e9e..f33aee75f 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -85,8 +85,7 @@ private[sbt] object xMain { ITerminal.withStreams(true, isSubProcess = detachStdio) { if (clientModByEnv || userCommands.exists(isClient)) { val args = userCommands.toList.filterNot(isClient) - NetworkClient.run(dealiasBaseDirectory(configuration), args) - Exit(0) + Exit(NetworkClient.run(dealiasBaseDirectory(configuration), args)) } else { val state0 = StandardMain .initialState( From d167dee7d26184f78b05797147df87035863a02c Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Fri, 27 Nov 2020 12:21:08 -0800 Subject: [PATCH 2/2] Add --sbt-launch-jar command line arg to client The intellij bsp integration launches sbt with the launcher and runs -bsp. This doesn't work if sbt is not on intellij's path. To try and work around this, we can add an option --sbt-launch-jar that is recognized by the network client and will make it use the launch jar rather than the sbt script to launch a new server if needed. --- .../sbt/internal/client/NetworkClient.scala | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) 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 9e47c279e..0882b8128 100644 --- a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala +++ b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala @@ -17,7 +17,7 @@ import java.util.UUID import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference } import java.util.concurrent.{ ConcurrentHashMap, LinkedBlockingQueue, TimeUnit } -import sbt.BasicCommandStrings.{ Shutdown, TerminateAction } +import sbt.BasicCommandStrings.{ DashDashDetachStdio, DashDashServer, Shutdown, TerminateAction } import sbt.internal.client.NetworkClient.Arguments import sbt.internal.langserver.{ LogMessageParams, MessageType, PublishDiagnosticsParams } import sbt.internal.protocol._ @@ -328,8 +328,15 @@ class NetworkClient( term.isSupershellEnabled ).mkString(",") - val cmd = List(arguments.sbtScript) ++ arguments.sbtArguments ++ - List(BasicCommandStrings.DashDashDetachStdio, BasicCommandStrings.DashDashServer) + val cmd = arguments.sbtLaunchJar match { + case Some(lj) => + List("java") ++ arguments.sbtArguments ++ + List("-jar", lj, DashDashDetachStdio, DashDashServer) + case _ => + List(arguments.sbtScript) ++ arguments.sbtArguments ++ + List(DashDashDetachStdio, DashDashServer) + } + val processBuilder = new ProcessBuilder(cmd: _*) .directory(arguments.baseDirectory) @@ -1015,9 +1022,18 @@ object NetworkClient { val completionArguments: Seq[String], val sbtScript: String, val bsp: Boolean, + val sbtLaunchJar: Option[String], ) { def withBaseDirectory(file: File): Arguments = - new Arguments(file, sbtArguments, commandArguments, completionArguments, sbtScript, bsp) + new Arguments( + file, + sbtArguments, + commandArguments, + completionArguments, + sbtScript, + bsp, + sbtLaunchJar + ) } private[client] val completions = "--completions" private[client] val noTab = "--no-tab" @@ -1025,6 +1041,7 @@ object NetworkClient { private[client] val sbtBase = "--sbt-base-directory" private[client] def parseArgs(args: Array[String]): Arguments = { var sbtScript = if (Properties.isWin) "sbt.bat" else "sbt" + var launchJar: Option[String] = None var bsp = false val commandArgs = new mutable.ArrayBuffer[String] val sbtArguments = new mutable.ArrayBuffer[String] @@ -1047,10 +1064,18 @@ object NetworkClient { .lastOption .map(_.replaceAllLiterally("%20", " ")) .getOrElse(sbtScript) - case "-bsp" | "--bsp" => bsp = true case "--sbt-script" if i + 1 < sanitized.length => i += 1 sbtScript = sanitized(i).replaceAllLiterally("%20", " ") + case a if a.startsWith("--sbt-launch-jar=") => + launchJar = a + .split("--sbt-launch-jar=") + .lastOption + .map(_.replaceAllLiterally("%20", " ")) + case "--sbt-launch-jar" if i + 1 < sanitized.length => + i += 1 + launchJar = Option(sanitized(i).replaceAllLiterally("%20", " ")) + case "-bsp" | "--bsp" => bsp = true case a if !a.startsWith("-") => commandArgs += a case a @ SysProp(key, value) => System.setProperty(key, value) @@ -1061,7 +1086,7 @@ object NetworkClient { } val base = new File("").getCanonicalFile if (!sbtArguments.contains("-Dsbt.io.virtual=true")) sbtArguments += "-Dsbt.io.virtual=true" - new Arguments(base, sbtArguments, commandArgs, completionArguments, sbtScript, bsp) + new Arguments(base, sbtArguments, commandArgs, completionArguments, sbtScript, bsp, launchJar) } def client(