From c4e6cf54d29857d9dcf40c085ebfdaf11887976c Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 14 Jul 2021 10:24:52 +0200 Subject: [PATCH] Use java to start BSP client --- .../internal/bsp/BuildServerConnection.scala | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala index 9ee2da80c..593d925e3 100644 --- a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala +++ b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala @@ -13,6 +13,7 @@ import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter } import java.io.File import java.nio.file.{ Files, Paths } +import scala.util.Properties object BuildServerConnection { final val name = "sbt" @@ -23,34 +24,34 @@ object BuildServerConnection { private[sbt] def writeConnectionFile(sbtVersion: String, baseDir: File): Unit = { val bspConnectionFile = new File(baseDir, ".bsp/sbt.json") - val argv = Option(System.getProperty("sbt.script")) - .map(_.replaceAllLiterally("%20", " ")) - .orElse(sbtScriptInPath) match { - case Some(sbtScript) => - Vector(sbtScript, "-bsp", s"-Dsbt.script=${sbtScript.replaceAllLiterally(" ", "%20")}") - case None => - // IntelliJ can start sbt even if the sbt script is not accessible from $PATH. - // To do so it uses its own bundled sbt-launch.jar. - // In that case, we must pass the path of the sbt-launch.jar to the BSP connection - // so that the server can be started. - // A known problem in that situation is that the .sbtopts and .jvmopts are not loaded. - val javaHome = System.getProperty("java.home") - val classPath = System.getProperty("java.class.path") - val sbtLaunchJar = classPath - .split(File.pathSeparator) - .find(jar => SbtLaunchJar.findFirstIn(jar).nonEmpty) - .map(_.replaceAllLiterally(" ", "%20")) + val javaHome = System.getProperty("java.home") + val classPath = System.getProperty("java.class.path") - Vector( - s"$javaHome/bin/java", - "-Xms100m", - "-Xmx100m", - "-classpath", - classPath, - "xsbt.boot.Boot", - "-bsp" - ) ++ sbtLaunchJar.map(jar => s"--sbt-launch-jar=$jar") - } + val sbtScript = Option(System.getProperty("sbt.script")) + .orElse(sbtScriptInPath) + .map(script => s"-Dsbt.script=$script") + + // IntelliJ can start sbt even if the sbt script is not accessible from $PATH. + // To do so it uses its own bundled sbt-launch.jar. + // In that case, we must pass the path of the sbt-launch.jar to the BSP connection + // so that the server can be started. + // A known problem in that situation is that the .sbtopts and .jvmopts are not loaded. + val sbtLaunchJar = classPath + .split(File.pathSeparator) + .find(jar => SbtLaunchJar.findFirstIn(jar).nonEmpty) + .map(_.replaceAllLiterally(" ", "%20")) + .map(jar => s"--sbt-launch-jar=$jar") + + val argv = + Vector( + s"$javaHome/bin/java", + "-Xms100m", + "-Xmx100m", + "-classpath", + classPath, + "xsbt.boot.Boot", + "-bsp" + ) ++ sbtScript.orElse(sbtLaunchJar) val details = BspConnectionDetails(name, sbtVersion, bspVersion, languages, argv) val json = Converter.toJson(details).get IO.write(bspConnectionFile, CompactPrinter(json), append = false) @@ -61,6 +62,9 @@ object BuildServerConnection { // As a fallback we try to find the sbt script in $PATH val envPath = Option(System.getenv("PATH")).getOrElse("") val allPaths = envPath.split(File.pathSeparator).map(Paths.get(_)) - allPaths.map(_.resolve("sbt")).find(Files.exists(_)).map(_.toString) + allPaths + .map(_.resolve("sbt")) + .find(file => Files.exists(file)) + .map(_.toString.replaceAllLiterally(" ", "%20")) } }