summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBundlerbot <bot@bundler.io>2019-04-01 11:23:07 +0000
committerBundlerbot <bot@bundler.io>2019-04-01 11:23:07 +0000
commit3b6c6e35b36fc056ec3610f9f22f1cea2ef0b06f (patch)
treead57b45e759f910a2f27e3663795d5651b7b591b
parent61a56579cb6232fc02967ea2264b623ee64f16c6 (diff)
parent1239c8c7818e067502e2df2b300be948d385d173 (diff)
downloadbundler-3b6c6e35b36fc056ec3610f9f22f1cea2ef0b06f.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>
-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 c1d785a6e1..79ff277bbe 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -512,6 +512,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)
@@ -848,6 +857,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 f5575c34f6..35b5eaea00 100644
--- a/spec/commands/exec_spec.rb
+++ b/spec/commands/exec_spec.rb
@@ -140,6 +140,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}"