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 759067d860..491ea9d912 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 @@ -93,17 +93,19 @@ object SetupIde extends ScalaCommand[SetupIdeOptions] { previousCommandName: Option[String], args: Seq[String] ): Unit = - writeBspConfiguration( - SetupIdeOptions(shared = options), - inputs, - buildOptions, - previousCommandName, - args - ) match { - case Left(ex) => - logger.debug(s"Ignoring error during setup-ide: ${ex.message}") - case Right(_) => - } + if options.autoSetupIdeEnabled then + writeBspConfiguration( + SetupIdeOptions(shared = options), + inputs, + buildOptions, + previousCommandName, + args + ) match { + case Left(ex) => + logger.debug(s"Ignoring error during setup-ide: ${ex.message}") + case Right(_) => + } + else logger.debug("Auto setup-ide is disabled, skipping .bsp generation.") override def sharedOptions(options: SetupIdeOptions): Option[SharedOptions] = Some(options.shared) diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala index 4ea59433fd..71dd29d1f3 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala @@ -210,6 +210,13 @@ final case class SharedOptions( @HelpMessage("Force object wrapper for scripts") @Tag(tags.experimental) objectWrapper: Option[Boolean] = None, + @Group(HelpGroup.Scala.toString) + @HelpMessage( + "Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default." + ) + @Name("auto-setup-bsp") + @Tag(tags.implementation) + autoSetupIde: Option[Boolean] = None, @Recurse scope: ScopeOptions = ScopeOptions(), @@ -231,6 +238,14 @@ final case class SharedOptions( def logger: Logger = logging.logger override def global: GlobalOptions = GlobalOptions(logging = logging, globalSuppress = suppress.global, powerOptions = powerOptions) + def autoSetupIdeEnabled: Boolean = + autoSetupIde + .orElse( + ConfigDbUtils.getLatestConfigDbOpt(logger) + .flatMap(_.get(Keys.autoSetupIde).toOption) + .flatten + ) + .getOrElse(true) private def scalaJsOptions(opts: ScalaJsOptions): options.ScalaJsOptions = { import opts._ diff --git a/modules/config/src/main/scala/scala/cli/config/Keys.scala b/modules/config/src/main/scala/scala/cli/config/Keys.scala index 16dd6328fc..223e1cc843 100644 --- a/modules/config/src/main/scala/scala/cli/config/Keys.scala +++ b/modules/config/src/main/scala/scala/cli/config/Keys.scala @@ -54,6 +54,13 @@ object Keys { specificationLevel = SpecificationLevel.IMPLEMENTATION, description = "Globally enables actionable diagnostics. Enabled by default." ) + val autoSetupIde = new Key.BooleanEntry( + prefix = Seq("ide"), + name = "auto-setup", + specificationLevel = SpecificationLevel.IMPLEMENTATION, + description = + "Globally controls whether the BSP configuration in `.bsp/` is generated automatically by build commands. Enabled by default." + ) val interactive = new Key.BooleanEntry( prefix = Seq.empty, name = "interactive", @@ -184,6 +191,7 @@ object Keys { def all: Seq[Key[?]] = Seq[Key[?]]( actions, + autoSetupIde, defaultRepositories, deprecatedTestKey, ghToken, diff --git a/modules/integration/src/test/scala/scala/cli/integration/CompileTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/CompileTestDefinitions.scala index b4e5fdfeaa..b1fc5be60f 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/CompileTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/CompileTestDefinitions.scala @@ -212,6 +212,34 @@ abstract class CompileTestDefinitions } } + test("compile auto setup-ide enabled by default") { + TestInputs( + os.rel / "Main.scala" -> + """object Main { + | def main(args: Array[String]): Unit = println("Hello") + |} + |""".stripMargin + ).fromRoot { root => + val bspEntry = root / ".bsp" / "scala-cli.json" + os.proc(TestUtil.cli, "compile", extraOptions, ".").call(cwd = root) + assert(os.exists(bspEntry)) + } + } + + test("compile can disable auto setup-ide via --auto-setup-ide=false") { + TestInputs( + os.rel / "Main.scala" -> + """object Main { + | def main(args: Array[String]): Unit = println("Hello") + |} + |""".stripMargin + ).fromRoot { root => + val bspEntry = root / ".bsp" / "scala-cli.json" + os.proc(TestUtil.cli, "compile", extraOptions, ".", "--auto-setup-ide=false").call(cwd = root) + assert(!os.exists(bspEntry)) + } + } + test("exit code") { val inputs = TestInputs( os.rel / "Main.scala" -> diff --git a/modules/integration/src/test/scala/scala/cli/integration/ConfigTests.scala b/modules/integration/src/test/scala/scala/cli/integration/ConfigTests.scala index 4223d38e4a..8e47cea44a 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ConfigTests.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ConfigTests.scala @@ -46,6 +46,31 @@ class ConfigTests extends ScalaCliSuite { } } + test("ide.auto-setup controls implicit bsp generation for build commands") { + val configFile = os.rel / "config" / "config.json" + val configEnv = Map("SCALA_CLI_CONFIG" -> configFile.toString) + TestInputs( + os.rel / "Main.scala" -> + """object Main { + | def main(args: Array[String]): Unit = println("Hello") + |} + |""".stripMargin + ).fromRoot { root => + val bspEntry = root / ".bsp" / "scala-cli.json" + + os.proc(TestUtil.cli, "config", "ide.auto-setup", "false").call(cwd = root, env = configEnv) + + os.proc(TestUtil.cli, "compile", ".").call(cwd = root, env = configEnv) + assert(!os.exists(bspEntry)) + + os.proc(TestUtil.cli, "compile", "--auto-setup-ide=true", ".").call( + cwd = root, + env = configEnv + ) + assert(os.exists(bspEntry)) + } + } + test("password") { val configFile = os.rel / "config" / "config.json" val configEnv = Map("SCALA_CLI_CONFIG" -> configFile.toString) diff --git a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala index 6bb62f249e..fc05136374 100755 --- a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala @@ -123,6 +123,38 @@ abstract class RunTestDefinitions } } + test("run auto setup-ide enabled by default") { + TestInputs( + os.rel / "Main.scala" -> + """object Main { + | def main(args: Array[String]): Unit = println("Hello from run") + |} + |""".stripMargin + ).fromRoot { root => + val bspEntry = root / ".bsp" / "scala-cli.json" + val res = os.proc(TestUtil.cli, "run", extraOptions, ".").call(cwd = root) + expect(res.out.trim() == "Hello from run") + assert(os.exists(bspEntry)) + } + } + + test("run can disable auto setup-ide via --auto-setup-ide=false") { + TestInputs( + os.rel / "Main.scala" -> + """object Main { + | def main(args: Array[String]): Unit = println("Hello from run") + |} + |""".stripMargin + ).fromRoot { root => + val bspEntry = root / ".bsp" / "scala-cli.json" + val res = os.proc(TestUtil.cli, "run", extraOptions, ".", "--auto-setup-ide=false").call(cwd = + root + ) + expect(res.out.trim() == "Hello from run") + assert(!os.exists(bspEntry)) + } + } + test("Debugging") { val inputs = TestInputs( os.rel / "Foo.scala" -> diff --git a/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala index 363fd3ed1a..f1b45cc3e6 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala @@ -234,6 +234,27 @@ abstract class TestTestDefinitions extends ScalaCliSuite with TestScalaVersionAr } } + test("test auto setup-ide enabled by default") { + successfulTestInputs().fromRoot { root => + val bspEntry = root / ".bsp" / "scala-cli.json" + val output = os.proc(TestUtil.cli, "test", extraOptions, ".").call(cwd = root).out.text() + expect(output.contains("Hello from tests")) + assert(os.exists(bspEntry)) + } + } + + test("test can disable auto setup-ide via --auto-setup-ide=false") { + successfulTestInputs().fromRoot { root => + val bspEntry = root / ".bsp" / "scala-cli.json" + val output = + os.proc(TestUtil.cli, "test", extraOptions, ".", "--auto-setup-ide=false").call(cwd = root) + .out + .text() + expect(output.contains("Hello from tests")) + assert(!os.exists(bspEntry)) + } + } + if (!Properties.isMac || !TestUtil.isCI) test("--watching with --watch re-runs tests on external file change") { val sourceFile = os.rel / "MyTests.test.scala" diff --git a/website/docs/reference/cli-options.md b/website/docs/reference/cli-options.md index 0d31e53ad4..da2e8044c3 100644 --- a/website/docs/reference/cli-options.md +++ b/website/docs/reference/cli-options.md @@ -1713,6 +1713,12 @@ Exclude sources Force object wrapper for scripts +### `--auto-setup-ide` + +Aliases: `--auto-setup-bsp` + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + ### [deprecated] `--deprecated-test-option` **Deprecated**: For testing purposes only. diff --git a/website/docs/reference/commands.md b/website/docs/reference/commands.md index 5e7ccd12fb..f64e02c648 100644 --- a/website/docs/reference/commands.md +++ b/website/docs/reference/commands.md @@ -53,6 +53,7 @@ Available keys: - httpProxy.address HTTP proxy address. - httpProxy.password HTTP proxy password (used for authentication). - httpProxy.user HTTP proxy user (used for authentication). + - ide.auto-setup Globally controls whether the BSP configuration in `.bsp/` is generated automatically by build commands. Enabled by default. - interactive Globally enables interactive mode (the '--interactive' flag). - interactive-was-suggested Setting indicating if the global interactive mode was already suggested. - java.properties Java properties for Scala CLI's execution. diff --git a/website/docs/reference/scala-command/cli-options.md b/website/docs/reference/scala-command/cli-options.md index e1e618f31a..d4df9aac56 100644 --- a/website/docs/reference/scala-command/cli-options.md +++ b/website/docs/reference/scala-command/cli-options.md @@ -1164,6 +1164,14 @@ Add toolkit to classPath (not supported in Scala 2.12), 'default' version for Sc Exclude sources +### `--auto-setup-ide` + +Aliases: `--auto-setup-bsp` + +`IMPLEMENTATION specific` per Scala Runner specification + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + ### [deprecated] `--deprecated-test-option` **Deprecated**: For testing purposes only. diff --git a/website/docs/reference/scala-command/commands.md b/website/docs/reference/scala-command/commands.md index a13403a694..ce9c04a773 100644 --- a/website/docs/reference/scala-command/commands.md +++ b/website/docs/reference/scala-command/commands.md @@ -52,6 +52,7 @@ Available keys: - httpProxy.address HTTP proxy address. - httpProxy.password HTTP proxy password (used for authentication). - httpProxy.user HTTP proxy user (used for authentication). + - ide.auto-setup Globally controls whether the BSP configuration in `.bsp/` is generated automatically by build commands. Enabled by default. - interactive Globally enables interactive mode (the '--interactive' flag). - interactive-was-suggested Setting indicating if the global interactive mode was already suggested. - java.properties Java properties for Scala CLI's execution. diff --git a/website/docs/reference/scala-command/runner-specification.md b/website/docs/reference/scala-command/runner-specification.md index bb4731c748..a1007fa422 100644 --- a/website/docs/reference/scala-command/runner-specification.md +++ b/website/docs/reference/scala-command/runner-specification.md @@ -650,6 +650,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -684,6 +690,7 @@ Available keys: - httpProxy.address HTTP proxy address. - httpProxy.password HTTP proxy password (used for authentication). - httpProxy.user HTTP proxy user (used for authentication). + - ide.auto-setup Globally controls whether the BSP configuration in `.bsp/` is generated automatically by build commands. Enabled by default. - interactive Globally enables interactive mode (the '--interactive' flag). - interactive-was-suggested Setting indicating if the global interactive mode was already suggested. - java.properties Java properties for Scala CLI's execution. @@ -1452,6 +1459,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -2071,6 +2084,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -2720,6 +2739,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -3378,6 +3403,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -3994,6 +4025,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -4688,6 +4725,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -5392,6 +5435,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use) @@ -6379,6 +6428,12 @@ Aliases: `--toolkit` Exclude sources +**--auto-setup-ide** + +Automatically generate BSP configuration in `.bsp/` when running build commands. Enabled by default. + +Aliases: `--auto-setup-bsp` + **--deprecated-test-option** Deprecated test option (internal, do not use)