Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'bundle install' fails on Gentoo: Could not find command "_2.4.22_" #3022

Open
jameslikeslinux opened this issue Jan 7, 2025 · 3 comments
Open
Labels
bug Something isn't working vscode This pull request should be included in the VS Code extension's release notes

Comments

@jameslikeslinux
Copy link

Description

Gentoo Portage generates binstubs using a custom library, resulting in /usr/bin/bundle having the following structure:

#!/usr/bin/ruby32
# This is a simplified version of the RubyGems wrapper
#
# Generated by ruby-fakegem.eclass

require 'rubygems'

load Gem::default_path[-1] + "/gems/bundler-2.4.22/exe/bundle"

This implementation does not support the _VERSION_ argument used by standard RubyGems binstubs. Previously, I resolved this by installing a user instance of Bundler in my home directory and placing a standard binstub in ~/bin, which was included in my PATH.

However, starting with ruby-lsp 0.23, the bundle lookup behavior changed from using PATH to relying solely on Gem.default_bindir (#2987), which on my system resolves to:

> ruby -r rubygems -e 'puts Gem.default_bindir'
/usr/bin

This change makes it difficult to specify a custom Bundler instance, which limits the flexibility typically offered by being able to modify the PATH on Linux and Windows systems.

Ruby LSP Information

VS Code Version

1.96.1

Ruby LSP Extension Version

0.8.16

Ruby LSP Server Version

Unknown

Ruby LSP Addons

Ruby Version

3.2.5

Ruby Version Manager

none

Installed Extensions

Click to expand
  • copilot (1.255.0)
  • copilot-chat (0.23.2)
  • gitlens (16.1.1)
  • language-haskell (3.6.0)
  • puppet-vscode (1.5.4)
  • ruby-lsp (0.8.16)
  • vim (1.29.0)

Ruby LSP Settings

Click to expand
Workspace
{}
User
{
  "enabledFeatures": {
    "codeActions": true,
    "diagnostics": true,
    "documentHighlights": true,
    "documentLink": true,
    "documentSymbols": true,
    "foldingRanges": true,
    "formatting": true,
    "hover": true,
    "inlayHint": true,
    "onTypeFormatting": true,
    "selectionRanges": true,
    "semanticHighlighting": true,
    "completion": true,
    "codeLens": true,
    "definition": true,
    "workspaceSymbol": true,
    "signatureHelp": true,
    "typeHierarchy": true
  },
  "featuresConfiguration": {},
  "addonSettings": {},
  "rubyVersionManager": {
    "identifier": "auto"
  },
  "customRubyCommand": "",
  "formatter": "auto",
  "linters": null,
  "bundleGemfile": "",
  "testTimeout": 30,
  "branch": "",
  "pullDiagnosticsOn": "both",
  "useBundlerCompose": false,
  "bypassTypechecker": false,
  "rubyExecutablePath": "",
  "indexing": {},
  "erbSupport": true,
  "featureFlags": {}
}

Reproduction steps

  1. Start the Ruby LSP using VS Code
  2. Open a Ruby file
  3. See unexpected behavior

Code snippet or error message

2025-01-07 16:47:45.743 [info] (config) Checking if chruby is available on the path with command: /bin/zsh -i -c 'chruby --version'
2025-01-07 16:47:45.939 [info] (config) Checking if rbenv is available on the path with command: /bin/zsh -i -c 'rbenv --version'
2025-01-07 16:47:46.171 [info] (config) Checking if rvm is available on the path with command: /bin/zsh -i -c 'rvm --version'
2025-01-07 16:47:46.351 [info] (config) Checking if asdf is available on the path with command: /bin/zsh -i -c 'asdf --version'
2025-01-07 16:47:46.500 [info] (config) Discovered version manager none
2025-01-07 16:47:46.500 [info] (config) Running command: `ruby -W0 -rjson -e 'STDERR.print("RUBY_LSP_ACTIVATION_SEPARATOR" + { env: ENV.to_h, yjit: !!defined?(RubyVM::YJIT), version: RUBY_VERSION, gemPath: Gem.path }.to_json + "RUBY_LSP_ACTIVATION_SEPARATOR")'` in /home/james/projects/nest/config using shell: /usr/sbin/zsh
2025-01-07 16:47:46.992 [info] (config) /usr/bin/ruby32: warning: Ruby was built without YJIT support. You may need to install rustc to build Ruby with YJIT.

2025-01-07 16:47:47.347 [info] (config) Ruby LSP> Skipping composed bundle setup since /home/james/projects/nest/config/.ruby-lsp/Gemfile.lock already exists and is up to date

2025-01-07 16:47:47.395 [info] (config) Ruby LSP> Running bundle install for the composed bundle. This may take a while...
Ruby LSP> Command: (/usr/bin/ruby32 /usr/bin/bundle _2.4.22_ check || /usr/bin/ruby32 /usr/bin/bundle _2.4.22_ install) 1>&2

2025-01-07 16:47:47.414 [info] (config) /usr/bin/ruby32: warning: Ruby was built without YJIT support. You may need to install rustc to build Ruby with YJIT.

2025-01-07 16:47:47.585 [info] (config) Could not find command "_2.4.22_".

2025-01-07 16:47:47.608 [info] (config) /usr/bin/ruby32: warning: Ruby was built without YJIT support. You may need to install rustc to build Ruby with YJIT.

2025-01-07 16:47:47.756 [info] (config) Could not find command "_2.4.22_".

2025-01-07 16:47:47.760 [info] (config) Ruby LSP> Running bundle install failed. Trying to re-generate the composed bundle from scratch

2025-01-07 16:47:47.761 [info] (config) Ruby LSP> Running bundle install for the composed bundle. This may take a while...
Ruby LSP> Command: (/usr/bin/ruby32 /usr/bin/bundle _2.4.22_ check || /usr/bin/ruby32 /usr/bin/bundle _2.4.22_ install) 1>&2

2025-01-07 16:47:47.783 [info] (config) /usr/bin/ruby32: warning: Ruby was built without YJIT support. You may need to install rustc to build Ruby with YJIT.

2025-01-07 16:47:47.955 [info] (config) Could not find command "_2.4.22_".

2025-01-07 16:47:47.979 [info] (config) /usr/bin/ruby32: warning: Ruby was built without YJIT support. You may need to install rustc to build Ruby with YJIT.

2025-01-07 16:47:48.132 [info] (config) Could not find command "_2.4.22_".

2025-01-07 16:47:48.151 [info] (config) /usr/bin/ruby32: warning: Ruby was built without YJIT support. You may need to install rustc to build Ruby with YJIT.

2025-01-07 16:47:48.286 [info] (config) Could not find command "_2.4.22_".

2025-01-07 16:47:48.297 [info] (config) [Error - 4:47:48 PM] Server process exited with code 15.
2025-01-07 16:47:48.299 [info] (config) [Error - 4:47:48 PM] Server initialization failed.
2025-01-07 16:47:48.299 [info] (config)   Message: Pending response rejected since connection got disposed
  Code: -32097 
2025-01-07 16:47:48.300 [info] (config) [Error - 4:47:48 PM] Ruby LSP client: couldn't create connection to server.
2025-01-07 16:47:48.300 [info] (config)   Message: Pending response rejected since connection got disposed
  Code: -32097 
2025-01-07 16:47:48.300 [error] (config) Error starting the server: Pending response rejected since connection got disposed
2025-01-07 16:54:52.618 [info] (config) [Error - 4:54:52 PM] Connection to server got closed. Server will not be restarted.
@jameslikeslinux jameslikeslinux added bug Something isn't working vscode This pull request should be included in the VS Code extension's release notes labels Jan 7, 2025
@vinistock
Copy link
Member

Thank you for the bug report! Figuring out all possible scenarios for these binstubs is proving quite the adventure 😅. Please bare with me as I try to find a solution that is generic enough.

Essentially, your scenario seems like the exact opposite of the other bugs reported. In the other cases, users had custom binstubs under application/bin and added ./bin to their PATH, but those binstubs were the ones that did not support versions.

Do you do anything to have Gem.default_bindir return /usr/bin? Or is that what RubyGems returns for the OS? And is there no way to have the binstubs generated under /usr/bin accept versions?

@jameslikeslinux
Copy link
Author

It seems that the Gem.default_bindir value is determined by the OS during the build process, or at least, I have not found a way to modify it. Additionally, the method for generating binstubs is controlled by the package manager, leaving no room for customization on my end.

I’m curious about the decision to rely on undocumented, special arguments in this project. Based on my observations, the RubyGems wrapper uses the _VERSION_ argument solely to set the BUNDLER_VERSION environment variable:

str = ARGV.first  
if str  
  str = str.b[/\A_(.*)_\z/, 1]  
  if str and Gem::Version.correct?(str)  
    version = str  
    ENV['BUNDLER_VERSION'] = str  

    ARGV.shift  
  end  
end  

Wouldn’t it be more straightforward to set BUNDLER_VERSION as a standard environment variable rather than relying on this special argument?

jameslikeslinux added a commit to jameslikeslinux/nest-config that referenced this issue Jan 8, 2025
ruby-lsp calls bundle with an undocumented version number argument
supported by RubyGems binstubs. Portage binstubs don't support this. Use
a wrapper to throw away the version number argument.

See: Shopify/ruby-lsp#3022
jameslikeslinux added a commit to jameslikeslinux/nest-config that referenced this issue Jan 8, 2025
ruby-lsp doesn't execute `bundle` directly. No, that would be the
obvious unix way. Instead it assumes it's ruby and passes it to `ruby`
instead.

See: Shopify/ruby-lsp#3022
@vinistock
Copy link
Member

That's not all the binstub does. It uses the version you pass to eagerly activate the Bundler spec.

Gem.activate_bin_path('bundler', 'bundle', version)

To compose the bundle that the Ruby LSP uses, passing BUNDLER_VERSION as part of the environment was not enough. It prevented the Bundler initiated auto-restarts on version mismatches, which was only part of the problem.

However, it did not ensure that the composed bundle was built using the same version of Bundler as the main application. The reason is because, if you don't pass a version, the RubyGems stub eagerly activates the spec of the latest Bundler version.

That would lead to the main app being locked to one version of Bundler and our composed bundle being locked to a different one, which can also lead to issues. Only by passing the version argument can we ensure that the right spec of Bundler is eagerly activated and the composed bundle gets locked to the expected version.

Our first fix used bundle _version_ as the command, but that breaks for users that use custom binstubs under the bin directory and add that to their PATH (#2862, #2731).

The hope using Gem.default_bindir was that we could bypass people's custom binstubs and use the default one provided by RubyGems with the version to ensure the right spec is activated, but it seems even that is not generic enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working vscode This pull request should be included in the VS Code extension's release notes
Projects
None yet
Development

No branches or pull requests

2 participants