From be2c8273828b9be28defd9476dcf7bd6ff6e27ff Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 27 Sep 2023 19:32:36 +0200 Subject: [PATCH 01/11] chore : Update scala native to 0.4.15 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index b95923428f..956cb60194 100644 --- a/build.sc +++ b/build.sc @@ -66,7 +66,7 @@ object Dependencies { def scalaJsEnvJsdomNode1 = ivy"org.scala-js::scalajs-env-jsdom-nodejs:1.1.0" def scalaJsSbtTestAdapter1 = ivy"org.scala-js::scalajs-sbt-test-adapter:$scalaJs1Version" def scalaJsLogging1 = ivy"org.scala-js::scalajs-logging:1.1.1" - def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.14" + def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.15" def scalazCore = ivy"org.scalaz::scalaz-core:7.3.7" def snailgun = ivy"io.github.alexarchambault.scala-cli.snailgun::snailgun-core:0.4.1-sc2" def sourcecode = ivy"com.lihaoyi::sourcecode:0.3.0" From 9bc3d0c3d3de80eac5d5b4b9f6a0c05ef8ee3979 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 27 Sep 2023 19:34:40 +0200 Subject: [PATCH 02/11] chore: Update Scala to 2.13.12 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index 956cb60194..23eeab1b2b 100644 --- a/build.sc +++ b/build.sc @@ -15,7 +15,7 @@ import java.io.File object Dependencies { def scala212 = "2.12.18" - def scala213 = "2.13.11" + def scala213 = "2.13.12" def scalaVersions = Seq(scala212, scala213) From 5569116193590f0d5e3c46e7144f2e630ac65d75 Mon Sep 17 00:00:00 2001 From: tgodzik Date: Wed, 13 Sep 2023 10:34:16 +0200 Subject: [PATCH 03/11] chore: Change frameworks not supported message to warn Previously, we would show an error whenever a native project was loaded, since we can't currently run tests for native. However, this will pop up currently in Metals as a server error, while it's more of a warning. There is nothing the user can do about it. Now, we report this as a warning. --- frontend/src/main/scala/bloop/engine/tasks/TestTask.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala b/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala index 9e36d2ebb7..4778dc640a 100644 --- a/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala +++ b/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala @@ -249,7 +249,7 @@ object TestTask { } case _: Platform.Native => - logger.error("Detecting test frameworks in Scala Native projects is not yet supported") + logger.warn("Detecting test frameworks in Scala Native projects is not yet supported") Task.now(None) } } From d81db4a6f84452cd5b2c9b25b603e11bbbae971a Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 27 Sep 2023 19:35:32 +0200 Subject: [PATCH 04/11] chore: Update sbt test-agent to 1.9.6 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index 23eeab1b2b..6fc3c4cd1d 100644 --- a/build.sc +++ b/build.sc @@ -57,7 +57,7 @@ object Dependencies { def nailgun = ivy"io.github.alexarchambault.bleep:nailgun-server:1.0.7" def osLib = ivy"com.lihaoyi::os-lib:0.9.0" def pprint = ivy"com.lihaoyi::pprint:0.8.1" - def sbtTestAgent = ivy"org.scala-sbt:test-agent:1.9.4" + def sbtTestAgent = ivy"org.scala-sbt:test-agent:1.9.6" def sbtTestInterface = ivy"org.scala-sbt:test-interface:1.0" def scalaDebugAdapter = ivy"ch.epfl.scala::scala-debug-adapter:3.1.4" def scalaJsLinker1 = ivy"org.scala-js::scalajs-linker:$scalaJs1Version" From f7be234ae2b49be947860cfecc447195b814127a Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 27 Sep 2023 19:35:55 +0200 Subject: [PATCH 05/11] chore: Update zinc to 1.9.5 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index 6fc3c4cd1d..756e0278dc 100644 --- a/build.sc +++ b/build.sc @@ -73,7 +73,7 @@ object Dependencies { def svm = ivy"org.graalvm.nativeimage:svm:$graalvmVersion" def utest = ivy"com.lihaoyi::utest:0.8.1" def xxHashLibrary = ivy"net.jpountz.lz4:lz4:1.3.0" - def zinc = ivy"org.scala-sbt::zinc:1.9.3" + def zinc = ivy"org.scala-sbt::zinc:1.9.5" def zipkinSender = ivy"io.zipkin.reporter2:zipkin-sender-urlconnection:2.16.4" def zt = ivy"org.zeroturnaround:zt-zip:1.16" From 76508677e486371ff8d748d1eb4277ccfb2347cd Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 27 Sep 2023 19:36:28 +0200 Subject: [PATCH 06/11] chore: Update librarymanagement-ivy to 1.9.3 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index 756e0278dc..b699e8f4ef 100644 --- a/build.sc +++ b/build.sc @@ -48,7 +48,7 @@ object Dependencies { ivy"com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros:$jsoniterVersion" def junit = ivy"com.github.sbt:junit-interface:0.13.3" def libdaemonjvm = ivy"io.github.alexarchambault.libdaemon::libdaemon:0.0.11" - def libraryManagement = ivy"org.scala-sbt::librarymanagement-ivy:1.9.2" + def libraryManagement = ivy"org.scala-sbt::librarymanagement-ivy:1.9.3" def log4j = ivy"org.apache.logging.log4j:log4j-core:2.20.0" def logback = ivy"ch.qos.logback:logback-classic:1.4.6" def macroParadise = ivy"org.scalamacros:::paradise:2.1.1" From 9f428ac8c9b82c281d4cda78f7df6ec7788ea00c Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 27 Sep 2023 19:37:57 +0200 Subject: [PATCH 07/11] chore: Update sourcecode to 0.3.1 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index b699e8f4ef..76688b9958 100644 --- a/build.sc +++ b/build.sc @@ -69,7 +69,7 @@ object Dependencies { def scalaNativeTools04 = ivy"org.scala-native::tools:0.4.15" def scalazCore = ivy"org.scalaz::scalaz-core:7.3.7" def snailgun = ivy"io.github.alexarchambault.scala-cli.snailgun::snailgun-core:0.4.1-sc2" - def sourcecode = ivy"com.lihaoyi::sourcecode:0.3.0" + def sourcecode = ivy"com.lihaoyi::sourcecode:0.3.1" def svm = ivy"org.graalvm.nativeimage:svm:$graalvmVersion" def utest = ivy"com.lihaoyi::utest:0.8.1" def xxHashLibrary = ivy"net.jpountz.lz4:lz4:1.3.0" From cba9c0be0253210feb5fcfbf267aa73306bb4e8e Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Wed, 27 Sep 2023 19:38:45 +0200 Subject: [PATCH 08/11] chore: Update scalajs to 1.14.0 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index 76688b9958..0d46c7486e 100644 --- a/build.sc +++ b/build.sc @@ -23,7 +23,7 @@ object Dependencies { def coursierVersion = "2.1.0-M6-53-gb4f448130" def graalvmVersion = "22.2.0" def jsoniterVersion = "2.13.3.2" - def scalaJs1Version = "1.13.2" + def scalaJs1Version = "1.14.0" def scalaJsEnvsVersion = "1.1.1" def asm = ivy"org.ow2.asm:asm:$asmVersion" From ab059a9045da5128f10ae1b45b81c5b57a447c2f Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Tue, 26 Sep 2023 17:10:58 +0200 Subject: [PATCH 09/11] improvement: Disable tracing by default Previously, tracing was enabled by default and user could get stack traces logged by the zipkin trace. Now, we require setting `bloop.tracing.enabled` property. Tracing is not used heavily currently, so this should not be an issue. Fixes https://github.com/scalacenter/bloop/issues/2108 --- .../scala/bloop/tracing/BraveTracer.scala | 110 +++++++++++++++--- .../scala/bloop/tracing/TraceProperties.scala | 7 +- .../main/scala/bloop/data/TraceSettings.scala | 9 +- .../test/scala/bloop/BuildLoaderSpec.scala | 3 +- .../src/test/scala/bloop/TracerSpec.scala | 6 +- 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/backend/src/main/scala/bloop/tracing/BraveTracer.scala b/backend/src/main/scala/bloop/tracing/BraveTracer.scala index dbb162cc44..a52f4288fd 100644 --- a/backend/src/main/scala/bloop/tracing/BraveTracer.scala +++ b/backend/src/main/scala/bloop/tracing/BraveTracer.scala @@ -14,14 +14,100 @@ import brave.propagation.TraceContextOrSamplingFlags import zipkin2.codec.SpanBytesEncoder.JSON_V1 import zipkin2.codec.SpanBytesEncoder.JSON_V2 -final class BraveTracer private ( +sealed trait BraveTracer { + def startNewChildTracer(name: String, tags: (String, String)*): BraveTracer + + def trace[T](name: String, tags: (String, String)*)( + thunk: BraveTracer => T + ): T + + def traceVerbose[T](name: String, tags: (String, String)*)( + thunk: BraveTracer => T + ): T + + def traceTask[T](name: String, tags: (String, String)*)( + thunk: BraveTracer => Task[T] + ): Task[T] + + def traceTaskVerbose[T](name: String, tags: (String, String)*)( + thunk: BraveTracer => Task[T] + ): Task[T] + + def terminate(): Unit + + def currentSpan: Option[Span] + + def toIndependentTracer( + name: String, + traceProperties: TraceProperties, + tags: (String, String)* + ): BraveTracer + +} + +object NoopTracer extends BraveTracer { + + override def startNewChildTracer(name: String, tags: (String, String)*): BraveTracer = this + + override def trace[T](name: String, tags: (String, String)*)(thunk: BraveTracer => T): T = thunk( + this + ) + + override def traceVerbose[T](name: String, tags: (String, String)*)(thunk: BraveTracer => T): T = + thunk(this) + + override def traceTask[T](name: String, tags: (String, String)*)( + thunk: BraveTracer => Task[T] + ): Task[T] = thunk(this) + + override def traceTaskVerbose[T](name: String, tags: (String, String)*)( + thunk: BraveTracer => Task[T] + ): Task[T] = thunk(this) + + override def terminate(): Unit = () + + override def currentSpan: Option[Span] = None + + def toIndependentTracer( + name: String, + traceProperties: TraceProperties, + tags: (String, String)* + ): BraveTracer = this + +} + +object BraveTracer { + + def apply(name: String, properties: TraceProperties, tags: (String, String)*): BraveTracer = { + BraveTracer(name, properties, None, tags: _*) + } + + def apply( + name: String, + properties: TraceProperties, + ctx: Option[TraceContext], + tags: (String, String)* + ): BraveTracer = { + if (properties.enabled) { + BraveTracerInternal(name, properties, ctx, tags: _*) + } else { + NoopTracer + } + + } +} + +final class BraveTracerInternal private ( tracer: Tracer, - val currentSpan: Span, + val _currentSpan: Span, closeCurrentSpan: () => Unit, properties: TraceProperties -) { +) extends BraveTracer { + + def currentSpan = Some(_currentSpan) + def startNewChildTracer(name: String, tags: (String, String)*): BraveTracer = { - val span = tags.foldLeft(tracer.newChild(currentSpan.context).name(name)) { + val span = tags.foldLeft(tracer.newChild(_currentSpan.context).name(name)) { case (span, (tagKey, tagValue)) => span.tag(tagKey, tagValue) } @@ -32,7 +118,7 @@ final class BraveTracer private ( span.finish() } - new BraveTracer(tracer, span, closeHandler, properties) + new BraveTracerInternal(tracer, span, closeHandler, properties) } def trace[T](name: String, tags: (String, String)*)( @@ -67,7 +153,7 @@ final class BraveTracer private ( try thunk(newTracer) // Don't catch and report errors in spans catch { case NonFatal(t) => - newTracer.currentSpan.error(t) + newTracer.currentSpan.foreach(_.error(t)) throw t } finally { try newTracer.terminate() @@ -91,7 +177,7 @@ final class BraveTracer private ( case None => Task.eval(newTracer.terminate()) case Some(value) => Task.eval { - newTracer.currentSpan.error(value) + newTracer.currentSpan.foreach(_.error(value)) newTracer.terminate() } } @@ -116,10 +202,10 @@ final class BraveTracer private ( traceProperties: TraceProperties, tags: (String, String)* ): BraveTracer = - BraveTracer(name, traceProperties, Some(currentSpan.context), tags: _*) + BraveTracer(name, traceProperties, Some(_currentSpan.context), tags: _*) } -object BraveTracer { +object BraveTracerInternal { import brave._ import zipkin2.reporter.AsyncReporter import zipkin2.reporter.urlconnection.URLConnectionSender @@ -134,10 +220,6 @@ object BraveTracer { reporterCache.computeIfAbsent(url, newReporter) } - def apply(name: String, properties: TraceProperties, tags: (String, String)*): BraveTracer = { - BraveTracer(name, properties, None, tags: _*) - } - def apply( name: String, properties: TraceProperties, @@ -178,6 +260,6 @@ object BraveTracer { spanReporter.flush() } - new BraveTracer(tracer, rootSpan, closeEverything, properties) + new BraveTracerInternal(tracer, rootSpan, closeEverything, properties) } } diff --git a/backend/src/main/scala/bloop/tracing/TraceProperties.scala b/backend/src/main/scala/bloop/tracing/TraceProperties.scala index 53a239afbb..07d5cf3aea 100644 --- a/backend/src/main/scala/bloop/tracing/TraceProperties.scala +++ b/backend/src/main/scala/bloop/tracing/TraceProperties.scala @@ -8,12 +8,14 @@ case class TraceProperties( verbose: Boolean, localServiceName: String, traceStartAnnotation: Option[String], - traceEndAnnotation: Option[String] + traceEndAnnotation: Option[String], + enabled: Boolean ) object TraceProperties { val default: TraceProperties = { val verbose = Properties.propOrFalse("bloop.tracing.verbose") + val enabled = Properties.propOrFalse("bloop.tracing.enabled") val debugTracing = Properties.propOrFalse("bloop.tracing.debugTracing") val localServiceName = Properties.propOrElse("bloop.tracing.localServiceName", "bloop") val traceStartAnnotation = Properties.propOrNone("bloop.tracing.traceStartAnnotation") @@ -30,7 +32,8 @@ object TraceProperties { verbose, localServiceName, traceStartAnnotation, - traceEndAnnotation + traceEndAnnotation, + enabled ) } } diff --git a/frontend/src/main/scala/bloop/data/TraceSettings.scala b/frontend/src/main/scala/bloop/data/TraceSettings.scala index dea713fac9..38a1ed3785 100644 --- a/frontend/src/main/scala/bloop/data/TraceSettings.scala +++ b/frontend/src/main/scala/bloop/data/TraceSettings.scala @@ -8,7 +8,8 @@ case class TraceSettings( verbose: Option[Boolean], localServiceName: Option[String], traceStartAnnotation: Option[String], - traceEndAnnotation: Option[String] + traceEndAnnotation: Option[String], + enabled: Option[Boolean] ) object TraceSettings { @@ -20,7 +21,8 @@ object TraceSettings { settings.verbose.getOrElse(default.verbose), settings.localServiceName.getOrElse(default.localServiceName), settings.traceStartAnnotation.orElse(default.traceStartAnnotation), - settings.traceEndAnnotation.orElse(default.traceEndAnnotation) + settings.traceEndAnnotation.orElse(default.traceEndAnnotation), + settings.enabled.getOrElse(default.enabled) ) } @@ -31,7 +33,8 @@ object TraceSettings { verbose = Some(properties.verbose), localServiceName = Some(properties.localServiceName), traceStartAnnotation = properties.traceStartAnnotation, - traceEndAnnotation = properties.traceEndAnnotation + traceEndAnnotation = properties.traceEndAnnotation, + enabled = Some(properties.enabled) ) } } diff --git a/frontend/src/test/scala/bloop/BuildLoaderSpec.scala b/frontend/src/test/scala/bloop/BuildLoaderSpec.scala index 2af40598e6..14528e906b 100644 --- a/frontend/src/test/scala/bloop/BuildLoaderSpec.scala +++ b/frontend/src/test/scala/bloop/BuildLoaderSpec.scala @@ -302,7 +302,8 @@ object BuildLoaderSpec extends BaseSuite { verbose = Some(false), localServiceName = Some("42"), traceStartAnnotation = Some("start"), - traceEndAnnotation = Some("end") + traceEndAnnotation = Some("end"), + enabled = Some(true) ) ) ) diff --git a/frontend/src/test/scala/bloop/TracerSpec.scala b/frontend/src/test/scala/bloop/TracerSpec.scala index 40f22f3516..41d7e9e855 100644 --- a/frontend/src/test/scala/bloop/TracerSpec.scala +++ b/frontend/src/test/scala/bloop/TracerSpec.scala @@ -6,9 +6,11 @@ import bloop.tracing.BraveTracer import bloop.tracing.TraceProperties object TracerSpec extends BaseSuite { + + private val defaultOn = TraceProperties.default.copy(enabled = true) test("forty clients can send zipkin traces concurrently") { def sendTrace(id: String): Unit = { - val tracer = BraveTracer(s"encode ${id}", TraceProperties.default) + val tracer = BraveTracer(s"encode ${id}", defaultOn) Thread.sleep(700) tracer.trace(s"previous child ${id}") { tracer => Thread.sleep(500) @@ -23,7 +25,7 @@ object TracerSpec extends BaseSuite { Thread.sleep(750) val tracer2 = tracer.toIndependentTracer( s"independent encode ${id}", - TraceProperties.default + defaultOn ) tracer.terminate() tracer2.trace(s"previous independent child ${id}") { _ => From f041a7a61aaf7c0d9ea12d2d267dbdc1fca08979 Mon Sep 17 00:00:00 2001 From: tgodzik Date: Mon, 25 Sep 2023 22:25:29 +0200 Subject: [PATCH 10/11] chore: Adjust to recent bsp changes --- .../src/main/scala/bloop/io/ParallelOps.scala | 4 +- backend/src/main/scala/bloop/task/Task.scala | 2 +- .../internal/inc/BloopComponentCompiler.scala | 3 +- .../internal/BloopAnalysisCallback.scala | 8 +- .../internal/ConcurrentAnalysisCallback.scala | 8 +- .../scala/bloop/bsp/BloopBspServices.scala | 85 +++++++++++-------- .../scala/bloop/bsp/BloopLanguageClient.scala | 32 +++++-- .../main/scala/bloop/bsp/ProjectUris.scala | 6 +- .../scala/bloop/bsp/ScalaTestSuites.scala | 42 --------- .../bloop/bsp/ScalaTestSuitesResult.scala | 34 -------- .../main/scala/bloop/dap/BloopDebuggee.scala | 16 ++-- .../main/scala/bloop/engine/Interpreter.scala | 3 +- .../bloop/engine/caches/SemanticDBCache.scala | 5 +- .../main/scala/bloop/engine/tasks/Tasks.scala | 4 +- .../scala/bloop/engine/tasks/TestTask.scala | 7 +- .../scala/bloop/logging/BspServerLogger.scala | 7 +- .../test/scala/bloop/bsp/BspBaseSuite.scala | 26 +++--- .../test/scala/bloop/bsp/BspClientTest.scala | 19 +++-- .../test/scala/bloop/bsp/BspCompileSpec.scala | 6 +- .../scala/bloop/bsp/BspConnectionSpec.scala | 2 +- .../scala/bloop/bsp/BspProtocolSpec.scala | 20 +++-- .../test/scala/bloop/bsp/TestConstants.scala | 2 +- .../scala/bloop/dap/DebugProtocolSpec.scala | 15 +++- .../scala/bloop/dap/DebugServerSpec.scala | 12 +-- 24 files changed, 176 insertions(+), 192 deletions(-) delete mode 100644 frontend/src/main/scala/bloop/bsp/ScalaTestSuites.scala delete mode 100644 frontend/src/main/scala/bloop/bsp/ScalaTestSuitesResult.scala diff --git a/backend/src/main/scala/bloop/io/ParallelOps.scala b/backend/src/main/scala/bloop/io/ParallelOps.scala index 44bd3acb70..4f2e79f87e 100644 --- a/backend/src/main/scala/bloop/io/ParallelOps.scala +++ b/backend/src/main/scala/bloop/io/ParallelOps.scala @@ -10,7 +10,9 @@ import java.nio.file.attribute.BasicFileAttributes import java.util.concurrent.ConcurrentHashMap import scala.concurrent.Promise +import scala.util.control.NonFatal +import bloop.logging.Logger import bloop.task.Task import monix.eval.{Task => MonixTask} @@ -22,8 +24,6 @@ import monix.execution.cancelables.CompositeCancelable import monix.reactive.Consumer import monix.reactive.MulticastStrategy import monix.reactive.Observable -import bloop.logging.Logger -import scala.util.control.NonFatal object ParallelOps { diff --git a/backend/src/main/scala/bloop/task/Task.scala b/backend/src/main/scala/bloop/task/Task.scala index 6cb1dbe1d4..e1d37b4d5f 100644 --- a/backend/src/main/scala/bloop/task/Task.scala +++ b/backend/src/main/scala/bloop/task/Task.scala @@ -54,7 +54,7 @@ sealed trait Task[+A] { self => } final def doOnCancel(f: => Task[Unit]): Task[A] = - applyCancel(() => f.runAsync(monix.execution.Scheduler.Implicits.global)) + applyCancel { () => f.runAsync(monix.execution.Scheduler.Implicits.global); () } final def doOnFinish(f: Option[Throwable] => Task[Unit]): Task[A] = self.materialize.flatMap { v => diff --git a/backend/src/main/scala/sbt/internal/inc/BloopComponentCompiler.scala b/backend/src/main/scala/sbt/internal/inc/BloopComponentCompiler.scala index 32d84a8405..afd4ef72ca 100644 --- a/backend/src/main/scala/sbt/internal/inc/BloopComponentCompiler.scala +++ b/backend/src/main/scala/sbt/internal/inc/BloopComponentCompiler.scala @@ -14,6 +14,8 @@ import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths +import scala.util.control.NonFatal + import _root_.bloop.io.AbsolutePath import _root_.bloop.logging.DebugFilter import _root_.bloop.logging.{Logger => BloopLogger} @@ -27,7 +29,6 @@ import xsbti.ComponentProvider import xsbti.Logger import xsbti.compile.ClasspathOptionsUtil import xsbti.compile.CompilerBridgeProvider -import scala.util.control.NonFatal object BloopComponentCompiler { import xsbti.compile.ScalaInstance diff --git a/backend/src/main/scala/sbt/internal/inc/bloop/internal/BloopAnalysisCallback.scala b/backend/src/main/scala/sbt/internal/inc/bloop/internal/BloopAnalysisCallback.scala index 3d13ee573f..a173e84a57 100644 --- a/backend/src/main/scala/sbt/internal/inc/bloop/internal/BloopAnalysisCallback.scala +++ b/backend/src/main/scala/sbt/internal/inc/bloop/internal/BloopAnalysisCallback.scala @@ -6,6 +6,8 @@ import java.nio.file.FileSystems import java.nio.file.Path import java.{util => ju} +import scala.collection.JavaConverters._ + import sbt.internal.inc.Analysis import sbt.internal.inc.Compilation import sbt.internal.inc.Incremental @@ -17,6 +19,9 @@ import sbt.util.InterfaceUtil import xsbt.api.APIUtil import xsbt.api.HashAPI import xsbt.api.NameHashing +import xsbti.Action +import xsbti.DiagnosticCode +import xsbti.DiagnosticRelatedInformation import xsbti.Position import xsbti.Problem import xsbti.Severity @@ -37,9 +42,6 @@ import xsbti.compile.ClassFileManager import xsbti.compile.IncOptions import xsbti.compile.Output import xsbti.compile.analysis.ReadStamps -import xsbti.{Action, DiagnosticCode, DiagnosticRelatedInformation} - -import collection.JavaConverters._ trait IBloopAnalysisCallback extends xsbti.AnalysisCallback2 { def get: Analysis diff --git a/backend/src/main/scala/sbt/internal/inc/bloop/internal/ConcurrentAnalysisCallback.scala b/backend/src/main/scala/sbt/internal/inc/bloop/internal/ConcurrentAnalysisCallback.scala index c7c108ce1c..af923d7528 100644 --- a/backend/src/main/scala/sbt/internal/inc/bloop/internal/ConcurrentAnalysisCallback.scala +++ b/backend/src/main/scala/sbt/internal/inc/bloop/internal/ConcurrentAnalysisCallback.scala @@ -4,6 +4,8 @@ import java.io.File import java.nio.file.Path import java.{util => ju} +import scala.collection.JavaConverters._ + import sbt.internal.inc.Analysis import sbt.internal.inc.Compilation import sbt.internal.inc.Incremental @@ -15,6 +17,9 @@ import sbt.util.InterfaceUtil import xsbt.api.APIUtil import xsbt.api.HashAPI import xsbt.api.NameHashing +import xsbti.Action +import xsbti.DiagnosticCode +import xsbti.DiagnosticRelatedInformation import xsbti.Position import xsbti.Problem import xsbti.Severity @@ -35,9 +40,6 @@ import xsbti.compile.ClassFileManager import xsbti.compile.IncOptions import xsbti.compile.Output import xsbti.compile.analysis.ReadStamps -import xsbti.{Action, DiagnosticCode, DiagnosticRelatedInformation} - -import collection.JavaConverters._ /** * This class provides a thread-safe implementation of `xsbti.AnalysisCallback` which is required to compile with the diff --git a/frontend/src/main/scala/bloop/bsp/BloopBspServices.scala b/frontend/src/main/scala/bloop/bsp/BloopBspServices.scala index 261c740845..634d8b0e9b 100644 --- a/frontend/src/main/scala/bloop/bsp/BloopBspServices.scala +++ b/frontend/src/main/scala/bloop/bsp/BloopBspServices.scala @@ -137,7 +137,7 @@ final class BloopBspServices( .requestAsync(endpoints.BuildTarget.run)(p => schedule(run(p))) .requestAsync(endpoints.BuildTarget.cleanCache)(p => schedule(clean(p))) .requestAsync(endpoints.BuildTarget.scalaMainClasses)(p => schedule(scalaMainClasses(p))) - .requestAsync(ScalaTestClasses.endpoint)(p => schedule(scalaTestClasses(p))) + .requestAsync(endpoints.BuildTarget.scalaTestClasses)(p => schedule(scalaTestClasses(p))) .requestAsync(endpoints.BuildTarget.dependencySources)(p => schedule(dependencySources(p))) .requestAsync(endpoints.DebugSession.start)(p => schedule(startDebugSession(p))) .requestAsync(endpoints.BuildTarget.jvmTestEnvironment)(p => schedule(jvmTestEnvironment(p))) @@ -316,6 +316,7 @@ final class BloopBspServices( jvmRunEnvironmentProvider = Some(true), canReload = Some(false) ), + None, None ) ) @@ -567,12 +568,12 @@ final class BloopBspServices( def scalaTestClasses( params: bsp.ScalaTestClassesParams - ): BspEndpointResponse[ScalaTestClassesResult] = + ): BspEndpointResponse[bsp.ScalaTestClassesResult] = ifInitialized(params.originId) { (state: State, logger: BspServerLogger) => mapToProjects(params.targets, state) match { case Left(error) => logger.error(error) - Task.now((state, Right(ScalaTestClassesResult(Nil)))) + Task.now((state, Right(bsp.ScalaTestClassesResult(Nil)))) case Right(projects) => val subTasks = projects.toList.filter(p => TestTask.isTestProject(p._2)).map { @@ -583,7 +584,7 @@ final class BloopBspServices( .groupBy(_.framework) .map { case (framework, classes) => - ScalaTestClassesItem(id, classes.flatMap(_.classes), Some(framework)) + bsp.ScalaTestClassesItem(id, Some(framework), classes.flatMap(_.classes)) } .toList } @@ -591,7 +592,7 @@ final class BloopBspServices( } Task.sequence(subTasks).map { items => - val result = ScalaTestClassesResult(items.flatten) + val result = bsp.ScalaTestClassesResult(items.flatten) (state, Right(result)) } } @@ -608,33 +609,43 @@ final class BloopBspServices( def convert[A: JsonValueCodec]( f: A => Either[String, Debuggee] ): Either[Response.Error, Debuggee] = { - Try(readFromArray[A](params.data.value)) match { - case Failure(error) => - Left(Response.invalidRequest(error.getMessage())) - case Success(params) => - f(params) match { - case Right(adapter) => Right(adapter) - case Left(error) => Left(Response.invalidRequest(error)) + params.data match { + case Some(data) => + Try(readFromArray[A](data.value)) match { + case Failure(error) => + Left(Response.invalidRequest(error.getMessage())) + case Success(params) => + f(params) match { + case Right(adapter) => Right(adapter) + case Left(error) => Left(Response.invalidRequest(error)) + } } + case None => + Left(Response.invalidRequest("No debug data available")) } + } params.dataKind match { - case bsp.DebugSessionParamsDataKind.ScalaMainClass => + case Some(bsp.DebugSessionParamsDataKind.ScalaMainClass) => convert[bsp.ScalaMainClass](main => BloopDebuggeeRunner.forMainClass(projects, main, state, ioScheduler) ) - case bsp.DebugSessionParamsDataKind.ScalaTestSuites => + case Some(bsp.TestParamsDataKind.ScalaTestSuites) => implicit val codec = JsonCodecMaker.make[List[String]] convert[List[String]](classNames => { - val testClasses = ScalaTestSuites(classNames) + val testClasses = bsp.ScalaTestSuites( + classNames.map(className => bsp.ScalaTestSuiteSelection(className, Nil)), + Nil, + Nil + ) BloopDebuggeeRunner.forTestSuite(projects, testClasses, state, ioScheduler) }) - case "scala-test-suites-selection" => - convert[ScalaTestSuites](testClasses => { + case Some(bsp.TestParamsDataKind.ScalaTestSuitesSelection) => + convert[bsp.ScalaTestSuites](testClasses => { BloopDebuggeeRunner.forTestSuite(projects, testClasses, state, ioScheduler) }) - case bsp.DebugSessionParamsDataKind.ScalaAttachRemote => + case Some(bsp.DebugSessionParamsDataKind.ScalaAttachRemote) => Right(BloopDebuggeeRunner.forAttachRemote(state, ioScheduler, projects)) case dataKind => Left(Response.invalidRequest(s"Unsupported data kind: $dataKind")) } @@ -684,7 +695,9 @@ final class BloopBspServices( .map(_ => backgroundDebugServers -= handler.uri) .runAsync(ioScheduler) backgroundDebugServers += handler.uri -> listenAndUnsubscribe - Task.now((state, Right(new bsp.DebugSessionAddress(handler.uri.toString)))) + Task.now( + (state, Right(new bsp.DebugSessionAddress(bsp.Uri(handler.uri.toString())))) + ) case Left(error) => Task.now((state, Left(error))) @@ -704,7 +717,7 @@ final class BloopBspServices( List(project), Nil, testFilter, - ScalaTestSuites.empty, + bsp.ScalaTestSuites(Nil, Nil, Nil), handler, mode = RunMode.Normal ) @@ -804,13 +817,13 @@ final class BloopBspServices( def findMainClasses(state: State, project: Project): List[bsp.ScalaMainClass] = for { className <- Tasks.findMainClasses(state, project) - } yield bsp.ScalaMainClass(className, Nil, Nil, Nil) + } yield bsp.ScalaMainClass(className, Nil, Nil, None) ifInitialized(params.originId) { (state: State, logger: BspServerLogger) => mapToProjects(params.targets, state) match { case Left(error) => logger.error(error) - Task.now((state, Right(bsp.ScalaMainClassesResult(Nil)))) + Task.now((state, Right(bsp.ScalaMainClassesResult(Nil, params.originId)))) case Right(projects) => val items = for { @@ -818,7 +831,7 @@ final class BloopBspServices( mainClasses = findMainClasses(state, project) } yield bsp.ScalaMainClassesItem(id, mainClasses) - val result = new bsp.ScalaMainClassesResult(items) + val result = new bsp.ScalaMainClassesResult(items, params.originId) Task.now((state, Right(result))) } } @@ -843,7 +856,7 @@ final class BloopBspServices( val cmd = Commands.Run(List(project.name)) Interpreter.getMainClass(state, project, cmd.main) match { case Right(name) => - Right(new bsp.ScalaMainClass(name, cmd.args, Nil, Nil)) + Right(new bsp.ScalaMainClass(name, cmd.args, Nil, None)) case Left(_) => Left(new IllegalStateException(s"Main class for project $project not found")) } @@ -871,16 +884,16 @@ final class BloopBspServices( project, config, cwd, - mainClass.`class`, + mainClass.className, mainArgs, skipJargs = false, - mainClass.environmentVariables, + mainClass.environmentVariables.getOrElse(Nil), RunMode.Normal ) case platform @ Platform.Native(config, _, _) => val cmd = Commands.Run(List(project.name)) val target = ScalaNativeToolchain.linkTargetFrom(project, config) - linkMainWithNative(cmd, project, state, mainClass.`class`, target, platform) + linkMainWithNative(cmd, project, state, mainClass.className, target, platform) .flatMap { state => val args = (target.syntax +: cmd.args).toArray if (!state.status.isOk) Task.now(state) @@ -889,7 +902,7 @@ final class BloopBspServices( case platform @ Platform.Js(config, _, _) => val cmd = Commands.Run(List(project.name)) val target = ScalaJsToolchain.linkTargetFrom(project, config) - linkMainWithJs(cmd, project, state, mainClass.`class`, target, platform) + linkMainWithJs(cmd, project, state, mainClass.className, target, platform) .flatMap { state => // We use node to run the program (is this a special case?) val args = ("node" +: target.syntax +: cmd.args).toArray @@ -1040,10 +1053,10 @@ final class BloopBspServices( } val capabilities = bsp.BuildTargetCapabilities( - canCompile = true, - canTest = true, - canRun = true, - canDebug = true + canCompile = Some(true), + canTest = Some(true), + canRun = Some(true), + canDebug = Some(true) ) val isJavaOnly = p.scalaInstance.isEmpty val languageIds = @@ -1256,8 +1269,8 @@ final class BloopBspServices( bsp.ScalacOptionsItem( target = target, options = project.scalacOptions.toList, - classpath = classpath, - classDirectory = classesDir + classpath = classpath.map(_.value), + classDirectory = classesDir.value ) }.toList ) @@ -1290,8 +1303,8 @@ final class BloopBspServices( bsp.JavacOptionsItem( target = target, options = project.javacOptions.toList, - classpath = classpath, - classDirectory = classesDir + classpath = classpath.map(_.value), + classDirectory = classesDir.value ) }.toList ) diff --git a/frontend/src/main/scala/bloop/bsp/BloopLanguageClient.scala b/frontend/src/main/scala/bloop/bsp/BloopLanguageClient.scala index 67f8e68a1b..f0f6f62393 100644 --- a/frontend/src/main/scala/bloop/bsp/BloopLanguageClient.scala +++ b/frontend/src/main/scala/bloop/bsp/BloopLanguageClient.scala @@ -39,11 +39,21 @@ class BloopLanguageClient( def notify[A]( endpoint: Endpoint[A, Unit], - params: A, - headers: Map[String, String] = Map.empty + params: A + ): Future[Ack] = notify(endpoint, Some(params), Map.empty) + + def notify[A]( + endpoint: Endpoint[A, Unit], + params: Option[A] + ): Future[Ack] = notify(endpoint, params, Map.empty) + + def notify[A]( + endpoint: Endpoint[A, Unit], + params: Option[A], + headers: Map[String, String] ): Future[Ack] = { import endpoint.codecA - val msg = Notification(endpoint.method, Some(toJson(params)), headers) + val msg = Notification(endpoint.method, params.map(toJson(_)), headers) // Send notifications in the order they are sent by the caller notificationsLock.synchronized { @@ -53,14 +63,24 @@ class BloopLanguageClient( def request[A, B]( endpoint: Endpoint[A, B], - params: A, - headers: Map[String, String] = Map.empty + params: A + ): Task[RpcResponse[B]] = request(endpoint, Some(params), Map.empty) + + def request[A, B]( + endpoint: Endpoint[A, B], + params: Option[A] + ): Task[RpcResponse[B]] = request(endpoint, params, Map.empty) + + def request[A, B]( + endpoint: Endpoint[A, B], + params: Option[A], + headers: Map[String, String] ): Task[RpcResponse[B]] = { import endpoint.{codecA, codecB} val reqId = RequestId(counter.incrementAndGet()) val response = Task.create[Response] { (s, cb) => val scheduled = s.scheduleOnce(Duration(0, "s")) { - val json = Request(endpoint.method, Some(toJson(params)), reqId, headers) + val json = Request(endpoint.method, params.map(toJson(_)), reqId, headers) activeServerRequests.put(reqId, cb) out.onNext(json) () diff --git a/frontend/src/main/scala/bloop/bsp/ProjectUris.scala b/frontend/src/main/scala/bloop/bsp/ProjectUris.scala index eb8e15a54a..ac4d99cf24 100644 --- a/frontend/src/main/scala/bloop/bsp/ProjectUris.scala +++ b/frontend/src/main/scala/bloop/bsp/ProjectUris.scala @@ -44,8 +44,8 @@ object ProjectUris { ) } - def toPath(uri: Uri): Path = { - val existingUri = new URI(uri.value) + def toPath(uri: String) = { + val existingUri = new URI(uri) val uriWithNoQuery = new URI( existingUri.getScheme, existingUri.getUserInfo, @@ -58,4 +58,6 @@ object ProjectUris { java.nio.file.Paths.get(uriWithNoQuery) } + def toPath(uri: Uri): Path = toPath(uri.value) + } diff --git a/frontend/src/main/scala/bloop/bsp/ScalaTestSuites.scala b/frontend/src/main/scala/bloop/bsp/ScalaTestSuites.scala deleted file mode 100644 index 7ebe8c3e31..0000000000 --- a/frontend/src/main/scala/bloop/bsp/ScalaTestSuites.scala +++ /dev/null @@ -1,42 +0,0 @@ -package bloop.bsp - -import com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec -import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker - -/** - * Below datatypes are based on https://github.com/build-server-protocol/build-server-protocol/issues/249#issuecomment-983435766 - */ -case class ScalaTestSuites( - suites: List[ScalaTestSuiteSelection], - jvmOptions: List[String], - environmentVariables: List[String] -) { - def classNames: List[String] = suites.map(_.className) -} - -object ScalaTestSuites { - implicit val jsonCodec: JsonValueCodec[ScalaTestSuites] = - JsonCodecMaker.makeWithRequiredCollectionFields - val empty: ScalaTestSuites = ScalaTestSuites(Nil, Nil, Nil) - - def apply(classes: List[String]): ScalaTestSuites = ScalaTestSuites( - classes.map(className => ScalaTestSuiteSelection(className, Nil)), - Nil, - Nil - ) - - def forSuiteSelection(classes: List[ScalaTestSuiteSelection]): ScalaTestSuites = ScalaTestSuites( - classes, - Nil, - Nil - ) -} - -case class ScalaTestSuiteSelection( - className: String, - tests: List[String] -) -object ScalaTestSuiteSelection { - implicit val jsonCodec: JsonValueCodec[ScalaTestSuiteSelection] = - JsonCodecMaker.makeWithRequiredCollectionFields -} diff --git a/frontend/src/main/scala/bloop/bsp/ScalaTestSuitesResult.scala b/frontend/src/main/scala/bloop/bsp/ScalaTestSuitesResult.scala deleted file mode 100644 index 226bf7325e..0000000000 --- a/frontend/src/main/scala/bloop/bsp/ScalaTestSuitesResult.scala +++ /dev/null @@ -1,34 +0,0 @@ -package bloop.bsp - -import ch.epfl.scala.bsp.BuildTargetIdentifier -import ch.epfl.scala.bsp.ScalaTestClassesParams - -import com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec -import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker -import jsonrpc4s.Endpoint - -object ScalaTestClasses { - val endpoint = - new Endpoint[ScalaTestClassesParams, ScalaTestClassesResult]("buildTarget/scalaTestClasses") -} - -final case class ScalaTestClassesResult( - items: List[ScalaTestClassesItem] -) - -object ScalaTestClassesResult { - implicit val jsonCodec: JsonValueCodec[ScalaTestClassesResult] = - JsonCodecMaker.makeWithRequiredCollectionFields -} - -final case class ScalaTestClassesItem( - target: BuildTargetIdentifier, - // Fully qualified names of test classes - classes: List[String], - // Name of the sbt's test framework - framework: Option[String] -) -object ScalaTestClassesItem { - implicit val jsonCodec: JsonValueCodec[ScalaTestClassesItem] = - JsonCodecMaker.makeWithRequiredCollectionFields -} diff --git a/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala b/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala index eef064e7e2..b7614c72de 100644 --- a/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala +++ b/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala @@ -2,10 +2,10 @@ package bloop.dap import scala.collection.mutable +import ch.epfl.scala.bsp import ch.epfl.scala.bsp.ScalaMainClass import ch.epfl.scala.debugadapter._ -import bloop.bsp.ScalaTestSuites import bloop.cli.ExitStatus import bloop.data.ClientInfo import bloop.data.JdkConfig @@ -55,7 +55,7 @@ private final class MainClassDebugAdapter( scalaVersion: Option[String] ) extends BloopDebuggee(initialState, ioScheduler, scalaVersion) { val javaRuntime: Option[JavaRuntime] = JavaRuntime(env.javaHome.underlying) - def name: String = s"${getClass.getSimpleName}(${project.name}, ${mainClass.`class`})" + def name: String = s"${getClass.getSimpleName}(${project.name}, ${mainClass.className})" def start(state: State, listener: DebuggeeListener): Task[ExitStatus] = { // TODO: https://github.com/scalacenter/bloop/issues/1456 // Metals used to add the `-J` prefix but it is not needed anymore @@ -66,10 +66,10 @@ private final class MainClassDebugAdapter( project, env, project.workspaceDirectory.getOrElse(project.baseDirectory), - mainClass.`class`, + mainClass.className, mainClass.arguments.toArray, jvmOptions.toArray, - mainClass.environmentVariables, + mainClass.environmentVariables.getOrElse(Nil), RunMode.Debug ) runState.map(_.status) @@ -78,7 +78,7 @@ private final class MainClassDebugAdapter( private final class TestSuiteDebugAdapter( projects: Seq[Project], - testClasses: ScalaTestSuites, + testClasses: bsp.ScalaTestSuites, val modules: Seq[Module], val libraries: Seq[Library], val unmanagedEntries: Seq[UnmanagedEntry], @@ -170,13 +170,15 @@ object BloopDebuggeeRunner { def forTestSuite( projects: Seq[Project], - testClasses: ScalaTestSuites, + testClasses: bsp.ScalaTestSuites, state: State, ioScheduler: Scheduler ): Either[String, Debuggee] = { projects match { case Seq() => - Left(s"No projects specified for the test suites: [${testClasses.classNames.sorted}]") + Left( + s"No projects specified for the test suites: [${testClasses.suites.map(_.className).sorted}]" + ) case Seq(project) if project.platform.isInstanceOf[Platform.Jvm] => val dag = state.build.getDagFor(project) val modules = getModules(dag, state.client) diff --git a/frontend/src/main/scala/bloop/engine/Interpreter.scala b/frontend/src/main/scala/bloop/engine/Interpreter.scala index 675c51adfc..d48ea75239 100644 --- a/frontend/src/main/scala/bloop/engine/Interpreter.scala +++ b/frontend/src/main/scala/bloop/engine/Interpreter.scala @@ -9,7 +9,6 @@ import scala.concurrent.Promise import bloop.ScalaInstance import bloop.bsp.BspServer -import bloop.bsp.ScalaTestSuites import bloop.cli.Commands.CompilingCommand import bloop.cli.Validate import bloop.cli._ @@ -371,7 +370,7 @@ object Interpreter { projectsToTest, cmd.args, testFilter, - ScalaTestSuites.empty, + ch.epfl.scala.bsp.ScalaTestSuites(Nil, Nil, Nil), handler, cmd.parallel, RunMode.Normal diff --git a/frontend/src/main/scala/bloop/engine/caches/SemanticDBCache.scala b/frontend/src/main/scala/bloop/engine/caches/SemanticDBCache.scala index e711a8de70..09e8b4187a 100644 --- a/frontend/src/main/scala/bloop/engine/caches/SemanticDBCache.scala +++ b/frontend/src/main/scala/bloop/engine/caches/SemanticDBCache.scala @@ -1,9 +1,11 @@ package bloop.engine.caches import java.nio.file.Path +import java.util.concurrent.ConcurrentHashMap import scala.collection.JavaConverters._ import scala.concurrent.Await +import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration import scala.util.Failure import scala.util.Success @@ -15,13 +17,10 @@ import bloop.engine.ExecutionContext import bloop.io.AbsolutePath import bloop.io.Paths import bloop.logging.Logger -import bloop.task.Task import sbt.internal.inc.BloopComponentCompiler import sbt.internal.inc.BloopComponentManager import sbt.internal.inc.IfMissing -import java.util.concurrent.ConcurrentHashMap -import scala.concurrent.Future object SemanticDBCache { // to avoid resolving the same fallback semanticdb version multiple times diff --git a/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala b/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala index ef6dec13ad..b1df2daf6a 100644 --- a/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala +++ b/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala @@ -3,9 +3,9 @@ package bloop.engine.tasks import java.nio.file.Files import java.nio.file.Path +import ch.epfl.scala.bsp import ch.epfl.scala.debugadapter.testing.TestSuiteEvent -import bloop.bsp.ScalaTestSuites import bloop.cli.ExitStatus import bloop.data.JdkConfig import bloop.data.Project @@ -124,7 +124,7 @@ object Tasks { projectsToTest: List[Project], userTestOptions: List[String], testFilter: String => Boolean, - testClasses: ScalaTestSuites, + testClasses: bsp.ScalaTestSuites, testEventHandler: BloopTestSuiteEventHandler, runInParallel: Boolean = false, mode: RunMode diff --git a/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala b/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala index 4778dc640a..10b2da3c55 100644 --- a/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala +++ b/frontend/src/main/scala/bloop/engine/tasks/TestTask.scala @@ -4,7 +4,8 @@ import scala.util.Failure import scala.util.Success import scala.util.control.NonFatal -import bloop.bsp.ScalaTestSuites +import ch.epfl.scala.bsp + import bloop.cli.ExitStatus import bloop.config.Config import bloop.config.Tag @@ -74,7 +75,7 @@ object TestTask { cwd: AbsolutePath, rawTestOptions: List[String], testFilter: String => Boolean, - testClasses: ScalaTestSuites, + testClasses: bsp.ScalaTestSuites, handler: LoggingEventHandler, mode: RunMode ): Task[Int] = { @@ -292,7 +293,7 @@ object TestTask { frameworks: List[Framework], analysis: CompileAnalysis, testFilter: String => Boolean, - testClasses: ScalaTestSuites + testClasses: bsp.ScalaTestSuites ): Map[Framework, List[TaskDef]] = { import state.logger val tests = discoverTests(analysis, frameworks) diff --git a/frontend/src/main/scala/bloop/logging/BspServerLogger.scala b/frontend/src/main/scala/bloop/logging/BspServerLogger.scala index 9044d9a26c..68ee95528a 100644 --- a/frontend/src/main/scala/bloop/logging/BspServerLogger.scala +++ b/frontend/src/main/scala/bloop/logging/BspServerLogger.scala @@ -179,7 +179,7 @@ final class BspServerLogger private ( bsp.ScalaTextEdit(range, edit.newText()) } } - val workspaceEdit = bsp.ScalaWorkspaceEdit(Option(edits.toList)) + val workspaceEdit = bsp.ScalaWorkspaceEdit(edits.toList) bsp.ScalaAction(action.title(), description, Some(workspaceEdit)) } bsp.ScalaDiagnostic(Some(bspActions.toList)) @@ -310,10 +310,11 @@ final class BspServerLogger private ( event.taskId, Some(now), Some(event.msg), - Some(bsp.TaskDataKind.CompileTask), + Some(bsp.TaskStartDataKind.CompileTask), Some(RawJson(encoded)) ) ) + bsp.TaskFinishDataKind () } @@ -368,7 +369,7 @@ final class BspServerLogger private ( Some(now), Some(s"Compiled '${event.projectName}'"), event.code, - Some(bsp.TaskDataKind.CompileReport), + Some(bsp.TaskFinishDataKind.CompileReport), Some(RawJson(encoded)) ) ) diff --git a/frontend/src/test/scala/bloop/bsp/BspBaseSuite.scala b/frontend/src/test/scala/bloop/bsp/BspBaseSuite.scala index 9c3608f568..6cc6ce0f57 100644 --- a/frontend/src/test/scala/bloop/bsp/BspBaseSuite.scala +++ b/frontend/src/test/scala/bloop/bsp/BspBaseSuite.scala @@ -98,8 +98,13 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { def rpcRequest[A, B]( endpoint: Endpoint[A, B], params: A + ): Task[B] = rpcRequest(endpoint, Some(params)) + + def rpcRequest[A, B]( + endpoint: Endpoint[A, B], + params: Option[A] ): Task[B] = { - client0.request(endpoint, params).map { + client0.request(endpoint, params, Map.empty).map { case RpcFailure(_, e) => fail(s"The request ${endpoint.method} failed with $e") case RpcSuccess(a, _) => a } @@ -107,7 +112,7 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { def findBuildTarget(project: TestProject): bsp.BuildTarget = { val workspaceTargetTask = { - rpcRequest(Workspace.buildTargets, bsp.WorkspaceBuildTargetsRequest()).map { ts => + rpcRequest(Workspace.buildTargets, None).map { ts => ts.targets.map(t => t.id -> t).find(_._1 == project.bspId) match { case Some((_, target)) => target case None => fail(s"Target ${project.bspId} is missing in the workspace! Found ${ts}") @@ -120,7 +125,7 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { def workspaceTargets: bsp.WorkspaceBuildTargetsResult = { val workspaceTargetsTask = - rpcRequest(Workspace.buildTargets, bsp.WorkspaceBuildTargetsRequest()) + rpcRequest(Workspace.buildTargets, None) TestUtil.await(FiniteDuration(5, "s"))(workspaceTargetsTask) } @@ -128,7 +133,7 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { def runAfterTargets[T]( project: TestProject )(f: bsp.BuildTargetIdentifier => Task[T]): Task[T] = { - rpcRequest(Workspace.buildTargets, bsp.WorkspaceBuildTargetsRequest()).flatMap { ts => + rpcRequest(Workspace.buildTargets, None).flatMap { ts => ts.targets.map(_.id).find(_ == project.bspId) match { case Some(target) => f(target) case None => fail(s"Target ${project.bspId} is missing in the workspace! Found ${ts}") @@ -398,10 +403,10 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { TestUtil.await(FiniteDuration(5, "s"))(task) } - def testClasses(project: TestProject): ScalaTestClassesResult = { + def testClasses(project: TestProject): bsp.ScalaTestClassesResult = { val task = runAfterTargets(project) { target => val params = bsp.ScalaTestClassesParams(List(target), None) - rpcRequest(ScalaTestClasses.endpoint, params) + rpcRequest(endpoints.BuildTarget.scalaTestClasses, params) } TestUtil.await(FiniteDuration(5, "s"))(task) @@ -419,7 +424,7 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { val session = for { address <- sessionAddress - uri = URI.create(address.uri) + uri = URI.create(address.uri.value) client = DebugTestClient(uri)(defaultScheduler) result <- f(client) } yield result @@ -795,6 +800,7 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { BuildInfo.bspVersion, rootUri = bsp.Uri(cwd.toAbsolutePath.toUri), capabilities = bsp.BuildClientCapabilities(List("scala", "java")), + None, additionalData ) ) @@ -804,14 +810,14 @@ abstract class BspBaseSuite extends BaseSuite with BspClientTest { (startedServer *> initializeServer) .flatMap { _ => Task.fromFuture( - lsClient.notify(endpoints.Build.initialized, bsp.InitializedBuildParams()) + lsClient.notify(endpoints.Build.initialized, None) ) } } val closeTask = { - lsClient.request(endpoints.Build.shutdown, bsp.Shutdown()).flatMap { _ => - Task.fromFuture(lsClient.notify(endpoints.Build.exit, bsp.Exit())).map { _ => + lsClient.request(endpoints.Build.shutdown, None).flatMap { _ => + Task.fromFuture(lsClient.notify(endpoints.Build.exit, None)).map { _ => try { socket.close() } catch { diff --git a/frontend/src/test/scala/bloop/bsp/BspClientTest.scala b/frontend/src/test/scala/bloop/bsp/BspClientTest.scala index 59569ccd99..33abb7226a 100644 --- a/frontend/src/test/scala/bloop/bsp/BspClientTest.scala +++ b/frontend/src/test/scala/bloop/bsp/BspClientTest.scala @@ -161,22 +161,23 @@ trait BspClientTest { lsClient.request( endpoints.Build.initialize, bsp.InitializeBuildParams( - "test-bloop-client", - "1.0.0", - BuildInfo.bspVersion, + displayName = "test-bloop-client", + version = "1.0.0", + bspVersion = BuildInfo.bspVersion, rootUri = bsp.Uri(cwd.toAbsolutePath.toUri), capabilities = bsp.BuildClientCapabilities(List("scala")), - None + dataKind = None, + data = None ) ) for { // Delay the task to let the bloop server go live initializeResult <- initializeServer.delayExecution(FiniteDuration(1, "s")) - _ = lsClient.notify(endpoints.Build.initialized, bsp.InitializedBuildParams()) + _ = lsClient.notify(endpoints.Build.initialized, params = None) otherCalls <- runEndpoints(lsClient) - _ <- lsClient.request(endpoints.Build.shutdown, bsp.Shutdown()) - _ = lsClient.notify(endpoints.Build.exit, bsp.Exit()) + _ <- lsClient.request(endpoints.Build.shutdown, params = None) + _ = lsClient.notify(endpoints.Build.exit, params = None) } yield { socket.close() otherCalls match { @@ -263,7 +264,7 @@ trait BspClientTest { ): BloopRpcServices => BloopRpcServices = { (s: BloopRpcServices) => s.notification(endpoints.Build.taskStart) { taskStart => taskStart.dataKind match { - case Some(bsp.TaskDataKind.CompileTask) => + case Some(bsp.TaskStartDataKind.CompileTask) => val json = taskStart.data.get Try(readFromArray[bsp.CompileTask](json.value)) match { case Failure(_) => () @@ -288,7 +289,7 @@ trait BspClientTest { () }.notification(endpoints.Build.taskFinish) { taskFinish => taskFinish.dataKind match { - case Some(bsp.TaskDataKind.CompileReport) => + case Some(bsp.TaskFinishDataKind.CompileReport) => val json = taskFinish.data.get Try(readFromArray[bsp.CompileReport](json.value)) match { case Failure(_) => () diff --git a/frontend/src/test/scala/bloop/bsp/BspCompileSpec.scala b/frontend/src/test/scala/bloop/bsp/BspCompileSpec.scala index 2dedf26346..4766a785f2 100644 --- a/frontend/src/test/scala/bloop/bsp/BspCompileSpec.scala +++ b/frontend/src/test/scala/bloop/bsp/BspCompileSpec.scala @@ -42,10 +42,10 @@ class BspCompileSpec( assertNoDiff( allButInitializeRequest.mkString(lineSeparator), s"""| --> content: ${TestConstants.buildInitialize} - | --> content: {"method":"build/initialized","params":{},"jsonrpc":"2.0"} - | --> content: {"method":"build/shutdown","params":{},"id":3,"jsonrpc":"2.0"} + | --> content: {"method":"build/initialized","jsonrpc":"2.0"} + | --> content: {"method":"build/shutdown","id":3,"jsonrpc":"2.0"} | --> content: {"result":{},"id":3,"jsonrpc":"2.0"} - | --> content: {"method":"build/exit","params":{},"jsonrpc":"2.0"}""".stripMargin + | --> content: {"method":"build/exit","jsonrpc":"2.0"}""".stripMargin ) } diff --git a/frontend/src/test/scala/bloop/bsp/BspConnectionSpec.scala b/frontend/src/test/scala/bloop/bsp/BspConnectionSpec.scala index fe975f679e..9aaef58b7d 100644 --- a/frontend/src/test/scala/bloop/bsp/BspConnectionSpec.scala +++ b/frontend/src/test/scala/bloop/bsp/BspConnectionSpec.scala @@ -105,7 +105,7 @@ class BspConnectionSpec( allButInitializeRequest.mkString(lineSeparator), s"""| | --> content: ${TestConstants.buildInitialize} - | --> content: {"method":"build/initialized","params":{},"jsonrpc":"2.0"}""".stripMargin + | --> content: {"method":"build/initialized","jsonrpc":"2.0"}""".stripMargin ) } diff --git a/frontend/src/test/scala/bloop/bsp/BspProtocolSpec.scala b/frontend/src/test/scala/bloop/bsp/BspProtocolSpec.scala index 3331bc85be..be51b1de20 100644 --- a/frontend/src/test/scala/bloop/bsp/BspProtocolSpec.scala +++ b/frontend/src/test/scala/bloop/bsp/BspProtocolSpec.scala @@ -86,9 +86,9 @@ class BspProtocolSpec( assert(result.items.size == 1) val optionsItem = result.items.head assert(optionsItem.options == expectedOptions) - assert(optionsItem.classDirectory.toPath == expectedClassesDir) + assert(ProjectUris.toPath(optionsItem.classDirectory) == expectedClassesDir) assert(optionsItem.target == expectedId) - val pathClasspath = optionsItem.classpath.map(_.toPath) + val pathClasspath = optionsItem.classpath.map(ProjectUris.toPath) expectedProjectEntries.foreach { expectedProjectEntry => // Ensure there is only one match per every entry val matches = pathClasspath.filter(_ == expectedProjectEntry) @@ -224,26 +224,30 @@ class BspProtocolSpec( loadBspState(workspace, projects, logger, bloopExtraParams = extraBloopParams) { bspState => val (_, options) = bspState.scalaOptions(`A`) firstScalacOptions = options.items - firstScalacOptions.foreach(d => assertIsDirectory(AbsolutePath(d.classDirectory.toPath))) + firstScalacOptions.foreach(d => + assertIsDirectory(AbsolutePath(ProjectUris.toPath(d.classDirectory))) + ) } // Start second client and query for scalac options which should use same dirs as before loadBspState(workspace, projects, logger, bloopExtraParams = extraBloopParams) { bspState => val (_, options) = bspState.scalaOptions(`A`) secondScalacOptions = options.items - secondScalacOptions.foreach(d => assertIsDirectory(AbsolutePath(d.classDirectory.toPath))) + secondScalacOptions.foreach(d => + assertIsDirectory(AbsolutePath(ProjectUris.toPath(d.classDirectory))) + ) } firstScalacOptions.zip(secondScalacOptions).foreach { case (firstItem, secondItem) => assertNoDiff( - firstItem.classDirectory.value, - secondItem.classDirectory.value + firstItem.classDirectory, + secondItem.classDirectory ) } firstScalacOptions.foreach { option => - assertIsDirectory(AbsolutePath(option.classDirectory.toPath)) + assertIsDirectory(AbsolutePath(ProjectUris.toPath(option.classDirectory))) } } } @@ -288,7 +292,7 @@ class BspProtocolSpec( val items = mainClasses.items assert(items.size == 1) - val classes = items.head.classes.map(_.`class`).toSet + val classes = items.head.classes.map(_.className).toSet assert(classes == expectedClasses) } } diff --git a/frontend/src/test/scala/bloop/bsp/TestConstants.scala b/frontend/src/test/scala/bloop/bsp/TestConstants.scala index 22137c0173..db3b4359b2 100644 --- a/frontend/src/test/scala/bloop/bsp/TestConstants.scala +++ b/frontend/src/test/scala/bloop/bsp/TestConstants.scala @@ -18,8 +18,8 @@ object TestConstants { "dependencySourcesProvider": true, "resourcesProvider": true, "buildTargetChangedProvider": false, - "jvmTestEnvironmentProvider": true, "jvmRunEnvironmentProvider": true, + "jvmTestEnvironmentProvider": true, "canReload": false } }, diff --git a/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala b/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala index c76d5c4062..ddd5d9d8cb 100644 --- a/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala +++ b/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala @@ -4,7 +4,6 @@ import java.nio.charset.StandardCharsets import java.nio.file.Files import ch.epfl.scala.bsp -import ch.epfl.scala.bsp.DebugSessionParamsDataKind._ import bloop.logging.RecordingLogger import bloop.util.TestProject @@ -186,9 +185,13 @@ object DebugProtocolSpec extends DebugBspBaseSuite { def mainClassParams(mainClass: String): bsp.BuildTargetIdentifier => bsp.DebugSessionParams = { target => val targets = List(target) - val data = bsp.ScalaMainClass(mainClass, Nil, Nil, Nil) + val data = bsp.ScalaMainClass(mainClass, Nil, Nil, None) val json = writeToArray[bsp.ScalaMainClass](data) - bsp.DebugSessionParams(targets, ScalaMainClass, RawJson(json)) + bsp.DebugSessionParams( + targets, + Some(bsp.DebugSessionParamsDataKind.ScalaMainClass), + Some(RawJson(json)) + ) } def testSuiteParams( @@ -197,6 +200,10 @@ object DebugProtocolSpec extends DebugBspBaseSuite { val targets = List(target) implicit val codec = JsonCodecMaker.make[List[String]] val json = writeToArray[List[String]](filters) - bsp.DebugSessionParams(targets, ScalaTestSuites, RawJson(json)) + bsp.DebugSessionParams( + targets, + Some(bsp.TestParamsDataKind.ScalaTestSuites), + Some(RawJson(json)) + ) } } diff --git a/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala b/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala index 97475e1dc3..e27b1527e6 100644 --- a/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala +++ b/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala @@ -18,8 +18,7 @@ import ch.epfl.scala.bsp.ScalaMainClass import ch.epfl.scala.debugadapter._ import bloop.ScalaInstance -import bloop.bsp.ScalaTestSuiteSelection -import bloop.bsp.ScalaTestSuites +import ch.epfl.scala.bsp import bloop.cli.ExitStatus import bloop.data.Platform import bloop.data.Project @@ -856,9 +855,9 @@ object DebugServerSpec extends DebugBspBaseSuite { loadBspStateWithTask(workspace, List(project), logger) { state => val testClasses = - ScalaTestSuites( + bsp.ScalaTestSuites( List( - ScalaTestSuiteSelection( + bsp.ScalaTestSuiteSelection( "MySuite", List("test1") ) @@ -984,7 +983,8 @@ object DebugServerSpec extends DebugBspBaseSuite { private def testRunner( project: TestProject, state: ManagedBspTestState, - testClasses: ScalaTestSuites = ScalaTestSuites(List("MySuite")) + testClasses: bsp.ScalaTestSuites = + bsp.ScalaTestSuites(List(bsp.ScalaTestSuiteSelection("MySuite", Nil)), Nil, Nil) ): Debuggee = { val testState = state.compile(project).toTestState BloopDebuggeeRunner.forTestSuite( @@ -1008,7 +1008,7 @@ object DebugServerSpec extends DebugBspBaseSuite { val testState = state.compile(project).toTestState BloopDebuggeeRunner.forMainClass( Seq(testState.getProjectFor(project)), - new ScalaMainClass("Main", arguments, jvmOptions, environmentVariables), + new ScalaMainClass("Main", arguments, jvmOptions, Some(environmentVariables)), testState.state, defaultScheduler ) match { From 2b48ccfa216f886168b7888ffb25ab7b3ab083dd Mon Sep 17 00:00:00 2001 From: tgodzik Date: Thu, 28 Sep 2023 11:26:25 +0200 Subject: [PATCH 11/11] chore: Update bsp4s to 2.1.0-M6 --- .../src/bloop/rifle/BloopRifleLogger.scala | 16 ++++++++-------- build.sc | 2 +- cli/src/bloop/cli/Bloop.scala | 7 ++++--- cli/src/bloop/cli/options/LoggingOptions.scala | 9 +++++---- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/bloop-rifle/src/bloop/rifle/BloopRifleLogger.scala b/bloop-rifle/src/bloop/rifle/BloopRifleLogger.scala index fdbc20a3d4..6c45a7b4cf 100644 --- a/bloop-rifle/src/bloop/rifle/BloopRifleLogger.scala +++ b/bloop-rifle/src/bloop/rifle/BloopRifleLogger.scala @@ -37,13 +37,13 @@ trait BloopRifleLogger { self => object BloopRifleLogger { def nop: BloopRifleLogger = new BloopRifleLogger { - def info(msg: => String) = {} - def debug(msg: => String, ex: Throwable) = {} - def error(msg: => String, ex: Throwable) = {} - def error(msg: => String) = {} - def bloopBspStdout = None - def bloopBspStderr = None - def bloopCliInheritStdout = false - def bloopCliInheritStderr = false + def info(msg: => String) = {} + def debug(msg: => String, ex: Throwable) = {} + def error(msg: => String, ex: Throwable) = {} + def error(msg: => String) = {} + def bloopBspStdout: Option[java.io.OutputStream] = None + def bloopBspStderr: Option[java.io.OutputStream] = None + def bloopCliInheritStdout = false + def bloopCliInheritStderr = false } } diff --git a/build.sc b/build.sc index 0d46c7486e..62e2913397 100644 --- a/build.sc +++ b/build.sc @@ -31,7 +31,7 @@ object Dependencies { def bloopConfig = ivy"ch.epfl.scala::bloop-config:1.5.5" def brave = ivy"io.zipkin.brave:brave:5.16.0" def bsp4j = ivy"ch.epfl.scala:bsp4j:2.1.0-M6" - def bsp4s = ivy"ch.epfl.scala::bsp4s:2.1.0-M5" + def bsp4s = ivy"ch.epfl.scala::bsp4s:2.1.0-M6" def caseApp = ivy"com.github.alexarchambault::case-app:2.0.6" def caseApp21 = ivy"com.github.alexarchambault::case-app:2.1.0-M15" def collectionCompat = ivy"org.scala-lang.modules::scala-collection-compat:2.9.0" diff --git a/cli/src/bloop/cli/Bloop.scala b/cli/src/bloop/cli/Bloop.scala index c4e2640418..6e191e0e2c 100644 --- a/cli/src/bloop/cli/Bloop.scala +++ b/cli/src/bloop/cli/Bloop.scala @@ -1,14 +1,15 @@ package bloop.cli import caseapp.core.app.CommandsEntryPoint +import caseapp.core.app.Command object Bloop extends CommandsEntryPoint { - def progName = "bloop" - def commands = Seq( + def progName: String = "bloop" + def commands: Seq[Command[_]] = Seq( Exit, Output, Start, Status ) - override def defaultCommand = Some(Default) + override def defaultCommand: Option[Command[_]] = Some(Default) } diff --git a/cli/src/bloop/cli/options/LoggingOptions.scala b/cli/src/bloop/cli/options/LoggingOptions.scala index e2dea454b1..66e32a2ee1 100644 --- a/cli/src/bloop/cli/options/LoggingOptions.scala +++ b/cli/src/bloop/cli/options/LoggingOptions.scala @@ -4,6 +4,7 @@ import caseapp._ import coursier.cache.loggers.RefreshLogger import bloop.rifle.BloopRifleLogger import bloop.cli.Logger +import java.io.OutputStream // format: off final case class LoggingOptions( @@ -38,10 +39,10 @@ final case class LoggingOptions( RefreshLogger.create() def bloopRifleLogger: BloopRifleLogger = new BloopRifleLogger { - def bloopBspStderr = None - def bloopBspStdout = None - def bloopCliInheritStderr = false - def bloopCliInheritStdout = false + def bloopBspStderr: Option[OutputStream] = None + def bloopBspStdout: Option[OutputStream] = None + def bloopCliInheritStderr: Boolean = false + def bloopCliInheritStdout: Boolean = false def debug(msg: => String, ex: Throwable): Unit = if (verbosity >= 2) { System.err.println(msg)