diff options
author | Bundlerbot <bot@bundler.io> | 2019-04-01 11:23:07 +0000 |
---|---|---|
committer | Colby Swandale <me@colby.fyi> | 2019-04-04 22:47:16 +1100 |
commit | 9f83d7a92822ea8b23643682a9651249c6420c03 (patch) | |
tree | 52caedf74cf192e5675ff81b443eb76a67b240f3 | |
parent | 79b479c70101444da81f6b7c87bde80f26a0b882 (diff) | |
download | bundler-9f83d7a92822ea8b23643682a9651249c6420c03.tar.gz |
Merge #6963
6963: Allow to `bundle exec` default gems r=deivid-rodriguez a=deivid-rodriguez
### What was the end-user problem that led to this PR?
The problem was that since `irb` and others were moved to default gems, users cannot directly use them in a bundler context, unless they add it to their gemfiles. In my opinion, this completely defeats the purpose of default gems, and makes bundler degrade the user experience instead of making it better.
### What was your diagnosis of the problem?
My diagnosis was that when bundler replaces the set of gems known to rubygems, it restricts the world to what's in the Gemfile (or resolved from it), and that doesn't include default gems.
### What is your fix for the problem, implemented in this PR?
My fix is to also include the set of default gems, unless they are already included in the gemfile dependencies.
### Why did you choose this fix out of the possible options?
I chose this fix because it's reasonably simple and I think it shouldn't affect how other parts of bundler function.
Fixes #6929.
Fixes https://bugs.ruby-lang.org/issues/15503.
Co-authored-by: David RodrÃguez <deivid.rodriguez@riseup.net>
(cherry picked from commit 3b6c6e35b36fc056ec3610f9f22f1cea2ef0b06f)
-rw-r--r-- | lib/bundler/rubygems_integration.rb | 19 | ||||
-rw-r--r-- | spec/commands/exec_spec.rb | 77 |
2 files changed, 96 insertions, 0 deletions
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index a7d3368288..0209045fa1 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -513,6 +513,15 @@ module Bundler h end + Bundler.rubygems.default_stubs.each do |stub| + default_spec = stub.to_spec + default_spec_name = default_spec.name + next if specs_by_name.key?(default_spec_name) + + specs << default_spec + specs_by_name[default_spec_name] = default_spec + end + replace_gem(specs, specs_by_name) stub_rubygems(specs) replace_bin_path(specs, specs_by_name) @@ -849,6 +858,16 @@ module Bundler end end + if Gem::Specification.respond_to?(:default_stubs) + def default_stubs + Gem::Specification.default_stubs("*.gemspec") + end + else + def default_stubs + Gem::Specification.send(:default_stubs, "*.gemspec") + end + end + def use_gemdeps(gemfile) ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile) require "bundler/gemdeps" diff --git a/spec/commands/exec_spec.rb b/spec/commands/exec_spec.rb index 2e3cb6621e..67bdc97ac3 100644 --- a/spec/commands/exec_spec.rb +++ b/spec/commands/exec_spec.rb @@ -147,6 +147,83 @@ RSpec.describe "bundle exec" do end end + context "with default gems" do + let(:system_gems_to_install) { [] } + + let(:default_irb_version) { ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION" } + + context "when not specified in Gemfile" do + before do + skip "irb isn't a default gem" if default_irb_version.empty? + + install_gemfile "" + end + + it "uses version provided by ruby" do + bundle! "exec irb --version" + + expect(out).to include(default_irb_version) + expect(last_command.stderr).to be_empty + end + end + + context "when specified in Gemfile directly" do + let(:specified_irb_version) { "0.9.6" } + + before do + skip "irb isn't a default gem" if default_irb_version.empty? + + build_repo2 do + build_gem "irb", specified_irb_version do |s| + s.executables = "irb" + end + end + + install_gemfile <<-G + source "file://#{gem_repo2}" + gem "irb", "#{specified_irb_version}" + G + end + + it "uses version specified" do + bundle! "exec irb --version" + + expect(out).to include(specified_irb_version) + expect(last_command.stderr).to be_empty + end + end + + context "when specified in Gemfile indirectly" do + let(:indirect_irb_version) { "0.9.6" } + + before do + skip "irb isn't a default gem" if default_irb_version.empty? + + build_repo2 do + build_gem "irb", indirect_irb_version do |s| + s.executables = "irb" + end + + build_gem "gem_depending_on_old_irb" do |s| + s.add_dependency "irb", indirect_irb_version + end + end + + install_gemfile <<-G + source "file://#{gem_repo2}" + gem "gem_depending_on_old_irb" + G + + bundle! "exec irb --version" + end + + it "uses resolved version" do + expect(out).to include(indirect_irb_version) + expect(last_command.stderr).to be_empty + end + end + end + it "handles gems installed with --without" do install_gemfile <<-G, forgotten_command_line_options(:without => "middleware") source "file://#{gem_repo1}" |