diff options
Diffstat (limited to 'spec/bundler/commands/exec_spec.rb')
-rw-r--r-- | spec/bundler/commands/exec_spec.rb | 170 |
1 files changed, 124 insertions, 46 deletions
diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb index c6648f0a7a..d59b690d2f 100644 --- a/spec/bundler/commands/exec_spec.rb +++ b/spec/bundler/commands/exec_spec.rb @@ -2,11 +2,10 @@ RSpec.describe "bundle exec" do let(:system_gems_to_install) { %w[rack-1.0.0 rack-0.9.1] } - before :each do - system_gems(system_gems_to_install, :path => default_bundle_path) - end it "works with --gemfile flag" do + system_gems(system_gems_to_install, path: default_bundle_path) + create_file "CustomGemfile", <<-G source "#{file_uri_for(gem_repo1)}" gem "rack", "1.0.0" @@ -17,6 +16,8 @@ RSpec.describe "bundle exec" do end it "activates the correct gem" do + system_gems(system_gems_to_install, path: default_bundle_path) + gemfile <<-G source "#{file_uri_for(gem_repo1)}" gem "rack", "0.9.1" @@ -27,12 +28,14 @@ RSpec.describe "bundle exec" do end it "works and prints no warnings when HOME is not writable" do + system_gems(system_gems_to_install, path: default_bundle_path) + gemfile <<-G source "#{file_uri_for(gem_repo1)}" gem "rack", "0.9.1" G - bundle "exec rackup", :env => { "HOME" => "/" } + bundle "exec rackup", env: { "HOME" => "/" } expect(out).to eq("0.9.1") expect(err).to be_empty end @@ -105,7 +108,7 @@ RSpec.describe "bundle exec" do 2.1.4 L - bundle "exec bundle cache", :env => { "BUNDLER_VERSION" => Bundler::VERSION } + bundle "exec bundle cache", env: { "BUNDLER_VERSION" => Bundler::VERSION } expect(out).to include("Updating files in vendor/cache") end @@ -195,7 +198,7 @@ RSpec.describe "bundle exec" do gem "rack", "0.9.1" G - install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2 + install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2 source "#{file_uri_for(gem_repo2)}" gem "rack_two", "1.0.0" G @@ -204,14 +207,12 @@ RSpec.describe "bundle exec" do expect(out).to eq("0.9.1") - bundle "exec rackup", :dir => bundled_app2 + bundle "exec rackup", dir: bundled_app2 expect(out).to eq("1.0.0") end context "with default gems" do - let(:system_gems_to_install) { [] } - - let(:default_irb_version) { ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", :raise_on_error => false } + let(:default_irb_version) { ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", raise_on_error: false } context "when not specified in Gemfile" do before do @@ -291,14 +292,14 @@ RSpec.describe "bundle exec" do end end - bundle "config set path.system true" + bundle "config set --global path.system true" install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" gem "rack", "0.9.1" G - install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2 + install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2 source "#{file_uri_for(gem_repo2)}" gem "rack_two", "1.0.0" G @@ -343,7 +344,7 @@ RSpec.describe "bundle exec" do bundle "exec 'echo $RUBYOPT'" expect(out.split(" ").count(bundler_setup_opt)).to eq(1) - bundle "exec 'echo $RUBYOPT'", :env => { "RUBYOPT" => rubyopt } + bundle "exec 'echo $RUBYOPT'", env: { "RUBYOPT" => rubyopt } expect(out.split(" ").count(bundler_setup_opt)).to eq(1) end @@ -362,7 +363,7 @@ RSpec.describe "bundle exec" do bundle "exec 'echo $RUBYLIB'" expect(out).to include(rubylib) - bundle "exec 'echo $RUBYLIB'", :env => { "RUBYLIB" => rubylib } + bundle "exec 'echo $RUBYLIB'", env: { "RUBYLIB" => rubylib } expect(out).to include(rubylib) end @@ -372,7 +373,7 @@ RSpec.describe "bundle exec" do gem "rack" G - bundle "exec foobarbaz", :raise_on_error => false + bundle "exec foobarbaz", raise_on_error: false expect(exitstatus).to eq(127) expect(err).to include("bundler: command not found: foobarbaz") expect(err).to include("Install missing gem executables with `bundle install`") @@ -385,7 +386,7 @@ RSpec.describe "bundle exec" do G bundle "exec touch foo" - bundle "exec ./foo", :raise_on_error => false + bundle "exec ./foo", raise_on_error: false expect(exitstatus).to eq(126) expect(err).to include("bundler: not executable: ./foo") end @@ -396,12 +397,14 @@ RSpec.describe "bundle exec" do gem "rack" G - bundle "exec", :raise_on_error => false + bundle "exec", raise_on_error: false expect(exitstatus).to eq(128) expect(err).to include("bundler: exec needs a command to run") end it "raises a helpful error when exec'ing to something outside of the bundle" do + system_gems(system_gems_to_install, path: default_bundle_path) + bundle "config set clean false" # want to keep the rackup binstub install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -409,7 +412,7 @@ RSpec.describe "bundle exec" do G [true, false].each do |l| bundle "config set disable_exec_load #{l}" - bundle "exec rackup", :raise_on_error => false + bundle "exec rackup", raise_on_error: false expect(err).to include "can't find executable rackup for gem rack. rack is not currently included in the bundle, perhaps you meant to add it to your Gemfile?" end end @@ -528,7 +531,7 @@ RSpec.describe "bundle exec" do describe "from gems bundled via :path" do before(:each) do - build_lib "fizz", :path => home("fizz") do |s| + build_lib "fizz", path: home("fizz") do |s| s.executables = "fizz" end @@ -577,7 +580,7 @@ RSpec.describe "bundle exec" do describe "from gems bundled via :git with no gemspec" do before(:each) do - build_git "fizz_no_gemspec", :gemspec => false do |s| + build_git "fizz_no_gemspec", gemspec: false do |s| s.executables = "fizz_no_gemspec" end @@ -612,6 +615,53 @@ RSpec.describe "bundle exec" do expect(out).to include("Installing foo 1.0") end + it "performs an automatic bundle install with git gems" do + build_git "foo" do |s| + s.executables = "foo" + end + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem "rack", "0.9.1" + gem "foo", :git => "#{lib_path("foo-1.0")}" + G + + bundle "config set auto_install 1" + bundle "exec foo" + expect(out).to include("Fetching rack 0.9.1") + expect(out).to include("Fetching #{lib_path("foo-1.0")}") + expect(out.lines).to end_with("1.0") + end + + it "loads the correct optparse when `auto_install` is set, and optparse is a dependency" do + if Gem.rubygems_version < Gem::Version.new("3.3.0.a") + skip "optparse is a default gem, and rubygems loads it during install" + end + + build_repo4 do + build_gem "fastlane", "2.192.0" do |s| + s.executables = "fastlane" + s.add_dependency "optparse", "~> 999.999.999" + end + + build_gem "optparse", "999.999.998" + build_gem "optparse", "999.999.999" + end + + system_gems "optparse-999.999.998", gem_repo: gem_repo4 + + bundle "config set auto_install 1" + bundle "config set --local path vendor/bundle" + + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + gem "fastlane" + G + + bundle "exec fastlane" + expect(out).to include("Installing optparse 999.999.999") + expect(out).to include("2.192.0") + end + describe "with gems bundled via :path with invalid gemspecs" do it "outputs the gemspec validation errors" do build_lib "foo" @@ -633,7 +683,7 @@ RSpec.describe "bundle exec" do gem "foo", :path => "#{lib_path("foo-1.0")}" G - bundle "exec irb", :raise_on_error => false + bundle "exec irb", raise_on_error: false expect(err).to match("The gemspec at #{lib_path("foo-1.0").join("foo.gemspec")} is not valid") expect(err).to match('"TODO" is not a summary') @@ -656,7 +706,7 @@ RSpec.describe "bundle exec" do G bundle "config set path.system true" bundle "install" - bundle "exec ruby -e '`bundle -v`; puts $?.success?'", :env => { "BUNDLER_VERSION" => Bundler::VERSION } + bundle "exec ruby -e '`bundle -v`; puts $?.success?'", env: { "BUNDLER_VERSION" => Bundler::VERSION } expect(out).to match("true") end end @@ -664,7 +714,7 @@ RSpec.describe "bundle exec" do context "`load`ing a ruby file instead of `exec`ing" do let(:path) { bundled_app("ruby_executable") } let(:shebang) { "#!/usr/bin/env ruby" } - let(:executable) { <<-RUBY.gsub(/^ */, "").strip } + let(:executable) { <<~RUBY.strip } #{shebang} require "rack" @@ -676,6 +726,8 @@ RSpec.describe "bundle exec" do RUBY before do + system_gems(system_gems_to_install, path: default_bundle_path) + bundled_app(path).open("w") {|f| f << executable } bundled_app(path).chmod(0o755) @@ -697,7 +749,7 @@ RSpec.describe "bundle exec" do let(:expected) { [exec, args, rack, process].join("\n") } let(:expected_err) { "" } - subject { bundle "exec #{path} arg1 arg2", :raise_on_error => false } + subject { bundle "exec #{path} arg1 arg2", raise_on_error: false } it "runs" do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? @@ -745,9 +797,7 @@ RSpec.describe "bundle exec" do end let(:expected_err) { "" } let(:exit_code) do - # signal mask 128 + plus signal 15 -> TERM - # this is specified by C99 - 128 + 15 + exit_status_for_signal(Signal.list["TERM"]) end it "runs" do @@ -781,8 +831,7 @@ RSpec.describe "bundle exec" do let(:executable) { super() << "\nraise 'ERROR'" } let(:exit_code) { 1 } let(:expected_err) do - "bundler: failed to load command: #{path} (#{path})" \ - "\n#{path}:10:in `<top (required)>': ERROR (RuntimeError)" + /\Abundler: failed to load command: #{Regexp.quote(path.to_s)} \(#{Regexp.quote(path.to_s)}\)\n#{Regexp.quote(path.to_s)}:10:in [`']<top \(required\)>': ERROR \(RuntimeError\)/ end it "runs like a normally executed executable" do @@ -790,7 +839,7 @@ RSpec.describe "bundle exec" do subject expect(exitstatus).to eq(exit_code) - expect(err).to start_with(expected_err) + expect(err).to match(expected_err) expect(out).to eq(expected) end end @@ -824,7 +873,7 @@ RSpec.describe "bundle exec" do end end - context "when Bundler.setup fails", :bundler => "< 3" do + context "when Bundler.setup fails", bundler: "< 3" do before do gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -836,8 +885,11 @@ RSpec.describe "bundle exec" do let(:exit_code) { Bundler::GemNotFound.new.status_code } let(:expected) { "" } let(:expected_err) { <<-EOS.strip } -Could not find gem 'rack (= 2)' in locally installed gems. -The source contains the following versions of 'rack': 0.9.1, 1.0.0 +Could not find gem 'rack (= 2)' in cached gems or installed locally. + +The source contains the following gems matching 'rack': + * rack-0.9.1 + * rack-1.0.0 Run `bundle install` to install missing gems. EOS @@ -851,7 +903,7 @@ Run `bundle install` to install missing gems. end end - context "when Bundler.setup fails", :bundler => "3" do + context "when Bundler.setup fails", bundler: "3" do before do gemfile <<-G source "#{file_uri_for(gem_repo1)}" @@ -863,8 +915,10 @@ Run `bundle install` to install missing gems. let(:exit_code) { Bundler::GemNotFound.new.status_code } let(:expected) { "" } let(:expected_err) { <<-EOS.strip } -Could not find gem 'rack (= 2)' in locally installed gems. -The source contains the following versions of 'rack': 1.0.0 +Could not find gem 'rack (= 2)' in cached gems or installed locally. + +The source contains the following gems matching 'rack': + * rack-1.0.0 Run `bundle install` to install missing gems. EOS @@ -878,6 +932,30 @@ Run `bundle install` to install missing gems. end end + context "when Bundler.setup fails and Gemfile is not the default" do + before do + create_file "CustomGemfile", <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'rack', '2' + G + ENV["BUNDLER_FORCE_TTY"] = "true" + ENV["BUNDLE_GEMFILE"] = "CustomGemfile" + ENV["BUNDLER_ORIG_BUNDLE_GEMFILE"] = nil + end + + let(:exit_code) { Bundler::GemNotFound.new.status_code } + let(:expected) { "" } + + it "prints proper suggestion" do + skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? + + subject + expect(exitstatus).to eq(exit_code) + expect(err).to include("Run `bundle install --gemfile CustomGemfile` to install missing gems.") + expect(out).to eq(expected) + end + end + context "when the executable exits non-zero via at_exit" do let(:executable) { super() + "\n\nat_exit { $! ? raise($!) : exit(1) }" } let(:exit_code) { 1 } @@ -962,7 +1040,7 @@ __FILE__: #{path.to_s.inspect} end context "signals being trapped by bundler" do - let(:executable) { strip_whitespace <<-RUBY } + let(:executable) { <<~RUBY } #{shebang} begin Thread.new do @@ -989,7 +1067,7 @@ __FILE__: #{path.to_s.inspect} end context "signals not being trapped by bunder" do - let(:executable) { strip_whitespace <<-RUBY } + let(:executable) { <<~RUBY } #{shebang} signals = #{test_signals.inspect} @@ -1034,7 +1112,7 @@ __FILE__: #{path.to_s.inspect} puts `bundle exec echo foo` RUBY file.chmod(0o777) - bundle "exec #{file}", :env => { "PATH" => path } + bundle "exec #{file}", env: { "PATH" => path } expect(out).to eq("foo") end end @@ -1127,7 +1205,7 @@ __FILE__: #{path.to_s.inspect} context "with a system gem that shadows a default gem" do let(:openssl_version) { "99.9.9" } - let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", :artifice => nil, :raise_on_error => false } + let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", artifice: nil, raise_on_error: false } it "only leaves the default gem in the stdlib available" do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? @@ -1143,7 +1221,7 @@ __FILE__: #{path.to_s.inspect} end end - system_gems("openssl-#{openssl_version}", :gem_repo => gem_repo4) + system_gems("openssl-#{openssl_version}", gem_repo: gem_repo4) file = bundled_app("require_openssl.rb") create_file(file, <<-RUBY) @@ -1156,15 +1234,15 @@ __FILE__: #{path.to_s.inspect} env = { "PATH" => path } aggregate_failures do - expect(bundle("exec #{file}", :artifice => nil, :env => env)).to eq(expected) - expect(bundle("exec bundle exec #{file}", :artifice => nil, :env => env)).to eq(expected) - expect(bundle("exec ruby #{file}", :artifice => nil, :env => env)).to eq(expected) - expect(run(file.read, :artifice => nil, :env => env)).to eq(expected) + expect(bundle("exec #{file}", artifice: nil, env: env)).to eq(expected) + expect(bundle("exec bundle exec #{file}", artifice: nil, env: env)).to eq(expected) + expect(bundle("exec ruby #{file}", artifice: nil, env: env)).to eq(expected) + expect(run(file.read, artifice: nil, env: env)).to eq(expected) end skip "ruby_core has openssl and rubygems in the same folder, and this test needs rubygems require but default openssl not in a directly added entry in $LOAD_PATH" if ruby_core? # sanity check that we get the newer, custom version without bundler - sys_exec "#{Gem.ruby} #{file}", :env => env, :raise_on_error => false + sys_exec "#{Gem.ruby} #{file}", env: env, raise_on_error: false expect(err).to include("custom openssl should not be loaded") end end |