From 12deebba2bcd395bf5ec7eada6f18776efea339c Mon Sep 17 00:00:00 2001 From: Pluto <128720033+it-education-md@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:04:55 -0600 Subject: [PATCH] [2.x] fix: restore CLI precedence over .sbtopts According to the issue, `.sbtopts` entries are appended after CLI args in sbt 1.12.x, so `.sbtopts` JVM memory settings (e.g., `-Xmx2g`) override CLI `--mem`, causing invalid JVM settings. --- .../src/test/scala/RunnerScriptTest.scala | 23 +++++++++++++++++++ sbt | 14 +++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/launcher-package/integration-test/src/test/scala/RunnerScriptTest.scala b/launcher-package/integration-test/src/test/scala/RunnerScriptTest.scala index d27e37bd2..a570dc47b 100644 --- a/launcher-package/integration-test/src/test/scala/RunnerScriptTest.scala +++ b/launcher-package/integration-test/src/test/scala/RunnerScriptTest.scala @@ -194,6 +194,29 @@ object RunnerScriptTest extends verify.BasicTestSuite with ShellScriptUtil: s"Machine config should appear before project config. machineIndex=$machineIndex, projectIndex=$projectIndex" ) + testOutput( + "command line options override project .sbtopts", + sbtOptsFileContents = + "-J-Xmx2g\n-J-XX:ReservedCodeCacheSize=1g\n-J-XX:MaxMetaspaceSize=2g\n-J-Xss512m\n-J-XX:+UseG1GC" + )("-d", "-v", "-mem", "12288"): (out: List[String]) => + if (isWindows) cancel("Test not supported on windows") + else + val cmdLineStart = out.indexWhere(_.contains("Executing command line")) + assert(cmdLineStart >= 0, "Command line section not found") + + val cmdLine = out.drop(cmdLineStart + 1).takeWhile(!_.trim.isEmpty) + val xmxCliIndex = cmdLine.indexWhere(_.contains("-Xmx12288m")) + val xmxSbtoptsIndex = cmdLine.indexWhere(_.contains("-Xmx2g")) + val g1Index = cmdLine.indexWhere(_.contains("-XX:+UseG1GC")) + + assert(xmxCliIndex >= 0, "CLI memory setting not found in command line") + assert(xmxSbtoptsIndex < 0, "sbtopts -Xmx2g should be overridden by CLI") + assert(g1Index >= 0, "sbtopts non-memory option not found in command line") + assert( + g1Index < xmxCliIndex, + s"sbtopts options should appear before CLI memory settings. g1Index=$g1Index, xmxCliIndex=$xmxCliIndex" + ) + // Test for issue #7289: Special characters in .jvmopts should not cause shell expansion testOutput( "sbt with special characters in .jvmopts (pipes, wildcards, ampersands)", diff --git a/sbt b/sbt index 9f1894c74..b32649048 100755 --- a/sbt +++ b/sbt @@ -859,17 +859,23 @@ runNativeClient() { original_args=("$@") +sbt_file_opts=() + # Pull in the machine-wide settings configuration. if [[ -f "$machine_sbt_opts_file" ]]; then - set -- "$@" $(loadConfigFile "$machine_sbt_opts_file") + sbt_file_opts+=($(loadConfigFile "$machine_sbt_opts_file")) else # Otherwise pull in the default settings configuration. - [[ -f "$dist_sbt_opts_file" ]] && set -- "$@" $(loadConfigFile "$dist_sbt_opts_file") + [[ -f "$dist_sbt_opts_file" ]] && sbt_file_opts+=($(loadConfigFile "$dist_sbt_opts_file")) fi # Pull in the project-level config file, if it exists (highest priority, overrides machine/dist). -# Append so it appears last in command line and wins for duplicate properties. -[[ -f "$sbt_opts_file" ]] && set -- "$@" $(loadConfigFile "$sbt_opts_file") +[[ -f "$sbt_opts_file" ]] && sbt_file_opts+=($(loadConfigFile "$sbt_opts_file")) + +# Prepend sbtopts so command line args appear last and win for duplicate properties. +if (( ${#sbt_file_opts[@]} > 0 )); then + set -- "${sbt_file_opts[@]}" "$@" +fi # Pull in the project-level java config, if it exists. [[ -f ".jvmopts" ]] && export JAVA_OPTS="$JAVA_OPTS $(loadConfigFile .jvmopts)"