[2.0.x] fix: Fixes -V parsing in sbt runners (#9636)

Problem: -V is consumed by the launcher instead of sbt in sbt tasks -V.

Solution: in the parser's -V behavior, lookback to see if there are commands going before it, in which case, forward -V to sbt.

Co-authored-by: Anatolii Kmetiuk <[email protected]>
This commit is contained in:
eugene yokota
2026-08-19 17:30:43 -04:00
committed by GitHub
co-authored by Anatolii Kmetiuk
parent 8d2e582c34
commit a3c503ad88
5 changed files with 88 additions and 3 deletions
@@ -47,6 +47,12 @@ object ExtendedRunnerTest extends BasicTestSuite:
()
}
test("sbt tasks -V lists verbose tasks") {
val out = sbtProcessInDir(IntegrationTestPaths.citestDir("citest2"))("tasks", "-V").!!
assert(out.linesIterator.exists(_.contains("allCredentials")))
assert(!out.linesIterator.exists(_.startsWith("sbt runner version:")))
}
def testVersion(lines: List[String]): Unit = {
assert(lines.size >= 2)
val expected0 = s"(?m)^sbt version in this project: $versionRegEx(\\r)?"
@@ -153,6 +153,67 @@ object RunnerScriptTest extends verify.BasicTestSuite with ShellScriptUtil:
assertVersionOutput(out)
()
testOutput("sbt -V should work")("-V"): (out: List[String]) =>
assertVersionOutput(out)
()
testOutput("sbt -version should work")("-version"): (out: List[String]) =>
assertVersionOutput(out)
()
testOutput("sbt -V followed by a launcher option should work")("-V", "-v"): (out: List[String]) =>
assertVersionOutput(out)
()
testOutput("sbt launcher option followed by --version should work")("--no-colors", "--version"):
(out: List[String]) =>
assertVersionOutput(out)
()
testOutput("sbt --version followed by an empty argument should work")("--version", ""):
(out: List[String]) =>
assertVersionOutput(out)
()
testOutput("sbt tasks -V forwards the tasks option")("tasks", "-V", "-v"): (out: List[String]) =>
assert(out.contains("-V"))
assert(!out.exists(_.startsWith("sbt runner version:")))
testOutput(
"sbt tasks -version forwards the tasks option",
windowsSupport = false,
)("tasks", "-version", "-v"): (out: List[String]) =>
assert(out.contains("-version"))
assert(!out.exists(_.startsWith("sbt runner version:")))
testOutput(
"sbt tasks --version forwards the tasks option",
windowsSupport = false,
)("tasks", "--version", "-v"): (out: List[String]) =>
assert(out.contains("--version"))
assert(!out.exists(_.startsWith("sbt runner version:")))
testOutput(
"sbt -V tasks forwards the tasks option",
windowsSupport = false,
)("-V", "tasks", "-v"): (out: List[String]) =>
assert(out.contains("-V"))
assert(!out.exists(_.startsWith("sbt runner version:")))
testOutput(
"sbt -version tasks forwards the tasks option",
windowsSupport = false,
)("-version", "tasks", "-v"): (out: List[String]) =>
assert(out.contains("-version"))
assert(!out.exists(_.startsWith("sbt runner version:")))
testOutput(
"sbt --version tasks forwards the tasks option",
windowsSupport = false,
)("--version", "tasks", "-v"): (out: List[String]) =>
assert(out.contains("--version"))
assert(!out.exists(_.startsWith("sbt runner version:")))
testOutput(
"sbt --version reports spaced sbt.version from project/build.properties (sbt 1.x)",
citestVariant = "citest",
+3 -1
View File
@@ -55,6 +55,7 @@ set sbt_args_client=-1
set sbt_args_jvm_client=
set sbt_args_no_server=
set sbt_args_experimental_execution_log=
set sbt_args_seen_command=
set is_this_dir_sbt=0
rem users can set SBT_OPTS via .sbtopts
@@ -183,7 +184,7 @@ if defined _verbose_arg (
goto args_loop
)
if "%~0" == "-V" set _version_arg=true
if "%~0" == "-V" if not defined sbt_args_seen_command set _version_arg=true
if "%~0" == "-version" set _version_arg=true
if "%~0" == "--version" set _version_arg=true
@@ -603,6 +604,7 @@ if defined sbt_new if "%g:~0,2%" == "--" (
)
rem the %0 (instead of %~0) preserves original argument quoting
set sbt_args_seen_command=1
set SBT_ARGS=!SBT_ARGS! %0
goto args_loop
+14 -1
View File
@@ -750,7 +750,7 @@ process_args () {
case "$1" in
-h|-help|--help) usage; exit 1 ;;
-v|-verbose|--verbose) sbt_verbose=1 && shift ;;
-V|-version|--version) print_version=1 && shift ;;
-V|-version|--version) print_version=1 && addResidual "$1" && shift ;;
--numeric-version) print_sbt_version=1 && shift ;;
--script-version) print_sbt_script_version=1 && shift ;;
shutdownall) shutdownall=1 && shift ;;
@@ -790,6 +790,19 @@ process_args () {
residual_args=()
process_my_args "${myargs[@]}"
}
if [[ $print_version ]]; then
for arg in "${residual_args[@]}"; do
case "$arg" in
-V|-version|--version) ;;
*) if [[ "$arg" =~ [^[:space:]] ]]; then
print_version=
break
fi ;;
esac
done
[[ $print_version ]] && residual_args=()
fi
}
loadConfigFile() {
+4 -1
View File
@@ -14,7 +14,10 @@ object ArgParser:
opt[Unit]('h', "help").action((_, c) => c.copy(help = true)),
opt[Unit]('v', "verbose").action((_, c) => c.copy(verbose = true)),
opt[Unit]('d', "debug").action((_, c) => c.copy(debug = true)),
opt[Unit]('V', "version").action((_, c) => c.copy(version = true)),
opt[Unit]('V', "version").action((_, c) =>
if c.residual.nonEmpty then c.copy(residual = c.residual :+ "-V")
else c.copy(version = true)
),
opt[Unit]("numeric-version").action((_, c) => c.copy(numericVersion = true)),
opt[Unit]("script-version").action((_, c) => c.copy(scriptVersion = true)),
opt[Unit]("shutdownall").action((_, c) => c.copy(shutdownAll = true)),