Skip to content

Commit

Permalink
Document custom bundle process (#2615)
Browse files Browse the repository at this point in the history
* Document custom bundle process

* Apply suggestions from code review

Co-authored-by: Andy Waite <andy.waite@shopify.com>

* Rename custom to composed bundle

---------

Co-authored-by: Andy Waite <andy.waite@shopify.com>
  • Loading branch information
vinistock and andyw8 authored Sep 30, 2024
1 parent f5f4446 commit 4df5ddf
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
43 changes: 43 additions & 0 deletions jekyll/composed-bundle.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
layout: default
title: Composed Ruby LSP bundle
nav_order: 40
parent: Ruby LSP
---

# Composed Ruby LSP bundle

In language ecosystems other than Ruby, it is not super common to have to add editor tooling as part of your project
dependencies. Usually, a language server is an executable that gets downloaded and then run independently from your
projects.

In the Ruby ecosystem, there are a few blockers to fully adopting this approach:

1. Not writing the language server in Ruby would make it challenging to integrate seamlessly with existing tools used by
the community that are already written in Ruby, like test frameworks, linters, formatters and so on
2. Discovering project dependencies automatically allows the language server to detect which files on disk must be read
and indexed, so that we can extract declarations from gems without requiring any configuration from the user. This means
that we need to integrate directly with Bundler
3. Bundler only allows requiring gems that are set up as part of the `$LOAD_PATH`. If the Ruby LSP executable was running
independently from a global installation, then the Ruby process would only be able to require the Ruby LSP's own
dependencies, but it would not be able to require any gems used by the project being worked on. Not being able to require
the project's dependencies limits integrations that the language server can automatically make with linters, formatters,
test frameworks and so on

To overcome these limitations, while at the same time not requiring users to add `ruby-lsp` as a dependency of their projects,
the Ruby LSP uses a composed bundle strategy. The flow of execution is as follows:

1. The executable is run as `ruby-lsp` without `bundle exec` to indicate that the composed bundle must first be configured
2. The executable sets up a composed bundle under `your_project/.ruby-lsp`. The generated Gemfile includes the `ruby-lsp` gem
and everything in the project's Gemfile as well. It may also include `debug` and `ruby-lsp-rails`
3. After the composed bundle is fully set up, then the original `ruby-lsp` Ruby process is fully replaced by
`BUNDLE_GEMFILE=.ruby-lsp/Gemfile bundle exec ruby-lsp`, thus launching the real language server with access to the project's
dependencies, but without requiring adding the gem to the project's own Gemfile

In addition to performing this setup, the composed bundle logic will also `bundle install` and attempt to auto-update
the `ruby-lsp` language server gem to ensure fast distribution of bug fixes and new features.

{: .note }
Setting up the composed bundle requires several integrations with Bundler and there are many edge cases to consider,
like how to handle configurations or installing private dependencies. If you encounter a problem with the composed
bundle setup, please let us know by [reporting an issue](https://github.com/Shopify/ruby-lsp/issues/new).
6 changes: 6 additions & 0 deletions jekyll/index.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Want to discuss Ruby developer experience? Consider joining the public
- [Usage](#usage)
- [With VS Code](#with-vs-code)
- [With other editors](#with-other-editors)
- [Composed Ruby LSP bundle](#composed-ruby-lsp-bundle)
- [Add-ons](#add-ons)
- [General features](#general-features)
- [Hover](#hover)
Expand Down Expand Up @@ -80,6 +81,11 @@ gem install ruby-lsp
and the language server can be launched running `ruby-lsp` (without bundle exec in order to properly hook into your
project's dependencies).

### Composed Ruby LSP bundle

The Ruby LSP executable generates a composed bundle with the goal of not requiring users to add the `ruby-lsp` gem to
their Gemfiles, and at the same time being able to hook into project dependencies. [Learn more](composed-bundle).

## Add-ons

The Ruby LSP provides an add-on system that allows other gems to enhance the base functionality with more editor
Expand Down

0 comments on commit 4df5ddf

Please sign in to comment.