diff --git a/modules/build/src/main/scala/scala/build/bsp/BspServer.scala b/modules/build/src/main/scala/scala/build/bsp/BspServer.scala index 375dd555f2..95c85c0d11 100644 --- a/modules/build/src/main/scala/scala/build/bsp/BspServer.scala +++ b/modules/build/src/main/scala/scala/build/bsp/BspServer.scala @@ -26,7 +26,6 @@ class BspServer( with JavaBuildServerForwardStubs with JvmBuildServerForwardStubs with HasGeneratedSourcesImpl { - private var client: Option[BuildClient] = None @volatile private var intelliJ: Boolean = presetIntelliJ @@ -200,7 +199,7 @@ class BspServer( super.buildTargetCleanCache(check(params)) override def buildTargetCompile(params: b.CompileParams): CompletableFuture[b.CompileResult] = - compile(() => super.buildTargetCompile(check(params))) + compile(() => super.buildTargetCompile(check(params.withVerbosity(logger.verbosity > 0)))) override def buildTargetDependencySources( params: b.DependencySourcesParams diff --git a/modules/build/src/main/scala/scala/build/bsp/package.scala b/modules/build/src/main/scala/scala/build/bsp/package.scala index 25a3844a40..5f3fe3e632 100644 --- a/modules/build/src/main/scala/scala/build/bsp/package.scala +++ b/modules/build/src/main/scala/scala/build/bsp/package.scala @@ -9,6 +9,31 @@ import scala.jdk.CollectionConverters.* package object bsp { + extension (compileParams: b.CompileParams) { + def duplicate(): b.CompileParams = { + val params = new b.CompileParams(compileParams.getTargets) + params.setOriginId(compileParams.getOriginId) + params.setArguments(compileParams.getArguments) + params + } + + def withExtraArgs(extraArgs: List[String]): b.CompileParams = { + val params = compileParams.duplicate() + val previousArguments = Option(params.getArguments).toList.flatMap(_.asScala) + val newArguments = (previousArguments ++ extraArgs).asJava + params.setArguments(newArguments) + params + } + + def withVerbosity(verbose: Boolean): b.CompileParams = { + val verboseArg = "--verbose" + val argumentsContainVerboseArg = + Option(compileParams.getArguments).exists(_.contains(verboseArg)) + if verbose && !argumentsContainVerboseArg then compileParams.withExtraArgs(List(verboseArg)) + else compileParams + } + } + implicit class Ext[T](private val f: CompletableFuture[T]) extends AnyVal { def logF: CompletableFuture[T] = f.handle { (res, err) => 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 bf732018c5..2719fcf925 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/BspTestDefinitions.scala @@ -2215,4 +2215,64 @@ abstract class BspTestDefinitions extends ScalaCliSuite with TestScalaVersionArg expect(bspConfig.argv.indexOfSlice(javaProps) < bspConfig.argv.indexOf("bsp")) } } + + test("BSP loads verbosity on compile") { + val stderrFile = os.rel / "stderr.txt" + val inputs = TestInputs( + os.rel / "Hello.scala" -> + s"""object Hello extends App { + | println("Hello World") + |} + |""".stripMargin + ) + withBsp(inputs, Seq(".", "-v"), stdErrOpt = Some(stderrFile)) { + (root, _, remoteServer) => + async { + val buildTargetsResp = await(remoteServer.workspaceBuildTargets().asScala) + val targets = buildTargetsResp.getTargets.asScala.map(_.getId()) + val compileResp = await { + remoteServer + .buildTargetCompile(new b.CompileParams(targets.asJava)) + .asScala + } + expect(compileResp.getStatusCode == b.StatusCode.OK) + expect(os.read(root / stderrFile).contains("Scheduling compilation")) + } + } + } + + test("BSP loads verbosity on compile when passed from setup-ide") { + val stderrFile = os.rel / "stderr.txt" + val inputs = TestInputs( + os.rel / "Hello.scala" -> + s"""object Hello extends App { + | println("Hello World") + |} + |""".stripMargin + ) + inputs.fromRoot { root => + os.proc(TestUtil.cli, "setup-ide", ".", "-v").call(cwd = root) + val ideOptionsPath = root / Constants.workspaceDirName / "ide-options-v2.json" + val jsonOptions = List("--json-options", ideOptionsPath.toString) + withBsp( + inputs = inputs, + args = Seq("."), + bspOptions = jsonOptions, + stdErrOpt = Some(stderrFile) + ) { + (root, _, remoteServer) => + async { + val buildTargetsResp = await(remoteServer.workspaceBuildTargets().asScala) + val targets = buildTargetsResp.getTargets.asScala.map(_.getId()) + val compileResp = await { + remoteServer + .buildTargetCompile(new b.CompileParams(targets.asJava)) + .asScala + } + expect(compileResp.getStatusCode == b.StatusCode.OK) + expect(os.read(root / stderrFile).contains("Scheduling compilation")) + } + } + } + } }