summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBundlerbot <bot@bundler.io>2019-04-01 11:23:07 +0000
committerColby Swandale <me@colby.fyi>2019-04-04 22:47:16 +1100
commit9f83d7a92822ea8b23643682a9651249c6420c03 (patch)
tree52caedf74cf192e5675ff81b443eb76a67b240f3
parent79b479c70101444da81f6b7c87bde80f26a0b882 (diff)
downloadbundler-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.rb19
-rw-r--r--spec/commands/exec_spec.rb77
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}"