mirror of https://github.com/sbt/sbt.git
fix: Handle JVM parameters with spaces in sbtopts and jvmopts (#7333)
This commit is contained in:
parent
c7da2b72c3
commit
07d7553dc3
|
|
@ -253,6 +253,30 @@ object RunnerScriptTest extends verify.BasicTestSuite with ShellScriptUtil:
|
||||||
s"sbtopts options should appear before CLI memory settings. g1Index=$g1Index, xmxCliIndex=$xmxCliIndex"
|
s"sbtopts options should appear before CLI memory settings. g1Index=$g1Index, xmxCliIndex=$xmxCliIndex"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Test for issue #7333: JVM parameters with spaces in .sbtopts
|
||||||
|
testOutput(
|
||||||
|
"sbt with -J--add-modules jdk.incubator.concurrent in .sbtopts (args with spaces)",
|
||||||
|
sbtOptsFileContents = "-J--add-modules jdk.incubator.concurrent",
|
||||||
|
windowsSupport = false,
|
||||||
|
)("-v"): (out: List[String]) =>
|
||||||
|
assert(out.contains[String]("--add-modules"))
|
||||||
|
assert(out.contains[String]("jdk.incubator.concurrent"))
|
||||||
|
|
||||||
|
// Test for issue #7333: -D with spaces in .jvmopts
|
||||||
|
testOutput(
|
||||||
|
"sbt with -Dkey=\"value with spaces\" in .jvmopts",
|
||||||
|
jvmoptsFileContents = """-Dtest.7333="value with spaces"""",
|
||||||
|
windowsSupport = false,
|
||||||
|
)("-v"): (out: List[String]) =>
|
||||||
|
assert(
|
||||||
|
out.exists(_.contains("test.7333")),
|
||||||
|
s"Expected -Dtest.7333= in output, got: ${out.filter(_.contains("test.7333")).mkString(", ")}"
|
||||||
|
)
|
||||||
|
assert(
|
||||||
|
out.exists(_.contains("value with spaces")),
|
||||||
|
"Expected 'value with spaces' in -D value"
|
||||||
|
)
|
||||||
|
|
||||||
// Test for issue #7289: Special characters in .jvmopts should not cause shell expansion
|
// Test for issue #7289: Special characters in .jvmopts should not cause shell expansion
|
||||||
testOutput(
|
testOutput(
|
||||||
"sbt with special characters in .jvmopts (pipes, wildcards, ampersands)",
|
"sbt with special characters in .jvmopts (pipes, wildcards, ampersands)",
|
||||||
|
|
|
||||||
66
sbt
66
sbt
|
|
@ -766,6 +766,61 @@ process_args () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Parse a line into words respecting double and single quotes.
|
||||||
|
# Outputs one word per line. Used for .sbtopts and .jvmopts to handle args with spaces (#7333).
|
||||||
|
parseLineIntoWords() {
|
||||||
|
local line="$1"
|
||||||
|
local word=""
|
||||||
|
local i=0
|
||||||
|
local len=${#line}
|
||||||
|
local in_dq=0 in_sq=0
|
||||||
|
while (( i < len )); do
|
||||||
|
local c="${line:$i:1}"
|
||||||
|
if (( in_dq )); then
|
||||||
|
word+="$c"
|
||||||
|
[[ "$c" == '"' ]] && in_dq=0
|
||||||
|
elif (( in_sq )); then
|
||||||
|
word+="$c"
|
||||||
|
[[ "$c" == "'" ]] && in_sq=0
|
||||||
|
else
|
||||||
|
case "$c" in
|
||||||
|
'"') in_dq=1; word+="$c" ;;
|
||||||
|
"'") in_sq=1; word+="$c" ;;
|
||||||
|
' '|$'\t')
|
||||||
|
[[ -n "$word" ]] && printf '%s\n' "$word"
|
||||||
|
word=""
|
||||||
|
;;
|
||||||
|
*) word+="$c" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
((i++))
|
||||||
|
done
|
||||||
|
[[ -n "$word" ]] && printf '%s\n' "$word"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load config file into array, parsing each line and respecting quotes.
|
||||||
|
# For -J lines: split the remainder and prepend -J to each token (so -J--add-modules jdk.incubator.concurrent
|
||||||
|
# becomes -J--add-modules and -Jjdk.incubator.concurrent). Fixes #7333.
|
||||||
|
loadConfigFileIntoArray() {
|
||||||
|
local -n arr=$1
|
||||||
|
local file="$2"
|
||||||
|
[[ ! -f "$file" ]] && return
|
||||||
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
|
line=$(printf '%s' "$line" | sed $'/^\#/d;s/\r$//')
|
||||||
|
[[ -z "$line" ]] && continue
|
||||||
|
if [[ "$line" == -J* ]]; then
|
||||||
|
local rest="${line#-J}"
|
||||||
|
while IFS= read -r token; do
|
||||||
|
[[ -n "$token" ]] && arr+=("-J$token")
|
||||||
|
done < <(parseLineIntoWords "$rest")
|
||||||
|
else
|
||||||
|
while IFS= read -r token; do
|
||||||
|
[[ -n "$token" ]] && arr+=("$token")
|
||||||
|
done < <(parseLineIntoWords "$line")
|
||||||
|
fi
|
||||||
|
done < <(cat "$file")
|
||||||
|
}
|
||||||
|
|
||||||
loadConfigFile() {
|
loadConfigFile() {
|
||||||
# Make sure the last line is read even if it doesn't have a terminating \n
|
# Make sure the last line is read even if it doesn't have a terminating \n
|
||||||
# Output lines literally without shell expansion to handle special characters safely
|
# Output lines literally without shell expansion to handle special characters safely
|
||||||
|
|
@ -861,14 +916,14 @@ sbt_file_opts=()
|
||||||
|
|
||||||
# Pull in the machine-wide settings configuration.
|
# Pull in the machine-wide settings configuration.
|
||||||
if [[ -f "$machine_sbt_opts_file" ]]; then
|
if [[ -f "$machine_sbt_opts_file" ]]; then
|
||||||
sbt_file_opts+=($(loadConfigFile "$machine_sbt_opts_file"))
|
loadConfigFileIntoArray sbt_file_opts "$machine_sbt_opts_file"
|
||||||
else
|
else
|
||||||
# Otherwise pull in the default settings configuration.
|
# Otherwise pull in the default settings configuration.
|
||||||
[[ -f "$dist_sbt_opts_file" ]] && sbt_file_opts+=($(loadConfigFile "$dist_sbt_opts_file"))
|
[[ -f "$dist_sbt_opts_file" ]] && loadConfigFileIntoArray sbt_file_opts "$dist_sbt_opts_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Pull in the project-level config file, if it exists (highest priority, overrides machine/dist).
|
# Pull in the project-level config file, if it exists (highest priority, overrides machine/dist).
|
||||||
[[ -f "$sbt_opts_file" ]] && sbt_file_opts+=($(loadConfigFile "$sbt_opts_file"))
|
[[ -f "$sbt_opts_file" ]] && loadConfigFileIntoArray sbt_file_opts "$sbt_opts_file"
|
||||||
|
|
||||||
# Prepend sbtopts so command line args appear last and win for duplicate properties.
|
# Prepend sbtopts so command line args appear last and win for duplicate properties.
|
||||||
if (( ${#sbt_file_opts[@]} > 0 )); then
|
if (( ${#sbt_file_opts[@]} > 0 )); then
|
||||||
|
|
@ -876,14 +931,15 @@ if (( ${#sbt_file_opts[@]} > 0 )); then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Pull in the project-level java config, if it exists.
|
# Pull in the project-level java config, if it exists.
|
||||||
[[ -f ".jvmopts" ]] && export JAVA_OPTS="$JAVA_OPTS $(loadConfigFile .jvmopts)"
|
jvmopts_args=()
|
||||||
|
[[ -f ".jvmopts" ]] && loadConfigFileIntoArray jvmopts_args ".jvmopts"
|
||||||
|
|
||||||
# Pull in default JAVA_OPTS
|
# Pull in default JAVA_OPTS
|
||||||
[[ -z "${JAVA_OPTS// }" ]] && export JAVA_OPTS="$default_java_opts"
|
[[ -z "${JAVA_OPTS// }" ]] && export JAVA_OPTS="$default_java_opts"
|
||||||
|
|
||||||
[[ -f "$build_props_file" ]] && loadPropFile "$build_props_file"
|
[[ -f "$build_props_file" ]] && loadPropFile "$build_props_file"
|
||||||
|
|
||||||
java_args=($JAVA_OPTS)
|
java_args=($JAVA_OPTS "${jvmopts_args[@]}")
|
||||||
sbt_options0=(${SBT_OPTS:-$default_sbt_opts})
|
sbt_options0=(${SBT_OPTS:-$default_sbt_opts})
|
||||||
java_tool_options=($JAVA_TOOL_OPTIONS)
|
java_tool_options=($JAVA_TOOL_OPTIONS)
|
||||||
jdk_java_options=($JDK_JAVA_OPTIONS)
|
jdk_java_options=($JDK_JAVA_OPTIONS)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue