| date | March 2020 | |
|---|---|---|
| accepted | true | |
| updates | ||
| status | completed |
Submitted by Bill Venners, based on a proposal by Justin Kaeser, JetBrains, January 2020
The Build Server Protocol (BSP) was developed by the Scala Center with cooperation from JetBrains to ease integration of build tools with IDEs and language servers. Currently the IntelliJ Scala plugin and Metals rely on injecting sbt plugins into user projects to export the build structure. This approach causes friction that can be addressed by supporting the Build Server Protocol directly within sbt.
Implement Build Server Protocol support for sbt in sbt core. Three possible approaches are:
- Integrate sbt-bloop into sbt core.
- Implement BSP in sbt core (probably through sbt server), directly using the task graph.
- Implement BSP in sbt core (probably through sbt server), delegating to Bloop for tasks that bloop can handle.
Integration of IntelliJ and Metals with sbt is burdened by some overhead and friction. The IntelliJ Scala plugin injects several sbt plugins into a user's project to be able to export the project model and interact with the sbt shell. This is quite brittle and does not give a good user experience in terms of IDE integration.
Metals injects the sbt-bloop plugin to export Bloop config files, then uses Bloop directly for compilation. Bloop already implements BSP as a server, so towards the front end there is a good user experience. The drawback is that Bloop does not run the full sbt task graph, so anything more sophisticated than just compilation, such as source code generation or packaging, still needs to be done from sbt directly.
One alternative approach is to add BSP support to sbt as a plugin. This approach has the drawback that either the user needs to configure their environment or projects to explicitly install the plugin, or BSP clients need to inject the plugin into the user's sbt environment, requiring tool-specific logic.
BSP is designed to enable integration between IDEs/language servers and build tools without either side needing to know specifics of each other. Native support in sbt makes this possible with the least friction for the user.
An implementation should support at least:
- server lifetime endpoints
- workspace/buildTargets
- buildTarget/sources
- buildTarget/dependencySources
- buildTarget/resources
- buildTarget/compile
- Scala extensions
An implementation with good feature coverage will also include:
- sbt extension
- task notifications
- for compilation of individual subprojects
- for individual sbt tasks
- buildTarget/test
- test notifications per test suite / test
BSP defines a standard way for clients to discover and connect to BSP servers. One way to support this from sbt is create a BSP wrapper around an sbt shell process.
The sbt server protocol, like BSP, can be viewed as an extension of Language Server Protocol (LSP). It could thus be a reasonable approach to extend sbt server with BSP endpoints.
- Alexandra Dima's BSP support for Mill, with almost no prior exposure to Scala or Mill, took about two months for a largely complete implementation
- Justin Kaeser's BSP support in Fury, which implements only project structure resolution, took one to two weeks.
Sbt BSP support will likely be more complex than these tasks, but overall similar in scope.
Ideally BSP support in sbt would be ready for sbt 1.4 support, and be ready in time for IntelliJ release to support it.