diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 0534d7c36b17c8..162a50fdb76813 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -343,6 +343,8 @@ def install Gem::Specification.add_spec(spec) + load_plugin + run_post_install_hooks spec @@ -1006,4 +1008,17 @@ def bash_prolog_script "" end end + + def load_plugin + specs = Gem::Specification.find_all_by_name(spec.name) + # If old version already exists, this plugin isn't loaded + # immediately. It's for avoiding a case that multiple versions + # are loaded at the same time. + return unless specs.size == 1 + + plugin_files = spec.plugins.map do |plugin| + File.join(@plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}") + end + Gem.load_plugin_files(plugin_files) + end end diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 126aad2602a27d..6d36a8bb629fa5 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -1449,6 +1449,8 @@ def test_self_vendor_dir_missing def test_load_plugins plugin_path = File.join "lib", "rubygems_plugin.rb" + foo1_plugin_path = nil + foo2_plugin_path = nil Dir.chdir @tempdir do FileUtils.mkdir_p "lib" File.open plugin_path, "w" do |fp| @@ -1458,17 +1460,22 @@ def test_load_plugins foo1 = util_spec "foo", "1" do |s| s.files << plugin_path end + foo1_plugin_path = File.join(foo1.gem_dir, plugin_path) install_gem foo1 foo2 = util_spec "foo", "2" do |s| s.files << plugin_path end + foo2_plugin_path = File.join(foo2.gem_dir, plugin_path) install_gem foo2 end Gem::Specification.reset + PLUGINS_LOADED.clear + $LOADED_FEATURES.delete(foo1_plugin_path) + $LOADED_FEATURES.delete(foo2_plugin_path) gem "foo" diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb index 51b097dfbda634..ff5e6f166d85b3 100644 --- a/test/rubygems/test_gem_commands_pristine_command.rb +++ b/test/rubygems/test_gem_commands_pristine_command.rb @@ -546,7 +546,7 @@ def test_execute_only_plugins fp.puts "puts __FILE__" end write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |fp| - fp.puts "puts __FILE__" + fp.puts "# do nothing" end write_file File.join(@tempdir, "bin", "foo") do |fp| fp.puts "#!/usr/bin/ruby" diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb index 41fe4e0045f9fc..cd94f61247cfb2 100644 --- a/test/rubygems/test_gem_commands_setup_command.rb +++ b/test/rubygems/test_gem_commands_setup_command.rb @@ -431,7 +431,7 @@ def gem_install_with_plugin(name) s.files = %W[lib/rubygems_plugin.rb] end write_file File.join @tempdir, "lib", "rubygems_plugin.rb" do |f| - f.puts "require '#{gem.plugins.first}'" + f.puts "# do nothing" end install_gem gem diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 30113c629bce28..3a4566ce8ceb43 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -769,7 +769,7 @@ def test_generate_bin_with_dangling_symlink def test_generate_plugins installer = util_setup_installer do |spec| write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| - io.write "puts __FILE__" + io.write "# do nothing" end spec.files += %w[lib/rubygems_plugin.rb] @@ -856,11 +856,59 @@ def test_generate_plugins_with_build_root refute_includes File.read(build_root_path), build_root end + class << self + attr_accessor :plugin_loaded + attr_accessor :post_install_is_called + end + + def test_use_plugin_immediately + self.class.plugin_loaded = false + self.class.post_install_is_called = false + spec_version = nil + plugin_path = nil + installer = util_setup_installer do |spec| + spec_version = spec.version + plugin_path = File.join("lib", "rubygems_plugin.rb") + write_file File.join(@tempdir, plugin_path) do |io| + io.write <<-PLUGIN +#{self.class}.plugin_loaded = true +Gem.post_install do + #{self.class}.post_install_is_called = true +end + PLUGIN + end + spec.files += [plugin_path] + plugin_path = File.join(spec.gem_dir, plugin_path) + end + build_rake_in do + installer.install + end + assert self.class.plugin_loaded, "plugin is not loaded" + assert self.class.post_install_is_called, + "post install hook registered by plugin is not called" + + self.class.plugin_loaded = false + $LOADED_FEATURES.delete(plugin_path) + installer_new = util_setup_installer do |spec_new| + spec_new.version = spec_version.version.succ + plugin_path = File.join("lib", "rubygems_plugin.rb") + write_file File.join(@tempdir, plugin_path) do |io| + io.write "#{self.class}.plugin_loaded = true" + end + spec_new.files += [plugin_path] + end + build_rake_in do + installer_new.install + end + assert !self.class.plugin_loaded, + "plugin is loaded even when old version is already loaded" + end + def test_keeps_plugins_up_to_date # NOTE: version a-2 is already installed by setup hooks write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| - io.write "puts __FILE__" + io.write "# do nothing" end build_rake_in do diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb index dd296b080734b9..dfa01768bc349b 100644 --- a/test/rubygems/test_gem_uninstaller.rb +++ b/test/rubygems/test_gem_uninstaller.rb @@ -173,7 +173,7 @@ def test_remove_symlinked_gem_home def test_remove_plugins write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| - io.write "puts __FILE__" + io.write "# do nothing" end @spec.files += %w[lib/rubygems_plugin.rb] @@ -190,7 +190,7 @@ def test_remove_plugins def test_remove_plugins_with_install_dir write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| - io.write "puts __FILE__" + io.write "# do nothing" end @spec.files += %w[lib/rubygems_plugin.rb] @@ -208,7 +208,7 @@ def test_remove_plugins_with_install_dir def test_regenerate_plugins_for write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| - io.write "puts __FILE__" + io.write "# do nothing" end @spec.files += %w[lib/rubygems_plugin.rb] @@ -635,7 +635,7 @@ def test_uninstall_no_permission def test_uninstall_keeps_plugins_up_to_date write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| - io.write "puts __FILE__" + io.write "# do nothing" end plugin_path = File.join Gem.plugindir, "a_plugin.rb"