From 45b511433d652c46d5652ab295367f41341697af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 13 Dec 2023 14:42:21 +0100 Subject: [PATCH] [rubygems/rubygems] Improve install advice when some gems are not found This problem is quite specific to our dev environment, but I guess the fix could be handy for other situations. After merging a change to treat default gems as regular gems, I get this when trying to run `rubocop` on our repo: ``` $ bin/rubocop --only Performance/RegexpMatch Could not find json-2.6.3 in locally installed gems Run `bundle install --gemfile /Users/deivid/code/rubygems/rubygems/tool/bundler/lint_gems.rb` to install missing gems. ``` However, when running the suggested command, nothing changes and I still get the same error: ``` $ bundle install --gemfile /Users/deivid/code/rubygems/rubygems/tool/bundler/lint_gems.rb Using ast 2.4.2 Using bundler 2.4.10 Using json 2.6.3 Using parallel 1.23.0 Using racc 1.7.1 Using parser 3.2.2.3 Using rainbow 3.1.1 Using regexp_parser 2.8.1 Using rexml 3.2.5 Using rubocop-ast 1.29.0 Using ruby-progressbar 1.13.0 Using unicode-display_width 2.4.2 Using rubocop 1.52.1 Using rubocop-performance 1.14.2 Bundle complete! 2 Gemfile dependencies, 14 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. $ bin/rubocop --only Performance/RegexpMatch Could not find json-2.6.3 in locally installed gems Run `bundle install --gemfile /Users/deivid/code/rubygems/rubygems/tool/bundler/lint_gems.rb` to install missing gems. ``` The problem is that our `bin/rubocop` script uses the development version of Bundler (which has the change causing the problem), but the advice recommands the default version of Bundler, which does not yet have the change. This commit changes the advice to recommend to use the same version of Bundler that run into the problem in the first place. So in the above situation you now get: ``` $ bin/rubocop --only Performance/RegexpMatch Could not find json-2.6.3 in locally installed gems Run `/Users/deivid/code/rubygems/rubygems/bundler/exe/bundle install --gemfile /Users/deivid/code/rubygems/rubygems/tool/bundler/lint_gems.rb` to install missing gems. ``` And running that fixes the problem: ``` $ /Users/deivid//rubygems/rubygems/bundler/exe/bundle install --gemfile /Users/deivid/code/rubygems/rubygems/tool/bundler/lint_gems.rb Fetching gem metadata from https://rubygems.org/......... Fetching json 2.6.3 Installing json 2.6.3 with native extensions Bundle complete! 2 Gemfile dependencies, 14 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. ``` https://github.com/rubygems/rubygems/commit/10a9588c6d --- lib/bundler/setup.rb | 3 ++- lib/bundler/shared_helpers.rb | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/bundler/setup.rb b/lib/bundler/setup.rb index 801fd5312aade7..c40607a0f08159 100644 --- a/lib/bundler/setup.rb +++ b/lib/bundler/setup.rb @@ -12,7 +12,8 @@ Bundler.ui.error e.message Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"] if e.is_a?(Bundler::GemNotFound) - suggested_cmd = "bundle install" + suggested_bundle = Gem.loaded_specs["bundler"] ? "bundle" : Bundler::SharedHelpers.bundle_bin_path + suggested_cmd = "#{suggested_bundle} install" original_gemfile = Bundler.original_env["BUNDLE_GEMFILE"] suggested_cmd += " --gemfile #{original_gemfile}" if original_gemfile Bundler.ui.warn "Run `#{suggested_cmd}` to install missing gems." diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index a214641ae187d8..78760e6fa48c64 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -304,6 +304,13 @@ def set_env(key, value) public :set_env def set_bundle_variables + Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", bundle_bin_path + Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s + Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION + Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__) + end + + def bundle_bin_path # bundler exe & lib folders have same root folder, typical gem installation exe_file = File.expand_path("../../exe/bundle", __dir__) @@ -313,11 +320,9 @@ def set_bundle_variables # bundler is a default gem, exe path is separate exe_file = Bundler.rubygems.bin_path("bundler", "bundle", VERSION) unless File.exist?(exe_file) - Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file - Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s - Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION - Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__) + exe_file end + public :bundle_bin_path def set_path validate_bundle_path