diff --git a/modules/cli/src/main/scala/scala/cli/ScalaCli.scala b/modules/cli/src/main/scala/scala/cli/ScalaCli.scala index 8047549c04..63bdd558ae 100644 --- a/modules/cli/src/main/scala/scala/cli/ScalaCli.scala +++ b/modules/cli/src/main/scala/scala/cli/ScalaCli.scala @@ -12,6 +12,7 @@ import java.util.Locale import scala.build.Directories import scala.build.internal.Constants import scala.build.internals.EnvVar +import scala.cli.commands.CommandUtils import scala.cli.config.{ConfigDb, Keys} import scala.cli.internal.Argv0 import scala.cli.javaLauncher.JavaLauncherCli @@ -244,10 +245,26 @@ object ScalaCli { case Some(ver) => val powerArgs = launcherOpts.powerOptions.toCliArgs val initialScalaRunnerArgs = launcherOpts.scalaRunner - val finalScalaRunnerArgs = - // if the version was specified, it doesn't make sense to check for CLI updates - (if Version(ver) < Version("1.4.0") then initialScalaRunnerArgs - else initialScalaRunnerArgs.copy(skipCliUpdates = Some(true))).toCliArgs + val finalScalaRunnerArgs = (Version(ver) match + case v if v < Version("1.4.0") && !ver.contains("nightly") => + initialScalaRunnerArgs.copy( + skipCliUpdates = None, + predefinedCliVersion = None, + initialLauncherPath = None + ) + case v if v < Version("1.5.1") && !ver.contains("nightly") => + initialScalaRunnerArgs.copy( + predefinedCliVersion = None, + initialLauncherPath = None + ) + case _ if initialScalaRunnerArgs.initialLauncherPath.nonEmpty => + initialScalaRunnerArgs + case _ => + initialScalaRunnerArgs.copy( + predefinedCliVersion = Some(ver), + initialLauncherPath = Some(CommandUtils.getAbsolutePathToScalaCli(progName)) + ) + ).toCliArgs val newArgs = powerArgs ++ finalScalaRunnerArgs ++ args0 LauncherCli.runAndExit(ver, launcherOpts, newArgs) case _ if diff --git a/modules/cli/src/main/scala/scala/cli/commands/setupide/SetupIde.scala b/modules/cli/src/main/scala/scala/cli/commands/setupide/SetupIde.scala index d8d4fe8ec5..0e196d84b1 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/setupide/SetupIde.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/setupide/SetupIde.scala @@ -154,9 +154,14 @@ object SetupIde extends ScalaCommand[SetupIdeOptions] { s"-J-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:$port,suspend=y" ) + val launcher = launcherOptions.scalaRunner.initialLauncherPath + .getOrElse(CommandUtils.getAbsolutePathToScalaCli(progName)) + val finalLauncherOptions = launcherOptions.copy(cliVersion = + launcherOptions.cliVersion.orElse(launcherOptions.scalaRunner.predefinedCliVersion) + ) val bspArgs = - List(CommandUtils.getAbsolutePathToScalaCli(progName)) ++ - launcherOptions.toCliArgs ++ + List(launcher) ++ + finalLauncherOptions.toCliArgs ++ List("bsp") ++ debugOpt ++ List("--json-options", scalaCliBspJsonDestination.toString) ++ @@ -184,7 +189,7 @@ object SetupIde extends ScalaCommand[SetupIdeOptions] { val json = gson.toJson(details) val scalaCliOptionsForBspJson = writeToArray(options.shared)(SharedOptions.jsonCodec) - val scalaCliLaunchOptsForBspJson = writeToArray(launcherOptions)(LauncherOptions.jsonCodec) + val scalaCliLaunchOptsForBspJson = writeToArray(finalLauncherOptions)(LauncherOptions.jsonCodec) val scalaCliBspInputsJson = writeToArray(ideInputs) val envsForBsp = sys.env.filter((key, _) => EnvVar.allBsp.map(_.name).contains(key)) val scalaCliBspEnvsJson = writeToArray(envsForBsp) diff --git a/modules/cli/src/main/scala/scala/cli/launcher/ScalaRunnerLauncherOptions.scala b/modules/cli/src/main/scala/scala/cli/launcher/ScalaRunnerLauncherOptions.scala index 091837b2d7..09ed8aedfe 100644 --- a/modules/cli/src/main/scala/scala/cli/launcher/ScalaRunnerLauncherOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/launcher/ScalaRunnerLauncherOptions.scala @@ -39,12 +39,22 @@ case class ScalaRunnerLauncherOptions( ) @Hidden @Tag(tags.implementation) - skipCliUpdates: Option[Boolean] = None + skipCliUpdates: Option[Boolean] = None, + @Hidden + @Tag(tags.implementation) + predefinedCliVersion: Option[String] = None, + @Hidden + @Tag(tags.implementation) + @Name("initialLauncher") + initialLauncherPath: Option[String] = None ) { def toCliArgs: List[String] = cliUserScalaVersion.toList.flatMap(v => List("--cli-default-scala-version", v)) ++ cliPredefinedRepository.flatMap(v => List("--repository", v)) ++ - progName.toList.flatMap(v => List("--prog-name", v)) + progName.toList.flatMap(v => List("--prog-name", v)) ++ + skipCliUpdates.toList.filter(v => v).map(_ => "--skip-cli-updates") ++ + predefinedCliVersion.toList.flatMap(v => List("--predefined-cli-version", v)) ++ + initialLauncherPath.toList.flatMap(v => List("--initial-launcher-path", v)) } object ScalaRunnerLauncherOptions { diff --git a/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala index 593cbb237b..99311eebe1 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala @@ -2162,4 +2162,22 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg } } } + + // TODO: uncomment when the fix for https://github.com/VirtusLab/scala-cli/issues/3157 is on nightly +// test("setup-ide prepares a valid BSP configuration with --cli-version") { +// val scriptName = "cli-version.sc" +// val cliVersion = "nightly" +// val inputs = TestInputs(os.rel / scriptName -> s"""println("Hello from launcher v$cliVersion""") +// inputs.fromRoot { root => +// val cliVersionArgs = List("--cli-version", cliVersion) +// os.proc(TestUtil.cli, cliVersionArgs, "setup-ide", scriptName, extraOptions).call(cwd = root) +// val expectedIdeLauncherFile = root / Constants.workspaceDirName / "ide-launcher-options.json" +// expect(expectedIdeLauncherFile.toNIO.toFile.exists()) +// expect(os.read(expectedIdeLauncherFile).contains(cliVersion)) +// val bspConfig = readBspConfig(root) +// expect(bspConfig.argv.head == TestUtil.cliPath) +// expect(bspConfig.argv.containsSlice(cliVersionArgs)) +// expect(bspConfig.argv.indexOfSlice(cliVersionArgs) < bspConfig.argv.indexOf("bsp")) +// } +// } }