summaryrefslogtreecommitdiff
path: root/spec/bundler/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'spec/bundler/runtime')
-rw-r--r--spec/bundler/runtime/env_helpers_spec.rb (renamed from spec/bundler/runtime/with_unbundled_env_spec.rb)110
-rw-r--r--spec/bundler/runtime/executable_spec.rb52
-rw-r--r--spec/bundler/runtime/gem_tasks_spec.rb74
-rw-r--r--spec/bundler/runtime/inline_spec.rb167
-rw-r--r--spec/bundler/runtime/load_spec.rb2
-rw-r--r--spec/bundler/runtime/platform_spec.rb42
-rw-r--r--spec/bundler/runtime/require_spec.rb69
-rw-r--r--spec/bundler/runtime/requiring_spec.rb8
-rw-r--r--spec/bundler/runtime/self_management_spec.rb152
-rw-r--r--spec/bundler/runtime/setup_spec.rb197
10 files changed, 529 insertions, 344 deletions
diff --git a/spec/bundler/runtime/with_unbundled_env_spec.rb b/spec/bundler/runtime/env_helpers_spec.rb
index 8c3582f7ac..c4ebdd1fd2 100644
--- a/spec/bundler/runtime/with_unbundled_env_spec.rb
+++ b/spec/bundler/runtime/env_helpers_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "Bundler.with_env helpers" do
+RSpec.describe "env helpers" do
def bundle_exec_ruby(args, options = {})
build_bundler_context options.dup
bundle "exec '#{Gem.ruby}' #{args}", options
@@ -24,7 +24,7 @@ RSpec.describe "Bundler.with_env helpers" do
path = `getconf PATH`.strip + "#{File::PATH_SEPARATOR}/foo"
with_path_as(path) do
bundle_exec_ruby(bundled_app("source.rb").to_s)
- expect(last_command.stdboth).to eq(path)
+ expect(stdboth).to eq(path)
end
end
@@ -35,7 +35,7 @@ RSpec.describe "Bundler.with_env helpers" do
gem_path = ENV["GEM_PATH"] + "#{File::PATH_SEPARATOR}/foo"
with_gem_path_as(gem_path) do
bundle_exec_ruby(bundled_app("source.rb").to_s)
- expect(last_command.stdboth).to eq(gem_path)
+ expect(stdboth).to eq(gem_path)
end
end
@@ -62,9 +62,6 @@ RSpec.describe "Bundler.with_env helpers" do
end
it "removes variables that bundler added", :ruby_repo do
- # Simulate bundler has not yet been loaded
- ENV.replace(ENV.to_hash.delete_if {|k, _v| k.start_with?(Bundler::EnvironmentPreserver::BUNDLER_PREFIX) })
-
original = ruby('puts ENV.to_a.map {|e| e.join("=") }.sort.join("\n")', artifice: "fail")
create_file("source.rb", <<-RUBY)
puts Bundler.original_env.to_a.map {|e| e.join("=") }.sort.join("\n")
@@ -74,68 +71,65 @@ RSpec.describe "Bundler.with_env helpers" do
end
end
- shared_examples_for "an unbundling helper" do
+ describe "Bundler.unbundled_env" do
it "should delete BUNDLE_PATH" do
create_file("source.rb", <<-RUBY)
- print #{modified_env}.has_key?('BUNDLE_PATH')
+ print Bundler.unbundled_env.has_key?('BUNDLE_PATH')
RUBY
ENV["BUNDLE_PATH"] = "./foo"
bundle_exec_ruby bundled_app("source.rb")
- expect(last_command.stdboth).to include "false"
+ expect(stdboth).to include "false"
end
it "should remove absolute path to 'bundler/setup' from RUBYOPT even if it was present in original env" do
create_file("source.rb", <<-RUBY)
- print #{modified_env}['RUBYOPT']
+ print Bundler.unbundled_env['RUBYOPT']
RUBY
setup_require = "-r#{lib_dir}/bundler/setup"
ENV["BUNDLER_ORIG_RUBYOPT"] = "-W2 #{setup_require} #{ENV["RUBYOPT"]}"
bundle_exec_ruby bundled_app("source.rb")
- expect(last_command.stdboth).not_to include(setup_require)
+ expect(stdboth).not_to include(setup_require)
end
it "should remove relative path to 'bundler/setup' from RUBYOPT even if it was present in original env" do
create_file("source.rb", <<-RUBY)
- print #{modified_env}['RUBYOPT']
+ print Bundler.unbundled_env['RUBYOPT']
RUBY
ENV["BUNDLER_ORIG_RUBYOPT"] = "-W2 -rbundler/setup #{ENV["RUBYOPT"]}"
bundle_exec_ruby bundled_app("source.rb")
- expect(last_command.stdboth).not_to include("-rbundler/setup")
+ expect(stdboth).not_to include("-rbundler/setup")
+ end
+
+ it "should delete BUNDLER_SETUP even if it was present in original env" do
+ create_file("source.rb", <<-RUBY)
+ print Bundler.unbundled_env.has_key?('BUNDLER_SETUP')
+ RUBY
+ ENV["BUNDLER_ORIG_BUNDLER_SETUP"] = system_gem_path("gems/bundler-#{Bundler::VERSION}/lib/bundler/setup").to_s
+ bundle_exec_ruby bundled_app("source.rb")
+ expect(stdboth).to include "false"
end
it "should restore RUBYLIB", :ruby_repo do
create_file("source.rb", <<-RUBY)
- print #{modified_env}['RUBYLIB']
+ print Bundler.unbundled_env['RUBYLIB']
RUBY
ENV["RUBYLIB"] = lib_dir.to_s + File::PATH_SEPARATOR + "/foo"
ENV["BUNDLER_ORIG_RUBYLIB"] = lib_dir.to_s + File::PATH_SEPARATOR + "/foo-original"
bundle_exec_ruby bundled_app("source.rb")
- expect(last_command.stdboth).to include("/foo-original")
+ expect(stdboth).to include("/foo-original")
end
it "should restore the original MANPATH" do
create_file("source.rb", <<-RUBY)
- print #{modified_env}['MANPATH']
+ print Bundler.unbundled_env['MANPATH']
RUBY
ENV["MANPATH"] = "/foo"
ENV["BUNDLER_ORIG_MANPATH"] = "/foo-original"
bundle_exec_ruby bundled_app("source.rb")
- expect(last_command.stdboth).to include("/foo-original")
+ expect(stdboth).to include("/foo-original")
end
end
- describe "Bundler.unbundled_env" do
- let(:modified_env) { "Bundler.unbundled_env" }
-
- it_behaves_like "an unbundling helper"
- end
-
- describe "Bundler.clean_env", bundler: 2 do
- let(:modified_env) { "Bundler.clean_env" }
-
- it_behaves_like "an unbundling helper"
- end
-
describe "Bundler.with_original_env" do
it "should set ENV to original_env in the block" do
expected = Bundler.original_env
@@ -152,26 +146,6 @@ RSpec.describe "Bundler.with_env helpers" do
end
end
- describe "Bundler.with_clean_env", bundler: 2 do
- it "should set ENV to unbundled_env in the block" do
- expected = Bundler.unbundled_env
-
- actual = Bundler.ui.silence do
- Bundler.with_clean_env { ENV.to_hash }
- end
-
- expect(actual).to eq(expected)
- end
-
- it "should restore the environment after execution" do
- Bundler.ui.silence do
- Bundler.with_clean_env { ENV["FOO"] = "hello" }
- end
-
- expect(ENV).not_to have_key("FOO")
- end
- end
-
describe "Bundler.with_unbundled_env" do
it "should set ENV to unbundled_env in the block" do
expected = Bundler.unbundled_env
@@ -203,21 +177,6 @@ RSpec.describe "Bundler.with_env helpers" do
end
end
- describe "Bundler.clean_system", bundler: 2 do
- before do
- create_file("source.rb", <<-'RUBY')
- Bundler.ui.silence { Bundler.clean_system("ruby", "-e", "exit(42) unless ENV['BUNDLE_FOO'] == 'bar'") }
-
- exit $?.exitstatus
- RUBY
- end
-
- it "runs system inside with_clean_env" do
- run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
- expect($?.exitstatus).to eq(42)
- end
- end
-
describe "Bundler.unbundled_system" do
before do
create_file("source.rb", <<-'RUBY')
@@ -254,27 +213,6 @@ RSpec.describe "Bundler.with_env helpers" do
end
end
- describe "Bundler.clean_exec", bundler: 2 do
- before do
- create_file("source.rb", <<-'RUBY')
- Process.fork do
- exit Bundler.ui.silence { Bundler.clean_exec(%(test "\$BUNDLE_FOO" = "bar")) }
- end
-
- _, status = Process.wait2
-
- exit(status.exitstatus)
- RUBY
- end
-
- it "runs exec inside with_clean_env" do
- skip "Fork not implemented" if Gem.win_platform?
-
- run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
- expect($?.exitstatus).to eq(1)
- end
- end
-
describe "Bundler.unbundled_exec" do
before do
create_file("source.rb", <<-'RUBY')
@@ -288,7 +226,7 @@ RSpec.describe "Bundler.with_env helpers" do
RUBY
end
- it "runs exec inside with_clean_env" do
+ it "runs exec inside with_unbundled_env" do
skip "Fork not implemented" if Gem.win_platform?
run_bundler_script({ "BUNDLE_FOO" => "bar" }, bundled_app("source.rb"))
diff --git a/spec/bundler/runtime/executable_spec.rb b/spec/bundler/runtime/executable_spec.rb
index b11c48539a..89cee21b00 100644
--- a/spec/bundler/runtime/executable_spec.rb
+++ b/spec/bundler/runtime/executable_spec.rb
@@ -19,8 +19,9 @@ RSpec.describe "Running bin/* commands" do
expect(out).to eq("1.0.0")
end
- it "allows the location of the gem stubs to be specified" do
- bundle "binstubs myrack", path: "gbin"
+ it "allows the location of the gem stubs to be configured" do
+ bundle_config "bin gbin"
+ bundle "binstubs myrack"
expect(bundled_app("bin")).not_to exist
expect(bundled_app("gbin/myrackup")).to exist
@@ -30,7 +31,8 @@ RSpec.describe "Running bin/* commands" do
end
it "allows absolute paths as a specification of where to install bin stubs" do
- bundle "binstubs myrack", path: tmp("bin")
+ bundle_config "bin #{tmp("bin")}"
+ bundle "binstubs myrack"
gembin tmp("bin/myrackup")
expect(out).to eq("1.0.0")
@@ -77,7 +79,7 @@ RSpec.describe "Running bin/* commands" do
expect(out).to eq("1.0")
end
- it "creates a bundle binstub" do
+ it "does not create a bundle binstub" do
gemfile <<-G
source "https://gem.repo1"
gem "bundler"
@@ -85,7 +87,9 @@ RSpec.describe "Running bin/* commands" do
bundle "binstubs bundler"
- expect(bundled_app("bin/bundle")).to exist
+ expect(bundled_app("bin/bundle")).not_to exist
+
+ expect(err).to include("Bundler itself does not use binstubs because its version is selected by RubyGems")
end
it "does not generate bin stubs if the option was not specified" do
@@ -94,39 +98,7 @@ RSpec.describe "Running bin/* commands" do
expect(bundled_app("bin/myrackup")).not_to exist
end
- it "allows you to stop installing binstubs", bundler: "< 3" do
- skip "delete permission error" if Gem.win_platform?
-
- bundle "install --binstubs bin/"
- bundled_app("bin/myrackup").rmtree
- bundle "install --binstubs \"\""
-
- expect(bundled_app("bin/myrackup")).not_to exist
-
- bundle "config bin"
- expect(out).to include("You have not configured a value for `bin`")
- end
-
- it "remembers that the option was specified", bundler: "< 3" do
- gemfile <<-G
- source "https://gem.repo1"
- gem "activesupport"
- G
-
- bundle :install, binstubs: "bin"
-
- gemfile <<-G
- source "https://gem.repo1"
- gem "activesupport"
- gem "myrack"
- G
-
- bundle "install"
-
- expect(bundled_app("bin/myrackup")).to exist
- end
-
- it "rewrites bins on binstubs (to maintain backwards compatibility)" do
+ it "rewrites bins on binstubs with --force option" do
install_gemfile <<-G
source "https://gem.repo1"
gem "myrack"
@@ -134,9 +106,9 @@ RSpec.describe "Running bin/* commands" do
create_file("bin/myrackup", "OMG")
- bundle "binstubs myrack"
+ bundle "binstubs myrack", { force: true }
- expect(bundled_app("bin/myrackup").read).to_not eq("OMG")
+ expect(bundled_app("bin/myrackup").read.strip).to_not eq("OMG")
end
it "use BUNDLE_GEMFILE gemfile for binstub" do
diff --git a/spec/bundler/runtime/gem_tasks_spec.rb b/spec/bundler/runtime/gem_tasks_spec.rb
index 1dffbd5c92..b855142e60 100644
--- a/spec/bundler/runtime/gem_tasks_spec.rb
+++ b/spec/bundler/runtime/gem_tasks_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe "require 'bundler/gem_tasks'" do
- before :each do
+ let(:define_local_gem_using_gem_tasks) do
bundled_app("foo.gemspec").open("w") do |f|
f.write <<-GEMSPEC
Gem::Specification.new do |s|
@@ -26,11 +26,48 @@ RSpec.describe "require 'bundler/gem_tasks'" do
G
end
- it "includes the relevant tasks" do
- with_gem_path_as(base_system_gem_path.to_s) do
- sys_exec "#{rake} -T", env: { "GEM_HOME" => system_gem_path.to_s }
+ let(:define_local_gem_with_extensions_using_gem_tasks_and_gemspec_dsl) do
+ bundled_app("foo.gemspec").open("w") do |f|
+ f.write <<-GEMSPEC
+ Gem::Specification.new do |s|
+ s.name = "foo"
+ s.version = "1.0"
+ s.summary = "dummy"
+ s.author = "Perry Mason"
+ s.extensions = "ext/extconf.rb"
+ end
+ GEMSPEC
+ end
+
+ bundled_app("Rakefile").open("w") do |f|
+ f.write <<-RAKEFILE
+ require "bundler/gem_tasks"
+ RAKEFILE
end
+ Dir.mkdir bundled_app("ext")
+
+ bundled_app("ext/extconf.rb").open("w") do |f|
+ f.write <<-EXTCONF
+ require "mkmf"
+ File.write("Makefile", dummy_makefile($srcdir).join)
+ EXTCONF
+ end
+
+ install_gemfile <<-G
+ source "https://gem.repo1"
+
+ gemspec
+
+ gem "rake"
+ G
+ end
+
+ it "includes the relevant tasks" do
+ define_local_gem_using_gem_tasks
+
+ in_bundled_app "rake -T"
+
expect(err).to be_empty
expected_tasks = [
"rake build",
@@ -44,11 +81,19 @@ RSpec.describe "require 'bundler/gem_tasks'" do
end
it "defines a working `rake install` task", :ruby_repo do
- with_gem_path_as(base_system_gem_path.to_s) do
- sys_exec "#{rake} install", env: { "GEM_HOME" => system_gem_path.to_s }
- end
+ define_local_gem_using_gem_tasks
+
+ in_bundled_app "rake install"
+
+ expect(err).to be_empty
+
+ bundle "exec rake install"
expect(err).to be_empty
+ end
+
+ it "defines a working `rake install` task for local gems with extensions", :ruby_repo do
+ define_local_gem_with_extensions_using_gem_tasks_and_gemspec_dsl
bundle "exec rake install"
@@ -57,6 +102,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do
context "rake build when path has spaces", :ruby_repo do
before do
+ define_local_gem_using_gem_tasks
+
spaced_bundled_app = tmp("bundled app")
FileUtils.cp_r bundled_app, spaced_bundled_app
bundle "exec rake build", dir: spaced_bundled_app
@@ -69,6 +116,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do
context "rake build when path has brackets", :ruby_repo do
before do
+ define_local_gem_using_gem_tasks
+
bracketed_bundled_app = tmp("bundled[app")
FileUtils.cp_r bundled_app, bracketed_bundled_app
bundle "exec rake build", dir: bracketed_bundled_app
@@ -81,7 +130,9 @@ RSpec.describe "require 'bundler/gem_tasks'" do
context "bundle path configured locally" do
before do
- bundle "config set path vendor/bundle"
+ define_local_gem_using_gem_tasks
+
+ bundle_config "path vendor/bundle"
end
it "works", :ruby_repo do
@@ -98,9 +149,10 @@ RSpec.describe "require 'bundler/gem_tasks'" do
end
it "adds 'pkg' to rake/clean's CLOBBER" do
- with_gem_path_as(base_system_gem_path.to_s) do
- sys_exec %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect'), env: { "GEM_HOME" => system_gem_path.to_s }
- end
+ define_local_gem_using_gem_tasks
+
+ in_bundled_app %(rake -e 'load "Rakefile"; puts CLOBBER.inspect')
+
expect(out).to eq '["pkg"]'
end
end
diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb
index f85eaf132d..c6f9bbdbd7 100644
--- a/spec/bundler/runtime/inline_spec.rb
+++ b/spec/bundler/runtime/inline_spec.rb
@@ -81,7 +81,7 @@ RSpec.describe "bundler/inline#gemfile" do
script <<-RUBY, artifice: "endpoint"
gemfile(true) do
- source "https://notaserver.com"
+ source "https://notaserver.test"
gem "activesupport", :require => true
end
RUBY
@@ -103,7 +103,7 @@ RSpec.describe "bundler/inline#gemfile" do
my_ui = MyBundlerUI.new
my_ui.level = "confirm"
gemfile(true, :ui => my_ui) do
- source "https://notaserver.com"
+ source "https://notaserver.test"
gem "activesupport", :require => true
end
RUBY
@@ -116,7 +116,7 @@ RSpec.describe "bundler/inline#gemfile" do
require 'bundler/inline'
gemfile(true, :quiet => true) do
- source "https://notaserver.com"
+ source "https://notaserver.test"
gem "activesupport", :require => true
end
RUBY
@@ -363,7 +363,7 @@ RSpec.describe "bundler/inline#gemfile" do
it "installs inline gems when a Gemfile.lock is present" do
gemfile <<-G
- source "https://notaserver.com"
+ source "https://notaserver.test"
gem "rake"
G
@@ -380,7 +380,7 @@ RSpec.describe "bundler/inline#gemfile" do
rake
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
G
script <<-RUBY
@@ -397,7 +397,7 @@ RSpec.describe "bundler/inline#gemfile" do
it "does not leak Gemfile.lock versions to the installation output" do
gemfile <<-G
- source "https://notaserver.com"
+ source "https://notaserver.test"
gem "rake"
G
@@ -414,7 +414,7 @@ RSpec.describe "bundler/inline#gemfile" do
rake
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
G
script <<-RUBY
@@ -499,7 +499,7 @@ RSpec.describe "bundler/inline#gemfile" do
end
it "skips platform warnings" do
- bundle "config set --local force_ruby_platform true"
+ bundle_config "force_ruby_platform true"
script <<-RUBY
gemfile(true) do
@@ -512,7 +512,7 @@ RSpec.describe "bundler/inline#gemfile" do
end
it "still installs if the application has `bundle package` no_install config set" do
- bundle "config set --local no_install true"
+ bundle_config "no_install true"
script <<-RUBY
gemfile do
@@ -590,37 +590,10 @@ RSpec.describe "bundler/inline#gemfile" do
expect(err).to be_empty
end
- it "when requiring fileutils after does not show redefinition warnings" do
- Dir.mkdir tmp("path_without_gemfile")
-
- default_fileutils_version = ruby "gem 'fileutils', '< 999999'; require 'fileutils'; puts FileUtils::VERSION", raise_on_error: false
- skip "fileutils isn't a default gem" if default_fileutils_version.empty?
-
- realworld_system_gems "fileutils --version 1.4.1"
-
- realworld_system_gems "pathname --version 0.2.0"
-
- script <<-RUBY, dir: tmp("path_without_gemfile"), env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s, "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
- require "bundler/inline"
-
- gemfile(true) do
- source "https://gem.repo2"
- end
-
- require "fileutils"
- RUBY
-
- expect(err).to eq("The Gemfile specifies no dependencies")
- end
-
- it "does not load default timeout" do
+ it "does not load default timeout", rubygems: ">= 3.5.0" do
default_timeout_version = ruby "gem 'timeout', '< 999999'; require 'timeout'; puts Timeout::VERSION", raise_on_error: false
skip "timeout isn't a default gem" if default_timeout_version.empty?
- # This only works on RubyGems 3.5.0 or higher
- ruby "require 'rubygems/timeout'", raise_on_error: false
- skip "rubygems under test does not yet vendor timeout" unless last_command.success?
-
build_repo4 do
build_gem "timeout", "999"
end
@@ -655,4 +628,124 @@ RSpec.describe "bundler/inline#gemfile" do
expect(out).to include("before: [\"Test_Variable\"]")
expect(out).to include("after: [\"Test_Variable\"]")
end
+
+ it "does not create a lockfile" do
+ script <<-RUBY
+ require 'bundler/inline'
+
+ gemfile do
+ source "https://gem.repo1"
+ end
+
+ puts Dir.glob("Gemfile.lock")
+ RUBY
+
+ expect(out).to be_empty
+ end
+
+ it "does not reset ENV" do
+ script <<-RUBY
+ require 'bundler/inline'
+
+ gemfile do
+ source "https://gem.repo1"
+
+ ENV['FOO'] = 'bar'
+ end
+
+ puts ENV['FOO']
+ RUBY
+
+ expect(out).to eq("bar")
+ end
+
+ it "does not load specified version of psych and stringio", :ruby_repo do
+ build_repo4 do
+ build_gem "psych", "999"
+ build_gem "stringio", "999"
+ end
+
+ script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ require "bundler/inline"
+
+ gemfile(true) do
+ source "https://gem.repo4"
+
+ gem "psych"
+ gem "stringio"
+ end
+ RUBY
+
+ expect(out).to include("Installing psych 999")
+ expect(out).to include("Installing stringio 999")
+ if Gem.respond_to?(:use_psych?) && Gem.use_psych?
+ expect(out).to include("The psych gem was resolved to 999")
+ expect(out).to include("The stringio gem was resolved to 999")
+ end
+ end
+
+ it "installs a conflicting default gem and non-default gems together" do
+ build_repo4 do
+ build_gem "securerandom", "999"
+ build_gem "myrack", "1.0.0"
+ end
+
+ script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ gemfile(true) do
+ source "https://gem.repo4"
+ gem "securerandom"
+ gem "myrack"
+ end
+
+ puts MYRACK
+ RUBY
+
+ expect(out).to include("Installing securerandom 999")
+ expect(out).to include("Installing myrack 1.0.0")
+ expect(out).to include("1.0.0")
+ expect(err).to be_empty
+ end
+
+ it "installs a conflicting default gem alongside git sources" do
+ build_repo4 do
+ build_gem "securerandom", "999"
+ end
+
+ build_git "foo", "1.0.0"
+
+ script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ gemfile(true) do
+ source "https://gem.repo4"
+ gem "securerandom"
+ gem "foo", :git => #{lib_path("foo-1.0.0").to_s.dump}
+ end
+
+ puts FOO
+ RUBY
+
+ expect(out).to include("Installing securerandom 999")
+ expect(out).to include("1.0.0")
+ expect(err).to be_empty
+ end
+
+ it "leaves a lockfile in the same directory as the inline script alone" do
+ install_gemfile <<~G
+ source "https://gem.repo1"
+ gem "foo"
+ G
+
+ original_lockfile = lockfile
+
+ script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
+ require "bundler/inline"
+
+ gemfile(true) do
+ source "https://gem.repo1"
+
+ gem "myrack"
+ end
+ RUBY
+
+ expect(lockfile).to eq(original_lockfile)
+ end
end
diff --git a/spec/bundler/runtime/load_spec.rb b/spec/bundler/runtime/load_spec.rb
index 15f3d0eb5b..472cde87c5 100644
--- a/spec/bundler/runtime/load_spec.rb
+++ b/spec/bundler/runtime/load_spec.rb
@@ -68,7 +68,7 @@ RSpec.describe "Bundler.load" do
begin
expect { Bundler.load }.to raise_error(Bundler::GemfileNotFound)
ensure
- bundler_gemfile.rmtree if @remove_bundler_gemfile
+ FileUtils.rm_rf bundler_gemfile if @remove_bundler_gemfile
end
end
end
diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb
index 007733d3de..6d96758956 100644
--- a/spec/bundler/runtime/platform_spec.rb
+++ b/spec/bundler/runtime/platform_spec.rb
@@ -100,7 +100,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
nokogiri (~> 1.11)
#{checksums}
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
L
gemfile <<-G
@@ -143,7 +143,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
nokogiri
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
L
bundle "install"
@@ -219,7 +219,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
gem "platform_specific"
G
- bundle "config set force_ruby_platform true"
+ bundle_config "force_ruby_platform true"
bundle "install"
@@ -233,7 +233,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
gem "platform_specific"
G
- bundle "config set force_ruby_platform true"
+ bundle_config "force_ruby_platform true"
bundle "install"
@@ -247,7 +247,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
gem "platform_specific"
G
- bundle "config set force_ruby_platform true"
+ bundle_config "force_ruby_platform true"
bundle "install"
@@ -282,7 +282,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
platform_specific
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
L
bundle "install"
@@ -316,7 +316,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
libv8
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
L
bundle "install"
@@ -344,7 +344,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
platform_specific
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
L
bundle "install"
@@ -370,14 +370,14 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
end
it "allows specifying only-ruby-platform on windows with dependency platforms" do
- simulate_windows do
+ simulate_platform "x86-mswin32" do
install_gemfile <<-G
source "https://gem.repo1"
- gem "nokogiri", :platforms => [:windows, :mswin, :mswin64, :mingw, :x64_mingw, :jruby]
+ gem "nokogiri", :platforms => [:windows, :jruby]
gem "platform_specific"
G
- bundle "config set force_ruby_platform true"
+ bundle_config "force_ruby_platform true"
bundle "install"
@@ -397,8 +397,8 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
G
bundle :lock
- simulate_windows do
- bundle "config set force_ruby_platform true"
+ simulate_platform "x86-mswin32" do
+ bundle_config "force_ruby_platform true"
bundle "install"
expect(the_bundle).to include_gems "myrack 1.0"
@@ -411,7 +411,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
s.add_dependency "platform_specific"
end
end
- simulate_windows x64_mingw32 do
+ simulate_platform "x64-mingw-ucrt" do
lockfile <<-L
GEM
remote: https://gem.repo2/
@@ -421,7 +421,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
platform_specific
PLATFORMS
- x64-mingw32
+ x64-mingw-ucrt
x86-mingw32
DEPENDENCIES
@@ -434,15 +434,13 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
G
expect(out).to include("lockfile does not have all gems needed for the current platform")
- expect(the_bundle).to include_gem "platform_specific 1.0 x64-mingw32"
+ expect(the_bundle).to include_gem "platform_specific 1.0 x64-mingw-ucrt"
end
end
- %w[x86-mswin32 x64-mswin64 x86-mingw32 x64-mingw32 x64-mingw-ucrt].each do |arch|
- it "allows specifying platform windows on #{arch} arch" do
- platform = send(arch.tr("-", "_"))
-
- simulate_windows platform do
+ %w[x86-mswin32 x64-mswin64 x86-mingw32 x64-mingw-ucrt aarch64-mingw-ucrt].each do |platform|
+ it "allows specifying platform windows on #{platform} platform" do
+ simulate_platform platform do
lockfile <<-L
GEM
remote: https://gem.repo1/
@@ -463,8 +461,6 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
gem "platform_specific", :platforms => [:windows]
G
- bundle "install"
-
expect(the_bundle).to include_gems "platform_specific 1.0 #{platform}"
end
end
diff --git a/spec/bundler/runtime/require_spec.rb b/spec/bundler/runtime/require_spec.rb
index ff45a3c5e2..46613286d2 100644
--- a/spec/bundler/runtime/require_spec.rb
+++ b/spec/bundler/runtime/require_spec.rb
@@ -119,11 +119,9 @@ RSpec.describe "Bundler.require" do
end
G
- load_error_run <<-R, "fail"
- Bundler.require
- R
+ run "Bundler.require", raise_on_error: false
- expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to include("cannot load such file -- fail")
end
it "displays a helpful message if the required gem throws an error" do
@@ -155,16 +153,9 @@ RSpec.describe "Bundler.require" do
end
G
- cmd = <<-RUBY
- begin
- Bundler.require
- rescue LoadError => e
- warn "ZOMG LOAD ERROR: \#{e.message}"
- end
- RUBY
- run(cmd)
+ run "Bundler.require", raise_on_error: false
- expect(err_without_deprecations).to eq("ZOMG LOAD ERROR: cannot load such file -- load-bar")
+ expect(err_without_deprecations).to include("cannot load such file -- load-bar")
end
describe "with namespaced gems" do
@@ -215,10 +206,9 @@ RSpec.describe "Bundler.require" do
end
G
- load_error_run <<-R, "jquery-rails"
- Bundler.require
- R
- expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
+ run "Bundler.require", raise_on_error: false
+
+ expect(err_without_deprecations).to include("cannot load such file -- jquery-rails")
end
it "handles the case where regex fails" do
@@ -233,16 +223,9 @@ RSpec.describe "Bundler.require" do
end
G
- cmd = <<-RUBY
- begin
- Bundler.require
- rescue LoadError => e
- warn "ZOMG LOAD ERROR" if e.message.include?("Could not open library 'libfuuu-1.0'")
- end
- RUBY
- run(cmd)
+ run "Bundler.require", raise_on_error: false
- expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
+ expect(err_without_deprecations).to include("libfuuu-1.0").and include("cannot open shared object file")
end
it "doesn't swallow the error when the library has an unrelated error" do
@@ -257,16 +240,9 @@ RSpec.describe "Bundler.require" do
end
G
- cmd = <<-RUBY
- begin
- Bundler.require
- rescue LoadError => e
- warn "ZOMG LOAD ERROR: \#{e.message}"
- end
- RUBY
- run(cmd)
+ run "Bundler.require", raise_on_error: false
- expect(err_without_deprecations).to eq("ZOMG LOAD ERROR: cannot load such file -- load-bar")
+ expect(err_without_deprecations).to include("cannot load such file -- load-bar")
end
end
@@ -375,10 +351,9 @@ RSpec.describe "Bundler.require" do
gem "busted_require"
G
- load_error_run <<-R, "no_such_file_omg"
- Bundler.require
- R
- expect(err_without_deprecations).to eq("ZOMG LOAD ERROR")
+ run "Bundler.require", raise_on_error: false
+
+ expect(err_without_deprecations).to include("cannot load such file -- no_such_file_omg")
end
end
end
@@ -431,6 +406,22 @@ RSpec.describe "Bundler.require" do
expect(out).to eq("WIN")
end
+ it "does not load plugins" do
+ install_gemfile <<-G
+ source "https://gem.repo1"
+ gem "myrack"
+ G
+
+ create_file "plugins/rubygems_plugin.rb", "puts 'FAIL'"
+
+ run <<~R, env: { "RUBYLIB" => rubylib.unshift(bundled_app("plugins").to_s).join(File::PATH_SEPARATOR) }
+ Bundler.require
+ puts "WIN"
+ R
+
+ expect(out).to eq("WIN")
+ end
+
it "does not extract gemspecs from application cache packages" do
gemfile <<-G
source "https://gem.repo1"
diff --git a/spec/bundler/runtime/requiring_spec.rb b/spec/bundler/runtime/requiring_spec.rb
index 1f32269622..f0e0aeacaf 100644
--- a/spec/bundler/runtime/requiring_spec.rb
+++ b/spec/bundler/runtime/requiring_spec.rb
@@ -2,14 +2,14 @@
RSpec.describe "Requiring bundler" do
it "takes care of requiring rubygems when entrypoint is bundler/setup" do
- sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler/setup -e'puts true'", env: { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
+ sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler/setup -e'puts true'", env: { "RUBYOPT" => "--disable=gems" })
- expect(last_command.stdboth).to eq("true")
+ expect(stdboth).to eq("true")
end
it "takes care of requiring rubygems when requiring just bundler" do
- sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler -e'puts true'", env: { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
+ sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler -e'puts true'", env: { "RUBYOPT" => "--disable=gems" })
- expect(last_command.stdboth).to eq("true")
+ expect(stdboth).to eq("true")
end
end
diff --git a/spec/bundler/runtime/self_management_spec.rb b/spec/bundler/runtime/self_management_spec.rb
index d2472dece2..176c2a3121 100644
--- a/spec/bundler/runtime/self_management_spec.rb
+++ b/spec/bundler/runtime/self_management_spec.rb
@@ -1,13 +1,13 @@
# frozen_string_literal: true
-RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do
+RSpec.describe "Self management" do
describe "auto switching" do
let(:previous_minor) do
- "2.3.0"
+ "9.3.0"
end
let(:current_version) do
- "2.4.0"
+ "9.4.0"
end
before do
@@ -24,22 +24,24 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do
gem "myrack"
G
+
+ pristine_system_gems "bundler-#{current_version}"
end
it "installs locked version when using system path and uses it" do
lockfile_bundled_with(previous_minor)
- bundle "config set --local path.system true"
- bundle "install", preserve_ruby_flags: true
- expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
+ bundle_config "path.system true"
+ bundle "install"
+ expect(out).to include("Bundler #{current_version} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
# It uninstalls the older system bundler
bundle "clean --force", artifice: nil
- expect(out).to eq("Removing bundler (#{Bundler::VERSION})")
+ expect(out).to eq("Removing bundler (#{current_version})")
# App now uses locked version
bundle "-v", artifice: nil
- expect(out).to end_with(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor)
+ expect(out).to eq(previous_minor)
# ruby-core test setup has always "lib" in $LOAD_PATH so `require "bundler/setup"` always activate the local version rather than using RubyGems gem activation stuff
unless ruby_core?
@@ -48,26 +50,26 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do
create_file file, <<-RUBY
#!#{Gem.ruby}
require 'bundler/setup'
- puts Bundler::VERSION
+ puts '#{previous_minor}'
RUBY
file.chmod(0o777)
cmd = Gem.win_platform? ? "#{Gem.ruby} bin/bundle_version.rb" : "bin/bundle_version.rb"
- sys_exec cmd, artifice: nil
+ in_bundled_app cmd
expect(out).to eq(previous_minor)
end
# Subsequent installs use the locked version without reinstalling
bundle "install --verbose", artifice: nil
expect(out).to include("Using bundler #{previous_minor}")
- expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
+ expect(out).not_to include("Bundler #{current_version} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
end
it "installs locked version when using local path and uses it" do
lockfile_bundled_with(previous_minor)
- bundle "config set --local path vendor/bundle"
- bundle "install", preserve_ruby_flags: true
- expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
+ bundle_config "path vendor/bundle"
+ bundle "install"
+ expect(out).to include("Bundler #{current_version} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
expect(vendored_gems("gems/bundler-#{previous_minor}")).to exist
# It does not uninstall the locked bundler
@@ -76,7 +78,11 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do
# App now uses locked version
bundle "-v"
- expect(out).to end_with(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor)
+ expect(out).to eq(previous_minor)
+
+ # Preserves original gem home when auto-switching
+ bundle "exec ruby -e 'puts Bundler.original_env[\"GEM_HOME\"]'"
+ expect(out).to eq(ENV["GEM_HOME"])
# ruby-core test setup has always "lib" in $LOAD_PATH so `require "bundler/setup"` always activate the local version rather than using RubyGems gem activation stuff
unless ruby_core?
@@ -85,26 +91,26 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do
create_file file, <<-RUBY
#!#{Gem.ruby}
require 'bundler/setup'
- puts Bundler::VERSION
+ puts '#{previous_minor}'
RUBY
file.chmod(0o777)
cmd = Gem.win_platform? ? "#{Gem.ruby} bin/bundle_version.rb" : "bin/bundle_version.rb"
- sys_exec cmd, artifice: nil
+ in_bundled_app cmd
expect(out).to eq(previous_minor)
end
# Subsequent installs use the locked version without reinstalling
bundle "install --verbose"
expect(out).to include("Using bundler #{previous_minor}")
- expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
+ expect(out).not_to include("Bundler #{current_version} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
end
it "installs locked version when using deployment option and uses it" do
lockfile_bundled_with(previous_minor)
- bundle "config set --local deployment true"
- bundle "install", preserve_ruby_flags: true
- expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
+ bundle_config "deployment true"
+ bundle "install"
+ expect(out).to include("Bundler #{current_version} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
expect(vendored_gems("gems/bundler-#{previous_minor}")).to exist
# It does not uninstall the locked bundler
@@ -113,12 +119,12 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do
# App now uses locked version
bundle "-v"
- expect(out).to end_with(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor)
+ expect(out).to eq(previous_minor)
# Subsequent installs use the locked version without reinstalling
bundle "install --verbose"
expect(out).to include("Using bundler #{previous_minor}")
- expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
+ expect(out).not_to include("Bundler #{current_version} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
end
it "does not try to install a development version" do
@@ -128,48 +134,126 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do
expect(out).not_to match(/restarting using that version/)
bundle "-v"
- expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION)
+ expect(out).to eq(current_version)
+ end
+
+ it "does not try to install when --local is passed" do
+ lockfile_bundled_with(previous_minor)
+ system_gems "myrack-1.0.0", path: local_gem_path
+
+ bundle "install --local"
+ expect(out).not_to match(/Installing Bundler/)
+
+ bundle "-v"
+ expect(out).to eq(current_version)
end
it "shows a discrete message if locked bundler does not exist" do
- missing_minor = "#{Bundler::VERSION[0]}.999.999"
+ missing_minor = "#{current_version[0]}.999.999"
lockfile_bundled_with(missing_minor)
bundle "install"
- expect(err).to eq("Your lockfile is locked to a version of bundler (#{missing_minor}) that doesn't exist at https://rubygems.org/. Going on using #{Bundler::VERSION}")
+ expect(err).to eq("Your lockfile is locked to a version of bundler (#{missing_minor}) that doesn't exist at https://rubygems.org/. Going on using #{current_version}")
bundle "-v"
- expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION)
+ expect(out).to eq(current_version)
end
it "installs BUNDLE_VERSION version when using bundle config version x.y.z" do
lockfile_bundled_with(current_version)
- bundle "config set --local version #{previous_minor}"
- bundle "install", preserve_ruby_flags: true
- expect(out).to include("Bundler #{Bundler::VERSION} is running, but your configuration was #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
+ bundle_config "version #{previous_minor}"
+ bundle "install"
+ expect(out).to include("Bundler #{current_version} is running, but your configuration was #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.")
bundle "-v"
- expect(out).to eq(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor)
+ expect(out).to eq(previous_minor)
+ end
+
+ it "requires the right bundler version from the config and run bundle CLI without re-exec" do
+ unless Bundler.rubygems.provides?(">= 4.1.0.dev")
+ skip "This spec can only run when Gem::BundlerVersionFinder.bundler_versions reads bundler configs"
+ end
+
+ lockfile_bundled_with(current_version)
+
+ bundle_config "version #{previous_minor}"
+ bundle_config "path.system true"
+ bundle "install"
+
+ script = bundled_app("script.rb")
+ create_file(script, "p 'executed once'")
+
+ bundle "-v", env: { "RUBYOPT" => "-r#{script}" }
+ expect(out).to eq(%("executed once"\n9.3.0))
end
it "does not try to install when using bundle config version global" do
lockfile_bundled_with(previous_minor)
- bundle "config set version system"
+ bundle_config "version system"
bundle "install"
expect(out).not_to match(/restarting using that version/)
bundle "-v"
- expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION)
+ expect(out).to eq(current_version)
+ end
+
+ it "does not try to install when using bundle config version <dev-version>" do
+ lockfile_bundled_with(previous_minor)
+
+ bundle_config "version #{previous_minor}.dev"
+ bundle "install"
+ expect(out).not_to match(/restarting using that version/)
+
+ bundle "-v"
+ expect(out).to eq(current_version)
end
it "ignores malformed lockfile version" do
lockfile_bundled_with("2.3.")
bundle "install --verbose"
- expect(out).to include("Using bundler #{Bundler::VERSION}")
+ expect(out).to include("Using bundler #{current_version}")
+ end
+
+ it "uses the right original script when re-execing, if `$0` has been changed to something that's not a script", :ruby_repo do
+ system_gems "bundler-9.9.9", path: local_gem_path
+
+ test = bundled_app("test.rb")
+
+ create_file test, <<~RUBY
+ $0 = "this is the program name"
+ require "bundler/setup"
+ RUBY
+
+ lockfile_bundled_with("9.9.9")
+
+ in_bundled_app "#{Gem.ruby} #{test}", raise_on_error: false
+ expect(err).to include("Could not find myrack-1.0.0")
+ expect(err).not_to include("this is the program name")
+ end
+
+ it "uses modified $0 when re-execing, if `$0` has been changed to a script", :ruby_repo do
+ system_gems "bundler-9.9.9", path: local_gem_path
+
+ runner = bundled_app("runner.rb")
+
+ create_file runner, <<~RUBY
+ $0 = ARGV.shift
+ load $0
+ RUBY
+
+ script = bundled_app("script.rb")
+ create_file script, <<~RUBY
+ require "bundler/setup"
+ RUBY
+
+ lockfile_bundled_with("9.9.9")
+
+ in_bundled_app "#{Gem.ruby} #{runner} #{script}", raise_on_error: false
+ expect(err).to include("Could not find myrack-1.0.0")
end
private
diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb
index ededaab410..ceb6fcf66a 100644
--- a/spec/bundler/runtime/setup_spec.rb
+++ b/spec/bundler/runtime/setup_spec.rb
@@ -135,7 +135,7 @@ RSpec.describe "Bundler.setup" do
end
it "orders the load path correctly when there are dependencies" do
- bundle "config set path.system true"
+ bundle_config "path.system true"
install_gemfile <<-G
source "https://gem.repo1"
@@ -163,7 +163,7 @@ RSpec.describe "Bundler.setup" do
end
it "falls back to order the load path alphabetically for backwards compatibility" do
- bundle "config set path.system true"
+ bundle_config "path.system true"
install_gemfile <<-G
source "https://gem.repo1"
@@ -286,7 +286,7 @@ RSpec.describe "Bundler.setup" do
G
bundle "install"
- bundle "config set --local deployment true"
+ bundle_config "deployment true"
ENV["BUNDLE_GEMFILE"] = "Gemfile"
ruby <<-R
@@ -303,6 +303,32 @@ RSpec.describe "Bundler.setup" do
expect(out).to eq("WIN")
end
end
+
+ context "user sets it via `config set --local gemfile`" do
+ it "uses the value in the config" do
+ gemfile <<-G
+ source "https://gem.repo1"
+ gem "myrack"
+ G
+
+ gemfile bundled_app("CustomGemfile"), <<-G
+ source "https://gem.repo1"
+ gem "activesupport", "2.3.5"
+ G
+
+ bundle_config "gemfile #{bundled_app("CustomGemfile")}"
+ bundle "install"
+
+ ruby <<-R
+ require 'bundler'
+ Bundler.setup
+ require 'activesupport'
+ puts ACTIVESUPPORT
+ R
+
+ expect(out).to eq("2.3.5")
+ end
+ end
end
it "prioritizes gems in BUNDLE_PATH over gems in GEM_HOME" do
@@ -366,7 +392,8 @@ RSpec.describe "Bundler.setup" do
it "removes system gems from Gem.source_index" do
run "require 'yard'"
- expect(out).to eq("bundler-#{Bundler::VERSION}\nyard-1.0")
+ expect(out).to include("bundler-#{Bundler::VERSION}").and include("yard-1.0")
+ expect(out).not_to include("activesupport-2.3.5")
end
context "when the ruby stdlib is a substring of Gem.path" do
@@ -457,14 +484,13 @@ RSpec.describe "Bundler.setup" do
end
it "works even when the cache directory has been deleted" do
- bundle "config set --local path vendor/bundle"
bundle :install
- FileUtils.rm_rf vendored_gems("cache")
+ FileUtils.rm_r default_cache_path
expect(the_bundle).to include_gems "myrack 1.0.0"
end
it "does not randomly change the path when specifying --path and the bundle directory becomes read only" do
- bundle "config set --local path vendor/bundle"
+ bundle_config "path vendor/bundle"
bundle :install
with_read_only("#{bundled_app}/**/*") do
@@ -473,7 +499,7 @@ RSpec.describe "Bundler.setup" do
end
it "finds git gem when default bundle path becomes read only" do
- bundle "config set --local path .bundle"
+ bundle_config "path .bundle"
bundle "install"
with_read_only("#{bundled_app(".bundle")}/**/*") do
@@ -496,7 +522,7 @@ RSpec.describe "Bundler.setup" do
bundle %(config set local.myrack #{lib_path("local-myrack")})
bundle :install
- FileUtils.rm_rf(lib_path("local-myrack"))
+ FileUtils.rm_r(lib_path("local-myrack"))
run "require 'myrack'", raise_on_error: false
expect(err).to match(/Cannot use local override for myrack-0.8 because #{Regexp.escape(lib_path("local-myrack").to_s)} does not exist/)
end
@@ -568,7 +594,7 @@ RSpec.describe "Bundler.setup" do
describe "when excluding groups" do
it "doesn't change the resolve if --without is used" do
- bundle "config set --local without rails"
+ bundle_config "without rails"
install_gemfile <<-G
source "https://gem.repo1"
gem "activesupport"
@@ -584,7 +610,7 @@ RSpec.describe "Bundler.setup" do
end
it "remembers --without and does not bail on bare Bundler.setup" do
- bundle "config set --local without rails"
+ bundle_config "without rails"
install_gemfile <<-G
source "https://gem.repo1"
gem "activesupport"
@@ -600,7 +626,7 @@ RSpec.describe "Bundler.setup" do
end
it "remembers --without and does not bail on bare Bundler.setup, even in the case of path gems no longer available" do
- bundle "config set --local without development"
+ bundle_config "without development"
path = bundled_app(File.join("vendor", "foo"))
build_lib "foo", path: path
@@ -611,7 +637,7 @@ RSpec.describe "Bundler.setup" do
gem 'foo', :path => 'vendor/foo', :group => :development
G
- FileUtils.rm_rf(path)
+ FileUtils.rm_r(path)
ruby "require 'bundler'; Bundler.setup", env: { "DEBUG" => "1" }
expect(out).to include("Assuming that source at `vendor/foo` has not changed since fetching its specs errored")
@@ -666,7 +692,7 @@ RSpec.describe "Bundler.setup" do
end
it "remembers --without and does not include groups passed to Bundler.setup" do
- bundle "config set --local without rails"
+ bundle_config "without rails"
install_gemfile <<-G
source "https://gem.repo1"
gem "activesupport"
@@ -706,6 +732,21 @@ RSpec.describe "Bundler.setup" do
expect(out).to be_empty
end
+ it "has gem_dir pointing to local repo" do
+ build_lib "foo", "1.0", path: bundled_app
+
+ install_gemfile <<-G
+ source "https://gem.repo1"
+ gemspec
+ G
+
+ run <<-R
+ puts Gem.loaded_specs['foo'].gem_dir
+ R
+
+ expect(out).to eq(bundled_app.to_s)
+ end
+
it "does not load all gemspecs" do
install_gemfile <<-G
source "https://gem.repo1"
@@ -713,46 +754,52 @@ RSpec.describe "Bundler.setup" do
G
run <<-R
- File.open(File.join(Gem.dir, "specifications", "broken.gemspec"), "w") do |f|
+ File.open(File.join(Gem.dir, "specifications", "invalid.gemspec"), "w") do |f|
f.write <<-RUBY
# -*- encoding: utf-8 -*-
-# stub: broken 1.0.0 ruby lib
+# stub: invalid 1.0.0 ruby lib
Gem::Specification.new do |s|
- s.name = "broken"
+ s.name = "invalid"
s.version = "1.0.0"
- raise "BROKEN GEMSPEC"
+ s.authors = ["Invalid Author"]
+ s.files = ["lib/invalid.rb"]
+ s.add_dependency "nonexistent-gem", "~> 999.999.999"
+ s.validate!
end
RUBY
end
R
run <<-R
- File.open(File.join(Gem.dir, "specifications", "broken-ext.gemspec"), "w") do |f|
+ File.open(File.join(Gem.dir, "specifications", "invalid-ext.gemspec"), "w") do |f|
f.write <<-RUBY
# -*- encoding: utf-8 -*-
-# stub: broken-ext 1.0.0 ruby lib
+# stub: invalid-ext 1.0.0 ruby lib
# stub: a.ext\\0b.ext
Gem::Specification.new do |s|
- s.name = "broken-ext"
+ s.name = "invalid-ext"
s.version = "1.0.0"
- raise "BROKEN GEMSPEC EXT"
+ s.authors = ["Invalid Author"]
+ s.files = ["lib/invalid.rb"]
+ s.required_ruby_version = "~> 0.8.0"
+ s.validate!
end
RUBY
end
# Need to write the gem.build_complete file,
# otherwise the full spec is loaded to check the installed_by_version
extensions_dir = Gem.default_ext_dir_for(Gem.dir) || File.join(Gem.dir, "extensions", Gem::Platform.local.to_s, Gem.extension_api_version)
- Bundler::FileUtils.mkdir_p(File.join(extensions_dir, "broken-ext-1.0.0"))
- File.open(File.join(extensions_dir, "broken-ext-1.0.0", "gem.build_complete"), "w") {}
+ Bundler::FileUtils.mkdir_p(File.join(extensions_dir, "invalid-ext-1.0.0"))
+ File.open(File.join(extensions_dir, "invalid-ext-1.0.0", "gem.build_complete"), "w") {}
R
run <<-R
- puts "WIN"
+ puts "Success"
R
- expect(out).to eq("WIN")
+ expect(out).to eq("Success")
end
it "ignores empty gem paths" do
@@ -865,7 +912,6 @@ end
it "should clean $LOAD_PATH properly" do
gem_name = "very_simple_binary"
full_gem_name = gem_name + "-1.0"
- ext_dir = File.join(tmp("extensions", full_gem_name))
system_gems full_gem_name
@@ -874,12 +920,6 @@ end
G
ruby <<-R
- s = Gem::Specification.find_by_name '#{gem_name}'
- s.extension_dir = '#{ext_dir}'
-
- # Don't build extensions.
- s.class.send(:define_method, :build_extensions) { nil }
-
require 'bundler'
gem '#{gem_name}'
@@ -1074,7 +1114,7 @@ end
describe "with system gems in the bundle" do
before :each do
- bundle "config set path.system true"
+ bundle_config "path.system true"
system_gems "myrack-1.0.0"
install_gemfile <<-G
@@ -1143,7 +1183,7 @@ end
bundler_module = class << Bundler; self; end
bundler_module.send(:remove_method, :require)
def Bundler.require(path)
- raise "LOSE"
+ raise StandardError, "didn't use binding from top level"
end
Bundler.load
RUBY
@@ -1188,7 +1228,7 @@ end
end
before do
- bundle "config set --local path.system true"
+ bundle_config "path.system true"
install_gemfile <<-G
source "https://gem.repo1"
@@ -1253,7 +1293,7 @@ end
lock += <<~L
BUNDLED WITH
- #{Bundler::VERSION}
+ #{Bundler::VERSION}
L
lock
@@ -1269,7 +1309,12 @@ end
end
context "is not present" do
- it "does not change the lock" do
+ # Skipped on ruby-core because `ruby "require 'bundler/setup'"` does not
+ # activate bundler as a gem there, so Source::Metadata falls back to a
+ # synthetic spec whose cache_file does not exist on disk and
+ # LockfileGenerator#bundler_checksum drops the bundler checksum, while
+ # the on-disk lockfile still has it.
+ it "does not change the lock", :ruby_repo do
expect { ruby "require 'bundler/setup'" }.not_to change { lockfile }
end
end
@@ -1315,7 +1360,7 @@ end
gem "bar", :git => "#{lib_path("bar-1.0")}"
G
- bundle :install
+ bundle :install, env: { "BUNDLE_LOCKFILE_CHECKSUMS" => "false" }
ruby <<-RUBY, artifice: nil
require 'bundler/setup'
@@ -1377,29 +1422,27 @@ end
end
it "activates default gems when they are part of the bundle, but not installed explicitly", :ruby_repo do
- default_json_version = ruby "gem 'json'; require 'json'; puts JSON::VERSION"
+ default_delegate_version = ruby "gem 'delegate'; require 'delegate'; puts Delegator::VERSION"
build_repo2 do
- build_gem "json", default_json_version
+ build_gem "delegate", default_delegate_version
end
- gemfile "source \"https://gem.repo2\"; gem 'json'"
+ gemfile "source \"https://gem.repo2\"; gem 'delegate'"
ruby <<-RUBY
require "bundler/setup"
- require "json"
- puts defined?(::JSON) ? "JSON defined" : "JSON undefined"
+ require "delegate"
+ puts defined?(::Delegator) ? "Delegator defined" : "Delegator undefined"
RUBY
+ expect(out).to eq("Delegator defined")
expect(err).to be_empty
end
describe "default gem activation" do
let(:exemptions) do
exempts = %w[did_you_mean bundler uri pathname]
- exempts << "etc" if (Gem.ruby_version < Gem::Version.new("3.2") || Gem.ruby_version >= Gem::Version.new("3.3.2")) && Gem.win_platform?
- exempts << "set" unless Gem.rubygems_version >= Gem::Version.new("3.2.6")
- exempts << "tsort" unless Gem.rubygems_version >= Gem::Version.new("3.2.31")
exempts << "error_highlight" # added in Ruby 3.1 as a default gem
exempts << "ruby2_keywords" # added in Ruby 3.1 as a default gem
exempts << "syntax_suggest" # added in Ruby 3.2 as a default gem
@@ -1458,7 +1501,7 @@ end
install_gemfile "source 'https://gem.repo1'"
create_file("script.rb", "#!/usr/bin/env ruby\n\n#{code}")
FileUtils.chmod(0o777, bundled_app("script.rb"))
- bundle "exec ./script.rb", artifice: nil, env: { "RUBYOPT" => activation_warning_hack_rubyopt }
+ bundle "exec ./script.rb", env: { "RUBYOPT" => activation_warning_hack_rubyopt }
expect(out).to eq("{}")
end
@@ -1474,7 +1517,7 @@ end
gem "net-http-pipeline", "1.0.1"
G
- bundle "config set --local path vendor/bundle"
+ bundle_config "path vendor/bundle"
bundle :install
@@ -1518,22 +1561,7 @@ end
end
describe "after setup" do
- it "allows calling #gem on random objects", bundler: "< 3" do
- install_gemfile <<-G
- source "https://gem.repo1"
- gem "myrack"
- G
-
- ruby <<-RUBY
- require "bundler/setup"
- Object.new.gem "myrack"
- puts Gem.loaded_specs["myrack"].full_name
- RUBY
-
- expect(out).to eq("myrack-1.0.0")
- end
-
- it "keeps Kernel#gem private", bundler: "3" do
+ it "keeps Kernel#gem private" do
install_gemfile <<-G
source "https://gem.repo1"
gem "myrack"
@@ -1545,8 +1573,8 @@ end
puts "FAIL"
RUBY
- expect(last_command.stdboth).not_to include "FAIL"
- expect(err).to include "private method `gem'"
+ expect(stdboth).not_to include "FAIL"
+ expect(err).to match(/private method [`']gem'/)
end
it "keeps Kernel#require private" do
@@ -1561,7 +1589,7 @@ end
puts "FAIL"
RUBY
- expect(last_command.stdboth).not_to include "FAIL"
+ expect(stdboth).not_to include "FAIL"
expect(err).to match(/private method [`']require'/)
end
@@ -1640,7 +1668,7 @@ end
gem "myrack", :group => :test
G
- bundle "config set auto_install 1"
+ bundle_config "auto_install 1"
ruby <<-RUBY, artifice: "compact_index"
require 'bundler/setup'
@@ -1648,4 +1676,35 @@ end
expect(err).to be_empty
expect(out).to include("Installing myrack 1.0.0")
end
+
+ context "in a read-only filesystem" do
+ before do
+ gemfile <<-G
+ source "https://gem.repo4"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: https://gem.repo4/
+
+ PLATFORMS
+ x86_64-darwin-19
+
+ DEPENDENCIES
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "should fail loudly if the lockfile platforms don't include the current platform" do
+ simulate_platform "x86_64-linux" do
+ ruby <<-RUBY, raise_on_error: false, env: { "BUNDLER_SPEC_READ_ONLY" => "true", "BUNDLER_FORCE_TTY" => "true" }
+ require "bundler/setup"
+ RUBY
+ end
+
+ expect(err).to include("Your lockfile is missing the current platform, but can't be updated because file system is read-only")
+ end
+ end
end