Skip to content

[VS Code] Resolve ruby path correctly with chruby#3978

Open
davletovalmir wants to merge 1 commit intoShopify:mainfrom
davletovalmir:patch-1
Open

[VS Code] Resolve ruby path correctly with chruby#3978
davletovalmir wants to merge 1 commit intoShopify:mainfrom
davletovalmir:patch-1

Conversation

@davletovalmir
Copy link

Motivation

In VS Code and its forks (like Curser Cursor) Ruby LSP doesn't work as intended (if I did interpret the comment in vscode/chruby_activation.rb correctly LOL).

There is sentence in the comment:

In our activation script, we check if a directory using the patch exists and then prefer that over the default one.

I read this as: if we have ruby path with patch version (e.g. "/home/user/.gem/ruby/3.2.3") we should use it instead of no-patch one (e.g. "/home/user/.gem/ruby/3.2.0").

But look at the snippet output below:

irb(main):011> Gem.path
=> ["/home/user/.gem/ruby/3.2.3", "/home/user/.rubies/ruby-3.2.3/lib/ruby/gems/3.2.0"]
irb(main):012> Gem.user_dir
=> "/home/user/.gem/ruby/3.2.0"

Maybe it's just my setup, but I have exactly 2 paths. And condition never resolves, leaving me with gems installed by Ruby LSP in the wrong directory (the default one, that we tried to avoid).

Implementation

Path size checking condition is not needed, as Array#delete is safe for misses, and first_path's existence is checked anyways. So in case of any troubles (aka the only ruby version I have is the one without patch, and thus Gem.path returns exactly one path) - we still fall back to Gem.user_dir.

Automated Tests

N/A

Manual Tests

  • Removed $MY_PROJECT_DIR/.ruby-lsp
  • Removed /home/user/.gem/ruby/3.2.0
  • Restarted VS Code
  • Checked Output of Ruby LSP
  • Paths are resolved properly 🎉

@davletovalmir davletovalmir requested a review from a team as a code owner February 25, 2026 22:23
@davletovalmir
Copy link
Author

I have signed the CLA!

@vinistock
Copy link
Member

Thank you for the PR. I believe this is something specific to your setup. If you take a look at the implementation, chruby overrides $GEM_HOME using the exact Ruby version for the project.

You're correct that if you're using 3.2.3, the default $GEM_HOME is ~/.gem/3.2.0, but it gets overridden by chruby.

Do you have any additional RubyGems or Bundler settings?

Also, keep in mind that any configurations you make in shell scripts are not applied to the VS Code NodeJS process. So if you have any RubyGems, Bundler or even chruby configurations in something like ~/.zshrc, the extension may not know about them.

@davletovalmir
Copy link
Author

davletovalmir commented Mar 3, 2026

Hey @vinistock, thanks for the response!

My setup is standard chruby + Ruby 3.2.3 with no custom RubyGems or Bundler configuration.

The core issue is that Gem.user_dir is computed from RbConfig::CONFIG["ruby_version"] (compile-time 3.2.0) and ignores $GEM_HOME entirely. Meanwhile, Gem.path does respect $GEM_HOME. So when chruby sets GEM_HOME=~/.gem/ruby/3.2.3, these two disagree - which is exactly what the block tries to resolve (if I understand correctly).

But standard chruby sets GEM_PATH to $GEM_HOME:$GEM_ROOT, which always gives Gem.path.length == 2 (unless something else also sets GEM_PATH before chruby).

With chruby env:

Gem.path      => ["~/.gem/ruby/3.2.3", "~/.rubies/ruby-3.2.3/lib/ruby/gems/3.2.0"]
Gem.user_dir  => "~/.gem/ruby/3.2.0"
paths.length  => 2  # condition > 2 is false, block is skipped

Without chruby env:

Gem.path      => ["~/.gem/ruby/3.2.0", "~/.rubies/ruby-3.2.3/lib/ruby/gems/3.2.0"]
Gem.user_dir  => "~/.gem/ruby/3.2.0"
paths.length  => 2  # same

The > 2 guard would only be true if something external pre-populates $GEM_PATH with extra entries, which isn't standard chruby behavior. Removing it is safe since Array#delete handles misses and first_path is checked for nil.

I realize the newer_gem_home fallback on line 18 may cover this in practice, but the block's stated intent (per the comment) is to prefer the patch-versioned path from Gem.path - and the guard prevents that from running AFAICT. Not sure though why it didn't work out for, I can investigate it later on.

UPD: for me newer_gem_home didn't resolve properly because came out that we didn't specify the patch version in .ruby-version, so it's 3.2 out there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants