[rubygems/rubygems] Prevent gem activation in standalone mode

As discussed in https://github.com/rubygems/rubygems/issues/6273#issuecomment-1449176658

The `gem` method behaves awkwardly in standalone mode. Assuming bundler
isn't loaded at all, a call to gem might activate a gem that is not part
of the bundle (because it's the gem method defined in
lib/rubygems/core_ext/kernel_gem.rb and not
lib/bundler/rubygems_integration.rb). And when running with
`--disable-gems`, the gem method won't be defined at all so we'll get a
NoMethodError.

Calls to `gem` can appear in dependencies outside an application's
control. To work around this at GitHub we defined our own `Kernel#gem`
that no-ops.

I agree with https://github.com/rubygems/rubygems/issues/6273#issuecomment-1440755882

> people using standalone mode don't want to activate gems like Kernel.gem

This commit redefines `Kernel#gem` in the standalone script to no-op.

https://github.com/rubygems/rubygems/commit/bea17b55f1
This commit is contained in:
Daniel Colson 2023-08-29 08:41:28 -04:00 коммит произвёл git
Родитель 1992aef722
Коммит accda74cbe
2 изменённых файлов: 30 добавлений и 0 удалений

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

@ -12,6 +12,7 @@ module Bundler
end
File.open File.join(bundler_path, "setup.rb"), "w" do |file|
file.puts "require 'rbconfig'"
file.puts prevent_gem_activation
file.puts define_path_helpers
file.puts reverse_rubygems_kernel_mixin
paths.each do |path|
@ -62,6 +63,19 @@ module Bundler
raise Gem::InvalidSpecificationException.new(error_message)
end
def prevent_gem_activation
<<~'END'
module Kernel
remove_method(:gem) if private_method_defined?(:gem)
def gem(*)
end
private :gem
end
END
end
def define_path_helpers
<<~'END'
unless defined?(Gem)

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

@ -101,6 +101,22 @@ RSpec.shared_examples "bundle install --standalone" do
expect(out).to eq(expected_gems.values.join("\n"))
end
it "skips activating gems" do
testrb = String.new <<-RUBY
$:.unshift File.expand_path("bundle")
require "bundler/setup"
gem "do_not_activate_me"
RUBY
expected_gems.each do |k, _|
testrb << "\nrequire \"#{k}\""
testrb << "\nputs #{k.upcase}"
end
sys_exec %(#{Gem.ruby} -w -e #{testrb.shellescape})
expect(out).to eq(expected_gems.values.join("\n"))
end
end
describe "with simple gems" do