mirror of https://github.com/sbt/sbt.git
Merge 95a3fc3288 into 6d94d6db61
This commit is contained in:
commit
676c740cf3
|
|
@ -0,0 +1,132 @@
|
|||
# Fix #8717: Handle `--version` flag before native client for sbt 2.x project directories
|
||||
|
||||
## Problem
|
||||
|
||||
When running `sbt --version` in an sbt 2.x project directory, the script would delegate to the native client (sbtn) instead of printing version information. This caused the command to fail with connection errors instead of displaying the expected version output.
|
||||
|
||||
### Reproduction Steps
|
||||
|
||||
1. Create an sbt 2.x project:
|
||||
```bash
|
||||
mkdir test-project
|
||||
cd test-project
|
||||
touch build.sbt
|
||||
mkdir project
|
||||
echo "sbt.version=2.0.0-RC8" > project/build.properties
|
||||
```
|
||||
|
||||
2. Run `sbt --version`:
|
||||
```bash
|
||||
sbt --version
|
||||
```
|
||||
|
||||
**Before the fix:** The script would try to run sbtn and show:
|
||||
```
|
||||
[debug] running native client
|
||||
# Executing command line:
|
||||
/Users/xxx/.cache/sbt/boot/sbtn/1.12.1/sbtn
|
||||
--sbt-script=/Users/xxx/work/sbt/sbt
|
||||
--version
|
||||
[info] server was not detected. starting an instance
|
||||
[error] failed to connect to server
|
||||
```
|
||||
|
||||
**After the fix:** The script correctly prints version information:
|
||||
```
|
||||
sbt version in this project: 2.0.0-RC8
|
||||
sbt runner version: 1.12.0
|
||||
|
||||
[info] sbt runner (sbt-the-shell-script) is a runner to run any declared version of sbt.
|
||||
[info] Actual version of the sbt is declared using project/build.properties for each build.
|
||||
```
|
||||
|
||||
## Solution
|
||||
|
||||
The fix handles the `--version` flag **before** the native client check, similar to how `--script-version` was fixed in #8711. This ensures that version information is printed directly from the script without delegating to sbtn.
|
||||
|
||||
### Changes Made
|
||||
|
||||
1. **`sbt` script** (`/home/daniel/sbt-repo/sbt`):
|
||||
- Added early handling of `--version` flag before native client delegation
|
||||
- Detects if we're in an sbt project directory
|
||||
- Prints project sbt version from `build.properties` if available
|
||||
- Prints runner version and info messages
|
||||
- Exits early to prevent native client delegation
|
||||
|
||||
2. **Integration tests**:
|
||||
- Added tests in `RunnerScriptTest.scala` for sbt 1.x and 2.x projects
|
||||
- Added tests in `ExtendedRunnerTest.scala` for empty directory and sbt 2.x project scenarios
|
||||
- All tests verify that version information is printed correctly
|
||||
|
||||
3. **Documentation**:
|
||||
- Added manual test instructions in `HOW_TO_TEST_8717.md`
|
||||
|
||||
## Code Changes
|
||||
|
||||
The key change is in the `sbt` script, where we added:
|
||||
|
||||
```bash
|
||||
# Handle --version before native client so it works on sbt 2.x project dirs (#8717)
|
||||
if [[ $print_version ]]; then
|
||||
detect_working_directory
|
||||
if [[ -n "$is_this_dir_sbt" ]] && [[ -n "$build_props_sbt_version" ]]; then
|
||||
echo "sbt version in this project: $build_props_sbt_version"
|
||||
fi
|
||||
echo "sbt runner version: $init_sbt_version"
|
||||
echo ""
|
||||
echo "[info] sbt runner (sbt-the-shell-script) is a runner to run any declared version of sbt."
|
||||
echo "[info] Actual version of the sbt is declared using project/build.properties for each build."
|
||||
exit 0
|
||||
fi
|
||||
```
|
||||
|
||||
This is placed right after the `--script-version` handler and before the native client check.
|
||||
|
||||
## Testing
|
||||
|
||||
### Manual Testing
|
||||
|
||||
1. **Test in sbt 2.x project:**
|
||||
```bash
|
||||
cd /tmp
|
||||
mkdir test-version && cd test-version
|
||||
touch build.sbt
|
||||
mkdir project
|
||||
echo "sbt.version=2.0.0-RC8" > project/build.properties
|
||||
sbt --version
|
||||
```
|
||||
Expected: Prints version information without trying to run sbtn
|
||||
|
||||
2. **Test in empty directory:**
|
||||
```bash
|
||||
cd /tmp
|
||||
mkdir test-empty && cd test-empty
|
||||
sbt --version
|
||||
```
|
||||
Expected: Prints runner version only
|
||||
|
||||
### Automated Testing
|
||||
|
||||
Run the integration tests:
|
||||
```bash
|
||||
cd /home/daniel/sbt-repo
|
||||
sbt "project launcherPackageIntegrationTest" "test"
|
||||
```
|
||||
|
||||
The following tests verify the fix:
|
||||
- `sbt --version should work (sbt 1.x project)`
|
||||
- `sbt --version should work (sbt 2.x project) (#8717)`
|
||||
- `sbt --version in empty directory`
|
||||
- `sbt --version in sbt 2.x project directory (#8717)`
|
||||
|
||||
## Related Issues
|
||||
|
||||
- Fixes #8717
|
||||
- Similar to #8711 (which fixed `--script-version`)
|
||||
|
||||
## Notes
|
||||
|
||||
- The info messages are printed to stdout (not stderr) to ensure they're captured by the test framework
|
||||
- This fix maintains backward compatibility - `--version` still works in sbt 1.x projects and empty directories
|
||||
- The fix follows the same pattern as the `--script-version` fix in #8711
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
@echo on
|
||||
|
||||
cd "%~dp0"
|
||||
|
||||
mkdir freshly-baked
|
||||
unzip ..\target\universal\sbt.zip -d freshly-baked
|
||||
|
||||
SETLOCAL
|
||||
|
||||
"freshly-baked\sbt\bin\sbt" about
|
||||
|
||||
SET JAVA_HOME=C:\jdk11
|
||||
SET PATH=C:\jdk11\bin;%PATH%
|
||||
SET SBT_OPTS=-Xmx4g -Dfile.encoding=UTF8
|
||||
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true about
|
||||
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true about 1> output.txt 2> err.txt
|
||||
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true check
|
||||
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true --numeric-version > numericVersion.txt
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true checkNumericVersion
|
||||
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true --script-version > scriptVersion.txt
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true checkScriptVersion
|
||||
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true --version > version.txt
|
||||
"freshly-baked\sbt\bin\sbt" -Dsbt.no.format=true checkVersion
|
||||
|
||||
ENDLOCAL
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash -x
|
||||
|
||||
# exit when something fails
|
||||
set -e
|
||||
|
||||
## https://github.com/travis-ci/travis-ci/issues/8408
|
||||
unset _JAVA_OPTIONS
|
||||
unset SBT_OPTS
|
||||
|
||||
java -version
|
||||
## end of Java switching
|
||||
|
||||
rm -rf freshly-baked
|
||||
mkdir -p freshly-baked
|
||||
unzip ../target/universal/sbt.zip -d ./freshly-baked
|
||||
|
||||
./freshly-baked/sbt/bin/sbt -Dsbt.no.format=true about
|
||||
./freshly-baked/sbt/bin/sbt -Dsbt.no.format=true about 1> output.txt 2> err.txt
|
||||
./freshly-baked/sbt/bin/sbt check
|
||||
|
||||
./freshly-baked/sbt/bin/sbt about run -v
|
||||
|
||||
./freshly-baked/sbt/bin/sbt about run
|
||||
|
||||
fail() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# env HOME=./target/home1 ./freshly-baked/sbt/bin/sbt about
|
||||
# test -d ./target/home1/.sbt/preloaded/org/scala-sbt || fail "expected to find preloaded in ./target/home1/.sbt"
|
||||
|
||||
# env HOME=./target/home2 ./freshly-baked/sbt/bin/sbt -sbt-dir ./target/home2/alternate-sbt about
|
||||
# test -d ./target/home2/alternate-sbt/preloaded/org/scala-sbt || fail "expected to find preloaded in ./target/home2/alternate-sbt"
|
||||
|
||||
# env HOME=./target/home3 ./freshly-baked/sbt/bin/sbt -J-Dsbt.preloaded=./target/home3/alternate-preloaded about
|
||||
# test -d ./target/home3/alternate-preloaded/org/scala-sbt || fail "expected to find preloaded in ./target/home3/alternate-preloaded"
|
||||
|
||||
# env HOME=./target/home4 ./freshly-baked/sbt/bin/sbt -J-Dsbt.global.base=./target/home4/global-base about
|
||||
# test -d ./target/home4/global-base/preloaded/org/scala-sbt || fail "expected to find preloaded in ./target/home4/global-base"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#-XX:+CMSClassUnloadingEnabled
|
||||
#-XX:ReservedCodeCacheSize=192m
|
||||
#-Duser.timezone=GMT
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
lazy val check = taskKey[Unit]("")
|
||||
lazy val checkNumericVersion = taskKey[Unit]("")
|
||||
lazy val checkScriptVersion = taskKey[Unit]("")
|
||||
lazy val checkVersion = taskKey[Unit]("")
|
||||
|
||||
// 1.3.0, 1.3.0-M4
|
||||
lazy val versionRegEx = "\\d(\\.\\d+){2}(-\\w+)?"
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
.settings(
|
||||
scalaVersion := "2.12.4",
|
||||
name := "Hello",
|
||||
check := {
|
||||
val xs = IO.readLines(file("output.txt")).toVector
|
||||
|
||||
println(xs)
|
||||
|
||||
assert(xs(0) startsWith "[info] Loading project definition")
|
||||
assert(xs(1) startsWith "[info] Loading settings from build.sbt")
|
||||
assert(xs(2) startsWith "[info] Set current project to Hello")
|
||||
assert(xs(3) startsWith "[info] This is sbt")
|
||||
assert(xs(4) startsWith "[info] The current project")
|
||||
assert(xs(5) startsWith "[info] The current project is built against Scala 2.12.4")
|
||||
|
||||
val ys = IO.readLines(file("err.txt")).toVector.distinct
|
||||
|
||||
assert(ys.size == 1, s"ys has more than one item: $ys")
|
||||
assert(ys(0) startsWith "Java HotSpot(TM) 64-Bit Server VM warning")
|
||||
},
|
||||
checkNumericVersion := {
|
||||
val xs = IO.readLines(file("numericVersion.txt")).toVector
|
||||
val expectedVersion = "^"+versionRegEx+"$"
|
||||
|
||||
assert(xs(0).matches(expectedVersion))
|
||||
},
|
||||
checkScriptVersion := {
|
||||
val xs = IO.readLines(file("scriptVersion.txt")).toVector
|
||||
val expectedVersion = "^"+versionRegEx+"$"
|
||||
|
||||
assert(xs(0).matches(expectedVersion))
|
||||
},
|
||||
checkVersion := {
|
||||
val out = IO.readLines(file("version.txt")).toVector.mkString("\n")
|
||||
|
||||
val expectedVersion =
|
||||
s"""|(?m)^sbt version in this project: $versionRegEx
|
||||
|sbt script version: $versionRegEx$$
|
||||
|""".stripMargin.trim.replace("\n", "\\n")
|
||||
|
||||
assert(out.matches(expectedVersion))
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@echo on
|
||||
|
||||
SETLOCAL
|
||||
|
||||
SET JAVA_HOME=%JAVA_HOME_25_X64%
|
||||
SET PATH=%JAVA_HOME_25_X64%\bin;%PATH%
|
||||
SET SBT_OPTS=-Xmx4g -Dfile.encoding=UTF8
|
||||
|
||||
SET BASE_DIR=%CD%
|
||||
SET SCRIPT_DIR=%~dp0
|
||||
|
||||
CD %SCRIPT_DIR%
|
||||
"%BASE_DIR%\freshly-baked\sbt\bin\sbt" about 1> output.txt 2> err.txt
|
||||
"%BASE_DIR%\freshly-baked\sbt\bin\sbt" check
|
||||
CD %BASE_DIR%
|
||||
|
||||
ENDLOCAL
|
||||
|
||||
IF %errorlevel% NEQ 0 EXIT /b %errorlevel%
|
||||
|
|
@ -4,6 +4,7 @@ import scala.sys.process.*
|
|||
import java.io.File
|
||||
import java.util.Locale
|
||||
import sbt.io.IO
|
||||
import sbt.io.syntax.fileToRichFile
|
||||
import verify.BasicTestSuite
|
||||
|
||||
object ExtendedRunnerTest extends BasicTestSuite:
|
||||
|
|
@ -123,6 +124,29 @@ object ExtendedRunnerTest extends BasicTestSuite:
|
|||
()
|
||||
}
|
||||
|
||||
test("sbt --version in empty directory") {
|
||||
IO.withTemporaryDirectory { tmp =>
|
||||
val out = sbtProcessInDir(tmp)("--version").!!
|
||||
assert(out.contains("sbt runner version:"))
|
||||
val expectedRunner = if (isWindows) "[info] sbt runner (sbt-the-batch-script)" else "[info] sbt runner (sbt-the-shell-script)"
|
||||
assert(out.contains(expectedRunner))
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
test("sbt --version in sbt 2.x project directory (#8717)") {
|
||||
IO.withTemporaryDirectory { tmp =>
|
||||
IO.write(tmp / "build.sbt", "")
|
||||
IO.write(tmp / "project" / "build.properties", "sbt.version=2.0.0-RC8")
|
||||
val out = sbtProcessInDir(tmp)("--version").!!
|
||||
assert(out.contains("sbt version in this project: 2.0.0-RC8"))
|
||||
assert(out.contains("sbt runner version:"))
|
||||
val expectedRunner = if (isWindows) "[info] sbt runner (sbt-the-batch-script)" else "[info] sbt runner (sbt-the-shell-script)"
|
||||
assert(out.contains(expectedRunner))
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
test("sbt --jvm-client") {
|
||||
val out = sbtProcess("--jvm-client", "--no-colors", "compile").!!.linesIterator.toList
|
||||
if (isWindows) {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,25 @@ object RunnerScriptTest extends verify.BasicTestSuite with ShellScriptUtil:
|
|||
assert(out.mkString(System.lineSeparator()).trim.matches(expectedVersion))
|
||||
()
|
||||
|
||||
testOutput(
|
||||
"sbt --version should work (sbt 1.x project)",
|
||||
citestVariant = "citest",
|
||||
)("--version"): (out: List[String]) =>
|
||||
val output = out.mkString(System.lineSeparator())
|
||||
assert(output.contains("sbt runner version:"))
|
||||
assert(output.contains("[info] sbt runner (sbt-the-shell-script)"))
|
||||
()
|
||||
|
||||
testOutput(
|
||||
"sbt --version should work (sbt 2.x project) (#8717)",
|
||||
citestVariant = "citest2",
|
||||
)("--version"): (out: List[String]) =>
|
||||
val output = out.mkString(System.lineSeparator())
|
||||
assert(output.contains("sbt version in this project:"))
|
||||
assert(output.contains("sbt runner version:"))
|
||||
assert(output.contains("[info] sbt runner (sbt-the-shell-script)"))
|
||||
()
|
||||
|
||||
testOutput("--sbt-cache")("--sbt-cache", "./cachePath"): (out: List[String]) =>
|
||||
assert(out.contains[String]("-Dsbt.global.localcache=./cachePath"))
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
sbt.version=1.12.0
|
||||
|
|
@ -96,7 +96,7 @@ if defined JAVA_HOMES (
|
|||
if exist "project\build.properties" (
|
||||
for /F "eol=# delims== tokens=1*" %%a in (project\build.properties) do (
|
||||
if "%%a" == "sbt.version" if not "%%b" == "" (
|
||||
set build_props_sbt_version=%%b
|
||||
set "build_props_sbt_version=%%b"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -617,6 +617,26 @@ if !sbt_args_print_sbt_script_version! equ 1 (
|
|||
goto :eof
|
||||
)
|
||||
|
||||
rem Handle --version before native client so it works on sbt 2.x project dirs (#8717)
|
||||
if !sbt_args_print_version! equ 1 (
|
||||
set "local_build_props_version="
|
||||
if exist "project\build.properties" (
|
||||
for /F "eol=# delims== tokens=1*" %%a in (project\build.properties) do (
|
||||
if "%%a" == "sbt.version" if not "%%b" == "" (
|
||||
set "local_build_props_version=%%b"
|
||||
)
|
||||
)
|
||||
)
|
||||
if not "!local_build_props_version!" == "" (
|
||||
echo sbt version in this project: !local_build_props_version!
|
||||
)
|
||||
echo sbt runner version: !init_sbt_version!
|
||||
echo.
|
||||
echo [info] sbt runner (sbt-the-batch-script) is a runner to run any declared version of sbt.
|
||||
echo [info] Actual version of the sbt is declared using project\build.properties for each build.
|
||||
goto :eof
|
||||
)
|
||||
|
||||
if !run_native_client! equ 1 (
|
||||
goto :runnative !SBT_ARGS!
|
||||
goto :eof
|
||||
|
|
@ -725,17 +745,7 @@ if !sbt_args_print_sbt_version! equ 1 (
|
|||
goto :eof
|
||||
)
|
||||
|
||||
if !sbt_args_print_version! equ 1 (
|
||||
if !is_this_dir_sbt! equ 1 (
|
||||
call :set_sbt_version
|
||||
echo sbt version in this project: !sbt_version!
|
||||
)
|
||||
echo sbt runner version: !init_sbt_version!
|
||||
>&2 echo.
|
||||
>&2 echo [info] sbt runner ^(sbt-the-batch-script^) is a runner to run any declared version of sbt.
|
||||
>&2 echo [info] Actual version of the sbt is declared using project\build.properties for each build.
|
||||
goto :eof
|
||||
)
|
||||
rem This block is now handled earlier, before native client check
|
||||
|
||||
if defined sbt_args_verbose (
|
||||
echo # Executing command line:
|
||||
|
|
|
|||
15
sbt
15
sbt
|
|
@ -909,6 +909,21 @@ if [[ $print_sbt_script_version ]]; then
|
|||
exit 0
|
||||
fi
|
||||
|
||||
# Handle --version before native client so it works on sbt 2.x project dirs (#8717)
|
||||
if [[ $print_version ]]; then
|
||||
detect_working_directory
|
||||
if [[ -n "$is_this_dir_sbt" ]] && [[ -f ./project/build.properties ]]; then
|
||||
loadPropFile ./project/build.properties
|
||||
fi
|
||||
if [[ -n "$is_this_dir_sbt" ]] && [[ -n "$build_props_sbt_version" ]]; then
|
||||
echo "sbt version in this project: $build_props_sbt_version"
|
||||
fi
|
||||
echo "sbt runner version: $init_sbt_version"
|
||||
echo ""
|
||||
echo "[info] sbt runner (sbt-the-shell-script) is a runner to run any declared version of sbt."
|
||||
echo "[info] Actual version of the sbt is declared using project/build.properties for each build."
|
||||
exit 0
|
||||
fi
|
||||
if [[ "$(isRunNativeClient)" == "true" ]]; then
|
||||
set -- "${residual_args[@]}"
|
||||
argumentCount=$#
|
||||
|
|
|
|||
Loading…
Reference in New Issue