Shopify / ruby-lsp

An opinionated language server for Ruby
https://shopify.github.io/ruby-lsp/
MIT License
1.33k stars 118 forks source link

Error starting ruby-lsp when customizing `rubyLsp.bundleGemfile` #1975

Closed nholden closed 1 week ago

nholden commented 3 weeks ago

Description

I have a project that contains all Ruby files in an ./api subdirectory. Today, I have a ./Gemfile and a ./api/Gemfile, but I'd like to only have a ./api/Gemfile.

Whenever I try to set the rubyLsp.bundleGemfile setting to ./api/Gemfile, I see this error in the Ruby LSP output:

bundler: failed to load command: ruby-lsp (/Users/nickholden/.gem/ruby/3.2.2/bin/ruby-lsp)

I confirmed that /Users/nickholden/.gem/ruby/3.2.2/bin/ruby-lsp exists on my machine. I don't see this error when I don't set rubyLsp.bundleGemfile, and I always see this error whenever I set any value for rubyLsp.bundleGemfile.

I have ruby-lsp installed via the VSCode extension (latest version).

Any troubleshooting suggestions?

g-arjones commented 2 weeks ago

When you set rubyLsp.bundleGemfile you must add ruby-lsp manually to your bundle. Unfortunately, this is undocumented. I had the same issue a couple of days ago and had to dig into the source code to understand what was happening.

https://github.com/Shopify/ruby-lsp/blob/f6f42b163d72459a9be682b1e07769af39f1ecc4/vscode/src/client.ts#L45-L46

vinistock commented 2 weeks ago

@g-arjones this is documented in the VS Code extension's README. Also, this issue is not related to using a custom bundle.

@nholden for cases where the Ruby project is nested in a sub-directory, you have to configure that directory as a workspace using VS Code's multi-root workspace features.

We have documentation on multi-root workspaces here and the Ruby LSP itself is a multi-root workspace. You can find our own configs here.

The custom bundle feature is intended for users who have a separate Gemfile for their developer tools or for projects that are using EOL rubies.

Please, let us know if you have any doubts so that we can improve the docs.

g-arjones commented 2 weeks ago

Also, this issue is not related to using a custom bundle.

What do you mean?

vinistock commented 2 weeks ago

The custom bundle is only intended to be used in two scenarios: if your project is using a Ruby version past its end of life (< 3.0) or if you use a setup with a separate Gemfile for your development tools (some users don't like putting formatters, linters and other tooling into their project dependencies).

The scenario described here is a multi-root workspace, which is natively supported by VS Code and the Ruby LSP. As long as the .code-workspace file exists and you open the configured workspace, the Ruby LSP will automatically identify the available Ruby workspaces and launch the language server.

g-arjones commented 2 weeks ago

The scenario described here is a multi-root workspace

Where is that described? What I see here is a single project/root but he keeps his Gemfile in api/ instead of on the root of the repo. That's exactly my use case as well. Single project, single root, Gemfile not on root.

vinistock commented 2 weeks ago

Tools like language servers need to be able to determine where the root of workspaces exist, so that they can discover the package.json, Gemfile or whatever other configuration files are relevant.

It tells all VS Code extensions (and the editor itself), these are the relevant workspaces inside this project you may need to activate on. It's the way that VS Code users can configure monorepos.

Conceptually, the api directory is a workspace, even if there's just one project. The api directory is where the root of the Ruby project exists, where the Gemfile is located. These workspace declarations allow the Ruby LSP to automatically boot using the proper set of dependencies.

Without workspaces, there's no heuristic that would allow us to launch the language server and always have it work. In this particular use case, being able to point to the location of the Gemfile would be sufficient, but that doesn't cover all scenarios.

Some users have private gems defined inside a monorepo, inside many levels of nested subdirectories, alongside a main application. Others just have a single application and nothing else. Some have the frontend, backend directories under a top level directory.

There's no blanket rule that would account for all possible scenarios, which is why we rely on the user configuring their monorepos using VS Code's multi-root workspace feature.

As I mentioned, this is exactly the scenario for the Ruby LSP itself. The top level of this repository is a gem and the vscode subdirectory is a second workspace for the VS Code extension.

g-arjones commented 2 weeks ago

I have to disagree. Where I put my Gemfile does not dictate where the root of my workspace is (let alone how I name it). The location and the name of the Gemfile are irrelevant, bundler itself allows users to put their Gemfile wherever they want and name it whatever they want through the BUNDLE_GEMFILE environment variable.

Now, you as developers of ruby-lsp may choose to force your users to always have the Gemfile named Gemfile and always on the root of the workspace but that's a limitation introduced by ruby-lsp itself. Not bundler, not vscode.

My project has the gemfile in a separate folder with nothing else (not even ruby files) and I'm pretty sure that's not the root of my workspace. Everything works fine, the solargraph language server works fine, bundler works fine, vscode works fine, other extensions and tools work fine. The only thing that cares about my gemfile being ${workspaceFolder}/config/Gemfile instead of ${workspaceFolder}/Gemfile is ruby-lsp.

nholden commented 1 week ago

Thank you, @vinistock! I've created a new multi-root workspace, and ruby-lsp is working. My team is trying it out today.

The custom bundle feature is intended for users who have a separate Gemfile for their developer tools or for projects that are using EOL rubies.

Please, let us know if you have any doubts so that we can improve the docs.

I think it would be helpful to add a note to the bundle gemfile extension setting in VSCode. That setting looked like exactly what I wanted, so I was surprised when it didn't work. Would be helpful context there to know what the setting is intended for and that you must use a multi-root workspace if your Gemfile is located in a subdirectory.

vinistock commented 1 week ago

I'm glad to hear it's working. I tried expanding on the setting description, but the challenge is the length of the text https://github.com/Shopify/ruby-lsp/pull/2011. Do you have any suggestions that would make this clearer?

nholden commented 1 week ago

I'm glad to hear it's working. I tried expanding on the setting description, but the challenge is the length of the text https://github.com/Shopify/ruby-lsp/pull/2011. Do you have any suggestions that would make this clearer?

I think that's perfect. Thank you! 🙏