diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbc83f1d74..88c47b39e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,7 +161,8 @@ jobs: # test building sbtn on Linux sbt "-Dsbt.io.virtual=false" nativeImage # smoke test native Image - ./client/target/bin/sbtn shutdown + ./client/target/bin/sbtn --sbt-script=$(pwd)/sbt about + ./client/target/bin/sbtn --sbt-script=$(pwd)/sbt shutdown # test launcher script echo build using JDK 8 test using JDK 8 and JDK 11 cd launcher-package @@ -189,6 +190,9 @@ jobs: run: | # test building sbtn on Windows sbt "-Dsbt.io.virtual=false" nativeImage + # smoke test native Image + ./client/target/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat about + ./client/target/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat shutdown # test launcher script echo build using JDK 8, test using JDK 8, on Windows cd launcher-package diff --git a/build.sbt b/build.sbt index 7bc842facb..84d5c182cf 100644 --- a/build.sbt +++ b/build.sbt @@ -11,7 +11,7 @@ import scala.util.Try // ThisBuild settings take lower precedence, // but can be shared across the multi projects. ThisBuild / version := { - val v = "1.10.10-SNAPSHOT" + val v = "1.10.11-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/launcher-package/integration-test/src/test/scala/RunnerTest.scala b/launcher-package/integration-test/src/test/scala/RunnerTest.scala index 382b259d77..4ea58563b0 100755 --- a/launcher-package/integration-test/src/test/scala/RunnerTest.scala +++ b/launcher-package/integration-test/src/test/scala/RunnerTest.scala @@ -33,19 +33,32 @@ object SbtRunnerTest extends SimpleTestSuite with PowerAssertions { () } + def testVersion(lines: List[String]): Unit = { + assert(lines.size >= 2) + val expected0 = s"(?m)^sbt version in this project: $versionRegEx(\\r)?" + assert(lines(0).matches(expected0)) + val expected1 = s"sbt runner version: $versionRegEx$$" + assert(lines(1).matches(expected1)) + } + test("sbt -V|-version|--version should print sbtVersion") { val out = sbtProcess("-version").!!.trim - val expectedVersion = - s"""|(?m)^sbt version in this project: $versionRegEx(\\r)? - |sbt script version: $versionRegEx$$ - |""".stripMargin.trim.replace("\n", "\\n") - assert(out.matches(expectedVersion)) + testVersion(out.linesIterator.toList) val out2 = sbtProcess("--version").!!.trim - assert(out2.matches(expectedVersion)) + testVersion(out2.linesIterator.toList) val out3 = sbtProcess("-V").!!.trim - assert(out3.matches(expectedVersion)) + testVersion(out3.linesIterator.toList) + } + + test("sbt -V in empty directory") { + IO.withTemporaryDirectory { tmp => + val out = sbtProcessInDir(tmp)("-V").!!.trim + val expectedVersion = "^"+versionRegEx+"$" + val targetDir = new File(tmp, "target") + assert(!targetDir.exists, "expected target directory to not exist, but existed") + } () } diff --git a/launcher-package/src/universal/bin/sbt.bat b/launcher-package/src/universal/bin/sbt.bat index 3de1fbd88b..983b618a7d 100755 --- a/launcher-package/src/universal/bin/sbt.bat +++ b/launcher-package/src/universal/bin/sbt.bat @@ -51,6 +51,7 @@ set sbt_args_sbt_version= set sbt_args_mem= set sbt_args_client= set sbt_args_no_server= +set is_this_dir_sbt=0 rem users can set SBT_OPTS via .sbtopts if exist .sbtopts for /F %%A in (.sbtopts) do ( @@ -532,11 +533,18 @@ set SBT_ARGS=!SBT_ARGS! %0 goto args_loop :args_end +if exist build.sbt ( + set is_this_dir_sbt=1 +) +if exist project\build.properties ( + set is_this_dir_sbt=1 +) + rem Confirm a user's intent if the current directory does not look like an sbt rem top-level directory and the "new" command was not given. -if not defined sbt_args_allow_empty if not defined sbt_args_print_version if not defined sbt_args_print_sbt_version if not defined sbt_args_print_sbt_script_version if not defined shutdownall if not exist build.sbt ( - if not exist project\ ( +if not defined sbt_args_allow_empty if not defined sbt_args_print_version if not defined sbt_args_print_sbt_version if not defined sbt_args_print_sbt_script_version if not defined shutdownall ( + if not !is_this_dir_sbt! equ 1 ( if not defined sbt_new ( echo [error] Neither build.sbt nor a 'project' directory in the current directory: "%CD%" echo [error] run 'sbt new', touch build.sbt, or run 'sbt --allow-empty'. @@ -667,9 +675,14 @@ if !sbt_args_print_sbt_version! equ 1 ( ) if !sbt_args_print_version! equ 1 ( - call :set_sbt_version - echo sbt version in this project: !sbt_version! - echo sbt script version: !init_sbt_version! + 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! + 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 ) diff --git a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala index 3eea88c11a..6bc13337fb 100644 --- a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala +++ b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala @@ -153,6 +153,7 @@ class NetworkClient( private lazy val noTab = arguments.completionArguments.contains("--no-tab") private lazy val noStdErr = arguments.completionArguments.contains("--no-stderr") && !sys.env.contains("SBTN_AUTO_COMPLETE") && !sys.env.contains("SBTC_AUTO_COMPLETE") + private def shutdownOnly = arguments.commandArguments == Seq(Shutdown) private def mkSocket(file: File): (Socket, Option[String]) = ClientSocket.socket(file, useJNI) @@ -188,7 +189,10 @@ class NetworkClient( ): (Socket, Option[String]) = try { if (!portfile.exists) { - if (promptCompleteUsers) { + if (shutdownOnly) { + console.appendLog(Level.Info, "no sbt server is running. ciao") + System.exit(0) + } else if (promptCompleteUsers) { val msg = if (noTab) "" else "No sbt server is running. Press to start one..." errorStream.print(s"\n$msg") if (noStdErr) System.exit(0) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 0b54ba2e5f..dbbbe84b13 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1213,7 +1213,7 @@ object Defaults extends BuildCommon { for (lib <- scalaDeps.take(1)) { val libVer = lib.module.revision val libName = lib.module.name - val n = name.value + val proj = Def.displayBuildRelative(thisProjectRef.value.build, thisProjectRef.value) if (VersionNumber(sv).matchesSemVer(SemanticSelector(s"<$libVer"))) { val err = !allowUnsafeScalaLibUpgrade.value val fix = @@ -1227,13 +1227,13 @@ object Defaults extends BuildCommon { |Compilation (macro expansion) or using the Scala REPL in sbt may fail with a LinkageError.""".stripMargin val msg = - s"""Expected `$n/scalaVersion` to be $libVer or later, but found $sv. + s"""Expected `$proj scalaVersion` to be $libVer or later, but found $sv. |To support backwards-only binary compatibility (SIP-51), the Scala 2.13 compiler |should not be older than $libName on the dependency classpath. | |$fix | - |See `$n/evicted` to know why $libName $libVer is getting pulled in. + |See `$proj evicted` to know why $libName $libVer is getting pulled in. |""".stripMargin if (err) sys.error(msg) else s.log.warn(msg) diff --git a/main/src/main/scala/sbt/internal/server/BspCompileTask.scala b/main/src/main/scala/sbt/internal/server/BspCompileTask.scala index ed784f2441..b2aed4e55f 100644 --- a/main/src/main/scala/sbt/internal/server/BspCompileTask.scala +++ b/main/src/main/scala/sbt/internal/server/BspCompileTask.scala @@ -16,7 +16,6 @@ import sbt.internal.server.BspCompileTask.exchange import sbt.librarymanagement.Configuration import sbt.util.InterfaceUtil import sjsonnew.support.scalajson.unsafe.Converter -import xsbti.CompileCancelled import xsbti.CompileFailed import xsbti.Problem import xsbti.Severity @@ -39,7 +38,7 @@ object BspCompileTask { val task = BspCompileTask(targetId, project, config, ci) try { task.notifyStart() - val result = Retry(compile(task), classOf[CompileCancelled], classOf[CompileFailed]) + val result = Retry.io(compile(task)) task.notifySuccess(result) result } catch { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8e040b7e50..f3ef989a25 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -12,7 +12,7 @@ object Dependencies { sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") // sbt modules - private val ioVersion = nightlyVersion.getOrElse("1.10.4") + private val ioVersion = nightlyVersion.getOrElse("1.10.5") private val lmVersion = sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.10.4") val zincVersion = nightlyVersion.getOrElse("1.10.8") @@ -77,7 +77,7 @@ object Dependencies { def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompile", zincCompile) def addSbtZincCompileCore = addSbtModule(sbtZincPath, "zincCompileCore", zincCompileCore) - val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.1.7" + val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.1.8" def sjsonNew(n: String) = Def.setting("com.eed3si9n" %% n % "0.10.1") // contrabandSjsonNewVersion.value diff --git a/sbt b/sbt index c8176a38f2..217be39ecf 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.10.10" +declare builtin_sbt_version="1.10.11" declare -a residual_args declare -a java_args declare -a scalac_args @@ -26,6 +26,7 @@ declare no_server= declare sbtn_command="$SBTN_CMD" declare sbtn_version="1.10.8" declare use_colors=1 +declare is_this_dir_sbt="" ### ------------------------------- ### ### Helper methods for BASH scripts ### @@ -494,11 +495,17 @@ copyRt() { fi } +detect_working_directory() { + if [[ -f ./build.sbt || -f ./project/build.properties ]]; then + is_this_dir_sbt=1 + fi +} + # Confirm a user's intent if the current directory does not look like an sbt # top-level directory and neither the --allow-empty option nor the "new" command was given. checkWorkingDirectory() { if [[ ! -n "$allow_empty" ]]; then - [[ -f ./build.sbt || -d ./project || -n "$sbt_new" ]] || { + [[ -n "$is_this_dir_sbt" || -n "$sbt_new" ]] || { echoerr_error "Neither build.sbt nor a 'project' directory in the current directory: $(pwd)" echoerr_error "run 'sbt new', touch build.sbt, or run 'sbt --allow-empty'." echoerr_error "" @@ -531,13 +538,19 @@ run() { addJava "-Dsbt.cygwin=true" fi + detect_working_directory if [[ $print_sbt_version ]]; then execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]//g' elif [[ $print_sbt_script_version ]]; then echo "$init_sbt_version" elif [[ $print_version ]]; then - execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]/sbt version in this project:/g' - echo "sbt script version: $init_sbt_version" + if [[ -n "$is_this_dir_sbt" ]]; then + execRunner "$java_cmd" -jar "$sbt_jar" "sbtVersion" | tail -1 | sed -e 's/\[info\]/sbt version in this project:/g' + fi + echo "sbt runner version: $init_sbt_version" + echoerr "" + echoerr "[info] sbt runner (sbt-the-shell-script) is a runner to run any declared version of sbt." + echoerr "[info] Actual version of the sbt is declared using project/build.properties for each build." elif [[ $shutdownall ]]; then local sbt_processes=( $(jps -v | grep sbt-launch | cut -f1 -d ' ') ) for procId in "${sbt_processes[@]}"; do @@ -792,7 +805,12 @@ runNativeClient() { unset 'original_args[i]' fi done - sbt_script=$0 + + if [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then + sbt_script="$0.bat" + else + sbt_script="$0" + fi sbt_script=${sbt_script/ /%20} execRunner "$sbtn_command" "--sbt-script=$sbt_script" "${original_args[@]}" }