mirror of https://github.com/sbt/sbt.git
[2.x] fix: Propagate SBT_OPTS to BSP config (#8531)
Fixes #7469 When running 'sbt bspConfig', the generated .bsp/sbt.json now includes JVM options from the SBT_OPTS environment variable. This ensures that options like -Dsbt.boot.directory are propagated to the BSP server. The parseSbtOpts method extracts -D, -X, and -J prefixed options from SBT_OPTS and includes them in the BSP connection argv.
This commit is contained in:
parent
8433dd8db6
commit
1ed08f0034
|
|
@ -33,11 +33,8 @@ object BuildServerConnection {
|
|||
.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 sbtOptsArgs = parseSbtOpts(sys.env.get("SBT_OPTS"))
|
||||
|
||||
val sbtLaunchJar = classPath
|
||||
.split(File.pathSeparator)
|
||||
.find(jar => SbtLaunchJar.findFirstIn(jar).nonEmpty)
|
||||
|
|
@ -49,9 +46,12 @@ object BuildServerConnection {
|
|||
s"$javaHome/bin/java",
|
||||
"-Xms100m",
|
||||
"-Xmx100m",
|
||||
"-classpath",
|
||||
classPath,
|
||||
) ++
|
||||
sbtOptsArgs ++
|
||||
Vector(
|
||||
"-classpath",
|
||||
classPath,
|
||||
) ++
|
||||
sbtScript ++
|
||||
Vector("xsbt.boot.Boot", "-bsp") ++
|
||||
(if (sbtScript.isEmpty) sbtLaunchJar else None)
|
||||
|
|
@ -62,8 +62,6 @@ object BuildServerConnection {
|
|||
}
|
||||
|
||||
private def sbtScriptInPath: Option[String] = {
|
||||
// For those who use an old sbt script, the -Dsbt.script is not set
|
||||
// As a fallback we try to find the sbt script in $PATH
|
||||
val fileName = if (Properties.isWin) "sbt.bat" else "sbt"
|
||||
val envPath = sys.env.collectFirst {
|
||||
case (k, v) if k.toUpperCase() == "PATH" => v
|
||||
|
|
@ -76,4 +74,14 @@ object BuildServerConnection {
|
|||
.find(file => Files.exists(file) && Files.isExecutable(file))
|
||||
.map(_.toString.replace(" ", "%20"))
|
||||
}
|
||||
|
||||
private[sbt] def parseSbtOpts(sbtOpts: Option[String]): Vector[String] =
|
||||
sbtOpts match
|
||||
case Some(opts) if opts.nonEmpty =>
|
||||
opts
|
||||
.split("\\s+")
|
||||
.filter(arg => arg.startsWith("-D") || arg.startsWith("-X") || arg.startsWith("-J"))
|
||||
.map(arg => if (arg.startsWith("-J")) arg.stripPrefix("-J") else arg)
|
||||
.toVector
|
||||
case _ => Vector.empty
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2023, Scala center
|
||||
* Copyright 2011 - 2022, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal.bsp
|
||||
|
||||
import verify.BasicTestSuite
|
||||
|
||||
object BuildServerConnectionSpec extends BasicTestSuite:
|
||||
|
||||
test("parseSbtOpts should return empty vector for None"):
|
||||
val result = BuildServerConnection.parseSbtOpts(None)
|
||||
assert(result.isEmpty)
|
||||
|
||||
test("parseSbtOpts should return empty vector for empty string"):
|
||||
val result = BuildServerConnection.parseSbtOpts(Some(""))
|
||||
assert(result.isEmpty)
|
||||
|
||||
test("parseSbtOpts should parse -D system properties"):
|
||||
val result = BuildServerConnection.parseSbtOpts(Some("-Dsbt.boot.directory=/custom/path"))
|
||||
assert(result == Vector("-Dsbt.boot.directory=/custom/path"))
|
||||
|
||||
test("parseSbtOpts should parse -X JVM options"):
|
||||
val result = BuildServerConnection.parseSbtOpts(Some("-Xmx2g -Xms512m"))
|
||||
assert(result == Vector("-Xmx2g", "-Xms512m"))
|
||||
|
||||
test("parseSbtOpts should parse -J prefixed options and strip the prefix"):
|
||||
val result = BuildServerConnection.parseSbtOpts(Some("-J-Xmx4g"))
|
||||
assert(result == Vector("-Xmx4g"))
|
||||
|
||||
test("parseSbtOpts should parse multiple mixed options"):
|
||||
val result = BuildServerConnection.parseSbtOpts(
|
||||
Some("-Dsbt.boot.directory=/path -Xmx2g -J-XX:+UseG1GC")
|
||||
)
|
||||
assert(result == Vector("-Dsbt.boot.directory=/path", "-Xmx2g", "-XX:+UseG1GC"))
|
||||
|
||||
test("parseSbtOpts should filter out non-JVM options"):
|
||||
val result = BuildServerConnection.parseSbtOpts(Some("-Dfoo=bar --some-flag -Xmx1g"))
|
||||
assert(result == Vector("-Dfoo=bar", "-Xmx1g"))
|
||||
|
||||
test("parseSbtOpts should handle whitespace-separated options"):
|
||||
val result = BuildServerConnection.parseSbtOpts(Some(" -Dfoo=bar -Xmx1g "))
|
||||
assert(result == Vector("-Dfoo=bar", "-Xmx1g"))
|
||||
Loading…
Reference in New Issue