[2.x] refactor: Remove return from sbtw/Main (#9066)

This commit is contained in:
kenji yoshida 2026-04-12 02:06:50 +09:00 committed by GitHub
parent 78afa8fb96
commit 2e0a724c63
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 80 additions and 80 deletions

View File

@ -1023,10 +1023,6 @@ lazy val sbtwProj = (project in file("sbtw"))
description := "Windows drop-in launcher for sbt (replaces sbt.bat)",
scalaVersion := "3.8.3",
crossPaths := false,
Compile / scalafix / unmanagedSources := {
// https://github.com/scalameta/scalameta/issues/4531
(Compile / unmanagedSources).value.filterNot(_.getName == "Main.scala")
},
Compile / mainClass := Some("sbtw.Main"),
libraryDependencies += "com.github.scopt" %% "scopt" % "4.1.0",
libraryDependencies += scalaVerify % Test,

View File

@ -10,8 +10,9 @@ object Main:
val sbtHome = new File(
sys.env
.get("SBT_HOME")
.getOrElse:
.getOrElse(
sys.env.get("SBT_BIN_DIR").map(d => new File(d).getParent).getOrElse(cwd.getAbsolutePath)
)
)
val sbtBinDir = new File(sbtHome, "bin")
@ -26,86 +27,88 @@ object Main:
System.exit(if exitCode == 0 then 0 else 1)
private def run(cwd: File, sbtHome: File, sbtBinDir: File, opts: LauncherOptions): Int =
if opts.help then return printUsage()
if opts.version || opts.numericVersion || opts.scriptVersion then
return handleVersionCommands(cwd, sbtHome, sbtBinDir, opts)
if opts.shutdownAll then
if opts.help then printUsage()
else if opts.version || opts.numericVersion || opts.scriptVersion then
handleVersionCommands(cwd, sbtHome, sbtBinDir, opts)
else if opts.shutdownAll then
val javaCmd = Runner.findJavaCmd(opts.javaHome)
return Runner.shutdownAll(javaCmd)
if !opts.allowEmpty && !opts.sbtNew && !ConfigLoader.isSbtProjectDir(cwd) then
Runner.shutdownAll(javaCmd)
else if !opts.allowEmpty && !opts.sbtNew && !ConfigLoader.isSbtProjectDir(cwd) then
System.err.println(
"[error] Neither build.sbt nor a 'project' directory in the current directory: " + cwd
)
System.err.println("[error] run 'sbt new', touch build.sbt, or run 'sbt --allow-empty'.")
return 1
1
else
val buildPropsVersion = ConfigLoader.sbtVersionFromBuildProperties(cwd)
val buildPropsVersion = ConfigLoader.sbtVersionFromBuildProperties(cwd)
val javaCmd = Runner.findJavaCmd(opts.javaHome)
val javaVer = Runner.javaVersion(javaCmd)
val minJdk = Runner.minimumJdkVersion(buildPropsVersion)
if javaVer > 0 && javaVer < minJdk then
if minJdk >= 17 then
System.err.println(
"[error] sbt 2.x requires JDK 17 or above, but you have JDK " + javaVer
)
else System.err.println("[error] sbt requires at least JDK 8+, you have " + javaVer)
1
else
val bspMode = opts.residual.exists(a => a == "bsp" || a == "-bsp" || a == "--bsp")
val clientOpt = opts.client || sys.env.get("SBT_NATIVE_CLIENT").contains("true")
val useNativeClient =
if bspMode then false
else shouldRunNativeClient(opts.copy(client = clientOpt), buildPropsVersion)
val javaCmd = Runner.findJavaCmd(opts.javaHome)
val javaVer = Runner.javaVersion(javaCmd)
val minJdk = Runner.minimumJdkVersion(buildPropsVersion)
if javaVer > 0 && javaVer < minJdk then
if minJdk >= 17 then
System.err.println("[error] sbt 2.x requires JDK 17 or above, but you have JDK " + javaVer)
else System.err.println("[error] sbt requires at least JDK 8+, you have " + javaVer)
return 1
if useNativeClient then
val scriptPath = sbtBinDir.getAbsolutePath.replace("\\", "/") + "/sbt.bat"
Runner.runNativeClient(sbtBinDir, scriptPath, opts)
else
val sbtJar = opts.sbtJar
.filter(p => new File(p).isFile)
.getOrElse(new File(sbtBinDir, "sbt-launch.jar").getAbsolutePath)
if !new File(sbtJar).isFile then
System.err.println("[error] Launcher jar not found: " + sbtJar)
1
else
var javaOpts = ConfigLoader.loadJvmOpts(cwd)
if javaOpts.isEmpty then javaOpts = ConfigLoader.defaultJavaOpts
var sbtOpts = Runner.buildSbtOpts(opts)
val bspMode = opts.residual.exists(a => a == "bsp" || a == "-bsp" || a == "--bsp")
val clientOpt = opts.client || sys.env.get("SBT_NATIVE_CLIENT").contains("true")
val useNativeClient =
if bspMode then false
else shouldRunNativeClient(opts.copy(client = clientOpt), buildPropsVersion)
val (residualJava, bootArgs) = Runner.splitResidual(opts.residual)
javaOpts = javaOpts ++ residualJava
if useNativeClient then
val scriptPath = sbtBinDir.getAbsolutePath.replace("\\", "/") + "/sbt.bat"
return Runner.runNativeClient(sbtBinDir, scriptPath, opts)
val (finalJava, finalSbt) = if opts.mem.isDefined then
val evictedJava = Memory.evictMemoryOpts(javaOpts)
val evictedSbt = Memory.evictMemoryOpts(sbtOpts)
val memOpts = Memory.addMemory(opts.mem.get, javaVer)
(evictedJava ++ memOpts, evictedSbt)
else Memory.addDefaultMemory(javaOpts, sbtOpts, javaVer, LauncherOptions.defaultMemMb)
sbtOpts = finalSbt
val sbtJar = opts.sbtJar
.filter(p => new File(p).isFile)
.getOrElse(new File(sbtBinDir, "sbt-launch.jar").getAbsolutePath)
if !new File(sbtJar).isFile then
System.err.println("[error] Launcher jar not found: " + sbtJar)
return 1
if !opts.noHideJdkWarnings && javaVer == 25 then
sbtOpts = sbtOpts ++ Seq(
"--sun-misc-unsafe-memory-access=allow",
"--enable-native-access=ALL-UNNAMED"
)
val javaOptsWithDebug = opts.jvmDebug.fold(finalJava)(port =>
finalJava :+ s"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$port"
)
var javaOpts = ConfigLoader.loadJvmOpts(cwd)
if javaOpts.isEmpty then javaOpts = ConfigLoader.defaultJavaOpts
var sbtOpts = Runner.buildSbtOpts(opts)
val (residualJava, bootArgs) = Runner.splitResidual(opts.residual)
javaOpts = javaOpts ++ residualJava
val (finalJava, finalSbt) = if opts.mem.isDefined then
val evictedJava = Memory.evictMemoryOpts(javaOpts)
val evictedSbt = Memory.evictMemoryOpts(sbtOpts)
val memOpts = Memory.addMemory(opts.mem.get, javaVer)
(evictedJava ++ memOpts, evictedSbt)
else Memory.addDefaultMemory(javaOpts, sbtOpts, javaVer, LauncherOptions.defaultMemMb)
sbtOpts = finalSbt
if !opts.noHideJdkWarnings && javaVer == 25 then
sbtOpts = sbtOpts ++ Seq(
"--sun-misc-unsafe-memory-access=allow",
"--enable-native-access=ALL-UNNAMED"
)
val javaOptsWithDebug = opts.jvmDebug.fold(finalJava)(port =>
finalJava :+ s"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$port"
)
Runner.runJvm(javaCmd, javaOptsWithDebug, sbtOpts, sbtJar, bootArgs, opts.verbose)
Runner.runJvm(javaCmd, javaOptsWithDebug, sbtOpts, sbtJar, bootArgs, opts.verbose)
private def shouldRunNativeClient(
opts: LauncherOptions,
buildPropsVersion: Option[String]
): Boolean =
if opts.sbtNew then return false
if opts.jvmClient then return false
val version = buildPropsVersion.getOrElse(LauncherOptions.initSbtVersion)
val parts = version.split("[.-]").take(2).flatMap(s => scala.util.Try(s.toInt).toOption)
val (major, minor) = (parts.lift(0).getOrElse(0), parts.lift(1).getOrElse(0))
if major >= 2 then !opts.server
else if major >= 1 && minor >= 4 then opts.client
else false
if opts.sbtNew then false
else if opts.jvmClient then false
else
val version = buildPropsVersion.getOrElse(LauncherOptions.initSbtVersion)
val parts = version.split("[.-]").take(2).flatMap(s => scala.util.Try(s.toInt).toOption)
val (major, minor) = (parts.lift(0).getOrElse(0), parts.lift(1).getOrElse(0))
if major >= 2 then !opts.server
else if major >= 1 && minor >= 4 then opts.client
else false
private def handleVersionCommands(
cwd: File,
@ -115,8 +118,8 @@ object Main:
): Int =
if opts.scriptVersion then
println(LauncherOptions.initSbtVersion)
return 0
if opts.version then
0
else if opts.version then
if ConfigLoader.isSbtProjectDir(cwd) then
projectSbtVersion(cwd).foreach: version =>
println("sbt version in this project: " + version)
@ -125,21 +128,22 @@ object Main:
System.err.println(
"[info] Actual version of sbt is declared using project\\build.properties for each build."
)
return 0
if opts.numericVersion then
0
else if opts.numericVersion then
val javaCmd = Runner.findJavaCmd(opts.javaHome)
val sbtJar = opts.sbtJar
.filter(p => new File(p).isFile)
.getOrElse(new File(sbtBinDir, "sbt-launch.jar").getAbsolutePath)
if !new File(sbtJar).isFile then
System.err.println("[error] Launcher jar not found for version check")
return 1
try
val out = Process(Seq(javaCmd, "-jar", sbtJar, "sbtVersion")).!!
println(out.linesIterator.toSeq.lastOption.map(_.trim).getOrElse(""))
return 0
catch { case _: Exception => return 1 }
0
1
else
try
val out = Process(Seq(javaCmd, "-jar", sbtJar, "sbtVersion")).!!
println(out.linesIterator.toSeq.lastOption.map(_.trim).getOrElse(""))
0
catch { case _: Exception => 1 }
else 0
private def projectSbtVersion(cwd: File): Option[String] =
ConfigLoader.sbtVersionFromBuildProperties(cwd).flatMap(normalizeVersion)