build-server-protocol icon indicating copy to clipboard operation
build-server-protocol copied to clipboard

Clarify the motivation: which N x M problem is solved?

Open keyboardDrummer opened this issue 7 years ago • 13 comments

The motivation for the LSP protocol I understand, because given N IDE's and M languages there is an N x M complexity. Assuming that the BSP is connecting language servers and build tools, does a similar complexity exist between these two?

At first hand I might be inclined to answer no, because many languages have different build tools. However, I think my answer here is yes, since languages running on the same run-time often share build-tools. Here are some examples of what languages combine with which build tools:

  • C#/F#/VB.Net x MSBuild
  • Java/Scala/Kotlin x Ant/Maven/Sbt/Gradle
  • Javascript/Typescript x npm

So this to me confirms there is an N x M complexity, although it seems much less pronounced than for editors and languages.

I did not include Bazel and Pants out as build tools, since they need extensions to work for specific run-times. Correct me if I'm wrong but they seem to live on a higher level than the other build tools.

Could you confirm in the motivation what N x M problem is being solved by BSP? Some examples would be great.

keyboardDrummer avatar Jun 18 '18 21:06 keyboardDrummer

The motivating problem is the Scala tooling ecosystem. We have:

build tools:

  • Ant
  • Bazel
  • CBT
  • Gradle
  • Maven
  • Mill
  • Pants
  • sbt
  • more coming up

Language Servers

  • Metals
  • Dotty IDE

IDEs

  • IntelliJ
  • Scala IDE

Stand-alone editors: the usual

So depending on which layer you integrate in, this can be an Build Tool x Language Server x Editor problem

From my pont of view (IntelliJ Scala plugin) the plethora of build tools is enough motivation, as writing supporting sbt turned out to be complex enough that dedicated support for more tools would incur too much of a maintenance burden. But bsp is intended to be general enough to work with more than Scala build tools and IDEs.

jastice avatar Jun 18 '18 23:06 jastice

I understand that in the Scala case, you have multiple components that play a language server role, both the language servers themselves (Metals & Dotty), but possibly also the IDE's. Because of this, you have a language servers x build tools problem, even though you're only looking at a single language.

However, if you want gain traction for BSP, I think you should advertise that BSP is solving a general problem, which is the languages x build tools problem. For example, it would be great if both Dotty IDE and Eclipse JDT server both consume the same Maven and Gradle BSP servers.

I think BSP is a great idea, and obviously it relies on traction to be successful, so I think the motivation section has to be compelling. I'd make a PR but I want to make sure we're on the same page first.

keyboardDrummer avatar Jun 19 '18 07:06 keyboardDrummer

Thanks for bringing this up @keyboardDrummer! I agree with you that the motivation section still needs improvement and it would be good to refine it based on our discussions.

I did not include Bazel and Pants out as build tools, since they need extensions to work for specific run-times.

Can you elaborate on this? From my perspective, Bazel and Pants are build tools like Maven/Gradle that require the same IDE support. (PS. "IDE" for me includes "language server").

However, if you want gain traction for BSP, I think you should advertise that BSP is solving a general problem, which is the languages x build tools problem.

That is an interesting view. I am open to reformulate the BSP pitch in that direction if you think it would resonate more with people.

For me personally, the most exciting aspect of BSP is it can lower the barrier of entry for new build tools and IDEs. Both build tools and IDEs are an active area of development today and I think many exciting innovations are left to be made in this space. By having client/server communication between build tools and IDEs we can enable powerful features what are harder to implement with only static configuration files. For example, imagine a beautiful UI for running tests similar to https://github.com/Raathigesh/majestic that works with any build tool 😄

olafurpg avatar Jun 19 '18 09:06 olafurpg

Yes, I agree we still need to add this to our motivation. In the slides of my presentation with Justin at Scalasphere, we did explain more on the MxN problem we're trying to solve:

BSP creates the opportunity to reduce the m-times-n complexity problem of providing a high level of support for any build tool in any editor, IDE, or client endpoint to a simpler m-plus-n problem.

I'll try to submit this in a pull request, as well as adding a Docusaurus page to better communicate the intent of the project.

jvican avatar Jun 19 '18 12:06 jvican

On a general matter, what's BSP providing that a .travis.yml or a Jenkinsfile cannot perform? Aren't scripts a valid portable way to run builds across IDEs? What value does the BSP provide over them? Also, if I look at the draft, it seems like the "BSP" would proxy an actual build tool and translate the messages between the protocol and the build tool expectation. So, strictly speaking, it's not a server as it doesn't need to keep connected; but more an "adapter" (like the Debug Adapter Protocol) which is a translation layer. I think it'd be worth renaming it to "Build Adapter Protocol" to clarify that and better clarify the value to people who will only read the name.

mickaelistria avatar Jan 20 '19 09:01 mickaelistria

On a general matter, what's BSP providing that a .travis.yml or a Jenkinsfile cannot perform? Aren't scripts a valid portable way to run builds across IDEs? What value does the BSP provide over them?

Part of the protocol could indeed be covered by just a description language. What BSP aims for is to also standardize

  • discovering a build tool, either on project or system level, without necessarily needing a special file in the project
  • project structure description, so that it can be imported into IDEs with other project models
  • interface to communicate with build tools, i.e. running tasks and getting updates

Especially the last point is not covered by a simple script or description language, since in the IDE / frontend we would like a richer experience than just log entries. This includes

  • diagnostics (compile and test errors, warnings, etc) as they happen
  • structured information in the diagnostics, i.e. file location, line numbers
  • live progress updates during builds on currently running tasks
  • updates from the server to the client when the build definition changes
  • task cancellation

These are things that actually require a live connection.

jastice avatar Jan 20 '19 10:01 jastice

@mickaelistria in Metals we trigger BSP compile requests on file save and update the status bar with compilation progress based on build/taskStart and build/taskFinished notifications

2019-01-20 13 06 51

We could probably implement this functionality by scraping the console output from build scripts but I suspect it would be less robust.

Maybe "Build Adapter Protocol" is a more appropriate name, but it's an implementation detail IMO how the server chooses to handle requests and notifications. Regardless or the name, the protocol requires a long-running connection. A benefit of "server" at least is that client/server is more widely understood than client/adapter.

olafurpg avatar Jan 20 '19 12:01 olafurpg

Ok thanks.

This includes [...]

All those are covered by the Language Server Protocol already. So couldn't "build" be an action (or a namespace of actions) provided directly in the Language Server Protocol and implemented by language servers?

mickaelistria avatar Jan 20 '19 13:01 mickaelistria

All those are covered by the Language Server Protocol already

There is some overlap with LSP, and BSP is modeled closely after LSP, but the scope is a bit different. BSP is project structure-aware, and batch operation-aware. It is intended as the interface between batch-oriented build tools and editor-aware language servers, so the messages are a bit different. In the case of IntelliJ, there is no language server in between.

jastice avatar Jan 20 '19 21:01 jastice

I'd say the overlap is only in diagnostics, which are the two first points. However, the rest of things are not covered by LSP. BSP connects the state of the build tool with that of the client (be it an editor or another LSP server, as in the case of Metals).

So couldn't "build" be an action (or a namespace of actions) provided directly in the Language Server Protocol and implemented by language servers?

Maybe for a very basic use case would work? However, that would defeat the purpose of improving the communication between a build tool and a client since it would operate as a black box. Behind the execution of a task, there are a lot of details that are important for UX (overall number of tasks run, logs associated to those tasks, timings, status codes) -- those need ad-hoc support.

We're only talking about task execution here but there are more use cases that are important to build tool clients. Clients usually need to gather accurate build information such as how many build targets exist in a workspace, which language(s) they support, what compiler options should a client use to compile a target, what are the source and resource directories of a target, etc

BSP enables the client to understand a unified data model of the build and the actions that can be run on it regardless of the build tool or language used. This unified data model and a live connection with the build server enables a lot of use cases in common IDEs, improves UX across the board and speeds up integrations (e.g. you change a build definition, the build server immediately picks it up and forwards a notification to the client to update indices/data structures in the IDE).

jvican avatar Jan 21 '19 09:01 jvican

@olafurpg

By having client/server communication between build tools and IDEs we can enable powerful features what are harder to implement with only static configuration files.

I get the impression that here you are grouping IDE's and LSP servers both under the IDE flag. For me this confuses the discussion. I prefer to think from the standpoint of there being a language-agnostic IDE and a language-specific LSP server, and then seeing how a BSP server fits into that.

I'm already convinced that it is useful for the LSP server to communicate with a BSP server in scenario's like:

  • the JVM, where there are many languages each with their own LSP server, and many build-tools.
  • Scala, where there are many Scala LSP servers (Metals, Dotty, IntelliJ Scala-plugin, Eclipse Scala-plugin) and many build-tools.

However, I'm unconvinced that it would make sense for IDE's to communicate with a BSP server directly, next to talking to an LSP server. The clearest case for this is languages that have only 1 build-tool, in which case the BSP server is a useless concept, and it's simplest for the LSP server to have built-in support for the built-tool, and for the IDE to communicate with just this LSP server.

Another use-case is where a developer wants to use a new build-tool by consuming a new BSP server. With an architecture where the BSP server communicates with just the LSP server, the developer would only have to update the LSP server and not the IDE, while if the IDE communicates with the BSP server as well, the developer has to update both the IDE and LSP server.

I want to suggest that we identify use-cases where we think a direct line between the IDE and the BSP server, which circumvents the LSP server, is useful, and consider what it would take to route that through the LSP server instead.

I will start by taking a use-case that was mentioned by @jvican:

you change a build definition, the build server immediately picks it up and forwards a notification to the client to update indices/data structures in the IDE"

These indices/data structures that need updating are in the LSP server, so here communication between the LSP and BSP server suffices.

keyboardDrummer avatar Jan 21 '19 10:01 keyboardDrummer

However, I'm unconvinced that it would make sense for IDE's to communicate with a BSP server directly, next to talking to an LSP server

I think there's a bit of confusion here. BSP is intended as the backend protocol between LSP server and build tool, the editor should only need to talk to the LSP server. IntelliJ as an IDE has its own "language server", so talks directly to the build tool via BSP.

I can think of cases however where an editor might want to talk to both LSP and BSP server: To expose more details of the build, or a richer task progress API. But this could also be handled by the LSP server proxying those requests and notifications, and I'm not aware of a concrete use-case yet.

jastice avatar Jan 21 '19 11:01 jastice

However, I'm unconvinced that it would make sense for IDE's to communicate with a BSP server directly, next to talking to an LSP server

For example, let's imagine vim or sublime text want to highlight projects in your project view depending on the semantics they have. To highlight source directories as yellow and resource directories as green (like IntelliJ does), they need to know all the build targets defined in a workspace and the source and resource directories fields in them. When they change (because the user makes a change in the build definition), the client wants to update this data automatically without needing to poll the server again and extract all the build information.

That just illustrates how a LSP-BSP communication doesn't suffice. There are some more use cases like this (not only from IDEs but from other developer tools such as scripts and even build tools). Exposing build information to different kind of clients empowers existing developer tools and makes integrations with other developer tools more robust and easier to write.

Yes, so far the most important use cases come from a language server talking to a build server, but language servers are not the only clients. That's why, for example, we've created a BSP Connection Protocol to name one of the many differences between BSP and LSP.

the IDE and the BSP server, which circumvents the LSP server, is useful, and consider what it would take to route that through the LSP server instead.

I think that BSP being independent from LSP is a feature. There is no bijection between LSP and BSP servers, both are trying to solve different problems with different concepts and data structures. LSP abstracts away language-specific IDE support, BSP abstracts away build tools.

jvican avatar Jan 21 '19 12:01 jvican