From 80fd8463536cfb1db29aa7f784b41178243524cb Mon Sep 17 00:00:00 2001 From: Sarah Sehr Date: Wed, 8 May 2024 15:19:19 -0400 Subject: [PATCH] [rubygems/rubygems] Add useful error message for plugin load If a plugin has previously been installed, but the path is no longer valid, `rake setup` will fail with an unexpected error due to the file not existing. Instead, we want to present the user with what the issue is and how to resolve the problem. https://github.com/rubygems/rubygems/commit/0c6ad3ecbb --- lib/bundler/plugin.rb | 21 ++++++++++++++++++++- spec/bundler/bundler/plugin_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb index 588fa79be8..7790a3f6f8 100644 --- a/lib/bundler/plugin.rb +++ b/lib/bundler/plugin.rb @@ -342,7 +342,26 @@ module Bundler # done to avoid conflicts path = index.plugin_path(name) - Gem.add_to_load_path(*index.load_paths(name)) + paths = index.load_paths(name) + invalid_paths = paths.reject {|p| File.directory?(p) } + + if invalid_paths.any? + Bundler.ui.warn <<~MESSAGE + The following plugin paths don't exist: #{invalid_paths.join(", ")}. + + This can happen if the plugin was installed with a different version of Ruby that has since been uninstalled. + + If you would like to reinstall the plugin, run: + + bundler plugin uninstall #{name} && bundler plugin install #{name} + + Continuing without installing plugin #{name}. + MESSAGE + + return + end + + Gem.add_to_load_path(*paths) load path.join(PLUGIN_FILE_NAME) diff --git a/spec/bundler/bundler/plugin_spec.rb b/spec/bundler/bundler/plugin_spec.rb index 3ac7b251a3..fea3925000 100644 --- a/spec/bundler/bundler/plugin_spec.rb +++ b/spec/bundler/bundler/plugin_spec.rb @@ -333,5 +333,28 @@ RSpec.describe Bundler::Plugin do end.to output("win\n").to_stdout end end + + context "the plugin load_path is invalid" do + before do + allow(index).to receive(:load_paths).with("foo-plugin"). + and_return(["invalid-file-name1", "invalid-file-name2"]) + end + + it "outputs a useful warning" do + msg = + "The following plugin paths don't exist: invalid-file-name1, invalid-file-name2.\n\n" \ + "This can happen if the plugin was " \ + "installed with a different version of Ruby that has since been uninstalled.\n\n" \ + "If you would like to reinstall the plugin, run:\n\n" \ + "bundler plugin uninstall foo-plugin && bundler plugin install foo-plugin\n\n" \ + "Continuing without installing plugin foo-plugin.\n" + + expect(Bundler.ui).to receive(:warn).with(msg) + + Plugin.hook(Bundler::Plugin::Events::EVENT1) + + expect(subject.loaded?("foo-plugin")).to be_falsey + end + end end end