tindzk / seed

Build tool for Scala projects
https://tindzk.github.io/seed/
Apache License 2.0
238 stars 13 forks source link

Implement BSP support #63

Closed tindzk closed 4 years ago

tindzk commented 4 years ago

Build and run modules with the Build Server Protocol (BSP). Previously, we were using Bloop's CLI which has the following limitations:

Using BSP allows us to integrate more tightly with Bloop and avoid these limitations. When the user now executes a Seed command, the following steps are performed:

First, bloop bsp is run which will start a BSP server in the background and listen on a UNIX socket. Then, bsp4j is used to establish a connection using ZIO's exponential retry policy. Once the connection is active, the corresponding BSP tasks are executed sequentially. The BSP server responds asynchronously with the results of the running tasks (e.g. compilation diagnostics or progress updates). Finally, the BSP server can be gracefully shut down and the socket file removed.

BSP reports detailed information on the compilation progress which allows us to render a separate progress bar for each module. Compilation messages (warnings or errors) do not interfere with the progress bar since messages are printed above it. Progress bars are disabled in the Docker image to avoid verbose CI logs.

A new command for running modules was introduced, called run. It is currently limited to one module since programs can be non-terminating.

The package command now builds the supplied module prior to packaging it. This change was needed since BSP uses a different target path for class files compared to Bloop's CLI command.

The link command continues to use the Bloop CLI since this operation is not exposed via BSP yet.

A bug was fixed in server that resulted in the optimise parameter being ignored when sending a link request.

The commands build, run and link support a watch mode that can be enabled by passing in --watch. It was implemented based on EPFL's fork of the directory-watcher library which supports watching file paths. The watch events are then exposed as a ZIO stream.

With these changes, the user can run operations in parallel on multiple modules defined in the same build. We can also automatically restart JVM processes whenever source files are changed. As an example, this enables the following workflow for a client/server application:

seed link client --watch  # Terminal 1: Link Scala.js frontend
seed run server --watch   # Terminal 2: Run Scala JVM backend

Closes #58.