[rubygems/rubygems] Add plugin hooks for Bundler.require

https://github.com/rubygems/rubygems/commit/b373b7ed0d
This commit is contained in:
fatkodima 2019-10-30 18:17:56 +02:00 коммит произвёл git
Родитель 1984db2db8
Коммит 09cbbe0e3d
5 изменённых файлов: 156 добавлений и 19 удалений

Просмотреть файл

@ -184,6 +184,7 @@ module Bundler
# Bundler.require(:test) # requires second_gem
#
def require(*groups)
Bundler.load_plugins
setup(*groups).require(*groups)
end
@ -560,6 +561,24 @@ module Bundler
@feature_flag ||= FeatureFlag.new(VERSION)
end
def load_plugins(definition = Bundler.definition)
return if defined?(@load_plugins_ran)
Bundler.rubygems.load_plugins
requested_path_gems = definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
path_plugin_files = requested_path_gems.map do |spec|
begin
Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
rescue TypeError
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
raise Gem::InvalidSpecificationException, error_message
end
end.flatten
Bundler.rubygems.load_plugin_files(path_plugin_files)
@load_plugins_ran = true
end
def reset!
reset_paths!
Plugin.reset!

Просмотреть файл

@ -81,7 +81,7 @@ module Bundler
if resolve_if_needed(options)
ensure_specs_are_compatible!
load_plugins
Bundler.load_plugins(@definition)
options.delete(:jobs)
else
options[:jobs] = 1 # to avoid the overhead of Bundler::Worker
@ -213,20 +213,6 @@ module Bundler
Bundler.settings.processor_count
end
def load_plugins
Gem.load_plugins
requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
path_plugin_files = requested_path_gems.map do |spec|
Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
rescue TypeError
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
raise Gem::InvalidSpecificationException, error_message
end.flatten
Gem.load_plugin_files(path_plugin_files)
Gem.load_env_plugins
end
def ensure_specs_are_compatible!
@definition.specs.each do |spec|
unless spec.matches_current_ruby?

Просмотреть файл

@ -56,6 +56,30 @@ module Bundler
# Includes an Array of Bundler::Dependency objects
# GEM_AFTER_INSTALL_ALL = "after-install-all"
define :GEM_AFTER_INSTALL_ALL, "after-install-all"
# @!parse
# A hook called before each individual gem is required
# Includes a Bundler::Dependency.
# GEM_BEFORE_REQUIRE = "before-require"
define :GEM_BEFORE_REQUIRE, "before-require"
# @!parse
# A hook called after each individual gem is required
# Includes a Bundler::Dependency.
# GEM_AFTER_REQUIRE = "after-require"
define :GEM_AFTER_REQUIRE, "after-require"
# @!parse
# A hook called before any gems require
# Includes an Array of Bundler::Dependency objects.
# GEM_BEFORE_REQUIRE_ALL = "before-require-all"
define :GEM_BEFORE_REQUIRE_ALL, "before-require-all"
# @!parse
# A hook called after all gems required
# Includes an Array of Bundler::Dependency objects.
# GEM_AFTER_REQUIRE_ALL = "after-require-all"
define :GEM_AFTER_REQUIRE_ALL, "after-require-all"
end
end
end

Просмотреть файл

@ -41,12 +41,17 @@ module Bundler
groups.map!(&:to_sym)
groups = [:default] if groups.empty?
@definition.dependencies.each do |dep|
# Skip the dependency if it is not in any of the requested groups, or
# not for the current platform, or doesn't match the gem constraints.
next unless (dep.groups & groups).any? && dep.should_include?
dependencies = @definition.dependencies.select do |dep|
# Select the dependency if it is in any of the requested groups, and
# for the current platform, and matches the gem constraints.
(dep.groups & groups).any? && dep.should_include?
end
Plugin.hook(Plugin::Events::GEM_BEFORE_REQUIRE_ALL, dependencies)
dependencies.each do |dep|
required_file = nil
Plugin.hook(Plugin::Events::GEM_BEFORE_REQUIRE, dep)
begin
# Loop through all the specified autorequires for the
@ -76,7 +81,11 @@ module Bundler
end
end
end
Plugin.hook(Plugin::Events::GEM_AFTER_REQUIRE, dep)
end
Plugin.hook(Plugin::Events::GEM_AFTER_REQUIRE_ALL, dependencies)
end
def self.definition_method(meth)

Просмотреть файл

@ -106,4 +106,103 @@ RSpec.describe "hook plugins" do
expect(out).to include "installed gem rack : installed"
end
end
context "before-require-all hook" do
before do
build_repo2 do
build_plugin "before-require-all-plugin" do |s|
s.write "plugins.rb", <<-RUBY
Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_REQUIRE_ALL do |deps|
puts "gems to be required \#{deps.map(&:name).join(", ")}"
end
RUBY
end
end
bundle "plugin install before-require-all-plugin --source #{file_uri_for(gem_repo2)}"
end
it "runs before all rubygems are required" do
install_gemfile_and_bundler_require
expect(out).to include "gems to be required rake, rack"
end
end
context "before-require hook" do
before do
build_repo2 do
build_plugin "before-require-plugin" do |s|
s.write "plugins.rb", <<-RUBY
Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_REQUIRE do |dep|
puts "requiring gem \#{dep.name}"
end
RUBY
end
end
bundle "plugin install before-require-plugin --source #{file_uri_for(gem_repo2)}"
end
it "runs before each rubygem is required" do
install_gemfile_and_bundler_require
expect(out).to include "requiring gem rake"
expect(out).to include "requiring gem rack"
end
end
context "after-require-all hook" do
before do
build_repo2 do
build_plugin "after-require-all-plugin" do |s|
s.write "plugins.rb", <<-RUBY
Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_REQUIRE_ALL do |deps|
puts "required gems \#{deps.map(&:name).join(", ")}"
end
RUBY
end
end
bundle "plugin install after-require-all-plugin --source #{file_uri_for(gem_repo2)}"
end
it "runs after all rubygems are required" do
install_gemfile_and_bundler_require
expect(out).to include "required gems rake, rack"
end
end
context "after-require hook" do
before do
build_repo2 do
build_plugin "after-require-plugin" do |s|
s.write "plugins.rb", <<-RUBY
Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_REQUIRE do |dep|
puts "required gem \#{dep.name}"
end
RUBY
end
end
bundle "plugin install after-require-plugin --source #{file_uri_for(gem_repo2)}"
end
it "runs after each rubygem is required" do
install_gemfile_and_bundler_require
expect(out).to include "required gem rake"
expect(out).to include "required gem rack"
end
end
def install_gemfile_and_bundler_require
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rake"
gem "rack"
G
ruby! <<-RUBY
require "#{lib}/bundler"
Bundler.require
RUBY
end
end