summaryrefslogtreecommitdiff
path: root/spec/bundler/commands
diff options
context:
space:
mode:
Diffstat (limited to 'spec/bundler/commands')
-rw-r--r--spec/bundler/commands/add_spec.rb147
-rw-r--r--spec/bundler/commands/binstubs_spec.rb119
-rw-r--r--spec/bundler/commands/cache_spec.rb38
-rw-r--r--spec/bundler/commands/check_spec.rb125
-rw-r--r--spec/bundler/commands/clean_spec.rb58
-rw-r--r--spec/bundler/commands/config_spec.rb116
-rw-r--r--spec/bundler/commands/console_spec.rb2
-rw-r--r--spec/bundler/commands/doctor_spec.rb15
-rw-r--r--spec/bundler/commands/exec_spec.rb154
-rw-r--r--spec/bundler/commands/fund_spec.rb16
-rw-r--r--spec/bundler/commands/help_spec.rb13
-rw-r--r--spec/bundler/commands/info_spec.rb70
-rw-r--r--spec/bundler/commands/init_spec.rb60
-rw-r--r--spec/bundler/commands/inject_spec.rb12
-rw-r--r--spec/bundler/commands/install_spec.rb576
-rw-r--r--spec/bundler/commands/list_spec.rb12
-rw-r--r--spec/bundler/commands/lock_spec.rb1143
-rw-r--r--spec/bundler/commands/newgem_spec.rb281
-rw-r--r--spec/bundler/commands/open_spec.rb90
-rw-r--r--spec/bundler/commands/outdated_spec.rb382
-rw-r--r--spec/bundler/commands/platform_spec.rb1307
-rw-r--r--spec/bundler/commands/post_bundle_message_spec.rb16
-rw-r--r--spec/bundler/commands/pristine_spec.rb24
-rw-r--r--spec/bundler/commands/remove_spec.rb62
-rw-r--r--spec/bundler/commands/show_spec.rb26
-rw-r--r--spec/bundler/commands/update_spec.rb853
-rw-r--r--spec/bundler/commands/version_spec.rb16
-rw-r--r--spec/bundler/commands/viz_spec.rb20
28 files changed, 4916 insertions, 837 deletions
diff --git a/spec/bundler/commands/add_spec.rb b/spec/bundler/commands/add_spec.rb
index 4c533652ca..36e286793b 100644
--- a/spec/bundler/commands/add_spec.rb
+++ b/spec/bundler/commands/add_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe "bundle add" do
build_gem "bar", "0.12.3"
build_gem "cat", "0.12.3.pre"
build_gem "dog", "1.1.3.pre"
+ build_gem "lemur", "3.1.1.pre.2023.1.1"
end
build_git "foo", "2.0"
@@ -21,7 +22,7 @@ RSpec.describe "bundle add" do
context "when no gems are specified" do
it "shows error" do
- bundle "add", :raise_on_error => false
+ bundle "add", raise_on_error: false
expect(err).to include("Please specify gems to add")
end
@@ -51,6 +52,13 @@ RSpec.describe "bundle add" do
expect(bundled_app_gemfile.read).to match(/gem "dog", "~> 1.1.pre"/)
expect(the_bundle).to include_gems "dog 1.1.3.pre"
end
+
+ it "version requirement becomes ~> major.minor.pre.tail when resolved version has a very long tail pre version" do
+ bundle "add 'lemur'"
+ # the trailing pre purposely matches the release version to ensure that subbing the release doesn't change the pre.version"
+ expect(bundled_app_gemfile.read).to match(/gem "lemur", "~> 3.1.pre.2023.1.1"/)
+ expect(the_bundle).to include_gems "lemur 3.1.1.pre.2023.1.1"
+ end
end
describe "with --version" do
@@ -63,11 +71,23 @@ RSpec.describe "bundle add" do
it "adds multiple version constraints when specified" do
requirements = ["< 3.0", "> 1.0"]
bundle "add 'foo' --version='#{requirements.join(", ")}'"
- expect(bundled_app_gemfile.read).to match(/gem "foo", #{Gem::Requirement.new(requirements).as_list.map(&:dump).join(', ')}/)
+ expect(bundled_app_gemfile.read).to match(/gem "foo", #{Gem::Requirement.new(requirements).as_list.map(&:dump).join(", ")}/)
expect(the_bundle).to include_gems "foo 2.0"
end
end
+ describe "with --require" do
+ it "adds the require param for the gem" do
+ bundle "add 'foo' --require=foo/engine"
+ expect(bundled_app_gemfile.read).to match(%r{gem "foo",(?: .*,) :require => "foo\/engine"})
+ end
+
+ it "converts false to a boolean" do
+ bundle "add 'foo' --require=false"
+ expect(bundled_app_gemfile.read).to match(/gem "foo",(?: .*,) :require => false/)
+ end
+ end
+
describe "with --group" do
it "adds dependency for the specified group" do
bundle "add 'foo' --group='development'"
@@ -91,8 +111,17 @@ RSpec.describe "bundle add" do
end
end
+ describe "with --path" do
+ it "adds dependency with specified path" do
+ bundle "add 'foo' --path='#{lib_path("foo-2.0")}'"
+
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :path => "#{lib_path("foo-2.0")}"/)
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
describe "with --git" do
- it "adds dependency with specified github source" do
+ it "adds dependency with specified git source" do
bundle "add foo --git=#{lib_path("foo-2.0")}"
expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}"/)
@@ -102,10 +131,10 @@ RSpec.describe "bundle add" do
describe "with --git and --branch" do
before do
- update_git "foo", "2.0", :branch => "test"
+ update_git "foo", "2.0", branch: "test"
end
- it "adds dependency with specified github source and branch" do
+ it "adds dependency with specified git source and branch" do
bundle "add foo --git=#{lib_path("foo-2.0")} --branch=test"
expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}", :branch => "test"/)
@@ -113,6 +142,94 @@ RSpec.describe "bundle add" do
end
end
+ describe "with --git and --ref" do
+ it "adds dependency with specified git source and branch" do
+ bundle "add foo --git=#{lib_path("foo-2.0")} --ref=#{revision_for(lib_path("foo-2.0"))}"
+
+ expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2\.0", :git => "#{lib_path("foo-2.0")}", :ref => "#{revision_for(lib_path("foo-2.0"))}"/)
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --github" do
+ it "adds dependency with specified github source", :realworld do
+ bundle "add rake --github=ruby/rake"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake"})
+ end
+ end
+
+ describe "with --github and --branch" do
+ it "adds dependency with specified github source and branch", :realworld do
+ bundle "add rake --github=ruby/rake --branch=master"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :branch => "master"})
+ end
+ end
+
+ describe "with --github and --ref" do
+ it "adds dependency with specified github source and ref", :realworld do
+ bundle "add rake --github=ruby/rake --ref=5c60da8"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :ref => "5c60da8"})
+ end
+ end
+
+ describe "with --git and --glob" do
+ it "adds dependency with specified git source" do
+ bundle "add foo --git=#{lib_path("foo-2.0")} --glob='./*.gemspec'"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}", :glob => "\./\*\.gemspec"})
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --git and --branch and --glob" do
+ before do
+ update_git "foo", "2.0", branch: "test"
+ end
+
+ it "adds dependency with specified git source and branch" do
+ bundle "add foo --git=#{lib_path("foo-2.0")} --branch=test --glob='./*.gemspec'"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "foo", "~> 2.0", :git => "#{lib_path("foo-2.0")}", :branch => "test", :glob => "\./\*\.gemspec"})
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --git and --ref and --glob" do
+ it "adds dependency with specified git source and branch" do
+ bundle "add foo --git=#{lib_path("foo-2.0")} --ref=#{revision_for(lib_path("foo-2.0"))} --glob='./*.gemspec'"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "foo", "~> 2\.0", :git => "#{lib_path("foo-2.0")}", :ref => "#{revision_for(lib_path("foo-2.0"))}", :glob => "\./\*\.gemspec"})
+ expect(the_bundle).to include_gems "foo 2.0"
+ end
+ end
+
+ describe "with --github and --glob" do
+ it "adds dependency with specified github source", :realworld do
+ bundle "add rake --github=ruby/rake --glob='./*.gemspec'"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :glob => "\.\/\*\.gemspec"})
+ end
+ end
+
+ describe "with --github and --branch --and glob" do
+ it "adds dependency with specified github source and branch", :realworld do
+ bundle "add rake --github=ruby/rake --branch=master --glob='./*.gemspec'"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :branch => "master", :glob => "\.\/\*\.gemspec"})
+ end
+ end
+
+ describe "with --github and --ref and --glob" do
+ it "adds dependency with specified github source and ref", :realworld do
+ bundle "add rake --github=ruby/rake --ref=5c60da8 --glob='./*.gemspec'"
+
+ expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :ref => "5c60da8", :glob => "\.\/\*\.gemspec"})
+ end
+ end
+
describe "with --skip-install" do
it "adds gem to Gemfile but is not installed" do
bundle "add foo --skip-install --version=2.0"
@@ -129,24 +246,24 @@ RSpec.describe "bundle add" do
end
it "shows error message when version is not formatted correctly" do
- bundle "add 'foo' -v='~>1 . 0'", :raise_on_error => false
+ bundle "add 'foo' -v='~>1 . 0'", raise_on_error: false
expect(err).to match("Invalid gem requirement pattern '~>1 . 0'")
end
it "shows error message when gem cannot be found" do
bundle "config set force_ruby_platform true"
- bundle "add 'werk_it'", :raise_on_error => false
+ bundle "add 'werk_it'", raise_on_error: false
expect(err).to match("Could not find gem 'werk_it' in")
- bundle "add 'werk_it' -s='#{file_uri_for(gem_repo2)}'", :raise_on_error => false
+ bundle "add 'werk_it' -s='#{file_uri_for(gem_repo2)}'", raise_on_error: false
expect(err).to match("Could not find gem 'werk_it' in rubygems repository")
end
it "shows error message when source cannot be reached" do
- bundle "add 'baz' --source='http://badhostasdf'", :raise_on_error => false
+ bundle "add 'baz' --source='http://badhostasdf'", raise_on_error: false
expect(err).to include("Could not reach host badhostasdf. Check your network connection and try again.")
- bundle "add 'baz' --source='file://does/not/exist'", :raise_on_error => false
+ bundle "add 'baz' --source='file://does/not/exist'", raise_on_error: false
expect(err).to include("Could not fetch specs from file://does/not/exist/")
end
@@ -176,7 +293,7 @@ RSpec.describe "bundle add" do
describe "with --optimistic and --strict" do
it "throws error" do
- bundle "add 'foo' --strict --optimistic", :raise_on_error => false
+ bundle "add 'foo' --strict --optimistic", raise_on_error: false
expect(err).to include("You can not specify `--strict` and `--optimistic` at the same time")
end
@@ -191,7 +308,7 @@ RSpec.describe "bundle add" do
end
it "throws error if any of the specified gems are present in the gemfile with different version" do
- bundle "add weakling bar", :raise_on_error => false
+ bundle "add weakling bar", raise_on_error: false
expect(err).to include("You cannot specify the same gem twice with different version requirements")
expect(err).to include("You specified: weakling (~> 0.0.1) and weakling (>= 0).")
@@ -205,7 +322,7 @@ RSpec.describe "bundle add" do
gem "rack", "1.0"
G
- bundle "add 'rack' --version=1.1", :raise_on_error => false
+ bundle "add 'rack' --version=1.1", raise_on_error: false
expect(err).to include("You cannot specify the same gem twice with different version requirements")
expect(err).to include("If you want to update the gem version, run `bundle update rack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive")
@@ -217,7 +334,7 @@ RSpec.describe "bundle add" do
gem "rack", "1.0"
G
- bundle "add 'rack'", :raise_on_error => false
+ bundle "add 'rack'", raise_on_error: false
expect(err).to include("Gem already added.")
expect(err).to include("You cannot specify the same gem twice with different version requirements")
@@ -232,7 +349,7 @@ RSpec.describe "bundle add" do
gem "rack"
G
- bundle "add 'rack' --version=1.1", :raise_on_error => false
+ bundle "add 'rack' --version=1.1", raise_on_error: false
expect(err).to include("You cannot specify the same gem twice with different version requirements")
expect(err).to include("If you want to update the gem version, run `bundle update rack`.")
diff --git a/spec/bundler/commands/binstubs_spec.rb b/spec/bundler/commands/binstubs_spec.rb
index 1cd0e16d95..6c3dc7bb2d 100644
--- a/spec/bundler/commands/binstubs_spec.rb
+++ b/spec/bundler/commands/binstubs_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe "bundle binstubs <gem>" do
gem "rails"
G
- bundle :binstubs, :all => true
+ bundle :binstubs, all: true
expect(bundled_app("bin/rails")).to exist
expect(bundled_app("bin/rake")).to exist
@@ -69,7 +69,7 @@ RSpec.describe "bundle binstubs <gem>" do
gem "rack"
G
- bundle "binstubs", :raise_on_error => false
+ bundle "binstubs", raise_on_error: false
expect(exitstatus).to eq(1)
expect(err).to include("`bundle binstubs` needs at least one gem to run.")
end
@@ -80,7 +80,7 @@ RSpec.describe "bundle binstubs <gem>" do
gem "rack"
G
- bundle "binstubs rack", :all => true, :raise_on_error => false
+ bundle "binstubs rack", all: true, raise_on_error: false
expect(last_command).to be_failure
expect(err).to include("Cannot specify --all with specific gems")
end
@@ -98,7 +98,7 @@ RSpec.describe "bundle binstubs <gem>" do
file.print "OMG"
end
- sys_exec "bin/rackup", :raise_on_error => false
+ sys_exec "bin/rackup", raise_on_error: false
expect(err).to include("was not generated by Bundler")
end
@@ -132,13 +132,13 @@ RSpec.describe "bundle binstubs <gem>" do
let(:system_bundler_version) { Bundler::VERSION }
it "runs bundler" do
- sys_exec "bin/bundle install", :env => { "DEBUG" => "1" }
+ sys_exec "bin/bundle install", env: { "DEBUG" => "1" }
expect(out).to include %(Using bundler #{system_bundler_version}\n)
end
context "when BUNDLER_VERSION is set" do
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", :env => { "BUNDLER_VERSION" => "999.999.999" }, :raise_on_error => false
+ sys_exec "bin/bundle install", env: { "BUNDLER_VERSION" => "999.999.999" }, raise_on_error: false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (999.999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
@@ -147,7 +147,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "runs the correct version of bundler even if a higher version is installed" do
system_gems "bundler-999.999.998", "bundler-999.999.999"
- sys_exec "bin/bundle install", :env => { "BUNDLER_VERSION" => "999.999.998", "DEBUG" => "1" }, :raise_on_error => false
+ sys_exec "bin/bundle install", env: { "BUNDLER_VERSION" => "999.999.998", "DEBUG" => "1" }, raise_on_error: false
expect(out).to include %(Using bundler 999.999.998\n)
end
end
@@ -159,7 +159,22 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", :raise_on_error => false
+ sys_exec "bin/bundle install", raise_on_error: false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (~> 999.999) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`")
+ end
+ end
+
+ context "and the version is newer when given `gems.rb` and `gems.locked`" do
+ before do
+ gemfile bundled_app("gems.rb"), gemfile
+ lockfile bundled_app("gems.locked"), lockfile.gsub(system_bundler_version, "999.999")
+ end
+
+ it "runs the correct version of bundler" do
+ sys_exec "bin/bundle install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false
+
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`")
@@ -174,7 +189,23 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler" do
- sys_exec "bin/bundle install", :raise_on_error => false
+ sys_exec "bin/bundle install", raise_on_error: false
+ expect(exitstatus).to eq(42)
+ expect(err).to include("Activating bundler (~> 44.0) failed:").
+ and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`")
+ end
+ end
+
+ context "and the version is older and a different major when given `gems.rb` and `gems.locked`" do
+ let(:system_bundler_version) { "55" }
+
+ before do
+ gemfile bundled_app("gems.rb"), gemfile
+ lockfile bundled_app("gems.locked"), lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 44.0")
+ end
+
+ it "runs the correct version of bundler" do
+ sys_exec "bin/bundle install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 44.0) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`")
@@ -182,16 +213,26 @@ RSpec.describe "bundle binstubs <gem>" do
end
context "and the version is older and the same major" do
- let(:system_bundler_version) { "55.1" }
+ let(:system_bundler_version) { "2.999.999" }
before do
- lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 55.0")
+ lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.3.0")
+ end
+
+ it "installs and runs the exact version of bundler", rubygems: ">= 3.3.0.dev", realworld: true do
+ sys_exec "bin/bundle install --verbose", artifice: "vcr"
+ expect(exitstatus).not_to eq(42)
+ expect(out).to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.")
+ expect(out).to include("Using bundler 2.3.0")
+ expect(err).not_to include("Activating bundler (~> 2.3.0) failed:")
end
- it "runs the available version of bundler when the version is older and the same major" do
- sys_exec "bin/bundle install"
+ it "runs the available version of bundler", rubygems: "< 3.3.0.dev" do
+ sys_exec "bin/bundle install --verbose"
expect(exitstatus).not_to eq(42)
- expect(err).not_to include("Activating bundler (~> 55.0) failed:")
+ expect(out).not_to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.")
+ expect(out).to include("Using bundler 2.999.999")
+ expect(err).not_to include("Activating bundler (~> 2.3.0) failed:")
end
end
@@ -203,7 +244,7 @@ RSpec.describe "bundle binstubs <gem>" do
end
it "runs the correct version of bundler when the version is a pre-release" do
- sys_exec "bin/bundle install", :raise_on_error => false
+ sys_exec "bin/bundle install", raise_on_error: false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 2.12.a) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 2.12.a'`")
@@ -214,13 +255,16 @@ RSpec.describe "bundle binstubs <gem>" do
context "when update --bundler is called" do
before { lockfile.gsub(system_bundler_version, "1.1.1") }
- it "calls through to the latest bundler version" do
- sys_exec "bin/bundle update --bundler", :env => { "DEBUG" => "1" }
- expect(out).to include %(Using bundler #{system_bundler_version}\n)
+ it "calls through to the latest bundler version", :realworld do
+ sys_exec "bin/bundle update --bundler", env: { "DEBUG" => "1" }
+ using_bundler_line = /Using bundler ([\w\.]+)\n/.match(out)
+ expect(using_bundler_line).to_not be_nil
+ latest_version = using_bundler_line[1]
+ expect(Gem::Version.new(latest_version)).to be >= Gem::Version.new(system_bundler_version)
end
it "calls through to the explicit bundler version" do
- sys_exec "bin/bundle update --bundler=999.999.999", :raise_on_error => false
+ sys_exec "bin/bundle update --bundler=999.999.999", raise_on_error: false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (999.999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
@@ -230,7 +274,7 @@ RSpec.describe "bundle binstubs <gem>" do
context "without a lockfile" do
it "falls back to the latest installed bundler" do
FileUtils.rm bundled_app_lock
- sys_exec "bin/bundle install", :env => { "DEBUG" => "1" }
+ sys_exec "bin/bundle install", env: { "DEBUG" => "1" }
expect(out).to include "Using bundler #{system_bundler_version}\n"
end
end
@@ -245,7 +289,7 @@ RSpec.describe "bundle binstubs <gem>" do
before { lockfile lockfile.gsub(Bundler::VERSION, "999.999.999") }
it "attempts to load that version" do
- sys_exec bundled_app("bin/rackup").to_s, :raise_on_error => false
+ sys_exec bundled_app("bin/rackup").to_s, raise_on_error: false
expect(exitstatus).to eq(42)
expect(err).to include("Activating bundler (~> 999.999) failed:").
and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`")
@@ -257,7 +301,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "installs binstubs from git gems" do
FileUtils.mkdir_p(lib_path("foo/bin"))
FileUtils.touch(lib_path("foo/bin/foo"))
- build_git "foo", "1.0", :path => lib_path("foo") do |s|
+ build_git "foo", "1.0", path: lib_path("foo") do |s|
s.executables = %w[foo]
end
install_gemfile <<-G
@@ -273,7 +317,7 @@ RSpec.describe "bundle binstubs <gem>" do
it "installs binstubs from path gems" do
FileUtils.mkdir_p(lib_path("foo/bin"))
FileUtils.touch(lib_path("foo/bin/foo"))
- build_lib "foo", "1.0", :path => lib_path("foo") do |s|
+ build_lib "foo", "1.0", path: lib_path("foo") do |s|
s.executables = %w[foo]
end
install_gemfile <<-G
@@ -318,7 +362,7 @@ RSpec.describe "bundle binstubs <gem>" do
source "#{file_uri_for(gem_repo1)}"
G
- bundle "binstubs doesnt_exist", :raise_on_error => false
+ bundle "binstubs doesnt_exist", raise_on_error: false
expect(exitstatus).to eq(7)
expect(err).to include("Could not find gem 'doesnt_exist'.")
@@ -337,14 +381,14 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("exec/rackup")).to exist
end
- it "setting is saved for bundle install", :bundler => "< 3" do
+ it "setting is saved for bundle install", bundler: "< 3" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "rails"
G
- bundle "binstubs rack", :path => "exec"
+ bundle "binstubs rack", path: "exec"
bundle :install
expect(bundled_app("exec/rails")).to exist
@@ -356,6 +400,7 @@ RSpec.describe "bundle binstubs <gem>" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
+ gem "rails"
G
end
@@ -383,6 +428,26 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("bin/rackup.cmd")).to exist
end
end
+
+ context "when the gem is bundler" do
+ it "warns without generating a standalone binstub" do
+ bundle "binstubs bundler --standalone"
+ expect(bundled_app("bin/bundle")).not_to exist
+ expect(bundled_app("bin/bundler")).not_to exist
+ expect(err).to include("Sorry, Bundler can only be run via RubyGems.")
+ end
+ end
+
+ context "when specified --all option" do
+ it "generates standalone binstubs for all gems except bundler" do
+ bundle "binstubs --standalone --all"
+ expect(bundled_app("bin/rackup")).to exist
+ expect(bundled_app("bin/rails")).to exist
+ expect(bundled_app("bin/bundle")).not_to exist
+ expect(bundled_app("bin/bundler")).not_to exist
+ expect(err).not_to include("Sorry, Bundler can only be run via RubyGems.")
+ end
+ end
end
context "when the bin already exists" do
@@ -484,7 +549,7 @@ RSpec.describe "bundle binstubs <gem>" do
G
bundle "config set auto_install 1"
- bundle "binstubs rack", :env => { "BUNDLE_INSTALL" => "1" }
+ bundle "binstubs rack", env: { "BUNDLE_INSTALL" => "1" }
expect(out).not_to include("Installing rack 1.0.0")
end
end
diff --git a/spec/bundler/commands/cache_spec.rb b/spec/bundler/commands/cache_spec.rb
index 4f9c1c26c4..70e2c84961 100644
--- a/spec/bundler/commands/cache_spec.rb
+++ b/spec/bundler/commands/cache_spec.rb
@@ -158,7 +158,7 @@ RSpec.describe "bundle cache" do
end
end
- context "with --path", :bundler => "< 3" do
+ context "with --path", bundler: "< 3" do
it "sets root directory for gems" do
gemfile <<-D
source "#{file_uri_for(gem_repo1)}"
@@ -211,7 +211,17 @@ RSpec.describe "bundle cache" do
end
context "with --all-platforms" do
- it "puts the gems in vendor/cache even for other rubies" do
+ it "puts the gems in vendor/cache even for other rubies", bundler: ">= 2.4.0" do
+ gemfile <<-D
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack', :platforms => [:ruby_20, :windows_20]
+ D
+
+ bundle "cache --all-platforms"
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
+
+ it "puts the gems in vendor/cache even for legacy windows rubies", bundler: ">= 2.4.0" do
gemfile <<-D
source "#{file_uri_for(gem_repo1)}"
gem 'rack', :platforms => [:ruby_20, :x64_mingw_20]
@@ -262,7 +272,7 @@ RSpec.describe "bundle cache" do
end
G
- bundle :lock, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
+ bundle :lock, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
bundle :cache, "all-platforms" => true, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }
expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
end
@@ -279,7 +289,7 @@ RSpec.describe "bundle cache" do
subject do
bundle "config set --local frozen true"
- bundle :cache, :raise_on_error => false
+ bundle :cache, raise_on_error: false
end
it "tries to install with frozen" do
@@ -291,7 +301,7 @@ RSpec.describe "bundle cache" do
G
subject
expect(exitstatus).to eq(16)
- expect(err).to include("deployment mode")
+ expect(err).to include("frozen mode")
expect(err).to include("You have added to the Gemfile")
expect(err).to include("* rack-obama")
bundle "env"
@@ -383,7 +393,7 @@ RSpec.describe "bundle install with gem sources" do
G
bundle :cache
- build_gem "rack", "1.0.0", :path => bundled_app("vendor/cache") do |s|
+ build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") do |s|
s.write "lib/rack.rb", "raise 'omg'"
end
@@ -403,14 +413,14 @@ RSpec.describe "bundle install with gem sources" do
simulate_new_machine
- simulate_platform "ruby" do
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- gem "platform_specific"
- G
- run "require 'platform_specific' ; puts PLATFORM_SPECIFIC"
- expect(out).to eq("1.0.0 RUBY")
- end
+ bundle "config set --local force_ruby_platform true"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "platform_specific"
+ G
+ run "require 'platform_specific' ; puts PLATFORM_SPECIFIC"
+ expect(out).to eq("1.0.0 RUBY")
end
it "does not update the cache if --no-cache is passed" do
diff --git a/spec/bundler/commands/check_spec.rb b/spec/bundler/commands/check_spec.rb
index 1fa35136eb..02f9bb5b7a 100644
--- a/spec/bundler/commands/check_spec.rb
+++ b/spec/bundler/commands/check_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle "check --gemfile bundled_app/Gemfile", :dir => tmp
+ bundle "check --gemfile bundled_app/Gemfile", dir: tmp
expect(out).to include("The Gemfile's dependencies are satisfied")
end
@@ -55,7 +55,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
@@ -65,7 +65,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(exitstatus).to be > 0
expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
@@ -88,11 +88,11 @@ RSpec.describe "bundle check" do
gem "rails_pinned_to_old_activesupport"
G
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.")
end
- it "remembers --without option from install", :bundler => "< 3" do
+ it "remembers --without option from install", bundler: "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
group :foo do
@@ -132,7 +132,7 @@ RSpec.describe "bundle check" do
gem "rack"
G
- bundle "check", :raise_on_error => false
+ bundle "check", raise_on_error: false
expect(err).to include("* rack (1.0.0)")
expect(exitstatus).to eq(1)
end
@@ -146,9 +146,9 @@ RSpec.describe "bundle check" do
bundle "config set --local path vendor/bundle"
bundle :cache
- gem_command "uninstall rack", :env => { "GEM_HOME" => vendored_gems.to_s }
+ gem_command "uninstall rack", env: { "GEM_HOME" => vendored_gems.to_s }
- bundle "check", :raise_on_error => false
+ bundle "check", raise_on_error: false
expect(err).to include("* rack (1.0.0)")
expect(exitstatus).to eq(1)
end
@@ -162,7 +162,7 @@ RSpec.describe "bundle check" do
end
G
- system_gems "rack-1.0.0", :path => default_bundle_path
+ system_gems "rack-1.0.0", path: default_bundle_path
lockfile <<-G
GEM
@@ -172,7 +172,7 @@ RSpec.describe "bundle check" do
rack (1.0.0)
PLATFORMS
- #{local}
+ #{generic_local_platform}
#{not_local}
DEPENDENCIES
@@ -193,7 +193,7 @@ RSpec.describe "bundle check" do
end
G
- system_gems "rack-1.0.0", :path => default_bundle_path
+ system_gems "rack-1.0.0", path: default_bundle_path
lockfile <<-G
GEM
@@ -203,7 +203,7 @@ RSpec.describe "bundle check" do
rack (1.0.0)
PLATFORMS
- #{local}
+ #{generic_local_platform}
#{not_local}
DEPENDENCIES
@@ -216,13 +216,13 @@ RSpec.describe "bundle check" do
end
it "outputs an error when the default Gemfile is not found" do
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(exitstatus).to eq(10)
expect(err).to include("Could not locate Gemfile")
end
it "does not output fatal error message" do
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(exitstatus).to eq(10)
expect(err).not_to include("Unfortunately, a fatal error has occurred. ")
end
@@ -237,11 +237,11 @@ RSpec.describe "bundle check" do
bundle "install"
FileUtils.rm(bundled_app_lock)
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(last_command).to be_failure
end
- context "--path", :bundler => "< 3" do
+ context "--path", bundler: "< 3" do
context "after installing gems in the proper directory" do
before do
gemfile <<-G
@@ -271,7 +271,7 @@ RSpec.describe "bundle check" do
gem "rails"
G
- bundle "check --path vendor/bundle", :raise_on_error => false
+ bundle "check --path vendor/bundle", raise_on_error: false
end
it "returns false" do
@@ -298,7 +298,7 @@ RSpec.describe "bundle check" do
it "shows what is missing with the current Gemfile if it is not satisfied" do
simulate_new_machine
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(err).to match(/The following gems are missing/)
expect(err).to include("* rack (1.0")
end
@@ -326,7 +326,7 @@ RSpec.describe "bundle check" do
end
it "shows what is missing with the current Gemfile without duplications" do
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(err).to match(/The following gems are missing/)
expect(err).to include("* rack (1.0").once
end
@@ -351,7 +351,7 @@ RSpec.describe "bundle check" do
PLATFORMS
ruby
- #{specific_local_platform}
+ #{local_platform}
DEPENDENCIES
rack
@@ -362,7 +362,7 @@ RSpec.describe "bundle check" do
end
it "shows what is missing with the current Gemfile without duplications" do
- bundle :check, :raise_on_error => false
+ bundle :check, raise_on_error: false
expect(err).to match(/The following gems are missing/)
expect(err).to include("* rack (1.0").once
end
@@ -379,7 +379,7 @@ RSpec.describe "bundle check" do
end
it "returns success when the Gemfile is satisfied" do
- system_gems "rack-1.0.0", :path => default_bundle_path
+ system_gems "rack-1.0.0", path: default_bundle_path
bundle :check
expect(out).to include("The Gemfile's dependencies are satisfied")
end
@@ -404,8 +404,14 @@ RSpec.describe "bundle check" do
end
it "returns success when the Gemfile is satisfied and generates a correct lockfile" do
- system_gems "depends_on_rack-1.0", "rack-1.0", :gem_repo => gem_repo4, :path => default_bundle_path
+ system_gems "depends_on_rack-1.0", "rack-1.0", gem_repo: gem_repo4, path: default_bundle_path
bundle :check
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "depends_on_rack", "1.0"
+ c.no_checksum "rack", "1.0"
+ end
+
expect(out).to include("The Gemfile's dependencies are satisfied")
expect(lockfile).to eq <<~L
GEM
@@ -424,7 +430,76 @@ RSpec.describe "bundle check" do
DEPENDENCIES
depends_on_rack!
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "with gemspec directive and scoped sources" do
+ before do
+ build_repo4 do
+ build_gem "awesome_print"
+ end
+
+ build_repo2 do
+ build_gem "dex-dispatch-engine"
+ end
+
+ build_lib("bundle-check-issue", path: tmp.join("bundle-check-issue")) do |s|
+ s.write "Gemfile", <<-G
+ source "https://localgemserver.test"
+
+ gemspec
+
+ source "https://localgemserver.test/extra" do
+ gem "dex-dispatch-engine"
+ end
+ G
+
+ s.add_dependency "awesome_print"
+ end
+
+ bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, dir: tmp.join("bundle-check-issue")
+ end
+
+ it "does not corrupt lockfile when changing version" do
+ version_file = tmp.join("bundle-check-issue/bundle-check-issue.gemspec")
+ File.write(version_file, File.read(version_file).gsub(/s\.version = .+/, "s.version = '9999'"))
+
+ bundle "check --verbose", dir: tmp.join("bundle-check-issue")
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo4, "awesome_print", "1.0"
+ c.no_checksum "bundle-check-issue", "9999"
+ c.checksum gem_repo2, "dex-dispatch-engine", "1.0"
+ end
+
+ expect(File.read(tmp.join("bundle-check-issue/Gemfile.lock"))).to eq <<~L
+ PATH
+ remote: .
+ specs:
+ bundle-check-issue (9999)
+ awesome_print
+
+ GEM
+ remote: https://localgemserver.test/
+ specs:
+ awesome_print (1.0)
+
+ GEM
+ remote: https://localgemserver.test/extra/
+ specs:
+ dex-dispatch-engine (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ bundle-check-issue!
+ dex-dispatch-engine!
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -471,10 +546,10 @@ RSpec.describe "bundle check" do
end
context "is newer" do
- it "does not change the lock but warns" do
+ it "does not change the lock and does not warn" do
lockfile lock_with(Bundler::VERSION.succ)
bundle :check
- expect(err).to include("the running version of Bundler (#{Bundler::VERSION}) is older than the version that created the lockfile (#{Bundler::VERSION.succ})")
+ expect(err).to be_empty
expect(lockfile).to eq lock_with(Bundler::VERSION.succ)
end
end
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
index ffaf22dbb3..0b559a87c8 100644
--- a/spec/bundler/commands/clean_spec.rb
+++ b/spec/bundler/commands/clean_spec.rb
@@ -156,7 +156,7 @@ RSpec.describe "bundle clean" do
end
it "removes unused git gems" do
- build_git "foo", :path => lib_path("foo")
+ build_git "foo", path: lib_path("foo")
git_path = lib_path("foo")
revision = revision_for(git_path)
@@ -194,7 +194,7 @@ RSpec.describe "bundle clean" do
end
it "keeps used git gems even if installed to a symlinked location" do
- build_git "foo", :path => lib_path("foo")
+ build_git "foo", path: lib_path("foo")
git_path = lib_path("foo")
revision = revision_for(git_path)
@@ -208,7 +208,7 @@ RSpec.describe "bundle clean" do
G
FileUtils.mkdir_p(bundled_app("real-path"))
- FileUtils.ln_sf(bundled_app("real-path"), bundled_app("symlink-path"))
+ File.symlink(bundled_app("real-path"), bundled_app("symlink-path"))
bundle "config set path #{bundled_app("symlink-path")}"
bundle "install"
@@ -221,7 +221,7 @@ RSpec.describe "bundle clean" do
end
it "removes old git gems" do
- build_git "foo-bar", :path => lib_path("foo-bar")
+ build_git "foo-bar", path: lib_path("foo-bar")
revision = revision_for(lib_path("foo-bar"))
gemfile <<-G
@@ -236,10 +236,10 @@ RSpec.describe "bundle clean" do
bundle "config set path vendor/bundle"
bundle "install"
- update_git "foo-bar", :path => lib_path("foo-bar")
+ update_git "foo-bar", path: lib_path("foo-bar")
revision2 = revision_for(lib_path("foo-bar"))
- bundle "update", :all => true
+ bundle "update", all: true
bundle :clean
expect(out).to include("Removing foo-bar (#{revision[0..11]})")
@@ -254,8 +254,8 @@ RSpec.describe "bundle clean" do
end
it "does not remove nested gems in a git repo" do
- build_lib "activesupport", "3.0", :path => lib_path("rails/activesupport")
- build_git "rails", "3.0", :path => lib_path("rails") do |s|
+ build_lib "activesupport", "3.0", path: lib_path("rails/activesupport")
+ build_git "rails", "3.0", path: lib_path("rails") do |s|
s.add_dependency "activesupport", "= 3.0"
end
revision = revision_for(lib_path("rails"))
@@ -274,7 +274,7 @@ RSpec.describe "bundle clean" do
end
it "does not remove git sources that are in without groups" do
- build_git "foo", :path => lib_path("foo")
+ build_git "foo", path: lib_path("foo")
git_path = lib_path("foo")
revision = revision_for(git_path)
@@ -326,7 +326,7 @@ RSpec.describe "bundle clean" do
gem "rack", "1.0.0"
G
- bundle :clean, :raise_on_error => false
+ bundle :clean, raise_on_error: false
expect(exitstatus).to eq(15)
expect(err).to include("--force")
@@ -383,7 +383,7 @@ RSpec.describe "bundle clean" do
expect(out).to include("rack (1.0.0)").and include("thin (1.0)")
end
- it "--clean should override the bundle setting on install", :bundler => "< 3" do
+ it "--clean should override the bundle setting on install", bundler: "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -405,7 +405,7 @@ RSpec.describe "bundle clean" do
should_not_have_gems "thin-1.0"
end
- it "--clean should override the bundle setting on update", :bundler => "< 3" do
+ it "--clean should override the bundle setting on update", bundler: "< 3" do
build_repo2
gemfile <<-G
@@ -421,13 +421,13 @@ RSpec.describe "bundle clean" do
build_gem "foo", "1.0.1"
end
- bundle "update", :all => true
+ bundle "update", all: true
should_have_gems "foo-1.0.1"
should_not_have_gems "foo-1.0"
end
- it "automatically cleans when path has not been set", :bundler => "3" do
+ it "automatically cleans when path has not been set", bundler: "3" do
build_repo2
install_gemfile <<-G
@@ -440,7 +440,7 @@ RSpec.describe "bundle clean" do
build_gem "foo", "1.0.1"
end
- bundle "update", :all => true
+ bundle "update", all: true
files = Pathname.glob(bundled_app(".bundle", Bundler.ruby_scope, "*", "*"))
files.map! {|f| f.to_s.sub(bundled_app(".bundle", Bundler.ruby_scope).to_s, "") }
@@ -486,7 +486,7 @@ RSpec.describe "bundle clean" do
build_gem "foo", "1.0.1"
end
- bundle :update, :all => true
+ bundle :update, all: true
should_have_gems "foo-1.0", "foo-1.0.1"
end
@@ -505,7 +505,7 @@ RSpec.describe "bundle clean" do
update_repo2 do
build_gem "foo", "1.0.1"
end
- bundle :update, :all => true
+ bundle :update, all: true
gem_command :list
expect(out).to include("foo (1.0.1, 1.0)")
@@ -560,7 +560,7 @@ RSpec.describe "bundle clean" do
FileUtils.chmod(0o500, system_cache_path)
- bundle :clean, :force => true, :raise_on_error => false
+ bundle :clean, force: true, raise_on_error: false
expect(err).to include(system_gem_path.to_s)
expect(err).to include("grant write permissions")
@@ -625,26 +625,22 @@ RSpec.describe "bundle clean" do
expect(out).to eq("1.0")
end
- it "when using --force, it doesn't remove default gem binaries" do
- skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
-
- skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
-
- default_irb_version = ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", :raise_on_error => false
+ it "when using --force, it doesn't remove default gem binaries", :realworld do
+ default_irb_version = ruby "gem 'irb', '< 999999'; require 'irb'; puts IRB::VERSION", raise_on_error: false
skip "irb isn't a default gem" if default_irb_version.empty?
# simulate executable for default gem
- build_gem "irb", default_irb_version, :to_system => true, :default => true do |s|
+ build_gem "irb", default_irb_version, to_system: true, default: true do |s|
s.executables = "irb"
end
- realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
+ realworld_system_gems "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
G
- bundle "clean --force", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
+ bundle "clean --force", env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
expect(out).not_to include("Removing irb")
end
@@ -787,7 +783,7 @@ RSpec.describe "bundle clean" do
should_not_have_gems "foo-1.0"
end
- it "doesn't remove extensions artifacts from bundled git gems after clean", :ruby_repo do
+ it "doesn't remove extensions artifacts from bundled git gems after clean" do
build_git "very_simple_git_binary", &:add_c_extension
revision = revision_for(lib_path("very_simple_git_binary-1.0"))
@@ -810,7 +806,7 @@ RSpec.describe "bundle clean" do
expect(vendored_gems("bundler/gems/very_simple_git_binary-1.0-#{revision[0..11]}")).to exist
end
- it "removes extension directories", :ruby_repo do
+ it "removes extension directories" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -846,7 +842,7 @@ RSpec.describe "bundle clean" do
expect(simple_binary_extensions_dir).to exist
end
- it "removes git extension directories", :ruby_repo do
+ it "removes git extension directories" do
build_git "very_simple_git_binary", &:add_c_extension
revision = revision_for(lib_path("very_simple_git_binary-1.0"))
@@ -905,7 +901,7 @@ RSpec.describe "bundle clean" do
bundle :lock
bundle "config set without development"
bundle "config set path vendor/bundle"
- bundle "install"
+ bundle "install", verbose: true
bundle :clean
very_simple_binary_extensions_dir =
diff --git a/spec/bundler/commands/config_spec.rb b/spec/bundler/commands/config_spec.rb
index 2d0a7dc989..547fd2d869 100644
--- a/spec/bundler/commands/config_spec.rb
+++ b/spec/bundler/commands/config_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe ".bundle/config" do
context "with env overwrite" do
it "prints config with env" do
- bundle "config list --parseable", :env => { "BUNDLE_FOO" => "bar3" }
+ bundle "config list --parseable", env: { "BUNDLE_FOO" => "bar3" }
expect(out).to include("foo=bar3")
end
end
@@ -43,6 +43,12 @@ RSpec.describe ".bundle/config" do
G
end
+ it "is local by default" do
+ bundle "config set foo bar"
+ expect(bundled_app(".bundle/config")).to exist
+ expect(home(".bundle/config")).not_to exist
+ end
+
it "can be moved with an environment variable" do
ENV["BUNDLE_APP_CONFIG"] = tmp("foo/bar").to_s
bundle "config set --local path vendor/bundle"
@@ -58,15 +64,21 @@ RSpec.describe ".bundle/config" do
ENV["BUNDLE_APP_CONFIG"] = "../foo"
bundle "config set --local path vendor/bundle"
- bundle "install", :dir => bundled_app("omg")
+ bundle "install", dir: bundled_app("omg")
expect(bundled_app(".bundle")).not_to exist
expect(bundled_app("../foo/config")).to exist
- expect(the_bundle).to include_gems "rack 1.0.0", :dir => bundled_app("omg")
+ expect(the_bundle).to include_gems "rack 1.0.0", dir: bundled_app("omg")
end
end
describe "location without a gemfile" do
+ it "is global by default" do
+ bundle "config set foo bar"
+ expect(bundled_app(".bundle/config")).not_to exist
+ expect(home(".bundle/config")).to exist
+ end
+
it "works with an absolute path" do
ENV["BUNDLE_APP_CONFIG"] = tmp("foo/bar").to_s
bundle "config set --local path vendor/bundle"
@@ -84,8 +96,8 @@ RSpec.describe ".bundle/config" do
end
it "can be configured through BUNDLE_USER_CONFIG" do
- bundle "config set path vendor", :env => { "BUNDLE_USER_CONFIG" => bundle_user_config }
- bundle "config get path", :env => { "BUNDLE_USER_CONFIG" => bundle_user_config }
+ bundle "config set path vendor", env: { "BUNDLE_USER_CONFIG" => bundle_user_config }
+ bundle "config get path", env: { "BUNDLE_USER_CONFIG" => bundle_user_config }
expect(out).to include("Set for the current user (#{bundle_user_config}): \"vendor\"")
end
@@ -93,8 +105,8 @@ RSpec.describe ".bundle/config" do
let(:bundle_user_home) { bundled_app(".bundle").to_s }
it "uses the right location" do
- bundle "config set path vendor", :env => { "BUNDLE_USER_HOME" => bundle_user_home }
- bundle "config get path", :env => { "BUNDLE_USER_HOME" => bundle_user_home }
+ bundle "config set path vendor", env: { "BUNDLE_USER_HOME" => bundle_user_home }
+ bundle "config get path", env: { "BUNDLE_USER_HOME" => bundle_user_home }
expect(out).to include("Set for the current user (#{bundle_user_home}/config): \"vendor\"")
end
end
@@ -131,17 +143,15 @@ RSpec.describe ".bundle/config" do
end
it "has lower precedence than env" do
- begin
- ENV["BUNDLE_FOO"] = "env"
+ ENV["BUNDLE_FOO"] = "env"
- bundle "config set --global foo global"
- expect(out).to match(/You have a bundler environment variable for foo set to "env"/)
+ bundle "config set --global foo global"
+ expect(out).to match(/You have a bundler environment variable for foo set to "env"/)
- run "puts Bundler.settings[:foo]"
- expect(out).to eq("env")
- ensure
- ENV.delete("BUNDLE_FOO")
- end
+ run "puts Bundler.settings[:foo]"
+ expect(out).to eq("env")
+ ensure
+ ENV.delete("BUNDLE_FOO")
end
it "can be deleted" do
@@ -209,15 +219,13 @@ RSpec.describe ".bundle/config" do
end
it "has higher precedence than env" do
- begin
- ENV["BUNDLE_FOO"] = "env"
- bundle "config set --local foo local"
-
- run "puts Bundler.settings[:foo]"
- expect(out).to eq("local")
- ensure
- ENV.delete("BUNDLE_FOO")
- end
+ ENV["BUNDLE_FOO"] = "env"
+ bundle "config set --local foo local"
+
+ run "puts Bundler.settings[:foo]"
+ expect(out).to eq("local")
+ ensure
+ ENV.delete("BUNDLE_FOO")
end
it "can be deleted" do
@@ -359,7 +367,7 @@ E
it "doesn't return quotes around values" do
bundle "config set foo '1'"
- run "puts Bundler.settings.send(:global_config_file).read"
+ run "puts Bundler.settings.send(:local_config_file).read"
expect(out).to include('"1"')
run "puts Bundler.settings[:foo]"
expect(out).to eq("1")
@@ -423,29 +431,57 @@ E
end
end
+ describe "commented out settings with urls" do
+ before do
+ bundle "config set #mirror.https://rails-assets.org http://localhost:9292"
+ end
+
+ it "does not make bundler crash and ignores the configuration" do
+ bundle "config list --parseable"
+
+ expect(out).to eq("#mirror.https://rails-assets.org/=http://localhost:9292")
+ expect(err).to be_empty
+
+ ruby(<<~RUBY)
+ require "bundler"
+ print Bundler.settings.mirror_for("https://rails-assets.org")
+ RUBY
+ expect(out).to eq("https://rails-assets.org/")
+ expect(err).to be_empty
+
+ bundle "config set mirror.all http://localhost:9293"
+ ruby(<<~RUBY)
+ require "bundler"
+ print Bundler.settings.mirror_for("https://rails-assets.org")
+ RUBY
+ expect(out).to eq("http://localhost:9293/")
+ expect(err).to be_empty
+ end
+ end
+
describe "subcommands" do
it "list" do
- bundle "config list"
- expect(out).to eq "Settings are listed in order of priority. The top value will be used.\nspec_run\nSet via BUNDLE_SPEC_RUN: \"true\""
+ bundle "config list", env: { "BUNDLE_FOO" => "bar" }
+ expect(out).to eq "Settings are listed in order of priority. The top value will be used.\nfoo\nSet via BUNDLE_FOO: \"bar\""
- bundle "config list", :parseable => true
- expect(out).to eq "spec_run=true"
+ bundle "config list", env: { "BUNDLE_FOO" => "bar" }, parseable: true
+ expect(out).to eq "foo=bar"
end
it "list with credentials" do
- bundle "config list", :env => { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
- expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"user:[REDACTED]\"\n\nspec_run\nSet via BUNDLE_SPEC_RUN: \"true\""
+ bundle "config list", env: { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
+ expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"user:[REDACTED]\""
- bundle "config list", :parseable => true, :env => { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
- expect(out).to eq "gems.myserver.com=user:password\nspec_run=true"
+ bundle "config list", parseable: true, env: { "BUNDLE_GEMS__MYSERVER__COM" => "user:password" }
+ expect(out).to eq "gems.myserver.com=user:password"
end
it "list with API token credentials" do
- bundle "config list", :env => { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
- expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"[REDACTED]:x-oauth-basic\"\n\nspec_run\nSet via BUNDLE_SPEC_RUN: \"true\""
+ bundle "config list", env: { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
+ expect(out).to eq "Settings are listed in order of priority. The top value will be used.\ngems.myserver.com\nSet via BUNDLE_GEMS__MYSERVER__COM: \"[REDACTED]:x-oauth-basic\""
- bundle "config list", :parseable => true, :env => { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
- expect(out).to eq "gems.myserver.com=api_token:x-oauth-basic\nspec_run=true"
+ bundle "config list", parseable: true, env: { "BUNDLE_GEMS__MYSERVER__COM" => "api_token:x-oauth-basic" }
+ expect(out).to eq "gems.myserver.com=api_token:x-oauth-basic"
end
it "get" do
@@ -479,7 +515,7 @@ E
bundle "config set --local foo 4.1"
expect(out).to eq "You are replacing the current local value of foo, which is currently \"4\""
- bundle "config set --global --local foo 5", :raise_on_error => false
+ bundle "config set --global --local foo 5", raise_on_error: false
expect(last_command).to be_failure
expect(err).to eq "The options global and local were specified. Please only use one of the switches at a time."
end
@@ -519,7 +555,7 @@ E
expect(out).to eq ""
expect(bundle("config get foo")).to eq "Settings for `foo` in order of priority. The top value will be used\nYou have not configured a value for `foo`"
- bundle "config unset foo --local --global", :raise_on_error => false
+ bundle "config unset foo --local --global", raise_on_error: false
expect(last_command).to be_failure
expect(err).to eq "The options global and local were specified. Please only use one of the switches at a time."
end
diff --git a/spec/bundler/commands/console_spec.rb b/spec/bundler/commands/console_spec.rb
index aa76096e3d..a41432b88a 100644
--- a/spec/bundler/commands/console_spec.rb
+++ b/spec/bundler/commands/console_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "bundle console", :bundler => "< 3", :readline => true do
+RSpec.describe "bundle console", bundler: "< 3", readline: true do
before :each do
build_repo2 do
# A minimal fake pry console
diff --git a/spec/bundler/commands/doctor_spec.rb b/spec/bundler/commands/doctor_spec.rb
index 860b638f06..666b23a141 100644
--- a/spec/bundler/commands/doctor_spec.rb
+++ b/spec/bundler/commands/doctor_spec.rb
@@ -38,6 +38,11 @@ RSpec.describe "bundle doctor" do
allow(stat).to receive(:uid) { Process.uid }
allow(File).to receive(:writable?).with(unwritable_file) { true }
allow(File).to receive(:readable?).with(unwritable_file) { true }
+
+ # The following lines are for `Gem::PathSupport#initialize`.
+ allow(File).to receive(:exist?).with(Gem.default_dir)
+ allow(File).to receive(:writable?).with(Gem.default_dir)
+ allow(File).to receive(:writable?).with(File.expand_path("..", Gem.default_dir))
end
it "exits with no message if the installed gem has no C extensions" do
@@ -49,8 +54,8 @@ RSpec.describe "bundle doctor" do
doctor = Bundler::CLI::Doctor.new({})
expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/lib/libSystem.dylib"]
- allow(File).to receive(:exist?).with("/usr/lib/libSystem.dylib").and_return(true)
- expect { doctor.run }.not_to(raise_error, @stdout.string)
+ allow(Fiddle).to receive(:dlopen).with("/usr/lib/libSystem.dylib").and_return(true)
+ expect { doctor.run }.not_to raise_error
expect(@stdout.string).to be_empty
end
@@ -58,8 +63,8 @@ RSpec.describe "bundle doctor" do
doctor = Bundler::CLI::Doctor.new({})
expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"]
- allow(File).to receive(:exist?).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_return(false)
- expect { doctor.run }.to raise_error(Bundler::ProductionError, strip_whitespace(<<-E).strip), @stdout.string
+ allow(Fiddle).to receive(:dlopen).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_raise(Fiddle::DLError)
+ expect { doctor.run }.to raise_error(Bundler::ProductionError, <<~E.strip), @stdout.string
The following gems are missing OS dependencies:
* bundler: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
* rack: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib
@@ -134,7 +139,7 @@ RSpec.describe "bundle doctor" do
end
end
- context "when home contains filesname with special characters" do
+ context "when home contains filenames with special characters" do
it "escape filename before command execute" do
doctor = Bundler::CLI::Doctor.new({})
expect(doctor).to receive(:`).with("/usr/bin/otool -L \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string")
diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb
index 2c4c33f374..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,22 +615,39 @@ 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.ruby_version >= Gem::Version.new("3.0.0") && Gem.rubygems_version < Gem::Version.new("3.3.0.a")
- skip "optparse is a default gem, and rubygems loads install during install"
+ 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", "~> 0.1.1"
+ s.add_dependency "optparse", "~> 999.999.999"
end
- build_gem "optparse", "0.1.0"
- build_gem "optparse", "0.1.1"
+ build_gem "optparse", "999.999.998"
+ build_gem "optparse", "999.999.999"
end
- system_gems "optparse-0.1.0", :gem_repo => gem_repo4
+ system_gems "optparse-999.999.998", gem_repo: gem_repo4
bundle "config set auto_install 1"
bundle "config set --local path vendor/bundle"
@@ -638,7 +658,7 @@ RSpec.describe "bundle exec" do
G
bundle "exec fastlane"
- expect(out).to include("Installing optparse 0.1.1")
+ expect(out).to include("Installing optparse 999.999.999")
expect(out).to include("2.192.0")
end
@@ -663,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')
@@ -686,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
@@ -694,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"
@@ -706,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)
@@ -727,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?
@@ -775,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
@@ -811,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
@@ -820,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
@@ -854,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)}"
@@ -866,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
@@ -881,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)}"
@@ -893,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
@@ -908,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 }
@@ -992,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
@@ -1019,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}
@@ -1064,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
@@ -1157,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?
@@ -1173,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)
@@ -1186,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
diff --git a/spec/bundler/commands/fund_spec.rb b/spec/bundler/commands/fund_spec.rb
index 5a0c5411da..5415b88eeb 100644
--- a/spec/bundler/commands/fund_spec.rb
+++ b/spec/bundler/commands/fund_spec.rb
@@ -5,20 +5,20 @@ RSpec.describe "bundle fund" do
build_repo2 do
build_gem "has_funding_and_other_metadata" do |s|
s.metadata = {
- "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
- "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
+ "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
+ "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
"documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
- "homepage_uri" => "https://bestgemever.example.io",
- "mailing_list_uri" => "https://groups.example.com/bestgemever",
- "funding_uri" => "https://example.com/has_funding_and_other_metadata/funding",
- "source_code_uri" => "https://example.com/user/bestgemever",
- "wiki_uri" => "https://example.com/user/bestgemever/wiki",
+ "homepage_uri" => "https://bestgemever.example.io",
+ "mailing_list_uri" => "https://groups.example.com/bestgemever",
+ "funding_uri" => "https://example.com/has_funding_and_other_metadata/funding",
+ "source_code_uri" => "https://example.com/user/bestgemever",
+ "wiki_uri" => "https://example.com/user/bestgemever/wiki",
}
end
build_gem "has_funding", "1.2.3" do |s|
s.metadata = {
- "funding_uri" => "https://example.com/has_funding/funding",
+ "funding_uri" => "https://example.com/has_funding/funding",
}
end
diff --git a/spec/bundler/commands/help_spec.rb b/spec/bundler/commands/help_spec.rb
index f72763900e..0c7031e813 100644
--- a/spec/bundler/commands/help_spec.rb
+++ b/spec/bundler/commands/help_spec.rb
@@ -15,6 +15,13 @@ RSpec.describe "bundle help" do
expect(out).to eq(%(["#{man_dir}/bundle-install.1"]))
end
+ it "prexifes bundle commands with bundle- and resolves aliases when finding the man files" do
+ with_fake_man do
+ bundle "help package"
+ end
+ expect(out).to eq(%(["#{man_dir}/bundle-cache.1"]))
+ end
+
it "simply outputs the human readable file when there is no man on the path" do
with_path_as("") do
bundle "help install"
@@ -23,8 +30,8 @@ RSpec.describe "bundle help" do
end
it "still outputs the old help for commands that do not have man pages yet" do
- bundle "help version"
- expect(out).to include("Prints the bundler's version information")
+ bundle "help fund"
+ expect(out).to include("Lists information about gems seeking funding assistance")
end
it "looks for a binary and executes it with --help option if it's named bundler-<task>" do
@@ -71,7 +78,7 @@ RSpec.describe "bundle help" do
it "has helpful output when using --help flag for a non-existent command" do
with_fake_man do
- bundle "instill -h", :raise_on_error => false
+ bundle "instill -h", raise_on_error: false
end
expect(err).to include('Could not find command "instill".')
end
diff --git a/spec/bundler/commands/info_spec.rb b/spec/bundler/commands/info_spec.rb
index dbfb800c4c..a5a09bc147 100644
--- a/spec/bundler/commands/info_spec.rb
+++ b/spec/bundler/commands/info_spec.rb
@@ -6,13 +6,13 @@ RSpec.describe "bundle info" do
build_repo2 do
build_gem "has_metadata" do |s|
s.metadata = {
- "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
- "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
+ "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
+ "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
"documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
- "homepage_uri" => "https://bestgemever.example.io",
- "mailing_list_uri" => "https://groups.example.com/bestgemever",
- "source_code_uri" => "https://example.com/user/bestgemever",
- "wiki_uri" => "https://example.com/user/bestgemever/wiki",
+ "homepage_uri" => "https://bestgemever.example.io",
+ "mailing_list_uri" => "https://groups.example.com/bestgemever",
+ "source_code_uri" => "https://example.com/user/bestgemever",
+ "wiki_uri" => "https://example.com/user/bestgemever/wiki",
}
end
end
@@ -21,6 +21,7 @@ RSpec.describe "bundle info" do
source "#{file_uri_for(gem_repo2)}"
gem "rails"
gem "has_metadata"
+ gem "thin"
G
end
@@ -50,6 +51,11 @@ RSpec.describe "bundle info" do
expect(out).to eq(root.to_s)
end
+ it "prints gem version if exists in bundle" do
+ bundle "info rails --version"
+ expect(out).to eq("2.3.2")
+ end
+
it "doesn't claim that bundler has been deleted, even if using a custom path without bundler there" do
bundle "config set --local path vendor/bundle"
bundle "install"
@@ -59,7 +65,7 @@ RSpec.describe "bundle info" do
end
it "complains if gem not in bundle" do
- bundle "info missing", :raise_on_error => false
+ bundle "info missing", raise_on_error: false
expect(err).to eq("Could not find gem 'missing'.")
end
@@ -68,16 +74,16 @@ RSpec.describe "bundle info" do
bundle "info rails --path"
- expect(err).to match(/The gem rails has been deleted/i)
- expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
+ expect(err).to include("The gem rails has been deleted.")
+ expect(err).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
bundle "info rail --path"
- expect(err).to match(/The gem rails has been deleted/i)
- expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
+ expect(err).to include("The gem rails has been deleted.")
+ expect(err).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
bundle "info rails"
- expect(err).to match(/The gem rails has been deleted/i)
- expect(err).to match(default_bundle_path("gems", "rails-2.3.2").to_s)
+ expect(err).to include("The gem rails has been deleted.")
+ expect(err).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
end
context "given a default gem shippped in ruby", :ruby_repo do
@@ -118,6 +124,30 @@ RSpec.describe "bundle info" do
expect(out).to_not include("Homepage:")
end
end
+
+ context "when gem has a reverse dependency on any version" do
+ it "prints the details" do
+ bundle "info rack"
+
+ expect(out).to include("Reverse Dependencies: \n\t\tthin (1.0) depends on rack (>= 0)")
+ end
+ end
+
+ context "when gem has a reverse dependency on a specific version" do
+ it "prints the details" do
+ bundle "info actionpack"
+
+ expect(out).to include("Reverse Dependencies: \n\t\trails (2.3.2) depends on actionpack (= 2.3.2)")
+ end
+ end
+
+ context "when gem has no reverse dependencies" do
+ it "excludes the reverse dependencies field from the output" do
+ bundle "info rails"
+
+ expect(out).not_to include("Reverse Dependencies:")
+ end
+ end
end
context "with a git repo in the Gemfile" do
@@ -133,11 +163,11 @@ RSpec.describe "bundle info" do
expect(the_bundle).to include_gems "foo 1.0"
bundle "info foo"
- expect(out).to include("foo (1.0 #{@git.ref_for("master", 6)}")
+ expect(out).to include("foo (1.0 #{@git.ref_for("main", 6)}")
end
- it "prints out branch names other than master" do
- update_git "foo", :branch => "omg" do |s|
+ it "prints out branch names other than main" do
+ update_git "foo", branch: "omg" do |s|
s.write "lib/foo.rb", "FOO = '1.0.omg'"
end
@revision = revision_for(lib_path("foo-1.0"))[0...6]
@@ -164,7 +194,7 @@ RSpec.describe "bundle info" do
end
it "handles when a version is a '-' prerelease" do
- @git = build_git("foo", "1.0.0-beta.1", :path => lib_path("foo"))
+ @git = build_git("foo", "1.0.0-beta.1", path: lib_path("foo"))
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "foo", "1.0.0-beta.1", :git => "#{lib_path("foo")}"
@@ -185,7 +215,7 @@ RSpec.describe "bundle info" do
G
bundle "info rac"
- expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>)?\z/)
+ expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>.*)?\z/)
end
end
@@ -198,7 +228,7 @@ RSpec.describe "bundle info" do
invalid_regexp = "[]"
- bundle "info #{invalid_regexp}", :raise_on_error => false
+ bundle "info #{invalid_regexp}", raise_on_error: false
expect(err).to include("Could not find gem '#{invalid_regexp}'.")
end
end
@@ -212,7 +242,7 @@ RSpec.describe "bundle info" do
gem "rails", group: :test
G
- bundle "info rails", :raise_on_error => false
+ bundle "info rails", raise_on_error: false
expect(err).to include("Could not find gem 'rails', because it's in the group 'test', configured to be ignored.")
end
end
diff --git a/spec/bundler/commands/init_spec.rb b/spec/bundler/commands/init_spec.rb
index 683a453c7d..0a1336572a 100644
--- a/spec/bundler/commands/init_spec.rb
+++ b/spec/bundler/commands/init_spec.rb
@@ -7,6 +7,29 @@ RSpec.describe "bundle init" do
expect(bundled_app_gemfile).to be_file
end
+ context "with a template with permission flags not matching current process umask" do
+ let(:template_file) do
+ gemfile = Bundler.preferred_gemfile_name
+ templates_dir.join(gemfile)
+ end
+
+ let(:target_dir) { bundled_app("init_permissions_test") }
+
+ around do |example|
+ old_chmod = File.stat(template_file).mode
+ FileUtils.chmod(old_chmod | 0o111, template_file) # chmod +x
+ example.run
+ FileUtils.chmod(old_chmod, template_file)
+ end
+
+ it "honours the current process umask when generating from a template" do
+ FileUtils.mkdir(target_dir)
+ bundle :init, dir: target_dir
+ generated_mode = File.stat(File.join(target_dir, "Gemfile")).mode & 0o111
+ expect(generated_mode).to be_zero
+ end
+ end
+
context "when a Gemfile already exists" do
before do
create_file "Gemfile", <<-G
@@ -15,11 +38,11 @@ RSpec.describe "bundle init" do
end
it "does not change existing Gemfiles" do
- expect { bundle :init, :raise_on_error => false }.not_to change { File.read(bundled_app_gemfile) }
+ expect { bundle :init, raise_on_error: false }.not_to change { File.read(bundled_app_gemfile) }
end
it "notifies the user that an existing Gemfile already exists" do
- bundle :init, :raise_on_error => false
+ bundle :init, raise_on_error: false
expect(err).to include("Gemfile already exists")
end
end
@@ -32,7 +55,7 @@ RSpec.describe "bundle init" do
FileUtils.mkdir bundled_app(subdir)
- bundle :init, :dir => bundled_app(subdir)
+ bundle :init, dir: bundled_app(subdir)
expect(out).to include("Writing new Gemfile")
expect(bundled_app("#{subdir}/Gemfile")).to be_file
@@ -42,13 +65,13 @@ RSpec.describe "bundle init" do
context "when the dir is not writable by the current user" do
let(:subdir) { "child_dir" }
- it "notifies the user that it can not write to it" do
+ it "notifies the user that it cannot write to it" do
FileUtils.mkdir bundled_app(subdir)
# chmod a-w it
mode = File.stat(bundled_app(subdir)).mode ^ 0o222
FileUtils.chmod mode, bundled_app(subdir)
- bundle :init, :dir => bundled_app(subdir), :raise_on_error => false
+ bundle :init, dir: bundled_app(subdir), raise_on_error: false
expect(err).to include("directory is not writable")
expect(Dir[bundled_app("#{subdir}/*")]).to be_empty
@@ -69,7 +92,7 @@ RSpec.describe "bundle init" do
S
end
- bundle :init, :gemspec => spec_file
+ bundle :init, gemspec: spec_file
gemfile = bundled_app_gemfile.read
expect(gemfile).to match(%r{source 'https://rubygems.org'})
@@ -89,7 +112,7 @@ RSpec.describe "bundle init" do
S
end
- bundle :init, :gemspec => spec_file, :raise_on_error => false
+ bundle :init, gemspec: spec_file, raise_on_error: false
expect(err).to include("There was an error while loading `test.gemspec`")
end
end
@@ -112,11 +135,11 @@ RSpec.describe "bundle init" do
end
it "does not change existing Gemfiles" do
- expect { bundle :init, :raise_on_error => false }.not_to change { File.read(bundled_app("gems.rb")) }
+ expect { bundle :init, raise_on_error: false }.not_to change { File.read(bundled_app("gems.rb")) }
end
it "notifies the user that an existing gems.rb already exists" do
- bundle :init, :raise_on_error => false
+ bundle :init, raise_on_error: false
expect(err).to include("gems.rb already exists")
end
end
@@ -129,7 +152,7 @@ RSpec.describe "bundle init" do
FileUtils.mkdir bundled_app(subdir)
- bundle :init, :dir => bundled_app(subdir)
+ bundle :init, dir: bundled_app(subdir)
expect(out).to include("Writing new gems.rb")
expect(bundled_app("#{subdir}/gems.rb")).to be_file
@@ -152,7 +175,7 @@ RSpec.describe "bundle init" do
end
it "should generate from an existing gemspec" do
- bundle :init, :gemspec => spec_file
+ bundle :init, gemspec: spec_file
gemfile = bundled_app("gems.rb").read
expect(gemfile).to match(%r{source 'https://rubygems.org'})
@@ -162,10 +185,23 @@ RSpec.describe "bundle init" do
end
it "prints message to user" do
- bundle :init, :gemspec => spec_file
+ bundle :init, gemspec: spec_file
expect(out).to include("Writing new gems.rb")
end
end
end
+
+ describe "using the --gemfile" do
+ it "should use the --gemfile value to name the gemfile" do
+ custom_gemfile_name = "NiceGemfileName"
+
+ bundle :init, gemfile: custom_gemfile_name
+
+ expect(out).to include("Writing new #{custom_gemfile_name}")
+ used_template = File.read("#{source_root}/lib/bundler/templates/Gemfile")
+ generated_gemfile = bundled_app(custom_gemfile_name).read
+ expect(generated_gemfile).to eq(used_template)
+ end
+ end
end
diff --git a/spec/bundler/commands/inject_spec.rb b/spec/bundler/commands/inject_spec.rb
index 2d97bf6ff0..255a03c135 100644
--- a/spec/bundler/commands/inject_spec.rb
+++ b/spec/bundler/commands/inject_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "bundle inject", :bundler => "< 3" do
+RSpec.describe "bundle inject", bundler: "< 3" do
before :each do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -36,14 +36,14 @@ RSpec.describe "bundle inject", :bundler => "< 3" do
context "with injected gems already in the Gemfile" do
it "doesn't add existing gems" do
- bundle "inject 'rack' '> 0'", :raise_on_error => false
+ bundle "inject 'rack' '> 0'", raise_on_error: false
expect(err).to match(/cannot specify the same gem twice/i)
end
end
context "incorrect arguments" do
it "fails when more than 2 arguments are passed" do
- bundle "inject gem_name 1 v", :raise_on_error => false
+ bundle "inject gem_name 1 v", raise_on_error: false
expect(err).to eq(<<-E.strip)
ERROR: "bundle inject" was called with arguments ["gem_name", "1", "v"]
Usage: "bundle inject GEM VERSION"
@@ -99,7 +99,7 @@ Usage: "bundle inject GEM VERSION"
it "restores frozen afterwards" do
bundle "inject 'rack-obama' '> 0'"
- config = YAML.load(bundled_app(".bundle/config").read)
+ config = Psych.load(bundled_app(".bundle/config").read)
expect(config["BUNDLE_DEPLOYMENT"] || config["BUNDLE_FROZEN"]).to eq("true")
end
@@ -108,8 +108,8 @@ Usage: "bundle inject GEM VERSION"
source "#{file_uri_for(gem_repo1)}"
gem "rack-obama"
G
- bundle "inject 'rack' '> 0'", :raise_on_error => false
- expect(err).to match(/trying to install in deployment mode after changing/)
+ bundle "inject 'rack' '> 0'", raise_on_error: false
+ expect(err).to match(/the lockfile can't be updated because frozen mode is set/)
expect(bundled_app_lock.read).not_to match(/rack-obama/)
end
diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb
index e00caa5315..f0c9aaea8e 100644
--- a/spec/bundler/commands/install_spec.rb
+++ b/spec/bundler/commands/install_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "does not make a lockfile if the install fails" do
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
raise StandardError, "FAIL"
G
@@ -29,7 +29,7 @@ RSpec.describe "bundle install with gem sources" do
expect(bundled_app_lock).to exist
end
- it "does not create ./.bundle by default", :bundler => "< 3" do
+ it "does not create ./.bundle by default", bundler: "< 3" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -45,7 +45,7 @@ RSpec.describe "bundle install with gem sources" do
gem "rack"
G
- bundle :install, :env => { "BUNDLE_PATH__SYSTEM" => "true" } # can't use install_gemfile since it sets retry
+ bundle :install, env: { "BUNDLE_PATH__SYSTEM" => "true" } # can't use install_gemfile since it sets retry
expect(bundled_app(".bundle")).not_to exist
end
@@ -68,7 +68,7 @@ RSpec.describe "bundle install with gem sources" do
lockfile = File.read(bundled_app_lock)
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
raise StandardError, "FAIL"
G
@@ -130,7 +130,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "raises an appropriate error when gems are specified using symbols" do
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
source "#{file_uri_for(gem_repo1)}"
gem :rack
G
@@ -197,7 +197,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "does not reinstall any gem that is already available locally" do
- system_gems "activesupport-2.3.2", :path => default_bundle_path
+ system_gems "activesupport-2.3.2", path: default_bundle_path
build_repo2 do
build_gem "activesupport", "2.3.2" do |s|
@@ -214,7 +214,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "works when the gemfile specifies gems that only exist in the system" do
- build_gem "foo", :to_bundle => true
+ build_gem "foo", to_bundle: true
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@@ -225,7 +225,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "prioritizes local gems over remote gems" do
- build_gem "rack", "1.0.0", :to_bundle => true do |s|
+ build_gem "rack", "1.0.0", to_bundle: true do |s|
s.add_dependency "activesupport", "2.3.5"
end
@@ -241,7 +241,7 @@ RSpec.describe "bundle install with gem sources" do
plugin_msg = "hello from an env plugin!"
create_file "plugins/rubygems_plugin.rb", "puts '#{plugin_msg}'"
rubylib = ENV["RUBYLIB"].to_s.split(File::PATH_SEPARATOR).unshift(bundled_app("plugins").to_s).join(File::PATH_SEPARATOR)
- install_gemfile <<-G, :env => { "RUBYLIB" => rubylib }
+ install_gemfile <<-G, env: { "RUBYLIB" => rubylib }
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
@@ -285,7 +285,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "installs gems for windows" do
- simulate_platform mswin
+ simulate_platform x86_mswin32
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -293,7 +293,7 @@ RSpec.describe "bundle install with gem sources" do
G
run "require 'platform_specific' ; puts PLATFORM_SPECIFIC"
- expect(out).to eq("1.0.0 MSWIN")
+ expect(out).to eq("1.0 x86-mswin32")
end
end
@@ -311,14 +311,14 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems "rack 1.0"
end
- it "allows running bundle install --system without deleting foo", :bundler => "< 3" do
+ it "allows running bundle install --system without deleting foo", bundler: "< 3" do
bundle "install --path vendor"
bundle "install --system"
FileUtils.rm_rf(bundled_app("vendor"))
expect(the_bundle).to include_gems "rack 1.0"
end
- it "allows running bundle install --system after deleting foo", :bundler => "< 3" do
+ it "allows running bundle install --system after deleting foo", bundler: "< 3" do
bundle "install --path vendor"
FileUtils.rm_rf(bundled_app("vendor"))
bundle "install --system"
@@ -326,7 +326,7 @@ RSpec.describe "bundle install with gem sources" do
end
end
- it "finds gems in multiple sources", :bundler => "< 3" do
+ it "finds gems in multiple sources", bundler: "< 3" do
build_repo2 do
build_gem "rack", "1.2" do |s|
s.executables = "rackup"
@@ -345,7 +345,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "gives a useful error if no sources are set" do
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
gem "rack"
G
@@ -364,7 +364,9 @@ RSpec.describe "bundle install with gem sources" do
end
it "throws a warning if a gem is added twice in Gemfile without version requirements" do
- install_gemfile <<-G, :raise_on_error => false
+ build_repo2
+
+ install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "rack"
gem "rack"
@@ -376,7 +378,9 @@ RSpec.describe "bundle install with gem sources" do
end
it "throws a warning if a gem is added twice in Gemfile with same versions" do
- install_gemfile <<-G, :raise_on_error => false
+ build_repo2
+
+ install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "rack", "1.0"
gem "rack", "1.0"
@@ -387,8 +391,24 @@ RSpec.describe "bundle install with gem sources" do
expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.")
end
+ it "throws a warning if a gem is added twice under different platforms and does not crash when using the generated lockfile" do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack", :platform => :jruby
+ gem "rack"
+ G
+
+ bundle "install"
+
+ expect(err).to include("Your Gemfile lists the gem rack (>= 0) more than once.")
+ expect(err).to include("Remove any duplicate entries and specify the gem only once.")
+ expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.")
+ end
+
it "does not throw a warning if a gem is added once in Gemfile and also inside a gemspec as a development dependency" do
- build_lib "my-gem", :path => bundled_app do |s|
+ build_lib "my-gem", path: bundled_app do |s|
s.add_development_dependency "my-private-gem"
end
@@ -410,8 +430,155 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems("my-private-gem 1.0")
end
+ it "throws a warning if a gem is added once in Gemfile and also inside a gemspec as a development dependency, with different requirements" do
+ build_lib "my-gem", path: bundled_app do |s|
+ s.add_development_dependency "rubocop", "~> 1.36.0"
+ end
+
+ build_repo4 do
+ build_gem "rubocop", "1.36.0"
+ build_gem "rubocop", "1.37.1"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gemspec
+
+ gem "rubocop", group: :development
+ G
+
+ bundle :install
+
+ expect(err).to include("A gemspec development dependency (rubocop, ~> 1.36.0) is being overridden by a Gemfile dependency (rubocop, >= 0).")
+ expect(err).to include("This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement")
+
+ # This is not the best behavior I believe, it would be better if both
+ # requirements are considered if they are compatible, and a version
+ # satisfying both is chosen. But not sure about changing it right now, so
+ # I went with a warning for the time being.
+ expect(the_bundle).to include_gems("rubocop 1.37.1")
+ end
+
+ it "includes the gem without warning if two gemspecs add it with the same requirement" do
+ gem1 = tmp.join("my-gem-1")
+ gem2 = tmp.join("my-gem-2")
+
+ build_lib "my-gem", path: gem1 do |s|
+ s.add_development_dependency "rubocop", "~> 1.36.0"
+ end
+
+ build_lib "my-gem-2", path: gem2 do |s|
+ s.add_development_dependency "rubocop", "~> 1.36.0"
+ end
+
+ build_repo4 do
+ build_gem "rubocop", "1.36.0"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gemspec path: "#{gem1}"
+ gemspec path: "#{gem2}"
+ G
+
+ bundle :install
+
+ expect(err).to be_empty
+ expect(the_bundle).to include_gems("rubocop 1.36.0")
+ end
+
+ it "warns when a Gemfile dependency is overriding a gemspec development dependency, with different requirements" do
+ build_lib "my-gem", path: bundled_app do |s|
+ s.add_development_dependency "rails", ">= 5"
+ end
+
+ build_repo4 do
+ build_gem "rails", "7.0.8"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "rails", "~> 7.0.8"
+
+ gemspec
+ G
+
+ bundle :install
+
+ expect(err).to include("A gemspec development dependency (rails, >= 5) is being overridden by a Gemfile dependency (rails, ~> 7.0.8).")
+ expect(err).to include("This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement")
+
+ # This is not the best behavior I believe, it would be better if both
+ # requirements are considered if they are compatible, and a version
+ # satisfying both is chosen. But not sure about changing it right now, so
+ # I went with a warning for the time being.
+ expect(the_bundle).to include_gems("rails 7.0.8")
+ end
+
+ it "does not warn if a gem is added once in Gemfile and also inside a gemspec as a development dependency, with same requirements, and different sources" do
+ build_lib "my-gem", path: bundled_app do |s|
+ s.add_development_dependency "activesupport"
+ end
+
+ build_repo4 do
+ build_gem "activesupport"
+ end
+
+ build_git "activesupport", "1.0", path: lib_path("activesupport")
+
+ install_gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gemspec
+
+ gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}"
+ G
+
+ expect(err).to be_empty
+ expect(the_bundle).to include_gems "activesupport 1.0", source: "git@#{lib_path("activesupport")}"
+
+ # if the Gemfile dependency is specified first
+ install_gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}"
+
+ gemspec
+ G
+
+ expect(err).to be_empty
+ expect(the_bundle).to include_gems "activesupport 1.0", source: "git@#{lib_path("activesupport")}"
+ end
+
+ it "considers both dependencies for resolution if a gem is added once in Gemfile and also inside a local gemspec as a runtime dependency, with different requirements" do
+ build_lib "my-gem", path: bundled_app do |s|
+ s.add_dependency "rubocop", "~> 1.36.0"
+ end
+
+ build_repo4 do
+ build_gem "rubocop", "1.36.0"
+ build_gem "rubocop", "1.37.1"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gemspec
+
+ gem "rubocop"
+ G
+
+ bundle :install
+
+ expect(err).to be_empty
+ expect(the_bundle).to include_gems("rubocop 1.36.0")
+ end
+
it "throws an error if a gem is added twice in Gemfile when version of one dependency is not specified" do
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
source "#{file_uri_for(gem_repo2)}"
gem "rack"
gem "rack", "1.0"
@@ -422,7 +589,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "throws an error if a gem is added twice in Gemfile when different versions of both dependencies are specified" do
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
source "#{file_uri_for(gem_repo2)}"
gem "rack", "1.0"
gem "rack", "1.1"
@@ -435,7 +602,7 @@ RSpec.describe "bundle install with gem sources" do
it "gracefully handles error when rubygems server is unavailable" do
skip "networking issue" if Gem.win_platform?
- install_gemfile <<-G, :artifice => nil, :raise_on_error => false
+ install_gemfile <<-G, artifice: nil, raise_on_error: false
source "#{file_uri_for(gem_repo1)}"
source "http://0.0.0.0:9384" do
gem 'foo'
@@ -447,8 +614,8 @@ RSpec.describe "bundle install with gem sources" do
end
it "fails gracefully when downloading an invalid specification from the full index" do
- build_repo2 do
- build_gem "ajp-rails", "0.0.0", :gemspec => false, :skip_validation => true do |s|
+ build_repo2(build_compact_index: false) do
+ build_gem "ajp-rails", "0.0.0", gemspec: false, skip_validation: true do |s|
bad_deps = [["ruby-ajp", ">= 0.2.0"], ["rails", ">= 0.14"]]
s.
instance_variable_get(:@spec).
@@ -459,7 +626,7 @@ RSpec.describe "bundle install with gem sources" do
build_gem "ruby-ajp", "1.0.0"
end
- install_gemfile <<-G, :full_index => true, :raise_on_error => false
+ install_gemfile <<-G, full_index: true, raise_on_error: false
source "#{file_uri_for(gem_repo2)}"
gem "ajp-rails", "0.0.0"
@@ -494,30 +661,26 @@ RSpec.describe "bundle install with gem sources" do
end
describe "Ruby version in Gemfile.lock" do
- include Bundler::GemHelpers
-
context "and using an unsupported Ruby version" do
it "prints an error" do
- install_gemfile <<-G, :raise_on_error => false
- ::RUBY_VERSION = '2.0.1'
- ruby '~> 2.2'
+ install_gemfile <<-G, raise_on_error: false
+ ruby '~> 1.2'
source "#{file_uri_for(gem_repo1)}"
G
- expect(err).to include("Your Ruby version is 2.0.1, but your Gemfile specified ~> 2.2")
+ expect(err).to include("Your Ruby version is #{Gem.ruby_version}, but your Gemfile specified ~> 1.2")
end
end
context "and using a supported Ruby version" do
before do
install_gemfile <<-G
- ::RUBY_VERSION = '2.1.3'
- ::RUBY_PATCHLEVEL = 100
- ruby '~> 2.1.0'
+ ruby '~> #{Gem.ruby_version}'
source "#{file_uri_for(gem_repo1)}"
G
end
it "writes current Ruby version to Gemfile.lock" do
+ checksums = checksums_section_when_existing
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -527,23 +690,23 @@ RSpec.describe "bundle install with gem sources" do
#{lockfile_platforms}
DEPENDENCIES
-
+ #{checksums}
RUBY VERSION
- ruby 2.1.3p100
+ #{Bundler::RubyVersion.system}
BUNDLED WITH
#{Bundler::VERSION}
L
end
- it "updates Gemfile.lock with updated incompatible ruby version" do
+ it "updates Gemfile.lock with updated yet still compatible ruby version" do
install_gemfile <<-G
- ::RUBY_VERSION = '2.2.3'
- ::RUBY_PATCHLEVEL = 100
- ruby '~> 2.2.0'
+ ruby '~> #{current_ruby_minor}'
source "#{file_uri_for(gem_repo1)}"
G
+ checksums = checksums_section_when_existing
+
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
@@ -553,9 +716,9 @@ RSpec.describe "bundle install with gem sources" do
#{lockfile_platforms}
DEPENDENCIES
-
+ #{checksums}
RUBY VERSION
- ruby 2.2.3p100
+ #{Bundler::RubyVersion.system}
BUNDLED WITH
#{Bundler::VERSION}
@@ -590,7 +753,7 @@ RSpec.describe "bundle install with gem sources" do
file.puts gemfile
end
- bundle :install, :dir => root_dir
+ bundle :install, dir: root_dir
end
it "doesn't blow up when using the `gemspec` DSL" do
@@ -598,7 +761,7 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.mkdir_p(root_dir)
- build_lib "foo", :path => root_dir
+ build_lib "foo", path: root_dir
gemfile = <<-G
source "#{file_uri_for(gem_repo1)}"
gemspec
@@ -607,7 +770,7 @@ RSpec.describe "bundle install with gem sources" do
file.puts gemfile
end
- bundle :install, :dir => root_dir
+ bundle :install, dir: root_dir
end
end
@@ -620,7 +783,7 @@ RSpec.describe "bundle install with gem sources" do
gem 'rack'
G
- bundle :install, :quiet => true
+ bundle :install, quiet: true
expect(out).to be_empty
expect(err).to be_empty
end
@@ -650,7 +813,7 @@ RSpec.describe "bundle install with gem sources" do
gem 'non-existing-gem'
G
- bundle :install, :quiet => true, :raise_on_error => false, :env => { "RUBYOPT" => "-r#{bundled_app("install_with_warning.rb")}" }
+ bundle :install, quiet: true, raise_on_error: false, env: { "RUBYOPT" => "-r#{bundled_app("install_with_warning.rb")}" }
expect(out).to be_empty
expect(err).to include("Could not find gem 'non-existing-gem'")
expect(err).to include("BOOOOO")
@@ -672,7 +835,7 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.chmod(0o500, bundle_path)
bundle "config set --local path vendor"
- bundle :install, :raise_on_error => false
+ bundle :install, raise_on_error: false
expect(err).to include(bundle_path.to_s)
expect(err).to include("grant write permissions")
end
@@ -694,7 +857,7 @@ RSpec.describe "bundle install with gem sources" do
bundle "config set --local path vendor"
begin
- bundle :install, :raise_on_error => false
+ bundle :install, raise_on_error: false
ensure
FileUtils.chmod("+x", gems_path)
end
@@ -708,6 +871,36 @@ RSpec.describe "bundle install with gem sources" do
end
end
+ describe "when bundle extensions path does not have write access", :permissions do
+ let(:extensions_path) { bundled_app("vendor/#{Bundler.ruby_scope}/extensions/#{Gem::Platform.local}/#{Gem.extension_api_version}") }
+
+ before do
+ FileUtils.mkdir_p(extensions_path)
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'simple_binary'
+ G
+ end
+
+ it "should display a proper message to explain the problem" do
+ FileUtils.chmod("-x", extensions_path)
+ bundle "config set --local path vendor"
+
+ begin
+ bundle :install, raise_on_error: false
+ ensure
+ FileUtils.chmod("+x", extensions_path)
+ end
+
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+
+ expect(err).to include(
+ "There was an error while trying to create `#{extensions_path.join("simple_binary-1.0")}`. " \
+ "It is likely that you need to grant executable permissions for all parent directories and write permissions for `#{extensions_path}`."
+ )
+ end
+ end
+
describe "when the path of a specific gem is not writable", :permissions do
let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") }
let(:foo_path) { gems_path.join("foo-1.0.0") }
@@ -734,18 +927,79 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.chmod("-x", foo_path)
begin
- bundle "install --redownload", :raise_on_error => false
+ bundle "install --redownload", raise_on_error: false
ensure
FileUtils.chmod("+x", foo_path)
end
expect(err).not_to include("ERROR REPORT TEMPLATE")
+ expect(err).to include("Could not delete previous installation of `#{foo_path}`.")
+ expect(err).to include("The underlying error was Errno::EACCES")
+ end
+ end
- expect(err).to include(
- "There was an error while trying to delete `#{foo_path}`. " \
- "It is likely that you need to grant executable permissions for all parent directories " \
- "and write permissions for `#{gems_path}`, and the same thing for all subdirectories inside #{foo_path}."
- )
+ describe "when gem home does not have the writable bit set, yet it's still writable", :permissions do
+ let(:gem_home) { bundled_app("vendor/#{Bundler.ruby_scope}") }
+
+ before do
+ build_repo4 do
+ build_gem "foo", "1.0.0" do |s|
+ s.write "CHANGELOG.md", "foo"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'foo'
+ G
+ end
+
+ it "should display a proper message to explain the problem" do
+ bundle "config set --local path vendor"
+ bundle :install
+ expect(out).to include("Bundle complete!")
+ expect(err).to be_empty
+
+ FileUtils.chmod("-w", gem_home)
+
+ begin
+ bundle "install --redownload"
+ ensure
+ FileUtils.chmod("+w", gem_home)
+ end
+
+ expect(out).to include("Bundle complete!")
+ expect(err).to be_empty
+ end
+ end
+
+ describe "when gems path is world writable (no sticky bit set)", :permissions do
+ let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") }
+
+ before do
+ build_repo4 do
+ build_gem "foo", "1.0.0" do |s|
+ s.write "CHANGELOG.md", "foo"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'foo'
+ G
+ end
+
+ it "should display a proper message to explain the problem" do
+ bundle "config set --local path vendor"
+ bundle :install
+ expect(out).to include("Bundle complete!")
+ expect(err).to be_empty
+
+ FileUtils.chmod(0o777, gems_path)
+
+ bundle "install --redownload", raise_on_error: false
+
+ expect(err).to include("The installation path is insecure. Bundler cannot continue.")
end
end
@@ -764,7 +1018,7 @@ RSpec.describe "bundle install with gem sources" do
FileUtils.chmod(0o500, cache_path)
bundle "config set --local path vendor"
- bundle :install, :raise_on_error => false
+ bundle :install, raise_on_error: false
expect(err).to include(cache_path.to_s)
expect(err).to include("grant write permissions")
end
@@ -777,13 +1031,13 @@ RSpec.describe "bundle install with gem sources" do
gem "rack"
G
bundle "config set --local path bundle"
- bundle "install", :standalone => true
+ bundle "install", standalone: true
end
it "includes the standalone path" do
- bundle "binstubs rack", :standalone => true
+ bundle "binstubs rack", standalone: true
standalone_line = File.read(bundled_app("bin/rackup")).each_line.find {|line| line.include? "$:.unshift" }.strip
- expect(standalone_line).to eq %($:.unshift File.expand_path "../../bundle", path.realpath)
+ expect(standalone_line).to eq %($:.unshift File.expand_path "../bundle", __dir__)
end
end
@@ -796,7 +1050,7 @@ RSpec.describe "bundle install with gem sources" do
end
it "should display a helpful message explaining how to fix it" do
- bundle :install, :env => { "BUNDLE_RUBYGEMS__ORG" => "user:pass{word" }, :raise_on_error => false
+ bundle :install, env: { "BUNDLE_RUBYGEMS__ORG" => "user:pass{word" }, raise_on_error: false
expect(exitstatus).to eq(17)
expect(err).to eq("Please CGI escape your usernames and passwords before " \
"setting them for authentication.")
@@ -837,11 +1091,11 @@ RSpec.describe "bundle install with gem sources" do
end
it "should fail loudly if the lockfile platforms don't include the current platform" do
- simulate_platform(Gem::Platform.new("x86_64-linux")) { bundle "install", :raise_on_error => false }
+ simulate_platform(Gem::Platform.new("x86_64-linux")) { bundle "install", raise_on_error: false }
expect(err).to eq(
"Your bundle only supports platforms [\"x86_64-darwin-19\"] but your local platform is x86_64-linux. " \
- "Add the current platform to the lockfile with `bundle lock --add-platform x86_64-linux` and try again."
+ "Add the current platform to the lockfile with\n`bundle lock --add-platform x86_64-linux` and try again."
)
end
end
@@ -849,16 +1103,16 @@ RSpec.describe "bundle install with gem sources" do
context "with missing platform specific gems in lockfile" do
before do
build_repo4 do
- build_gem "racc", "1.5.2"
+ build_gem "racca", "1.5.2"
build_gem "nokogiri", "1.12.4" do |s|
s.platform = "x86_64-darwin"
- s.add_runtime_dependency "racc", "~> 1.4"
+ s.add_runtime_dependency "racca", "~> 1.4"
end
build_gem "nokogiri", "1.12.4" do |s|
s.platform = "x86_64-linux"
- s.add_runtime_dependency "racc", "~> 1.4"
+ s.add_runtime_dependency "racca", "~> 1.4"
end
build_gem "crass", "1.0.6"
@@ -872,11 +1126,18 @@ RSpec.describe "bundle install with gem sources" do
gemfile <<-G
source "https://gem.repo4"
- ruby "#{RUBY_VERSION}"
+ ruby "#{Gem.ruby_version}"
gem "loofah", "~> 2.12.0"
G
+ checksums = checksums_section do |c|
+ c.checksum gem_repo4, "crass", "1.0.6"
+ c.checksum gem_repo4, "loofah", "2.12.0"
+ c.checksum gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin"
+ c.checksum gem_repo4, "racca", "1.5.2"
+ end
+
lockfile <<-L
GEM
remote: https://gem.repo4/
@@ -886,8 +1147,8 @@ RSpec.describe "bundle install with gem sources" do
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
nokogiri (1.12.4-x86_64-darwin)
- racc (~> 1.4)
- racc (1.5.2)
+ racca (~> 1.4)
+ racca (1.5.2)
PLATFORMS
x86_64-darwin-20
@@ -895,7 +1156,7 @@ RSpec.describe "bundle install with gem sources" do
DEPENDENCIES
loofah (~> 2.12.0)
-
+ #{checksums}
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -908,7 +1169,15 @@ RSpec.describe "bundle install with gem sources" do
bundle "config set --local path vendor/bundle"
simulate_platform "x86_64-linux" do
- bundle "install", :artifice => "compact_index"
+ bundle "install", artifice: "compact_index"
+ end
+
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo4, "crass", "1.0.6"
+ c.checksum gem_repo4, "loofah", "2.12.0"
+ c.checksum gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin"
+ c.checksum gem_repo4, "racca", "1.5.2"
+ c.checksum gem_repo4, "nokogiri", "1.12.4", "x86_64-linux"
end
expect(lockfile).to eq <<~L
@@ -920,10 +1189,10 @@ RSpec.describe "bundle install with gem sources" do
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
nokogiri (1.12.4-x86_64-darwin)
- racc (~> 1.4)
+ racca (~> 1.4)
nokogiri (1.12.4-x86_64-linux)
- racc (~> 1.4)
- racc (1.5.2)
+ racca (~> 1.4)
+ racca (1.5.2)
PLATFORMS
x86_64-darwin-20
@@ -931,7 +1200,7 @@ RSpec.describe "bundle install with gem sources" do
DEPENDENCIES
loofah (~> 2.12.0)
-
+ #{checksums}
RUBY VERSION
#{Bundler::RubyVersion.system}
@@ -943,11 +1212,11 @@ RSpec.describe "bundle install with gem sources" do
context "with --local flag" do
before do
- system_gems "rack-1.0.0", :path => default_bundle_path
+ system_gems "rack-1.0.0", path: default_bundle_path
end
it "respects installed gems without fetching any remote sources" do
- install_gemfile <<-G, :local => true
+ install_gemfile <<-G, local: true
source "#{file_uri_for(gem_repo1)}"
source "https://not-existing-source" do
@@ -958,4 +1227,161 @@ RSpec.describe "bundle install with gem sources" do
expect(last_command).to be_success
end
end
+
+ context "with only option" do
+ before do
+ bundle "config set only a:b"
+ end
+
+ it "installs only gems of the specified groups" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ gem "rack", group: :a
+ gem "rake", group: :b
+ gem "yard", group: :c
+ G
+
+ expect(out).to include("Installing rack")
+ expect(out).to include("Installing rake")
+ expect(out).not_to include("Installing yard")
+ end
+ end
+
+ context "with --prefer-local flag" do
+ before do
+ build_repo4 do
+ build_gem "foo", "1.0.1"
+ build_gem "foo", "1.0.0"
+ build_gem "bar", "1.0.0"
+ end
+
+ system_gems "foo-1.0.0", path: default_bundle_path, gem_repo: gem_repo4
+ end
+
+ it "fetches remote sources only when not available locally" do
+ install_gemfile <<-G, "prefer-local": true, verbose: true
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "foo"
+ gem "bar"
+ G
+
+ expect(out).to include("Using foo 1.0.0").and include("Fetching bar 1.0.0").and include("Installing bar 1.0.0")
+ expect(last_command).to be_success
+ end
+ end
+
+ context "with a symlinked configured as bundle path and a gem with symlinks" do
+ before do
+ symlinked_bundled_app = tmp("bundled_app-symlink")
+ File.symlink(bundled_app, symlinked_bundled_app)
+ bundle "config path #{File.join(symlinked_bundled_app, ".vendor")}"
+
+ binman_path = tmp("binman")
+ FileUtils.mkdir_p binman_path
+
+ readme_path = File.join(binman_path, "README.markdown")
+ FileUtils.touch(readme_path)
+
+ man_path = File.join(binman_path, "man", "man0")
+ FileUtils.mkdir_p man_path
+
+ File.symlink("../../README.markdown", File.join(man_path, "README.markdown"))
+
+ build_repo4 do
+ build_gem "binman", path: gem_repo4("gems"), lib_path: binman_path, no_default: true do |s|
+ s.files = ["README.markdown", "man/man0/README.markdown"]
+ end
+ end
+ end
+
+ it "installs fine" do
+ install_gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "binman"
+ G
+ end
+ end
+
+ context "when a gem has equivalent versions with inconsistent dependencies" do
+ before do
+ build_repo4 do
+ build_gem "autobuild", "1.10.rc2" do |s|
+ s.add_dependency "utilrb", ">= 1.6.0"
+ end
+
+ build_gem "autobuild", "1.10.0.rc2" do |s|
+ s.add_dependency "utilrb", ">= 2.0"
+ end
+ end
+ end
+
+ it "does not crash unexpectedly" do
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "autobuild", "1.10.rc2"
+ G
+
+ bundle "install --jobs 1", raise_on_error: false
+
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+ expect(err).to include("Could not find compatible versions")
+ end
+ end
+
+ context "when a lockfile has unmet dependencies, and the Gemfile has no resolution" do
+ before do
+ build_repo4 do
+ build_gem "aaa", "0.2.0" do |s|
+ s.add_dependency "zzz", "< 0.2.0"
+ end
+
+ build_gem "zzz", "0.2.0"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "aaa"
+ gem "zzz"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ aaa (0.2.0)
+ zzz (< 0.2.0)
+ zzz (0.2.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ aaa!
+ zzz!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "does not install, but raises a resolution error" do
+ bundle "install", raise_on_error: false
+ expect(err).to include("Could not find compatible versions")
+ end
+ end
+
+ context "when --jobs option given" do
+ before do
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", jobs: 1
+ end
+
+ it "does not save the flag to config" do
+ expect(bundled_app(".bundle/config")).not_to exist
+ end
+ end
end
diff --git a/spec/bundler/commands/list_spec.rb b/spec/bundler/commands/list_spec.rb
index 66930ded75..5ac2077d81 100644
--- a/spec/bundler/commands/list_spec.rb
+++ b/spec/bundler/commands/list_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe "bundle list" do
context "with name-only and paths option" do
it "raises an error" do
- bundle "list --name-only --paths", :raise_on_error => false
+ bundle "list --name-only --paths", raise_on_error: false
expect(err).to eq "The `--name-only` and `--paths` options cannot be used together"
end
@@ -11,7 +11,7 @@ RSpec.describe "bundle list" do
context "with without-group and only-group option" do
it "raises an error" do
- bundle "list --without-group dev --only-group test", :raise_on_error => false
+ bundle "list --without-group dev --only-group test", raise_on_error: false
expect(err).to eq "The `--only-group` and `--without-group` options cannot be used together"
end
@@ -40,7 +40,7 @@ RSpec.describe "bundle list" do
context "when group is not found" do
it "raises an error" do
- bundle "list --without-group random", :raise_on_error => false
+ bundle "list --without-group random", raise_on_error: false
expect(err).to eq "`random` group could not be found."
end
@@ -79,7 +79,7 @@ RSpec.describe "bundle list" do
context "when group is not found" do
it "raises an error" do
- bundle "list --only-group random", :raise_on_error => false
+ bundle "list --only-group random", raise_on_error: false
expect(err).to eq "`random` group could not be found."
end
@@ -124,9 +124,9 @@ RSpec.describe "bundle list" do
build_gem "bar"
end
- build_git "git_test", "1.0.0", :path => lib_path("git_test")
+ build_git "git_test", "1.0.0", path: lib_path("git_test")
- build_lib("gemspec_test", :path => tmp.join("gemspec_test")) do |s|
+ build_lib("gemspec_test", path: tmp.join("gemspec_test")) do |s|
s.add_dependency "bar", "=1.0.0"
end
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index 22709f4528..f6793d393b 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -1,14 +1,6 @@
# frozen_string_literal: true
RSpec.describe "bundle lock" do
- def strip_lockfile(lockfile)
- strip_whitespace(lockfile).sub(/\n\Z/, "")
- end
-
- def read_lockfile(file = "Gemfile.lock")
- strip_lockfile bundled_app(file).read
- end
-
let(:repo) { gem_repo1 }
before :each do
@@ -19,7 +11,19 @@ RSpec.describe "bundle lock" do
gem "foo"
G
- @lockfile = strip_lockfile(<<-L)
+ checksums = checksums_section_when_existing do |c|
+ c.checksum repo, "actionmailer", "2.3.2"
+ c.checksum repo, "actionpack", "2.3.2"
+ c.checksum repo, "activerecord", "2.3.2"
+ c.checksum repo, "activeresource", "2.3.2"
+ c.checksum repo, "activesupport", "2.3.2"
+ c.checksum repo, "foo", "1.0"
+ c.checksum repo, "rails", "2.3.2"
+ c.checksum repo, "rake", rake_version
+ c.checksum repo, "weakling", "0.0.3"
+ end
+
+ @lockfile = <<~L
GEM
remote: #{file_uri_for(repo)}/
specs:
@@ -38,8 +42,8 @@ RSpec.describe "bundle lock" do
actionpack (= 2.3.2)
activerecord (= 2.3.2)
activeresource (= 2.3.2)
- rake (= 13.0.1)
- rake (13.0.1)
+ rake (= #{rake_version})
+ rake (#{rake_version})
weakling (0.0.3)
PLATFORMS
@@ -49,7 +53,7 @@ RSpec.describe "bundle lock" do
foo
rails
weakling
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -58,15 +62,23 @@ RSpec.describe "bundle lock" do
it "prints a lockfile when there is no existing lockfile with --print" do
bundle "lock --print"
- expect(out).to eq(@lockfile)
+ expect(out).to eq(@lockfile.chomp)
end
it "prints a lockfile when there is an existing lockfile with --print" do
+ lockfile remove_checksums_section_from_lockfile(@lockfile)
+
+ bundle "lock --print"
+
+ expect(out).to eq(remove_checksums_section_from_lockfile(@lockfile).chomp)
+ end
+
+ it "prints a lockfile when there is an existing checksums lockfile with --print" do
lockfile @lockfile
bundle "lock --print"
- expect(out).to eq(@lockfile)
+ expect(out).to eq(@lockfile.chomp)
end
it "writes a lockfile when there is no existing lockfile" do
@@ -75,7 +87,39 @@ RSpec.describe "bundle lock" do
expect(read_lockfile).to eq(@lockfile)
end
+ it "prints a lockfile without fetching new checksums if the existing lockfile had no checksums" do
+ lockfile remove_checksums_from_lockfile(@lockfile)
+
+ bundle "lock --print"
+
+ expect(out).to eq(remove_checksums_from_lockfile(@lockfile).chomp)
+ end
+
+ it "touches the lockfile when there is an existing lockfile that does not need changes" do
+ lockfile @lockfile
+
+ expect do
+ bundle "lock"
+ end.to change { bundled_app_lock.mtime }
+ end
+
+ it "does not touch lockfile with --print" do
+ lockfile @lockfile
+
+ expect do
+ bundle "lock --print"
+ end.not_to change { bundled_app_lock.mtime }
+ end
+
it "writes a lockfile when there is an outdated lockfile using --update" do
+ lockfile remove_checksums_from_lockfile(@lockfile.gsub("2.3.2", "2.3.1"), " (2.3.1)")
+
+ bundle "lock --update"
+
+ expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile))
+ end
+
+ it "writes a lockfile with checksums on --update when checksums exist" do
lockfile @lockfile.gsub("2.3.2", "2.3.1")
bundle "lock --update"
@@ -83,10 +127,27 @@ RSpec.describe "bundle lock" do
expect(read_lockfile).to eq(@lockfile)
end
+ it "writes a lockfile when there is an outdated lockfile and bundle is frozen" do
+ lockfile @lockfile.gsub("2.3.2", "2.3.1")
+
+ bundle "lock --update", env: { "BUNDLE_FROZEN" => "true" }
+
+ expect(read_lockfile).to eq(@lockfile)
+ end
+
it "does not fetch remote specs when using the --local option" do
- bundle "lock --update --local", :raise_on_error => false
+ bundle "lock --update --local", raise_on_error: false
- expect(err).to match(/locally installed gems/)
+ expect(err).to match(/cached gems or installed locally/)
+ end
+
+ it "does not fetch remote checksums with --local" do
+ lockfile remove_checksums_from_lockfile(@lockfile)
+
+ bundle "lock --print --local"
+
+ # No checksums because --local prevents fetching them
+ expect(out).to eq(remove_checksums_from_lockfile(@lockfile).chomp)
end
it "works with --gemfile flag" do
@@ -94,7 +155,11 @@ RSpec.describe "bundle lock" do
source "#{file_uri_for(repo)}"
gem "foo"
G
- lockfile = strip_lockfile(<<-L)
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
+
+ lockfile = <<~L
GEM
remote: #{file_uri_for(repo)}/
specs:
@@ -105,7 +170,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
foo
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -120,7 +185,7 @@ RSpec.describe "bundle lock" do
bundle "lock --lockfile=lock"
expect(out).to match(/Writing lockfile to.+lock/)
- expect(read_lockfile("lock")).to eq(@lockfile)
+ expect(read_lockfile("lock")).to eq(remove_checksums_from_lockfile(@lockfile))
expect { read_lockfile }.to raise_error(Errno::ENOENT)
end
@@ -128,22 +193,135 @@ RSpec.describe "bundle lock" do
bundle "install"
bundle "lock --lockfile=lock"
+ checksums = checksums_section_when_existing do |c|
+ c.checksum repo, "actionmailer", "2.3.2"
+ c.checksum repo, "actionpack", "2.3.2"
+ c.checksum repo, "activerecord", "2.3.2"
+ c.checksum repo, "activeresource", "2.3.2"
+ c.checksum repo, "activesupport", "2.3.2"
+ c.checksum repo, "foo", "1.0"
+ c.checksum repo, "rails", "2.3.2"
+ c.checksum repo, "rake", rake_version
+ c.checksum repo, "weakling", "0.0.3"
+ end
+
+ lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(repo)}/
+ specs:
+ actionmailer (2.3.2)
+ activesupport (= 2.3.2)
+ actionpack (2.3.2)
+ activesupport (= 2.3.2)
+ activerecord (2.3.2)
+ activesupport (= 2.3.2)
+ activeresource (2.3.2)
+ activesupport (= 2.3.2)
+ activesupport (2.3.2)
+ foo (1.0)
+ rails (2.3.2)
+ actionmailer (= 2.3.2)
+ actionpack (= 2.3.2)
+ activerecord (= 2.3.2)
+ activeresource (= 2.3.2)
+ rake (= #{rake_version})
+ rake (#{rake_version})
+ weakling (0.0.3)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo
+ rails
+ weakling
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
expect(out).to match(/Writing lockfile to.+lock/)
- expect(read_lockfile("lock")).to eq(@lockfile)
+ expect(read_lockfile("lock")).to eq(lockfile)
end
it "update specific gems using --update" do
- lockfile @lockfile.gsub("2.3.2", "2.3.1").gsub("13.0.1", "10.0.1")
+ lockfile @lockfile.gsub("2.3.2", "2.3.1").gsub(rake_version, "10.0.1")
bundle "lock --update rails rake"
- expect(read_lockfile).to eq(@lockfile)
+ expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile, "(2.3.2)", "(#{rake_version})"))
+ end
+
+ it "preserves unknown checksum algorithms" do
+ lockfile @lockfile.gsub(/(sha256=[a-f0-9]+)$/, "constant=true,\\1,xyz=123")
+
+ previous_lockfile = read_lockfile
+
+ bundle "lock"
+
+ expect(read_lockfile).to eq(previous_lockfile)
+ end
+
+ it "does not unlock git sources when only uri shape changes" do
+ build_git("foo")
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}"
+ G
+
+ # Change uri format to end with "/" and reinstall
+ install_gemfile <<-G, verbose: true
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}/"
+ G
+
+ expect(out).to include("using resolution from the lockfile")
+ expect(out).not_to include("re-resolving dependencies because the list of sources changed")
+ end
+
+ it "updates specific gems using --update using the locked revision of unrelated git gems for resolving" do
+ ref = build_git("foo").ref_for("HEAD")
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rake"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :branch => "deadbeef"
+ G
+
+ lockfile <<~L
+ GIT
+ remote: #{file_uri_for(lib_path("foo-1.0"))}
+ revision: #{ref}
+ branch: deadbeef
+ specs:
+ foo (1.0)
+
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+ rake (10.0.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+ rake
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "lock --update rake --verbose"
+ expect(out).to match(/Writing lockfile to.+lock/)
+ expect(lockfile).to include("rake (#{rake_version})")
end
it "errors when updating a missing specific gems using --update" do
lockfile @lockfile
- bundle "lock --update blahblah", :raise_on_error => false
+ bundle "lock --update blahblah", raise_on_error: false
expect(err).to eq("Could not find gem 'blahblah'.")
expect(read_lockfile).to eq(@lockfile)
@@ -157,9 +335,9 @@ RSpec.describe "bundle lock" do
gem "rack_middleware", :group => "test"
G
bundle "config set without test"
- bundle "config set path .bundle"
- bundle "lock"
- expect(bundled_app(".bundle")).not_to exist
+ bundle "config set path vendor/bundle"
+ bundle "lock", verbose: true
+ expect(bundled_app("vendor/bundle")).not_to exist
end
# see update_spec for more coverage on same options. logic is shared so it's not necessary
@@ -176,7 +354,10 @@ RSpec.describe "bundle lock" do
build_gem "foo", %w[1.5.1] do |s|
s.add_dependency "bar", "~> 3.0"
end
- build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
+ build_gem "foo", %w[2.0.0.pre] do |s|
+ s.add_dependency "bar"
+ end
+ build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 2.1.2.pre 3.0.0 3.1.0.pre 4.0.0.pre]
build_gem "qux", %w[1.0.0 1.0.1 1.1.0 2.0.0]
end
@@ -210,6 +391,112 @@ RSpec.describe "bundle lock" do
expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-1.5.0 bar-2.1.1 qux-1.1.0].sort)
end
+
+ it "shows proper error when Gemfile changes forbid patch upgrades, and --patch --strict is given" do
+ # force next minor via Gemfile
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'foo', '1.5.0'
+ gem 'qux'
+ G
+
+ bundle "lock --update foo --patch --strict", raise_on_error: false
+
+ expect(err).to include(
+ "foo is locked to 1.4.3, while Gemfile is requesting foo (= 1.5.0). " \
+ "--strict --patch was specified, but there are no patch level upgrades from 1.4.3 satisfying foo (= 1.5.0), so version solving has failed"
+ )
+ end
+
+ context "pre" do
+ it "defaults to major" do
+ bundle "lock --update --pre"
+
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-2.0.0.pre bar-4.0.0.pre qux-2.0.0].sort)
+ end
+
+ it "patch preferred" do
+ bundle "lock --update --patch --pre"
+
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-1.4.5 bar-2.1.2.pre qux-1.0.1].sort)
+ end
+
+ it "minor preferred" do
+ bundle "lock --update --minor --pre"
+
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-1.5.1 bar-3.1.0.pre qux-1.1.0].sort)
+ end
+
+ it "major preferred" do
+ bundle "lock --update --major --pre"
+
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[foo-2.0.0.pre bar-4.0.0.pre qux-2.0.0].sort)
+ end
+ end
+ end
+
+ context "conservative updates when minor update adds a new dependency" do
+ before do
+ build_repo4 do
+ build_gem "sequel", "5.71.0"
+ build_gem "sequel", "5.72.0" do |s|
+ s.add_dependency "bigdecimal", ">= 0"
+ end
+ build_gem "bigdecimal", %w[1.4.4 99.1.4]
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'sequel'
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ sequel (5.71.0)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ sequel
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ end
+
+ it "adds the latest version of the new dependency" do
+ bundle "lock --minor --update sequel"
+
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[sequel-5.72.0 bigdecimal-99.1.4].sort)
+ end
+ end
+
+ it "updates the bundler version in the lockfile to the latest bundler version" do
+ build_repo4 do
+ build_gem "bundler", "55"
+ end
+
+ system_gems "bundler-55", gem_repo: gem_repo4
+
+ install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ source "https://gems.repo4"
+ G
+ lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2')
+
+ bundle "lock --update --bundler --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ expect(lockfile).to end_with("BUNDLED WITH\n 55\n")
+
+ update_repo4 do
+ build_gem "bundler", "99"
+ end
+
+ bundle "lock --update --bundler --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ expect(lockfile).to end_with("BUNDLED WITH\n 99\n")
end
it "supports adding new platforms" do
@@ -217,7 +504,7 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(local_platforms.unshift(java, mingw).uniq)
+ expect(lockfile.platforms).to match_array(default_platform_list(java, x86_mingw32))
end
it "supports adding new platforms with force_ruby_platform = true" do
@@ -226,11 +513,11 @@ RSpec.describe "bundle lock" do
remote: #{file_uri_for(gem_repo1)}/
specs:
platform_specific (1.0)
- platform_specific (1.0-x86-linux)
+ platform_specific (1.0-x86-64_linux)
PLATFORMS
ruby
- x86-linux
+ x86_64-linux
DEPENDENCIES
platform_specific
@@ -241,7 +528,7 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to contain_exactly(rb, linux, java, mingw)
+ expect(lockfile.platforms).to contain_exactly(rb, linux, java, x86_mingw32)
end
it "supports adding the `ruby` platform" do
@@ -249,7 +536,7 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(local_platforms.unshift("ruby").uniq)
+ expect(lockfile.platforms).to match_array(default_platform_list("ruby"))
end
it "warns when adding an unknown platform" do
@@ -262,16 +549,78 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(local_platforms.unshift(java, mingw).uniq)
+ expect(lockfile.platforms).to match_array(default_platform_list(java, x86_mingw32))
bundle "lock --remove-platform java"
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array(local_platforms.unshift(mingw).uniq)
+ expect(lockfile.platforms).to match_array(default_platform_list(x86_mingw32))
+ end
+
+ it "also cleans up redundant platform gems when removing platforms" do
+ build_repo4 do
+ build_gem "nokogiri", "1.12.0"
+ build_gem "nokogiri", "1.12.0" do |s|
+ s.platform = "x86_64-darwin"
+ end
+ end
+
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo4, "nokogiri", "1.12.0"
+ c.checksum gem_repo4, "nokogiri", "1.12.0", "x86_64-darwin"
+ end
+
+ simulate_platform "x86_64-darwin-22" do
+ install_gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "nokogiri"
+ G
+ end
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.12.0)
+ nokogiri (1.12.0-x86_64-darwin)
+
+ PLATFORMS
+ ruby
+ x86_64-darwin
+
+ DEPENDENCIES
+ nokogiri
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ checksums.delete("nokogiri", Gem::Platform::RUBY)
+
+ simulate_platform "x86_64-darwin-22" do
+ bundle "lock --remove-platform ruby"
+ end
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.12.0-x86_64-darwin)
+
+ PLATFORMS
+ x86_64-darwin
+
+ DEPENDENCIES
+ nokogiri
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
it "errors when removing all platforms" do
- bundle "lock --remove-platform #{local_platforms.join(" ")}", :raise_on_error => false
+ bundle "lock --remove-platform #{local_platform}", raise_on_error: false
expect(err).to include("Removing all platforms from the bundle is not allowed")
end
@@ -280,7 +629,7 @@ RSpec.describe "bundle lock" do
build_repo4 do
build_gem "ffi", "1.9.14"
build_gem "ffi", "1.9.14" do |s|
- s.platform = mingw
+ s.platform = x86_mingw32
end
build_gem "gssapi", "0.1"
@@ -312,7 +661,14 @@ RSpec.describe "bundle lock" do
gem "gssapi"
G
- simulate_platform(mingw) { bundle :lock }
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "ffi", "1.9.14", "x86-mingw32"
+ c.no_checksum "gssapi", "1.2.0"
+ c.no_checksum "mixlib-shellout", "2.2.6", "universal-mingw32"
+ c.no_checksum "win32-process", "0.8.3"
+ end
+
+ simulate_platform(x86_mingw32) { bundle :lock }
expect(lockfile).to eq <<~G
GEM
@@ -332,12 +688,16 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
gssapi
mixlib-shellout
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
- simulate_platform(rb) { bundle :lock }
+ bundle "config set --local force_ruby_platform true"
+ bundle :lock
+
+ checksums.no_checksum "ffi", "1.9.14"
+ checksums.no_checksum "mixlib-shellout", "2.2.6"
expect(lockfile).to eq <<~G
GEM
@@ -360,7 +720,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
gssapi
mixlib-shellout
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -424,7 +784,12 @@ RSpec.describe "bundle lock" do
gem "libv8"
G
- simulate_platform(Gem::Platform.new("x86_64-darwin")) { bundle "lock" }
+ simulate_platform(Gem::Platform.new("x86_64-darwin-19")) { bundle "lock" }
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "libv8", "8.4.255.0", "x86_64-darwin-19"
+ c.no_checksum "libv8", "8.4.255.0", "x86_64-darwin-20"
+ end
expect(lockfile).to eq <<~G
GEM
@@ -434,11 +799,12 @@ RSpec.describe "bundle lock" do
libv8 (8.4.255.0-x86_64-darwin-20)
PLATFORMS
- x86_64-darwin
+ x86_64-darwin-19
+ x86_64-darwin-20
DEPENDENCIES
libv8
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -455,6 +821,11 @@ RSpec.describe "bundle lock" do
end
end
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-19"
+ c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-20"
+ end
+
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
@@ -473,7 +844,7 @@ RSpec.describe "bundle lock" do
DEPENDENCIES
libv8
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -492,22 +863,25 @@ RSpec.describe "bundle lock" do
end
it "does not conflict on ruby requirements when adding new platforms" do
- next_minor = Gem.ruby_version.segments[0..1].map.with_index {|s, i| i == 1 ? s + 1 : s }.join(".")
-
build_repo4 do
build_gem "raygun-apm", "1.0.78" do |s|
s.platform = "x86_64-linux"
- s.required_ruby_version = "< #{next_minor}.dev"
+ s.required_ruby_version = "< #{next_ruby_minor}.dev"
end
build_gem "raygun-apm", "1.0.78" do |s|
s.platform = "universal-darwin"
- s.required_ruby_version = "< #{next_minor}.dev"
+ s.required_ruby_version = "< #{next_ruby_minor}.dev"
end
build_gem "raygun-apm", "1.0.78" do |s|
s.platform = "x64-mingw32"
- s.required_ruby_version = "< #{next_minor}.dev"
+ s.required_ruby_version = "< #{next_ruby_minor}.dev"
+ end
+
+ build_gem "raygun-apm", "1.0.78" do |s|
+ s.platform = "x64-mingw-ucrt"
+ s.required_ruby_version = "< #{next_ruby_minor}.dev"
end
end
@@ -533,30 +907,687 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION}
L
- bundle "lock --add-platform x86_64-linux", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ bundle "lock --add-platform x86_64-linux", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
end
- context "when an update is available" do
- let(:repo) { gem_repo2 }
+ it "does not crash on conflicting ruby requirements between platform versions in two different gems" do
+ build_repo4 do
+ build_gem "unf_ext", "0.0.8.2"
- before do
- lockfile(@lockfile)
+ build_gem "unf_ext", "0.0.8.2" do |s|
+ s.required_ruby_version = [">= 2.4", "< #{previous_ruby_minor}"]
+ s.platform = "x64-mingw32"
+ end
+
+ build_gem "unf_ext", "0.0.8.2" do |s|
+ s.required_ruby_version = [">= #{previous_ruby_minor}", "< #{current_ruby_minor}"]
+ s.platform = "x64-mingw-ucrt"
+ end
+
+ build_gem "google-protobuf", "3.21.12"
+
+ build_gem "google-protobuf", "3.21.12" do |s|
+ s.required_ruby_version = [">= 2.5", "< #{previous_ruby_minor}"]
+ s.platform = "x64-mingw32"
+ end
+
+ build_gem "google-protobuf", "3.21.12" do |s|
+ s.required_ruby_version = [">= #{previous_ruby_minor}", "< #{current_ruby_minor}"]
+ s.platform = "x64-mingw-ucrt"
+ end
+ end
+
+ gemfile <<~G
+ source "https://gem.repo4"
+
+ gem "google-protobuf"
+ gem "unf_ext"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gem.repo4/
+ specs:
+ google-protobuf (3.21.12)
+ unf_ext (0.0.8.2)
+
+ PLATFORMS
+ x64-mingw-ucrt
+ x64-mingw32
+
+ DEPENDENCIES
+ google-protobuf
+ unf_ext
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "DEBUG_RESOLVER" => "1" }
+ end
+
+ it "respects lower bound ruby requirements" do
+ build_repo4 do
+ build_gem "our_private_gem", "0.1.0" do |s|
+ s.required_ruby_version = ">= #{Gem.ruby_version}"
+ end
+ end
+
+ gemfile <<-G
+ source "https://localgemserver.test"
+
+ gem "our_private_gem"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: https://localgemserver.test/
+ specs:
+ our_private_gem (0.1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ our_private_gem
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+ end
+
+ context "when an update is available" do
+ let(:repo) do
build_repo2 do
build_gem "foo", "2.0"
end
+ gem_repo2
+ end
+
+ before do
+ lockfile(@lockfile)
end
it "does not implicitly update" do
bundle "lock"
- expect(read_lockfile).to eq(@lockfile)
+ checksums = checksums_section_when_existing do |c|
+ c.checksum repo, "actionmailer", "2.3.2"
+ c.checksum repo, "actionpack", "2.3.2"
+ c.checksum repo, "activerecord", "2.3.2"
+ c.checksum repo, "activeresource", "2.3.2"
+ c.checksum repo, "activesupport", "2.3.2"
+ c.checksum repo, "foo", "1.0"
+ c.checksum repo, "rails", "2.3.2"
+ c.checksum repo, "rake", rake_version
+ c.checksum repo, "weakling", "0.0.3"
+ end
+
+ expected_lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(repo)}/
+ specs:
+ actionmailer (2.3.2)
+ activesupport (= 2.3.2)
+ actionpack (2.3.2)
+ activesupport (= 2.3.2)
+ activerecord (2.3.2)
+ activesupport (= 2.3.2)
+ activeresource (2.3.2)
+ activesupport (= 2.3.2)
+ activesupport (2.3.2)
+ foo (1.0)
+ rails (2.3.2)
+ actionmailer (= 2.3.2)
+ actionpack (= 2.3.2)
+ activerecord (= 2.3.2)
+ activeresource (= 2.3.2)
+ rake (= #{rake_version})
+ rake (#{rake_version})
+ weakling (0.0.3)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo
+ rails
+ weakling
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ expect(read_lockfile).to eq(expected_lockfile)
end
it "accounts for changes in the gemfile" do
gemfile gemfile.gsub('"foo"', '"foo", "2.0"')
bundle "lock"
- expect(read_lockfile).to eq(@lockfile.sub("foo (1.0)", "foo (2.0)").sub(/foo$/, "foo (= 2.0)"))
+ checksums = checksums_section_when_existing do |c|
+ c.checksum repo, "actionmailer", "2.3.2"
+ c.checksum repo, "actionpack", "2.3.2"
+ c.checksum repo, "activerecord", "2.3.2"
+ c.checksum repo, "activeresource", "2.3.2"
+ c.checksum repo, "activesupport", "2.3.2"
+ c.no_checksum "foo", "2.0"
+ c.checksum repo, "rails", "2.3.2"
+ c.checksum repo, "rake", rake_version
+ c.checksum repo, "weakling", "0.0.3"
+ end
+
+ expected_lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(repo)}/
+ specs:
+ actionmailer (2.3.2)
+ activesupport (= 2.3.2)
+ actionpack (2.3.2)
+ activesupport (= 2.3.2)
+ activerecord (2.3.2)
+ activesupport (= 2.3.2)
+ activeresource (2.3.2)
+ activesupport (= 2.3.2)
+ activesupport (2.3.2)
+ foo (2.0)
+ rails (2.3.2)
+ actionmailer (= 2.3.2)
+ actionpack (= 2.3.2)
+ activerecord (= 2.3.2)
+ activeresource (= 2.3.2)
+ rake (= #{rake_version})
+ rake (#{rake_version})
+ weakling (0.0.3)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo (= 2.0)
+ rails
+ weakling
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ expect(read_lockfile).to eq(expected_lockfile)
+ end
+ end
+
+ context "when a system gem has incorrect dependencies, different from the lockfile" do
+ before do
+ build_repo4 do
+ build_gem "debug", "1.6.3" do |s|
+ s.add_dependency "irb", ">= 1.3.6"
+ end
+
+ build_gem "irb", "1.5.0"
+ end
+
+ system_gems "irb-1.5.0", gem_repo: gem_repo4
+ system_gems "debug-1.6.3", gem_repo: gem_repo4
+
+ # simulate gemspec with wrong empty dependencies
+ debug_gemspec_path = system_gem_path("specifications/debug-1.6.3.gemspec")
+ debug_gemspec = Gem::Specification.load(debug_gemspec_path.to_s)
+ debug_gemspec.dependencies.clear
+ File.write(debug_gemspec_path, debug_gemspec.to_ruby)
+ end
+
+ it "respects the existing lockfile, even when reresolving" do
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "debug"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ debug (1.6.3)
+ irb (>= 1.3.6)
+ irb (1.5.0)
+
+ PLATFORMS
+ x86_64-linux
+
+ DEPENDENCIES
+ debug
+ #{checksums_section}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ simulate_platform "arm64-darwin-22" do
+ bundle "lock"
+ end
+
+ checksums = checksums_section do |c|
+ c.no_checksum "debug", "1.6.3"
+ c.no_checksum "irb", "1.5.0"
+ end
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ debug (1.6.3)
+ irb (>= 1.3.6)
+ irb (1.5.0)
+
+ PLATFORMS
+ arm64-darwin-22
+ x86_64-linux
+
+ DEPENDENCIES
+ debug
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ it "properly shows resolution errors including OR requirements" do
+ build_repo4 do
+ build_gem "activeadmin", "2.13.1" do |s|
+ s.add_dependency "railties", ">= 6.1", "< 7.1"
+ end
+ build_gem "actionpack", "6.1.4"
+ build_gem "actionpack", "7.0.3.1"
+ build_gem "actionpack", "7.0.4"
+ build_gem "railties", "6.1.4" do |s|
+ s.add_dependency "actionpack", "6.1.4"
+ end
+ build_gem "rails", "7.0.3.1" do |s|
+ s.add_dependency "railties", "7.0.3.1"
+ end
+ build_gem "rails", "7.0.4" do |s|
+ s.add_dependency "railties", "7.0.4"
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "rails", ">= 7.0.3.1"
+ gem "activeadmin", "2.13.1"
+ G
+
+ bundle "lock", raise_on_error: false
+
+ expect(err).to eq <<~ERR.strip
+ Could not find compatible versions
+
+ Because rails >= 7.0.4 depends on railties = 7.0.4
+ and rails < 7.0.4 depends on railties = 7.0.3.1,
+ railties = 7.0.3.1 OR = 7.0.4 is required.
+ So, because railties = 7.0.3.1 OR = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally,
+ version solving has failed.
+ ERR
+ end
+
+ it "is able to display some explanation on crazy irresolvable cases" do
+ build_repo4 do
+ build_gem "activeadmin", "2.13.1" do |s|
+ s.add_dependency "ransack", "= 3.1.0"
+ end
+
+ # Activemodel is missing as a dependency in lockfile
+ build_gem "ransack", "3.1.0" do |s|
+ s.add_dependency "activemodel", ">= 6.0.4"
+ s.add_dependency "activesupport", ">= 6.0.4"
+ end
+
+ %w[6.0.4 7.0.2.3 7.0.3.1 7.0.4].each do |version|
+ build_gem "activesupport", version
+
+ # Activemodel is only available on 6.0.4
+ if version == "6.0.4"
+ build_gem "activemodel", version do |s|
+ s.add_dependency "activesupport", version
+ end
+ end
+
+ build_gem "rails", version do |s|
+ # Depednencies of Rails 7.0.2.3 are in reverse order
+ if version == "7.0.2.3"
+ s.add_dependency "activesupport", version
+ s.add_dependency "activemodel", version
+ else
+ s.add_dependency "activemodel", version
+ s.add_dependency "activesupport", version
+ end
+ end
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "rails", ">= 7.0.2.3"
+ gem "activeadmin", "= 2.13.1"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ activeadmin (2.13.1)
+ ransack (= 3.1.0)
+ ransack (3.1.0)
+ activemodel (>= 6.0.4)
+
+ PLATFORMS
+ #{local_platform}
+
+ DEPENDENCIES
+ activeadmin (= 2.13.1)
+ ransack (= 3.1.0)
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "lock", raise_on_error: false
+
+ expect(err).to eq <<~ERR.strip
+ Could not find compatible versions
+
+ Because every version of activemodel depends on activesupport = 6.0.4
+ and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3,
+ every version of activemodel is incompatible with rails >= 7.0.2.3, < 7.0.3.1.
+ And because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3,
+ rails >= 7.0.2.3, < 7.0.3.1 cannot be used.
+ (1) So, because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1
+ and rails >= 7.0.4 depends on activemodel = 7.0.4,
+ rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4.
+
+ Because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3
+ and rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1,
+ rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 or activesupport = 7.0.3.1.
+ And because rails >= 7.0.4 depends on activesupport = 7.0.4
+ and every version of activemodel depends on activesupport = 6.0.4,
+ activemodel != 7.0.2.3 is incompatible with rails >= 7.0.2.3.
+ And because rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4 (1),
+ rails >= 7.0.2.3 cannot be used.
+ So, because Gemfile depends on rails >= 7.0.2.3,
+ version solving has failed.
+ ERR
+
+ lockfile lockfile.gsub(/PLATFORMS\n #{local_platform}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
+
+ bundle "lock", raise_on_error: false
+
+ expect(err).to eq <<~ERR.strip
+ Could not find compatible versions
+
+ Because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1
+ and rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3,
+ rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 OR = 7.0.3.1.
+ And because every version of activemodel depends on activesupport = 6.0.4,
+ rails >= 7.0.2.3, < 7.0.4 requires activesupport = 6.0.4.
+ Because rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1
+ and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3,
+ rails >= 7.0.2.3, < 7.0.4 requires activesupport = 7.0.2.3 OR = 7.0.3.1.
+ Thus, rails >= 7.0.2.3, < 7.0.4 cannot be used.
+ And because rails >= 7.0.4 depends on activemodel = 7.0.4,
+ rails >= 7.0.2.3 requires activemodel = 7.0.4.
+ So, because activemodel = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally
+ and Gemfile depends on rails >= 7.0.2.3,
+ version solving has failed.
+ ERR
+ end
+
+ it "does not accidentally resolves to prereleases" do
+ build_repo4 do
+ build_gem "autoproj", "2.0.3" do |s|
+ s.add_dependency "autobuild", ">= 1.10.0.a"
+ s.add_dependency "tty-prompt"
+ end
+
+ build_gem "tty-prompt", "0.6.0"
+ build_gem "tty-prompt", "0.7.0"
+
+ build_gem "autobuild", "1.10.0.b3"
+ build_gem "autobuild", "1.10.1" do |s|
+ s.add_dependency "tty-prompt", "~> 0.6.0"
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "autoproj", ">= 2.0.0"
+ G
+
+ bundle "lock"
+ expect(lockfile).to_not include("autobuild (1.10.0.b3)")
+ expect(lockfile).to include("autobuild (1.10.1)")
+ end
+
+ # Newer rails depends on Bundler, while ancient Rails does not. Bundler tries
+ # a first resolution pass that does not consider pre-releases. However, when
+ # using a pre-release Bundler (like the .dev version), that results in that
+ # pre-release being ignored and resolving to a version that does not depend on
+ # Bundler at all. We should avoid that and still consider .dev Bundler.
+ #
+ it "does not ignore prereleases with there's only one candidate" do
+ build_repo4 do
+ build_gem "rails", "7.4.0.2" do |s|
+ s.add_dependency "bundler", ">= 1.15.0"
+ end
+
+ build_gem "rails", "2.3.18"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rails"
+ G
+
+ bundle "lock"
+ expect(lockfile).to_not include("rails (2.3.18)")
+ expect(lockfile).to include("rails (7.4.0.2)")
+ end
+
+ it "deals with platform specific incompatibilities" do
+ build_repo4 do
+ build_gem "activerecord", "6.0.6"
+ build_gem "activerecord-jdbc-adapter", "60.4" do |s|
+ s.platform = "java"
+ s.add_dependency "activerecord", "~> 6.0.0"
+ end
+ build_gem "activerecord-jdbc-adapter", "61.0" do |s|
+ s.platform = "java"
+ s.add_dependency "activerecord", "~> 6.1.0"
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "activerecord", "6.0.6"
+ gem "activerecord-jdbc-adapter", "61.0"
+ G
+
+ simulate_platform "universal-java-19" do
+ bundle "lock", raise_on_error: false
+ end
+
+ expect(err).to include("Could not find compatible versions")
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+ end
+
+ context "when re-resolving to include prereleases" do
+ before do
+ build_repo4 do
+ build_gem "tzinfo-data", "1.2022.7"
+ build_gem "rails", "7.1.0.alpha" do |s|
+ s.add_dependency "activesupport"
+ end
+ build_gem "activesupport", "7.1.0.alpha"
+ end
+ end
+
+ it "does not end up including gems scoped to other platforms in the lockfile" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rails"
+ gem "tzinfo-data", platform: :windows
+ G
+
+ simulate_platform "x86_64-darwin-22" do
+ bundle "lock"
+ end
+
+ expect(lockfile).not_to include("tzinfo-data (1.2022.7)")
+ end
+ end
+
+ context "when resolving platform specific gems as indirect dependencies on truffleruby", :truffleruby_only do
+ before do
+ build_lib "foo", path: bundled_app do |s|
+ s.add_dependency "nokogiri"
+ end
+
+ build_repo4 do
+ build_gem "nokogiri", "1.14.2"
+ build_gem "nokogiri", "1.14.2" do |s|
+ s.platform = "x86_64-linux"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gemspec
+ G
+ end
+
+ it "locks ruby specs" do
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ c.no_checksum "nokogiri", "1.14.2"
+ end
+
+ simulate_platform "x86_64-linux" do
+ bundle "lock"
+ end
+
+ expect(lockfile).to eq <<~L
+ PATH
+ remote: .
+ specs:
+ foo (1.0)
+ nokogiri
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.14.2)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ foo!
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "when adding a new gem that requires unlocking other transitive deps" do
+ before do
+ build_repo4 do
+ build_gem "govuk_app_config", "0.1.0"
+
+ build_gem "govuk_app_config", "4.13.0" do |s|
+ s.add_dependency "railties", ">= 5.0"
+ end
+
+ %w[7.0.4.1 7.0.4.3].each do |v|
+ build_gem "railties", v do |s|
+ s.add_dependency "actionpack", v
+ s.add_dependency "activesupport", v
+ end
+
+ build_gem "activesupport", v
+ build_gem "actionpack", v
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "govuk_app_config"
+ gem "activesupport", "7.0.4.3"
+ G
+
+ # Simulate out of sync lockfile because top level dependency on
+ # activesuport has just been added to the Gemfile, and locked to a higher
+ # version
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ actionpack (7.0.4.1)
+ activesupport (7.0.4.1)
+ govuk_app_config (4.13.0)
+ railties (>= 5.0)
+ railties (7.0.4.1)
+ actionpack (= 7.0.4.1)
+ activesupport (= 7.0.4.1)
+
+ PLATFORMS
+ arm64-darwin-22
+
+ DEPENDENCIES
+ govuk_app_config
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "does not downgrade top level dependencies" do
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "actionpack", "7.0.4.3"
+ c.no_checksum "activesupport", "7.0.4.3"
+ c.no_checksum "govuk_app_config", "4.13.0"
+ c.no_checksum "railties", "7.0.4.3"
+ end
+
+ simulate_platform "arm64-darwin-22" do
+ bundle "lock"
+ end
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ actionpack (7.0.4.3)
+ activesupport (7.0.4.3)
+ govuk_app_config (4.13.0)
+ railties (>= 5.0)
+ railties (7.0.4.3)
+ actionpack (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
+
+ PLATFORMS
+ arm64-darwin-22
+
+ DEPENDENCIES
+ activesupport (= 7.0.4.3)
+ govuk_app_config
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
end
end
diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb
index ddefe0ba25..199340b131 100644
--- a/spec/bundler/commands/newgem_spec.rb
+++ b/spec/bundler/commands/newgem_spec.rb
@@ -12,14 +12,14 @@ RSpec.describe "bundle gem" do
def bundle_exec_rubocop
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
- bundle "config set path #{rubocop_gems}", :dir => bundled_app(gem_name)
- bundle "exec rubocop --debug --config .rubocop.yml", :dir => bundled_app(gem_name)
+ bundle "config set path #{rubocop_gems}", dir: bundled_app(gem_name)
+ bundle "exec rubocop --debug --config .rubocop.yml", dir: bundled_app(gem_name)
end
def bundle_exec_standardrb
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
- bundle "config set path #{standard_gems}", :dir => bundled_app(gem_name)
- bundle "exec standardrb --debug", :dir => bundled_app(gem_name)
+ bundle "config set path #{standard_gems}", dir: bundled_app(gem_name)
+ bundle "exec standardrb --debug", dir: bundled_app(gem_name)
end
let(:generated_gemspec) { Bundler.load_gemspec_uncached(bundled_app(gem_name).join("#{gem_name}.gemspec")) }
@@ -28,6 +28,10 @@ RSpec.describe "bundle gem" do
let(:require_path) { "mygem" }
+ let(:minitest_test_file_path) { "test/test_mygem.rb" }
+
+ let(:minitest_test_class_name) { "class TestMygem < Minitest::Test" }
+
before do
sys_exec("git config --global user.name 'Bundler User'")
sys_exec("git config --global user.email user@example.com")
@@ -59,7 +63,7 @@ RSpec.describe "bundle gem" do
end
it "properly initializes git repo", :readline do
- bundle "gem #{gem_name}", :dir => bundled_app("path with spaces")
+ bundle "gem #{gem_name}", dir: bundled_app("path with spaces")
expect(bundled_app("path with spaces/#{gem_name}/.git")).to exist
end
end
@@ -99,7 +103,7 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/README.md").read).to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
end
- it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", :git => ">= 2.28.0" do
+ it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", git: ">= 2.28.0" do
sys_exec("git config --global init.defaultBranch main")
bundle "gem #{gem_name} --coc"
@@ -144,7 +148,7 @@ RSpec.describe "bundle gem" do
end
shared_examples_for "--rubocop flag" do
- context "is deprecated", :bundler => "< 3" do
+ context "is deprecated", bundler: "< 3" do
before do
bundle "gem #{gem_name} --rubocop"
end
@@ -175,7 +179,7 @@ RSpec.describe "bundle gem" do
end
shared_examples_for "--no-rubocop flag" do
- context "is deprecated", :bundler => "< 3" do
+ context "is deprecated", bundler: "< 3" do
define_negated_matcher :exclude, :include
before do
@@ -306,30 +310,30 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --linter=rubocop"
+ bundle "gem #{gem_name} --ext=c --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext, --test=minitest, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c, --test=minitest, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --test=minitest --linter=rubocop"
+ bundle "gem #{gem_name} --ext=c --test=minitest --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext, --test=rspec, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c, --test=rspec, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --test=rspec --linter=rubocop"
+ bundle "gem #{gem_name} --ext=c --test=rspec --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext, --ext=test-unit, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c, --test=test-unit, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --test=test-unit --linter=rubocop"
+ bundle "gem #{gem_name} --ext=c --test=test-unit --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
@@ -341,10 +345,45 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
+ it "has no rubocop offenses when using --ext=rust and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
+
+ bundle "gem #{gem_name} --ext=rust --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no rubocop offenses when using --ext=rust, --test=minitest, and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
+
+ bundle "gem #{gem_name} --ext=rust --test=minitest --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no rubocop offenses when using --ext=rust, --test=rspec, and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
+
+ bundle "gem #{gem_name} --ext=rust --test=rspec --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
+ it "has no rubocop offenses when using --ext=rust, --test=test-unit, and --linter=rubocop flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
+
+ bundle "gem #{gem_name} --ext=rust --test=test-unit --linter=rubocop"
+ bundle_exec_rubocop
+ expect(last_command).to be_success
+ end
+
shared_examples_for "CI config is absent" do
it "does not create any CI files" do
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
- expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist
expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist
end
@@ -396,7 +435,7 @@ RSpec.describe "bundle gem" do
load_paths = [lib_dir, spec_dir]
load_path_str = "-I#{load_paths.join(File::PATH_SEPARATOR)}"
- sys_exec "#{Gem.ruby} #{load_path_str} #{bindir.join("bundle")} gem #{gem_name}", :env => { "PATH" => "" }
+ sys_exec "#{Gem.ruby} #{load_path_str} #{bindir.join("bundle")} gem #{gem_name}", env: { "PATH" => "" }
end
it "creates the gem without the need for git" do
@@ -417,10 +456,10 @@ RSpec.describe "bundle gem" do
prepare_gemspec(bundled_app("newgem", "newgem.gemspec"))
- gems = ["rake-13.0.1"]
- path = Bundler.feature_flag.default_install_uses_path? ? local_gem_path(:base => bundled_app("newgem")) : system_gem_path
- system_gems gems, :path => path
- bundle "exec rake build", :dir => bundled_app("newgem")
+ gems = ["rake-#{rake_version}"]
+ path = Bundler.feature_flag.default_install_uses_path? ? local_gem_path(base: bundled_app("newgem")) : system_gem_path
+ system_gems gems, path: path
+ bundle "exec rake build", dir: bundled_app("newgem")
expect(last_command.stdboth).not_to include("ERROR")
end
@@ -429,7 +468,7 @@ RSpec.describe "bundle gem" do
it "resolves ." do
create_temporary_dir("tmp")
- bundle "gem .", :dir => bundled_app("tmp")
+ bundle "gem .", dir: bundled_app("tmp")
expect(bundled_app("tmp/lib/tmp.rb")).to exist
end
@@ -437,7 +476,7 @@ RSpec.describe "bundle gem" do
it "resolves .." do
create_temporary_dir("temp/empty_dir")
- bundle "gem ..", :dir => bundled_app("temp/empty_dir")
+ bundle "gem ..", dir: bundled_app("temp/empty_dir")
expect(bundled_app("temp/lib/temp.rb")).to exist
end
@@ -445,7 +484,7 @@ RSpec.describe "bundle gem" do
it "resolves relative directory" do
create_temporary_dir("tmp/empty/tmp")
- bundle "gem ../../empty", :dir => bundled_app("tmp/empty/tmp")
+ bundle "gem ../../empty", dir: bundled_app("tmp/empty/tmp")
expect(bundled_app("tmp/empty/lib/empty.rb")).to exist
end
@@ -594,17 +633,25 @@ RSpec.describe "bundle gem" do
it "does not include the gemspec file in files" do
bundle "gem #{gem_name}"
- bundler_gemspec = Bundler::GemHelper.new(gemspec_dir).gemspec
+ bundler_gemspec = Bundler::GemHelper.new(bundled_app(gem_name), gem_name).gemspec
expect(bundler_gemspec.files).not_to include("#{gem_name}.gemspec")
end
+ it "does not include the Gemfile file in files" do
+ bundle "gem #{gem_name}"
+
+ bundler_gemspec = Bundler::GemHelper.new(bundled_app(gem_name), gem_name).gemspec
+
+ expect(bundler_gemspec.files).not_to include("Gemfile")
+ end
+
it "runs rake without problems" do
bundle "gem #{gem_name}"
- system_gems ["rake-13.0.1"]
+ system_gems ["rake-#{rake_version}"]
- rakefile = strip_whitespace <<-RAKEFILE
+ rakefile = <<~RAKEFILE
task :default do
puts 'SUCCESS'
end
@@ -613,7 +660,7 @@ RSpec.describe "bundle gem" do
file.puts rakefile
end
- sys_exec(rake, :dir => bundled_app(gem_name))
+ sys_exec(rake, dir: bundled_app(gem_name))
expect(out).to include("SUCCESS")
end
@@ -702,7 +749,7 @@ RSpec.describe "bundle gem" do
end
it "builds spec skeleton" do
- expect(bundled_app("#{gem_name}/test/test_#{require_path}.rb")).to exist
+ expect(bundled_app("#{gem_name}/#{minitest_test_file_path}")).to exist
expect(bundled_app("#{gem_name}/test/test_helper.rb")).to exist
end
end
@@ -722,7 +769,7 @@ RSpec.describe "bundle gem" do
end
it "builds spec skeleton" do
- expect(bundled_app("#{gem_name}/test/test_#{require_path}.rb")).to exist
+ expect(bundled_app("#{gem_name}/#{minitest_test_file_path}")).to exist
expect(bundled_app("#{gem_name}/test/test_helper.rb")).to exist
end
@@ -731,11 +778,15 @@ RSpec.describe "bundle gem" do
end
it "requires 'test_helper'" do
- expect(bundled_app("#{gem_name}/test/test_#{require_path}.rb").read).to include(%(require "test_helper"))
+ expect(bundled_app("#{gem_name}/#{minitest_test_file_path}").read).to include(%(require "test_helper"))
+ end
+
+ it "defines valid test class name" do
+ expect(bundled_app("#{gem_name}/#{minitest_test_file_path}").read).to include(minitest_test_class_name)
end
it "creates a default test which fails" do
- expect(bundled_app("#{gem_name}/test/test_#{require_path}.rb").read).to include("assert false")
+ expect(bundled_app("#{gem_name}/#{minitest_test_file_path}").read).to include("assert false")
end
end
@@ -746,17 +797,13 @@ RSpec.describe "bundle gem" do
end
it "creates a default rake task to run the test suite" do
- rakefile = strip_whitespace <<-RAKEFILE
+ rakefile = <<~RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
- require "rake/testtask"
+ require "minitest/test_task"
- Rake::TestTask.new(:test) do |t|
- t.libs << "test"
- t.libs << "lib"
- t.test_files = FileList["test/**/test_*.rb"]
- end
+ Minitest::TestTask.create
task default: :test
RAKEFILE
@@ -804,7 +851,7 @@ RSpec.describe "bundle gem" do
end
it "creates a default rake task to run the test suite" do
- rakefile = strip_whitespace <<-RAKEFILE
+ rakefile = <<~RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
@@ -880,7 +927,6 @@ RSpec.describe "bundle gem" do
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
- expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist
expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist
end
@@ -892,6 +938,12 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to exist
end
+
+ it "contained .gitlab-ci.yml into ignore list" do
+ bundle "gem #{gem_name} --ci=github"
+
+ expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include(".git .github appveyor")
+ end
end
context "--ci set to gitlab" do
@@ -900,6 +952,12 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to exist
end
+
+ it "contained .gitlab-ci.yml into ignore list" do
+ bundle "gem #{gem_name} --ci=gitlab"
+
+ expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include(".git .gitlab-ci.yml appveyor")
+ end
end
context "--ci set to circle" do
@@ -908,20 +966,17 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/.circleci/config.yml")).to exist
end
- end
- context "--ci set to travis" do
- it "generates a Travis CI config file" do
- bundle "gem #{gem_name} --ci=travis"
+ it "contained .circleci into ignore list" do
+ bundle "gem #{gem_name} --ci=circle"
- expect(bundled_app("#{gem_name}/.travis.yml")).to exist
+ expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include(".git .circleci appveyor")
end
end
context "gem.ci setting set to none" do
it "doesn't generate any CI config" do
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
- expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist
expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist
expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist
end
@@ -936,15 +991,6 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.ci setting set to travis" do
- it "generates a Travis CI config file" do
- bundle "config set gem.ci travis"
- bundle "gem #{gem_name}"
-
- expect(bundled_app("#{gem_name}/.travis.yml")).to exist
- end
- end
-
context "gem.ci setting set to gitlab" do
it "generates a GitLab CI config file" do
bundle "config set gem.ci gitlab"
@@ -1063,7 +1109,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.rubocop setting set to true", :bundler => "< 3" do
+ context "gem.rubocop setting set to true", bundler: "< 3" do
before do
bundle "config set gem.rubocop true"
bundle "gem #{gem_name}"
@@ -1300,6 +1346,10 @@ RSpec.describe "bundle gem" do
let(:require_relative_path) { "test_gem" }
+ let(:minitest_test_file_path) { "test/test_test_gem.rb" }
+
+ let(:minitest_test_class_name) { "class TestTestGem < Minitest::Test" }
+
let(:flags) { nil }
it "does not nest constants" do
@@ -1310,25 +1360,50 @@ RSpec.describe "bundle gem" do
include_examples "generating a gem"
- context "--ext parameter set" do
- let(:flags) { "--ext" }
+ context "--ext parameter with no value" do
+ context "is deprecated", bundler: "< 3" do
+ it "prints deprecation when used after gem name" do
+ bundle ["gem", "--ext", gem_name].compact.join(" ")
+ expect(err).to include "[DEPRECATED]"
+ expect(err).to include "`--ext` with no arguments has been deprecated"
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.c")).to exist
+ end
+
+ it "prints deprecation when used before gem name" do
+ bundle ["gem", gem_name, "--ext"].compact.join(" ")
+ expect(err).to include "[DEPRECATED]"
+ expect(err).to include "`--ext` with no arguments has been deprecated"
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.c")).to exist
+ end
+ end
+ end
+
+ context "--ext parameter set with C" do
+ let(:flags) { "--ext=c" }
before do
bundle ["gem", gem_name, flags].compact.join(" ")
end
+ it "is not deprecated" do
+ expect(err).not_to include "[DEPRECATED] Option `--ext` without explicit value is deprecated."
+ end
+
it "builds ext skeleton" do
expect(bundled_app("#{gem_name}/ext/#{gem_name}/extconf.rb")).to exist
expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.h")).to exist
expect(bundled_app("#{gem_name}/ext/#{gem_name}/#{gem_name}.c")).to exist
end
- it "includes rake-compiler" do
+ it "includes rake-compiler, but no Rust related changes" do
expect(bundled_app("#{gem_name}/Gemfile").read).to include('gem "rake-compiler"')
+
+ expect(bundled_app("#{gem_name}/Gemfile").read).to_not include('gem "rb_sys"')
+ expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to_not include('spec.required_rubygems_version = ">= ')
end
it "depends on compile task for build" do
- rakefile = strip_whitespace <<-RAKEFILE
+ rakefile = <<~RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
@@ -1336,7 +1411,9 @@ RSpec.describe "bundle gem" do
task build: :compile
- Rake::ExtensionTask.new("#{gem_name}") do |ext|
+ GEMSPEC = Gem::Specification.load("#{gem_name}.gemspec")
+
+ Rake::ExtensionTask.new("#{gem_name}", GEMSPEC) do |ext|
ext.lib_dir = "lib/#{gem_name}"
end
@@ -1346,6 +1423,66 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/Rakefile").read).to eq(rakefile)
end
end
+
+ context "--ext parameter set with rust and old RubyGems" do
+ it "fails in friendly way" do
+ if ::Gem::Version.new("3.3.11") <= ::Gem.rubygems_version
+ skip "RubyGems compatible with Rust builder"
+ end
+
+ expect do
+ bundle ["gem", gem_name, "--ext=rust"].compact.join(" ")
+ end.to raise_error(RuntimeError, /too old to build Rust extension/)
+ end
+ end
+
+ context "--ext parameter set with rust" do
+ let(:flags) { "--ext=rust" }
+
+ before do
+ skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
+
+ bundle ["gem", gem_name, flags].compact.join(" ")
+ end
+
+ it "is not deprecated" do
+ expect(err).not_to include "[DEPRECATED] Option `--ext` without explicit value is deprecated."
+ end
+
+ it "builds ext skeleton" do
+ expect(bundled_app("#{gem_name}/Cargo.toml")).to exist
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/Cargo.toml")).to exist
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/extconf.rb")).to exist
+ expect(bundled_app("#{gem_name}/ext/#{gem_name}/src/lib.rs")).to exist
+ end
+
+ it "includes rake-compiler, rb_sys gems and required_rubygems_version constraint" do
+ expect(bundled_app("#{gem_name}/Gemfile").read).to include('gem "rake-compiler"')
+ expect(bundled_app("#{gem_name}/Gemfile").read).to include('gem "rb_sys"')
+ expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include('spec.required_rubygems_version = ">= ')
+ end
+
+ it "depends on compile task for build" do
+ rakefile = <<~RAKEFILE
+ # frozen_string_literal: true
+
+ require "bundler/gem_tasks"
+ require "rb_sys/extensiontask"
+
+ task build: :compile
+
+ GEMSPEC = Gem::Specification.load("#{gem_name}.gemspec")
+
+ RbSys::ExtensionTask.new("#{gem_name}", GEMSPEC) do |ext|
+ ext.lib_dir = "lib/#{gem_name}"
+ end
+
+ task default: :compile
+ RAKEFILE
+
+ expect(bundled_app("#{gem_name}/Rakefile").read).to eq(rakefile)
+ end
+ end
end
context "gem naming with dashed", :readline do
@@ -1355,6 +1492,10 @@ RSpec.describe "bundle gem" do
let(:require_relative_path) { "gem" }
+ let(:minitest_test_file_path) { "test/test/test_gem.rb" }
+
+ let(:minitest_test_class_name) { "class Test::TestGem < Minitest::Test" }
+
it "nests constants so they work" do
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/lib/#{require_path}/version.rb").read).to match(/module Test\n module Gem/)
@@ -1372,22 +1513,22 @@ RSpec.describe "bundle gem" do
end
it "fails gracefully with a ." do
- bundle "gem foo.gemspec", :raise_on_error => false
+ bundle "gem foo.gemspec", raise_on_error: false
expect(err).to end_with("Invalid gem name foo.gemspec -- `Foo.gemspec` is an invalid constant name")
end
it "fails gracefully with a ^" do
- bundle "gem ^", :raise_on_error => false
+ bundle "gem ^", raise_on_error: false
expect(err).to end_with("Invalid gem name ^ -- `^` is an invalid constant name")
end
it "fails gracefully with a space" do
- bundle "gem 'foo bar'", :raise_on_error => false
+ bundle "gem 'foo bar'", raise_on_error: false
expect(err).to end_with("Invalid gem name foo bar -- `Foo bar` is an invalid constant name")
end
it "fails gracefully when multiple names are passed" do
- bundle "gem foo bar baz", :raise_on_error => false
+ bundle "gem foo bar baz", raise_on_error: false
expect(err).to eq(<<-E.strip)
ERROR: "bundle gem" was called with arguments ["foo", "bar", "baz"]
Usage: "bundle gem NAME [OPTIONS]"
@@ -1397,7 +1538,7 @@ Usage: "bundle gem NAME [OPTIONS]"
describe "#ensure_safe_gem_name", :readline do
before do
- bundle "gem #{subject}", :raise_on_error => false
+ bundle "gem #{subject}", raise_on_error: false
end
context "with an existing const name" do
@@ -1430,7 +1571,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
expect(bundled_app("foobar/spec/spec_helper.rb")).to exist
- rakefile = strip_whitespace <<-RAKEFILE
+ rakefile = <<~RAKEFILE
# frozen_string_literal: true
require "bundler/gem_tasks"
@@ -1492,7 +1633,7 @@ Usage: "bundle gem NAME [OPTIONS]"
context "on conflicts with a previously created file", :readline do
it "should fail gracefully" do
FileUtils.touch(bundled_app("conflict-foobar"))
- bundle "gem conflict-foobar", :raise_on_error => false
+ bundle "gem conflict-foobar", raise_on_error: false
expect(err).to eq("Couldn't create a new gem named `conflict-foobar` because there's an existing file named `conflict-foobar`.")
expect(exitstatus).to eql(32)
end
diff --git a/spec/bundler/commands/open_spec.rb b/spec/bundler/commands/open_spec.rb
index 53dc35c2c7..97374f30c3 100644
--- a/spec/bundler/commands/open_spec.rb
+++ b/spec/bundler/commands/open_spec.rb
@@ -10,66 +10,124 @@ RSpec.describe "bundle open" do
end
it "opens the gem with BUNDLER_EDITOR as highest priority" do
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
expect(out).to include("bundler_editor #{default_bundle_path("gems", "rails-2.3.2")}")
end
it "opens the gem with VISUAL as 2nd highest priority" do
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "" }
expect(out).to include("visual #{default_bundle_path("gems", "rails-2.3.2")}")
end
it "opens the gem with EDITOR as 3rd highest priority" do
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "rails-2.3.2")}")
end
it "complains if no EDITOR is set" do
- bundle "open rails", :env => { "EDITOR" => "", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", env: { "EDITOR" => "", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to eq("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR")
end
it "complains if gem not in bundle" do
- bundle "open missing", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
+ bundle "open missing", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
expect(err).to match(/could not find gem 'missing'/i)
end
it "does not blow up if the gem to open does not have a Gemfile" do
git = build_git "foo"
- ref = git.ref_for("master", 11)
+ ref = git.ref_for("main", 11)
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem 'foo', :git => "#{lib_path("foo-1.0")}"
G
- bundle "open foo", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
- expect(out).to match("editor #{default_bundle_path.join("bundler/gems/foo-1.0-#{ref}")}")
+ bundle "open foo", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("editor #{default_bundle_path.join("bundler", "gems", "foo-1.0-#{ref}")}")
end
it "suggests alternatives for similar-sounding gems" do
- bundle "open Rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
+ bundle "open Rails", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
expect(err).to match(/did you mean rails\?/i)
end
it "opens the gem with short words" do
- bundle "open rec", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open rec", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}")
end
+ it "opens subpath of the gem" do
+ bundle "open activerecord --path lib/activerecord", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/activerecord")
+ end
+
+ it "opens subpath file of the gem" do
+ bundle "open activerecord --path lib/version.rb", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/version.rb")
+ end
+
+ it "opens deep subpath of the gem" do
+ bundle "open activerecord --path lib/active_record", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/active_record")
+ end
+
+ it "requires value for --path arg" do
+ bundle "open activerecord --path", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ expect(err).to eq "Cannot specify `--path` option without a value"
+ end
+
+ it "suggests alternatives for similar-sounding gems when using subpath" do
+ bundle "open Rails --path README.md", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ expect(err).to match(/did you mean rails\?/i)
+ end
+
+ it "suggests alternatives for similar-sounding gems when using deep subpath" do
+ bundle "open Rails --path some/path/here", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
+ expect(err).to match(/did you mean rails\?/i)
+ end
+
+ it "opens subpath of the short worded gem" do
+ bundle "open rec --path CHANGELOG.md", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/CHANGELOG.md")
+ end
+
+ it "opens deep subpath of the short worded gem" do
+ bundle "open rec --path lib/activerecord", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/activerecord")
+ end
+
+ it "opens subpath of the selected matching gem", :readline do
+ env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open active --path CHANGELOG.md", env: env do |input, _, _|
+ input.puts "2"
+ end
+
+ expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2").join("CHANGELOG.md")}")
+ end
+
+ it "opens deep subpath of the selected matching gem", :readline do
+ env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open active --path lib/activerecord/version.rb", env: env do |input, _, _|
+ input.puts "2"
+ end
+
+ expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2").join("lib", "activerecord", "version.rb")}")
+ end
+
it "select the gem from many match gems", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle "open active", :env => env do |input, _, _|
+ bundle "open active", env: env do |input, _, _|
input.puts "2"
end
- expect(out).to match(/bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}\z/)
+ expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}")
end
it "allows selecting exit from many match gems", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
- bundle "open active", :env => env do |input, _, _|
+ bundle "open active", env: env do |input, _, _|
input.puts "0"
end
end
@@ -82,12 +140,12 @@ RSpec.describe "bundle open" do
G
bundle "config set auto_install 1"
- bundle "open rails", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
+ bundle "open rails", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("Installing foo 1.0")
end
it "opens the editor with a clean env" do
- bundle "open", :env => { "EDITOR" => "sh -c 'env'", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
+ bundle "open", env: { "EDITOR" => "sh -c 'env'", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
expect(out).not_to include("BUNDLE_GEMFILE=")
end
end
@@ -111,7 +169,7 @@ RSpec.describe "bundle open" do
end
it "throws proper error when trying to open default gem" do
- bundle "open json", :env => { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
+ bundle "open json", env: { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
expect(out).to include("Unable to open json because it's a default gem, so the directory it would normally be installed to does not exist.")
end
end
diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb
index 731d67af1b..e7edc67e57 100644
--- a/spec/bundler/commands/outdated_spec.rb
+++ b/spec/bundler/commands/outdated_spec.rb
@@ -4,8 +4,8 @@ RSpec.describe "bundle outdated" do
describe "with no arguments" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -23,11 +23,11 @@ RSpec.describe "bundle outdated" do
update_repo2 do
build_gem "activesupport", "3.0"
build_gem "weakling", "0.2"
- update_git "foo", :path => lib_path("foo")
- update_git "zebra", :path => lib_path("zebra")
+ update_git "foo", path: lib_path("foo")
+ update_git "zebra", path: lib_path("zebra")
end
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
Gem Current Latest Requested Groups
@@ -50,7 +50,7 @@ RSpec.describe "bundle outdated" do
gem "AAA", "1.0.0"
G
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expected_output = <<~TABLE
Gem Current Latest Requested Groups
@@ -63,10 +63,10 @@ RSpec.describe "bundle outdated" do
it "returns non zero exit status if outdated gems present" do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", :path => lib_path("foo")
+ update_git "foo", path: lib_path("foo")
end
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expect(exitstatus).to_not be_zero
end
@@ -89,7 +89,7 @@ RSpec.describe "bundle outdated" do
update_repo2 { build_gem "activesupport", "3.0" }
update_repo2 { build_gem "terranova", "9" }
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -104,8 +104,8 @@ RSpec.describe "bundle outdated" do
describe "with --verbose option" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -139,7 +139,7 @@ RSpec.describe "bundle outdated" do
gem 'activesupport', '2.3.5'
G
- bundle "outdated --verbose", :raise_on_error => false
+ bundle "outdated --verbose", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups Path
@@ -151,7 +151,7 @@ RSpec.describe "bundle outdated" do
end
end
- describe "with multiple, duplicated sources, with lockfile in old format", :bundler => "< 3" do
+ describe "with multiple, duplicated sources, with lockfile in old format", bundler: "< 3" do
before do
build_repo2 do
build_gem "dotenv", "2.7.6"
@@ -192,7 +192,7 @@ RSpec.describe "bundle outdated" do
vcr (6.0.0)
PLATFORMS
- #{specific_local_platform}
+ #{local_platform}
DEPENDENCIES
dotenv
@@ -205,8 +205,8 @@ RSpec.describe "bundle outdated" do
end
it "works" do
- bundle :install, :artifice => "compact_index"
- bundle :outdated, :artifice => "compact_index", :raise_on_error => false
+ bundle :install, artifice: "compact_index"
+ bundle :outdated, artifice: "compact_index", raise_on_error: false
expected_output = <<~TABLE
Gem Current Latest Requested Groups
@@ -220,8 +220,8 @@ RSpec.describe "bundle outdated" do
describe "with --group option" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -243,7 +243,7 @@ RSpec.describe "bundle outdated" do
build_gem "duradura", "8.0"
end
- bundle "outdated --group #{group}", :raise_on_error => false
+ bundle "outdated --group #{group}", raise_on_error: false
end
it "works when the bundle is up to date" do
@@ -290,8 +290,8 @@ RSpec.describe "bundle outdated" do
describe "with --groups option and outdated transitive dependencies" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
build_gem "bar", %w[2.0.0]
@@ -312,7 +312,7 @@ RSpec.describe "bundle outdated" do
end
it "returns a sorted list of outdated gems" do
- bundle "outdated --groups", :raise_on_error => false
+ bundle "outdated --groups", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -326,8 +326,8 @@ RSpec.describe "bundle outdated" do
describe "with --groups option" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -354,7 +354,7 @@ RSpec.describe "bundle outdated" do
build_gem "duradura", "8.0"
end
- bundle "outdated --groups", :raise_on_error => false
+ bundle "outdated --groups", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -370,8 +370,8 @@ RSpec.describe "bundle outdated" do
describe "with --local option" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -398,7 +398,7 @@ RSpec.describe "bundle outdated" do
gem "activesupport", "2.3.4"
G
- bundle "outdated --local", :raise_on_error => false
+ bundle "outdated --local", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -420,8 +420,8 @@ RSpec.describe "bundle outdated" do
context "and gems are outdated" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
build_gem "activesupport", "3.0"
build_gem "weakling", "0.2"
@@ -455,13 +455,13 @@ RSpec.describe "bundle outdated" do
end
describe "with --parseable option" do
- subject { bundle "outdated --parseable", :raise_on_error => false }
+ subject { bundle "outdated --parseable", raise_on_error: false }
it_behaves_like "a minimal output is desired"
end
describe "with aliased --porcelain option" do
- subject { bundle "outdated --porcelain", :raise_on_error => false }
+ subject { bundle "outdated --porcelain", raise_on_error: false }
it_behaves_like "a minimal output is desired"
end
@@ -469,8 +469,8 @@ RSpec.describe "bundle outdated" do
describe "with specified gems" do
it "returns list of outdated gems" do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -485,10 +485,10 @@ RSpec.describe "bundle outdated" do
update_repo2 do
build_gem "activesupport", "3.0"
- update_git "foo", :path => lib_path("foo")
+ update_git "foo", path: lib_path("foo")
end
- bundle "outdated foo", :raise_on_error => false
+ bundle "outdated foo", raise_on_error: false
expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
Gem Current Latest Requested Groups
@@ -502,8 +502,8 @@ RSpec.describe "bundle outdated" do
describe "pre-release gems" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -535,7 +535,7 @@ RSpec.describe "bundle outdated" do
build_gem "activesupport", "3.0.0.beta"
end
- bundle "outdated --pre", :raise_on_error => false
+ bundle "outdated --pre", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -558,7 +558,7 @@ RSpec.describe "bundle outdated" do
gem "activesupport", "3.0.0.beta.1"
G
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -570,12 +570,11 @@ RSpec.describe "bundle outdated" do
end
end
- filter_strict_option = Bundler.feature_flag.bundler_2_mode? ? :"filter-strict" : :strict
- describe "with --#{filter_strict_option} option" do
+ describe "with --filter-strict option" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -595,7 +594,23 @@ RSpec.describe "bundle outdated" do
build_gem "weakling", "0.0.5"
end
- bundle :outdated, filter_strict_option => true, :raise_on_error => false
+ bundle :outdated, "filter-strict": true, raise_on_error: false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ weakling 0.0.3 0.0.5 ~> 0.0.1 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+
+ it "only reports gems that have a newer version that matches the specified dependency version requirements, using --strict alias" do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ build_gem "weakling", "0.0.5"
+ end
+
+ bundle :outdated, strict: true, raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -611,7 +626,7 @@ RSpec.describe "bundle outdated" do
gem "activesupport", platforms: [:ruby_22]
G
- bundle :outdated, filter_strict_option => true
+ bundle :outdated, "filter-strict": true
expect(out).to end_with("Bundle up to date!")
end
@@ -622,7 +637,7 @@ RSpec.describe "bundle outdated" do
gem "rack_middleware", "1.0"
G
- bundle :outdated, filter_strict_option => true
+ bundle :outdated, "filter-strict": true
expect(out).to end_with("Bundle up to date!")
end
@@ -640,7 +655,7 @@ RSpec.describe "bundle outdated" do
build_gem "weakling", "0.0.5"
end
- bundle :outdated, filter_strict_option => true, "filter-patch" => true, :raise_on_error => false
+ bundle :outdated, :"filter-strict" => true, "filter-patch" => true, :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -662,7 +677,7 @@ RSpec.describe "bundle outdated" do
build_gem "weakling", "0.1.5"
end
- bundle :outdated, filter_strict_option => true, "filter-minor" => true, :raise_on_error => false
+ bundle :outdated, :"filter-strict" => true, "filter-minor" => true, :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -684,7 +699,7 @@ RSpec.describe "bundle outdated" do
build_gem "weakling", "1.1.5"
end
- bundle :outdated, filter_strict_option => true, "filter-major" => true, :raise_on_error => false
+ bundle :outdated, :"filter-strict" => true, "filter-major" => true, :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -699,8 +714,8 @@ RSpec.describe "bundle outdated" do
describe "with invalid gem name" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -715,12 +730,12 @@ RSpec.describe "bundle outdated" do
end
it "returns could not find gem name" do
- bundle "outdated invalid_gem_name", :raise_on_error => false
+ bundle "outdated invalid_gem_name", raise_on_error: false
expect(err).to include("Could not find gem 'invalid_gem_name'.")
end
it "returns non-zero exit code" do
- bundle "outdated invalid_gem_name", :raise_on_error => false
+ bundle "outdated invalid_gem_name", raise_on_error: false
expect(exitstatus).to_not be_zero
end
end
@@ -733,11 +748,11 @@ RSpec.describe "bundle outdated" do
G
bundle "config set auto_install 1"
- bundle :outdated, :raise_on_error => false
+ bundle :outdated, raise_on_error: false
expect(out).to include("Installing foo 1.0")
end
- context "after bundle install --deployment", :bundler => "< 3" do
+ context "after bundle install --deployment", bundler: "< 3" do
before do
build_repo2
@@ -748,13 +763,13 @@ RSpec.describe "bundle outdated" do
gem "foo"
G
bundle :lock
- bundle :install, :deployment => true
+ bundle :install, deployment: true
end
it "outputs a helpful message about being in deployment mode" do
update_repo2 { build_gem "activesupport", "3.0" }
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expect(last_command).to be_failure
expect(err).to include("You are trying to check outdated gems in deployment mode.")
expect(err).to include("Run `bundle outdated` elsewhere.")
@@ -766,8 +781,8 @@ RSpec.describe "bundle outdated" do
context "after bundle config set --local deployment true" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -782,7 +797,7 @@ RSpec.describe "bundle outdated" do
it "outputs a helpful message about being in deployment mode" do
update_repo2 { build_gem "activesupport", "3.0" }
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expect(last_command).to be_failure
expect(err).to include("You are trying to check outdated gems in deployment mode.")
expect(err).to include("Run `bundle outdated` elsewhere.")
@@ -822,13 +837,13 @@ RSpec.describe "bundle outdated" do
expect(out).to end_with("Bundle up to date!")
end
- it "reports that updates are available if the JRuby platform is used", :jruby do
+ it "reports that updates are available if the JRuby platform is used", :jruby_only do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby]
G
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -852,8 +867,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "major version updates are detected" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -878,8 +893,8 @@ RSpec.describe "bundle outdated" do
context "when on a new machine" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -894,22 +909,22 @@ RSpec.describe "bundle outdated" do
simulate_new_machine
- update_git "foo", :path => lib_path("foo")
+ update_git "foo", path: lib_path("foo")
update_repo2 do
build_gem "activesupport", "3.3.5"
build_gem "weakling", "0.8.0"
end
end
- subject { bundle "outdated", :raise_on_error => false }
+ subject { bundle "outdated", raise_on_error: false }
it_behaves_like "version update is detected"
end
shared_examples_for "minor version updates are detected" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -934,8 +949,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "patch version updates are detected" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -967,8 +982,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "major version is ignored" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -993,8 +1008,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "minor version is ignored" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -1019,8 +1034,8 @@ RSpec.describe "bundle outdated" do
shared_examples_for "patch version is ignored" do
before do
build_repo2 do
- build_git "foo", :path => lib_path("foo")
- build_git "zebra", :path => lib_path("zebra")
+ build_git "foo", path: lib_path("foo")
+ build_git "zebra", path: lib_path("zebra")
end
install_gemfile <<-G
@@ -1043,7 +1058,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major option" do
- subject { bundle "outdated --filter-major", :raise_on_error => false }
+ subject { bundle "outdated --filter-major", raise_on_error: false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version is ignored"
@@ -1051,7 +1066,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-minor option" do
- subject { bundle "outdated --filter-minor", :raise_on_error => false }
+ subject { bundle "outdated --filter-minor", raise_on_error: false }
it_behaves_like "minor version updates are detected"
it_behaves_like "major version is ignored"
@@ -1059,7 +1074,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-patch option" do
- subject { bundle "outdated --filter-patch", :raise_on_error => false }
+ subject { bundle "outdated --filter-patch", raise_on_error: false }
it_behaves_like "patch version updates are detected"
it_behaves_like "major version is ignored"
@@ -1067,7 +1082,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-minor --filter-patch options" do
- subject { bundle "outdated --filter-minor --filter-patch", :raise_on_error => false }
+ subject { bundle "outdated --filter-minor --filter-patch", raise_on_error: false }
it_behaves_like "minor version updates are detected"
it_behaves_like "patch version updates are detected"
@@ -1075,7 +1090,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-minor options" do
- subject { bundle "outdated --filter-major --filter-minor", :raise_on_error => false }
+ subject { bundle "outdated --filter-major --filter-minor", raise_on_error: false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version updates are detected"
@@ -1083,7 +1098,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-patch options" do
- subject { bundle "outdated --filter-major --filter-patch", :raise_on_error => false }
+ subject { bundle "outdated --filter-major --filter-patch", raise_on_error: false }
it_behaves_like "major version updates are detected"
it_behaves_like "patch version updates are detected"
@@ -1091,7 +1106,7 @@ RSpec.describe "bundle outdated" do
end
describe "with --filter-major --filter-minor --filter-patch options" do
- subject { bundle "outdated --filter-major --filter-minor --filter-patch", :raise_on_error => false }
+ subject { bundle "outdated --filter-major --filter-minor --filter-patch", raise_on_error: false }
it_behaves_like "major version updates are detected"
it_behaves_like "minor version updates are detected"
@@ -1099,116 +1114,125 @@ RSpec.describe "bundle outdated" do
end
context "conservative updates" do
- context "without update-strict" do
- before do
- build_repo4 do
- build_gem "patch", %w[1.0.0 1.0.1]
- build_gem "minor", %w[1.0.0 1.0.1 1.1.0]
- build_gem "major", %w[1.0.0 1.0.1 1.1.0 2.0.0]
- end
+ before do
+ build_repo4 do
+ build_gem "patch", %w[1.0.0 1.0.1]
+ build_gem "minor", %w[1.0.0 1.0.1 1.1.0]
+ build_gem "major", %w[1.0.0 1.0.1 1.1.0 2.0.0]
+ end
- # establish a lockfile set to 1.0.0
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem 'patch', '1.0.0'
- gem 'minor', '1.0.0'
- gem 'major', '1.0.0'
- G
+ # establish a lockfile set to 1.0.0
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'patch', '1.0.0'
+ gem 'minor', '1.0.0'
+ gem 'major', '1.0.0'
+ G
- # remove 1.4.3 requirement and bar altogether
- # to setup update specs below
- gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem 'patch'
- gem 'minor'
- gem 'major'
- G
- end
+ # remove all version requirements
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'patch'
+ gem 'minor'
+ gem 'major'
+ G
+ end
- it "shows nothing when patching and filtering to minor" do
- bundle "outdated --patch --filter-minor"
+ it "shows nothing when patching and filtering to minor" do
+ bundle "outdated --patch --filter-minor"
- expect(out).to end_with("No minor updates to display.")
- end
+ expect(out).to end_with("No minor updates to display.")
+ end
- it "shows all gems when patching and filtering to patch" do
- bundle "outdated --patch --filter-patch", :raise_on_error => false
+ it "shows all gems when patching and filtering to patch" do
+ bundle "outdated --patch --filter-patch", raise_on_error: false
- expected_output = <<~TABLE.strip
- Gem Current Latest Requested Groups
- major 1.0.0 1.0.1 >= 0 default
- minor 1.0.0 1.0.1 >= 0 default
- patch 1.0.0 1.0.1 >= 0 default
- TABLE
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ major 1.0.0 1.0.1 >= 0 default
+ minor 1.0.0 1.0.1 >= 0 default
+ patch 1.0.0 1.0.1 >= 0 default
+ TABLE
- expect(out).to end_with(expected_output)
- end
+ expect(out).to end_with(expected_output)
+ end
- it "shows minor and major when updating to minor and filtering to patch and minor" do
- bundle "outdated --minor --filter-minor", :raise_on_error => false
+ it "shows minor and major when updating to minor and filtering to patch and minor" do
+ bundle "outdated --minor --filter-minor", raise_on_error: false
- expected_output = <<~TABLE.strip
- Gem Current Latest Requested Groups
- major 1.0.0 1.1.0 >= 0 default
- minor 1.0.0 1.1.0 >= 0 default
- TABLE
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ major 1.0.0 1.1.0 >= 0 default
+ minor 1.0.0 1.1.0 >= 0 default
+ TABLE
- expect(out).to end_with(expected_output)
- end
+ expect(out).to end_with(expected_output)
+ end
- it "shows minor when updating to major and filtering to minor with parseable" do
- bundle "outdated --major --filter-minor --parseable", :raise_on_error => false
+ it "shows minor when updating to major and filtering to minor with parseable" do
+ bundle "outdated --major --filter-minor --parseable", raise_on_error: false
- expect(out).not_to include("patch (newest")
- expect(out).to include("minor (newest")
- expect(out).not_to include("major (newest")
- end
+ expect(out).not_to include("patch (newest")
+ expect(out).to include("minor (newest")
+ expect(out).not_to include("major (newest")
end
+ end
- context "with update-strict" do
- before do
- build_repo4 do
- build_gem "foo", %w[1.4.3 1.4.4] do |s|
- s.add_dependency "bar", "~> 2.0"
- end
- build_gem "foo", %w[1.4.5 1.5.0] do |s|
- s.add_dependency "bar", "~> 2.1"
- end
- build_gem "foo", %w[1.5.1] do |s|
- s.add_dependency "bar", "~> 3.0"
- end
- build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
- build_gem "qux", %w[1.0.0 1.1.0 2.0.0]
+ context "tricky conservative updates" do
+ before do
+ build_repo4 do
+ build_gem "foo", %w[1.4.3 1.4.4] do |s|
+ s.add_dependency "bar", "~> 2.0"
+ end
+ build_gem "foo", %w[1.4.5 1.5.0] do |s|
+ s.add_dependency "bar", "~> 2.1"
end
+ build_gem "foo", %w[1.5.1] do |s|
+ s.add_dependency "bar", "~> 3.0"
+ end
+ build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
+ build_gem "qux", %w[1.0.0 1.1.0 2.0.0]
+ end
- # establish a lockfile set to 1.4.3
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem 'foo', '1.4.3'
- gem 'bar', '2.0.3'
- gem 'qux', '1.0.0'
- G
+ # establish a lockfile set to 1.4.3
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'foo', '1.4.3'
+ gem 'bar', '2.0.3'
+ gem 'qux', '1.0.0'
+ G
- # remove 1.4.3 requirement and bar altogether
- # to setup update specs below
- gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem 'foo'
- gem 'qux'
- G
- end
+ # remove 1.4.3 requirement and bar altogether
+ # to setup update specs below
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem 'foo'
+ gem 'qux'
+ G
+ end
- it "shows gems with update-strict updating to patch and filtering to patch" do
- bundle "outdated --patch --update-strict --filter-patch", :raise_on_error => false
+ it "shows gems updating to patch and filtering to patch" do
+ bundle "outdated --patch --filter-patch", raise_on_error: false, env: { "DEBUG_RESOLVER" => "1" }
- expected_output = <<~TABLE.strip
- Gem Current Latest Requested Groups
- bar 2.0.3 2.0.5
- foo 1.4.3 1.4.4 >= 0 default
- TABLE
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ bar 2.0.3 2.0.5
+ foo 1.4.3 1.4.4 >= 0 default
+ TABLE
- expect(out).to end_with(expected_output)
- end
+ expect(out).to end_with(expected_output)
+ end
+
+ it "shows gems updating to patch and filtering to patch, in debug mode" do
+ bundle "outdated --patch --filter-patch", raise_on_error: false, env: { "DEBUG" => "1" }
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups Path
+ bar 2.0.3 2.0.5
+ foo 1.4.3 1.4.4 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
end
end
@@ -1232,7 +1256,7 @@ RSpec.describe "bundle outdated" do
gem 'weakling'
G
- bundle "outdated --only-explicit", :raise_on_error => false
+ bundle "outdated --only-explicit", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -1282,7 +1306,7 @@ RSpec.describe "bundle outdated" do
end
it "reports a single entry per gem" do
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
@@ -1331,7 +1355,7 @@ RSpec.describe "bundle outdated" do
end
it "works" do
- bundle "outdated", :raise_on_error => false
+ bundle "outdated", raise_on_error: false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
diff --git a/spec/bundler/commands/platform_spec.rb b/spec/bundler/commands/platform_spec.rb
new file mode 100644
index 0000000000..61e615acae
--- /dev/null
+++ b/spec/bundler/commands/platform_spec.rb
@@ -0,0 +1,1307 @@
+# frozen_string_literal: true
+
+RSpec.describe "bundle platform" do
+ context "without flags" do
+ it "returns all the output" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ #{ruby_version_correct}
+
+ gem "foo"
+ G
+
+ bundle "platform"
+ expect(out).to eq(<<-G.chomp)
+Your platform is: #{Gem::Platform.local}
+
+Your app has gems that work on these platforms:
+* #{local_platform}
+
+Your Gemfile specifies a Ruby version requirement:
+* ruby #{Gem.ruby_version}
+
+Your current platform satisfies the Ruby version requirement.
+G
+ end
+
+ it "returns all the output including the patchlevel" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ #{ruby_version_correct_patchlevel}
+
+ gem "foo"
+ G
+
+ bundle "platform"
+ expect(out).to eq(<<-G.chomp)
+Your platform is: #{Gem::Platform.local}
+
+Your app has gems that work on these platforms:
+* #{local_platform}
+
+Your Gemfile specifies a Ruby version requirement:
+* #{Bundler::RubyVersion.system.single_version_string}
+
+Your current platform satisfies the Ruby version requirement.
+G
+ end
+
+ it "doesn't print ruby version requirement if it isn't specified" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "foo"
+ G
+
+ bundle "platform"
+ expect(out).to eq(<<-G.chomp)
+Your platform is: #{Gem::Platform.local}
+
+Your app has gems that work on these platforms:
+* #{local_platform}
+
+Your Gemfile does not specify a Ruby version requirement.
+G
+ end
+
+ it "doesn't match the ruby version requirement" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ #{ruby_version_incorrect}
+
+ gem "foo"
+ G
+
+ bundle "platform"
+ expect(out).to eq(<<-G.chomp)
+Your platform is: #{Gem::Platform.local}
+
+Your app has gems that work on these platforms:
+* #{local_platform}
+
+Your Gemfile specifies a Ruby version requirement:
+* ruby #{not_local_ruby_version}
+
+Your Ruby version is #{Gem.ruby_version}, but your Gemfile specified #{not_local_ruby_version}
+G
+ end
+ end
+
+ context "--ruby" do
+ it "returns ruby version when explicit" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "1.9.3", :engine => 'ruby', :engine_version => '1.9.3'
+
+ gem "foo"
+ G
+
+ bundle "platform --ruby"
+
+ expect(out).to eq("ruby 1.9.3")
+ end
+
+ it "defaults to MRI" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "1.9.3"
+
+ gem "foo"
+ G
+
+ bundle "platform --ruby"
+
+ expect(out).to eq("ruby 1.9.3")
+ end
+
+ it "handles jruby" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "1.8.7", :engine => 'jruby', :engine_version => '1.6.5'
+
+ gem "foo"
+ G
+
+ bundle "platform --ruby"
+
+ expect(out).to eq("ruby 1.8.7 (jruby 1.6.5)")
+ end
+
+ it "handles rbx" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "1.8.7", :engine => 'rbx', :engine_version => '1.2.4'
+
+ gem "foo"
+ G
+
+ bundle "platform --ruby"
+
+ expect(out).to eq("ruby 1.8.7 (rbx 1.2.4)")
+ end
+
+ it "handles truffleruby" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "2.5.1", :engine => 'truffleruby', :engine_version => '1.0.0-rc6'
+
+ gem "foo"
+ G
+
+ bundle "platform --ruby"
+
+ expect(out).to eq("ruby 2.5.1 (truffleruby 1.0.0-rc6)")
+ end
+
+ it "raises an error if engine is used but engine version is not" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "1.8.7", :engine => 'rbx'
+
+ gem "foo"
+ G
+
+ bundle "platform", raise_on_error: false
+
+ expect(exitstatus).not_to eq(0)
+ end
+
+ it "raises an error if engine_version is used but engine is not" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "1.8.7", :engine_version => '1.2.4'
+
+ gem "foo"
+ G
+
+ bundle "platform", raise_on_error: false
+
+ expect(exitstatus).not_to eq(0)
+ end
+
+ it "raises an error if engine version doesn't match ruby version for MRI" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "1.8.7", :engine => 'ruby', :engine_version => '1.2.4'
+
+ gem "foo"
+ G
+
+ bundle "platform", raise_on_error: false
+
+ expect(exitstatus).not_to eq(0)
+ end
+
+ it "should print if no ruby version is specified" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "foo"
+ G
+
+ bundle "platform --ruby"
+
+ expect(out).to eq("No ruby version specified")
+ end
+
+ it "handles when there is a locked requirement" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby "< 1.8.7"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+
+ RUBY VERSION
+ ruby 1.0.0p127
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "platform --ruby"
+ expect(out).to eq("ruby 1.0.0")
+ end
+
+ it "handles when there is a lockfile with no requirement" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "platform --ruby"
+ expect(out).to eq("No ruby version specified")
+ end
+
+ it "handles when there is a requirement in the gemfile" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby ">= 1.8.7"
+ G
+
+ bundle "platform --ruby"
+ expect(out).to eq("ruby 1.8.7")
+ end
+
+ it "handles when there are multiple requirements in the gemfile" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ ruby ">= 1.8.7", "< 2.0.0"
+ G
+
+ bundle "platform --ruby"
+ expect(out).to eq("ruby 1.8.7")
+ end
+ end
+
+ let(:ruby_version_correct) { "ruby \"#{Gem.ruby_version}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{local_engine_version}\"" }
+ let(:ruby_version_correct_engineless) { "ruby \"#{Gem.ruby_version}\"" }
+ let(:ruby_version_correct_patchlevel) { "#{ruby_version_correct}, :patchlevel => '#{RUBY_PATCHLEVEL}'" }
+ let(:ruby_version_incorrect) { "ruby \"#{not_local_ruby_version}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{not_local_ruby_version}\"" }
+ let(:engine_incorrect) { "ruby \"#{Gem.ruby_version}\", :engine => \"#{not_local_tag}\", :engine_version => \"#{Gem.ruby_version}\"" }
+ let(:engine_version_incorrect) { "ruby \"#{Gem.ruby_version}\", :engine => \"#{local_ruby_engine}\", :engine_version => \"#{not_local_engine_version}\"" }
+ let(:patchlevel_incorrect) { "#{ruby_version_correct}, :patchlevel => '#{not_local_patchlevel}'" }
+ let(:patchlevel_fixnum) { "#{ruby_version_correct}, :patchlevel => #{RUBY_PATCHLEVEL}1" }
+
+ def should_be_ruby_version_incorrect
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your Ruby version is #{Gem.ruby_version}, but your Gemfile specified #{not_local_ruby_version}")
+ end
+
+ def should_be_engine_incorrect
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your Ruby engine is #{local_ruby_engine}, but your Gemfile specified #{not_local_tag}")
+ end
+
+ def should_be_engine_version_incorrect
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your #{local_ruby_engine} version is #{local_engine_version}, but your Gemfile specified #{local_ruby_engine} #{not_local_engine_version}")
+ end
+
+ def should_be_patchlevel_incorrect
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("Your Ruby patchlevel is #{RUBY_PATCHLEVEL}, but your Gemfile specified #{not_local_patchlevel}")
+ end
+
+ def should_be_patchlevel_fixnum
+ expect(exitstatus).to eq(18)
+ expect(err).to be_include("The Ruby patchlevel in your Gemfile must be a string")
+ end
+
+ context "bundle install" do
+ it "installs fine when the ruby version matches" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{ruby_version_correct}
+ G
+
+ expect(bundled_app_lock).to exist
+ end
+
+ it "installs fine with any engine", :jruby_only do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{ruby_version_correct_engineless}
+ G
+
+ expect(bundled_app_lock).to exist
+ end
+
+ it "installs fine when the patchlevel matches" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{ruby_version_correct_patchlevel}
+ G
+
+ expect(bundled_app_lock).to exist
+ end
+
+ it "doesn't install when the ruby version doesn't match" do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{ruby_version_incorrect}
+ G
+
+ expect(bundled_app_lock).not_to exist
+ should_be_ruby_version_incorrect
+ end
+
+ it "doesn't install when engine doesn't match" do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{engine_incorrect}
+ G
+
+ expect(bundled_app_lock).not_to exist
+ should_be_engine_incorrect
+ end
+
+ it "doesn't install when engine version doesn't match", :jruby_only do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{engine_version_incorrect}
+ G
+
+ expect(bundled_app_lock).not_to exist
+ should_be_engine_version_incorrect
+ end
+
+ it "doesn't install when patchlevel doesn't match" do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+
+ expect(bundled_app_lock).not_to exist
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle check" do
+ it "checks fine when the ruby version matches" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{ruby_version_correct}
+ G
+
+ bundle :check
+ expect(out).to match(/\AResolving dependencies\.\.\.\.*\nThe Gemfile's dependencies are satisfied\z/)
+ end
+
+ it "checks fine with any engine", :jruby_only do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{ruby_version_correct_engineless}
+ G
+
+ bundle :check
+ expect(out).to match(/\AResolving dependencies\.\.\.\.*\nThe Gemfile's dependencies are satisfied\z/)
+ end
+
+ it "fails when ruby version doesn't match" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{ruby_version_incorrect}
+ G
+
+ bundle :check, raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails when engine doesn't match" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{engine_incorrect}
+ G
+
+ bundle :check, raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ it "fails when engine version doesn't match", :jruby_only do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{engine_version_incorrect}
+ G
+
+ bundle :check, raise_on_error: false
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when patchlevel doesn't match" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+
+ bundle :check, raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle update" do
+ before do
+ build_repo2
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+ G
+ end
+
+ it "updates successfully when the ruby version matches" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+
+ #{ruby_version_correct}
+ G
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle "update", all: true
+ expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
+ end
+
+ it "updates fine with any engine", :jruby_only do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+
+ #{ruby_version_correct_engineless}
+ G
+ update_repo2 do
+ build_gem "rack", "1.2" do |s|
+ s.executables = "rackup"
+ end
+
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle "update", all: true
+ expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
+ end
+
+ it "fails when ruby version doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+
+ #{ruby_version_incorrect}
+ G
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle :update, all: true, raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails when ruby engine doesn't match", :jruby_only do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+
+ #{engine_incorrect}
+ G
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle :update, all: true, raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ it "fails when ruby engine version doesn't match", :jruby_only do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport"
+ gem "rack-obama"
+
+ #{engine_version_incorrect}
+ G
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle :update, all: true, raise_on_error: false
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when patchlevel doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle :update, all: true, raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle info" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+ G
+ end
+
+ it "prints path if ruby version is correct" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+
+ #{ruby_version_correct}
+ G
+
+ bundle "info rails --path"
+ expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
+ end
+
+ it "prints path if ruby version is correct for any engine", :jruby_only do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+
+ #{ruby_version_correct_engineless}
+ G
+
+ bundle "info rails --path"
+ expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
+ end
+
+ it "fails if ruby version doesn't match", bundler: "< 3" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+
+ #{ruby_version_incorrect}
+ G
+
+ bundle "show rails", raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails if engine doesn't match", bundler: "< 3" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+
+ #{engine_incorrect}
+ G
+
+ bundle "show rails", raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ it "fails if engine version doesn't match", bundler: "< 3", jruby_only: true do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails"
+
+ #{engine_version_incorrect}
+ G
+
+ bundle "show rails", raise_on_error: false
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when patchlevel doesn't match", bundler: "< 3" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ end
+
+ bundle "show rails", raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle cache" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+ end
+
+ it "copies the .gem file to vendor/cache when ruby version matches" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{ruby_version_correct}
+ G
+
+ bundle :cache
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
+
+ it "copies the .gem file to vendor/cache when ruby version matches for any engine", :jruby_only do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{ruby_version_correct_engineless}
+ G
+
+ bundle :cache
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
+
+ it "fails if the ruby version doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{ruby_version_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails if the engine doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{engine_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ it "fails if the engine version doesn't match", :jruby_only do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{engine_version_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when patchlevel doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle pack" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+ end
+
+ it "copies the .gem file to vendor/cache when ruby version matches" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{ruby_version_correct}
+ G
+
+ bundle :cache
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
+
+ it "copies the .gem file to vendor/cache when ruby version matches any engine", :jruby_only do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{ruby_version_correct_engineless}
+ G
+
+ bundle :cache
+ expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
+ end
+
+ it "fails if the ruby version doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{ruby_version_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails if the engine doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{engine_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ it "fails if the engine version doesn't match", :jruby_only do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+
+ #{engine_version_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when patchlevel doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+
+ bundle :cache, raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle exec" do
+ before do
+ ENV["BUNDLER_FORCE_TTY"] = "true"
+ system_gems "rack-1.0.0", "rack-0.9.1", path: default_bundle_path
+ end
+
+ it "activates the correct gem when ruby version matches" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+
+ #{ruby_version_correct}
+ G
+
+ bundle "exec rackup"
+ expect(out).to include("0.9.1")
+ end
+
+ it "activates the correct gem when ruby version matches any engine", :jruby_only do
+ system_gems "rack-1.0.0", "rack-0.9.1", path: default_bundle_path
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+
+ #{ruby_version_correct_engineless}
+ G
+
+ bundle "exec rackup"
+ expect(out).to include("0.9.1")
+ end
+
+ it "fails when the ruby version doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+
+ #{ruby_version_incorrect}
+ G
+
+ bundle "exec rackup", raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails when the engine doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack", "0.9.1"
+
+ #{engine_incorrect}
+ G
+
+ bundle "exec rackup", raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ # it "fails when the engine version doesn't match", :jruby_only do
+ # gemfile <<-G
+ # gem "rack", "0.9.1"
+ #
+ # #{engine_version_incorrect}
+ # G
+ #
+ # bundle "exec rackup"
+ # should_be_engine_version_incorrect
+ # end
+
+ it "fails when patchlevel doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+
+ bundle "exec rackup", raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle console", bundler: "< 3" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
+ G
+ end
+
+ it "starts IRB with the default group loaded when ruby version matches", :readline do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
+
+ #{ruby_version_correct}
+ G
+
+ bundle "console" do |input, _, _|
+ input.puts("puts RACK")
+ input.puts("exit")
+ end
+ expect(out).to include("0.9.1")
+ end
+
+ it "starts IRB with the default group loaded when ruby version matches", :readline, :jruby_only do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
+
+ #{ruby_version_correct_engineless}
+ G
+
+ bundle "console" do |input, _, _|
+ input.puts("puts RACK")
+ input.puts("exit")
+ end
+ expect(out).to include("0.9.1")
+ end
+
+ it "fails when ruby version doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
+
+ #{ruby_version_incorrect}
+ G
+
+ bundle "console", raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails when engine doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
+
+ #{engine_incorrect}
+ G
+
+ bundle "console", raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ it "fails when engine version doesn't match", :jruby_only do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
+
+ #{engine_version_incorrect}
+ G
+
+ bundle "console", raise_on_error: false
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when patchlevel doesn't match" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ gem "activesupport", :group => :test
+ gem "rack_middleware", :group => :development
+
+ #{patchlevel_incorrect}
+ G
+
+ bundle "console", raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "Bundler.setup" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack", :group => :test
+ G
+
+ ENV["BUNDLER_FORCE_TTY"] = "true"
+ end
+
+ it "makes a Gemfile.lock if setup succeeds" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
+
+ #{ruby_version_correct}
+ G
+
+ FileUtils.rm(bundled_app_lock)
+
+ run "1"
+ expect(bundled_app_lock).to exist
+ end
+
+ it "makes a Gemfile.lock if setup succeeds for any engine", :jruby_only do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
+
+ #{ruby_version_correct_engineless}
+ G
+
+ FileUtils.rm(bundled_app_lock)
+
+ run "1"
+ expect(bundled_app_lock).to exist
+ end
+
+ it "fails when ruby version doesn't match" do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
+
+ #{ruby_version_incorrect}
+ G
+
+ FileUtils.rm(bundled_app_lock)
+
+ ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+
+ expect(bundled_app_lock).not_to exist
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails when engine doesn't match" do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
+
+ #{engine_incorrect}
+ G
+
+ FileUtils.rm(bundled_app_lock)
+
+ ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+
+ expect(bundled_app_lock).not_to exist
+ should_be_engine_incorrect
+ end
+
+ it "fails when engine version doesn't match", :jruby_only do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
+
+ #{engine_version_incorrect}
+ G
+
+ FileUtils.rm(bundled_app_lock)
+
+ ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+
+ expect(bundled_app_lock).not_to exist
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when patchlevel doesn't match" do
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo1)}"
+ gem "yard"
+ gem "rack"
+
+ #{patchlevel_incorrect}
+ G
+
+ FileUtils.rm(bundled_app_lock)
+
+ ruby "require 'bundler/setup'", env: { "BUNDLER_VERSION" => Bundler::VERSION }, raise_on_error: false
+
+ expect(bundled_app_lock).not_to exist
+ should_be_patchlevel_incorrect
+ end
+ end
+
+ context "bundle outdated" do
+ before do
+ build_repo2 do
+ build_git "foo", path: lib_path("foo")
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+ G
+ end
+
+ it "returns list of outdated gems when the ruby version matches" do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", path: lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+
+ #{ruby_version_correct}
+ G
+
+ bundle "outdated", raise_on_error: false
+
+ expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 default
+ foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default
+ TABLE
+
+ expect(out).to match(Regexp.new(expected_output))
+ end
+
+ it "returns list of outdated gems when the ruby version matches for any engine", :jruby_only do
+ bundle :install
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", path: lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+
+ #{ruby_version_correct_engineless}
+ G
+
+ bundle "outdated", raise_on_error: false
+
+ expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip
+ Gem Current Latest Requested Groups
+ activesupport 2.3.5 3.0 = 2.3.5 default
+ foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default
+ TABLE
+
+ expect(out).to match(Regexp.new(expected_output))
+ end
+
+ it "fails when the ruby version doesn't match" do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", path: lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+
+ #{ruby_version_incorrect}
+ G
+
+ bundle "outdated", raise_on_error: false
+ should_be_ruby_version_incorrect
+ end
+
+ it "fails when the engine doesn't match" do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", path: lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+
+ #{engine_incorrect}
+ G
+
+ bundle "outdated", raise_on_error: false
+ should_be_engine_incorrect
+ end
+
+ it "fails when the engine version doesn't match", :jruby_only do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", path: lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+
+ #{engine_version_incorrect}
+ G
+
+ bundle "outdated", raise_on_error: false
+ should_be_engine_version_incorrect
+ end
+
+ it "fails when the patchlevel doesn't match", :jruby_only do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", path: lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+
+ #{patchlevel_incorrect}
+ G
+
+ bundle "outdated", raise_on_error: false
+ should_be_patchlevel_incorrect
+ end
+
+ it "fails when the patchlevel is a fixnum", :jruby_only do
+ update_repo2 do
+ build_gem "activesupport", "3.0"
+ update_git "foo", path: lib_path("foo")
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "activesupport", "2.3.5"
+ gem "foo", :git => "#{lib_path("foo")}"
+
+ #{patchlevel_fixnum}
+ G
+
+ bundle "outdated", raise_on_error: false
+ should_be_patchlevel_fixnum
+ end
+ end
+end
diff --git a/spec/bundler/commands/post_bundle_message_spec.rb b/spec/bundler/commands/post_bundle_message_spec.rb
index 3050b87754..07fd5a79e9 100644
--- a/spec/bundler/commands/post_bundle_message_spec.rb
+++ b/spec/bundler/commands/post_bundle_message_spec.rb
@@ -114,13 +114,13 @@ RSpec.describe "post bundle message" do
end
it "should report a helpful error message" do
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "not-a-gem", :group => :development
G
expect(err).to include <<-EOS.strip
-Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}/ or installed locally.
+Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}/, cached gems or installed locally.
EOS
end
@@ -131,7 +131,7 @@ Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}
G
bundle :cache
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "not-a-gem", :group => :development
@@ -142,7 +142,7 @@ Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}
end
end
- describe "for second bundle install run", :bundler => "< 3" do
+ describe "for second bundle install run", bundler: "< 3" do
it "without any options" do
2.times { bundle :install }
expect(out).to include(bundle_show_message)
@@ -179,25 +179,25 @@ Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}
describe "for bundle update" do
it "shows proper messages according to the configured groups" do
- bundle :update, :all => true
+ bundle :update, all: true
expect(out).not_to include("Gems in the groups")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo"
bundle :install
- bundle :update, :all => true
+ bundle :update, all: true
expect(out).to include("Gems in the group 'emo' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo test"
bundle :install
- bundle :update, :all => true
+ bundle :update, all: true
expect(out).to include("Gems in the groups 'emo' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo obama test"
bundle :install
- bundle :update, :all => true
+ bundle :update, all: true
expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
end
diff --git a/spec/bundler/commands/pristine_spec.rb b/spec/bundler/commands/pristine_spec.rb
index 2f730bd4e2..1aec37f850 100644
--- a/spec/bundler/commands/pristine_spec.rb
+++ b/spec/bundler/commands/pristine_spec.rb
@@ -2,9 +2,9 @@
require "bundler/vendored_fileutils"
-RSpec.describe "bundle pristine", :ruby_repo do
+RSpec.describe "bundle pristine" do
before :each do
- build_lib "baz", :path => bundled_app do |s|
+ build_lib "baz", path: bundled_app do |s|
s.version = "1.0.0"
s.add_development_dependency "baz-dev", "=1.0.0"
end
@@ -13,16 +13,16 @@ RSpec.describe "bundle pristine", :ruby_repo do
build_gem "weakling"
build_gem "baz-dev", "1.0.0"
build_gem "very_simple_binary", &:add_c_extension
- build_git "foo", :path => lib_path("foo")
- build_git "git_with_ext", :path => lib_path("git_with_ext"), &:add_c_extension
- build_lib "bar", :path => lib_path("bar")
+ build_git "foo", path: lib_path("foo")
+ build_git "git_with_ext", path: lib_path("git_with_ext"), &:add_c_extension
+ build_lib "bar", path: lib_path("bar")
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "weakling"
gem "very_simple_binary"
- gem "foo", :git => "#{lib_path("foo")}", :branch => "master"
+ gem "foo", :git => "#{lib_path("foo")}", :branch => "main"
gem "git_with_ext", :git => "#{lib_path("git_with_ext")}"
gem "bar", :path => "#{lib_path("bar")}"
@@ -164,7 +164,7 @@ RSpec.describe "bundle pristine", :ruby_repo do
end
it "raises when one of them is not in the lockfile" do
- bundle "pristine abcabcabc", :raise_on_error => false
+ bundle "pristine abcabcabc", raise_on_error: false
expect(err).to include("Could not find gem 'abcabcabc'.")
end
end
@@ -181,8 +181,8 @@ RSpec.describe "bundle pristine", :ruby_repo do
bundle "pristine"
makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
- expect(makefile_contents).to match(/libpath =.*#{c_ext_dir}/)
- expect(makefile_contents).to match(/LIBPATH =.*-L#{c_ext_dir}/)
+ expect(makefile_contents).to match(/libpath =.*#{Regexp.escape(c_ext_dir.to_s)}/)
+ expect(makefile_contents).to match(/LIBPATH =.*-L#{Regexp.escape(c_ext_dir.to_s)}/)
end
end
@@ -198,14 +198,14 @@ RSpec.describe "bundle pristine", :ruby_repo do
bundle "pristine"
makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
- expect(makefile_contents).to match(/libpath =.*#{c_ext_dir}/)
- expect(makefile_contents).to match(/LIBPATH =.*-L#{c_ext_dir}/)
+ expect(makefile_contents).to match(/libpath =.*#{Regexp.escape(c_ext_dir.to_s)}/)
+ expect(makefile_contents).to match(/LIBPATH =.*-L#{Regexp.escape(c_ext_dir.to_s)}/)
end
end
context "when BUNDLE_GEMFILE doesn't exist" do
before do
- bundle "pristine", :env => { "BUNDLE_GEMFILE" => "does/not/exist" }, :raise_on_error => false
+ bundle "pristine", env: { "BUNDLE_GEMFILE" => "does/not/exist" }, raise_on_error: false
end
it "shows a meaningful error" do
diff --git a/spec/bundler/commands/remove_spec.rb b/spec/bundler/commands/remove_spec.rb
index 70dc09c9b6..197fcde091 100644
--- a/spec/bundler/commands/remove_spec.rb
+++ b/spec/bundler/commands/remove_spec.rb
@@ -7,13 +7,43 @@ RSpec.describe "bundle remove" do
source "#{file_uri_for(gem_repo1)}"
G
- bundle "remove", :raise_on_error => false
+ bundle "remove", raise_on_error: false
expect(err).to include("Please specify gems to remove.")
end
end
- context "when --install flag is specified", :bundler => "< 3" do
+ context "after 'bundle install' is run" do
+ describe "running 'bundle remove GEM_NAME'" do
+ it "removes it from the lockfile" do
+ rack_dep = <<~L
+
+ DEPENDENCIES
+ rack
+
+ L
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+
+ gem "rack"
+ G
+
+ bundle "install"
+
+ expect(lockfile).to include(rack_dep)
+
+ bundle "remove rack"
+
+ expect(gemfile).to eq <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ G
+ expect(lockfile).to_not include(rack_dep)
+ end
+ end
+ end
+
+ context "when --install flag is specified", bundler: "< 3" do
it "removes gems from .bundle" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@@ -48,13 +78,15 @@ RSpec.describe "bundle remove" do
context "when gem is specified in multiple lines" do
it "shows success for removed gem" do
+ build_git "rack"
+
gemfile <<-G
source '#{file_uri_for(gem_repo1)}'
gem 'git'
gem 'rack',
- git: 'https://github.com/rack/rack',
- branch: 'master'
+ git: "#{lib_path("rack-1.0")}",
+ branch: 'main'
gem 'nokogiri'
G
@@ -77,7 +109,7 @@ RSpec.describe "bundle remove" do
source "#{file_uri_for(gem_repo1)}"
G
- bundle "remove rack", :raise_on_error => false
+ bundle "remove rack", raise_on_error: false
expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
end
@@ -114,7 +146,7 @@ RSpec.describe "bundle remove" do
gem "rspec"
G
- bundle "remove rails rack minitest", :raise_on_error => false
+ bundle "remove rails rack minitest", raise_on_error: false
expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
expect(gemfile).to eq <<~G
@@ -341,7 +373,7 @@ RSpec.describe "bundle remove" do
gem "rack"; gem "rails"
G
- bundle "remove rails", :raise_on_error => false
+ bundle "remove rails", raise_on_error: false
expect(err).to include("Gems could not be removed. rack (>= 0) would also have been removed.")
expect(gemfile).to eq <<~G
@@ -353,7 +385,7 @@ RSpec.describe "bundle remove" do
context "when some gems could not be removed" do
it "shows warning for gems not removed and success for those removed" do
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
source "#{file_uri_for(gem_repo1)}"
gem"rack"
gem"rspec"
@@ -459,7 +491,7 @@ RSpec.describe "bundle remove" do
eval_gemfile "Gemfile-other"
G
- bundle "remove rack", :raise_on_error => false
+ bundle "remove rack", raise_on_error: false
expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.")
end
@@ -478,7 +510,7 @@ RSpec.describe "bundle remove" do
gem "rack"
G
- bundle "remove rack", :raise_on_error => false
+ bundle "remove rack", raise_on_error: false
expect(out).to include("rack was removed.")
expect(err).to include("`rack` is not specified in #{bundled_app("Gemfile-other")} so it could not be removed.")
@@ -490,7 +522,7 @@ RSpec.describe "bundle remove" do
end
end
- context "when gems can not be removed from other gemfile" do
+ context "when gems cannot be removed from other gemfile" do
it "shows error" do
create_file "Gemfile-other", <<-G
gem "rails"; gem "rack"
@@ -503,7 +535,7 @@ RSpec.describe "bundle remove" do
gem "rack"
G
- bundle "remove rack", :raise_on_error => false
+ bundle "remove rack", raise_on_error: false
expect(out).to include("rack was removed.")
expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.")
@@ -528,7 +560,7 @@ RSpec.describe "bundle remove" do
gem "rails"; gem "rack"
G
- bundle "remove rack", :raise_on_error => false
+ bundle "remove rack", raise_on_error: false
expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.")
expect(bundled_app("Gemfile-other").read).to include("gem \"rack\"")
@@ -542,7 +574,7 @@ RSpec.describe "bundle remove" do
end
context "when gem present in gemfiles but could not be removed from one from one of them" do
- it "removes gem which can be removed and shows warning for file from which it can not be removed" do
+ it "removes gem which can be removed and shows warning for file from which it cannot be removed" do
create_file "Gemfile-other", <<-G
gem "rack"
G
@@ -602,7 +634,7 @@ RSpec.describe "bundle remove" do
context "with gemspec" do
it "should not remove the gem" do
- build_lib("foo", :path => tmp.join("foo")) do |s|
+ build_lib("foo", path: tmp.join("foo")) do |s|
s.write("foo.gemspec", "")
s.add_dependency "rack"
end
diff --git a/spec/bundler/commands/show_spec.rb b/spec/bundler/commands/show_spec.rb
index 2adb121616..2b6d4d2d00 100644
--- a/spec/bundler/commands/show_spec.rb
+++ b/spec/bundler/commands/show_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.describe "bundle show", :bundler => "< 3" do
+RSpec.describe "bundle show", bundler: "< 3" do
context "with a standard Gemfile" do
before :each do
install_gemfile <<-G
@@ -50,14 +50,14 @@ RSpec.describe "bundle show", :bundler => "< 3" do
end
it "complains if gem not in bundle" do
- bundle "show missing", :raise_on_error => false
+ bundle "show missing", raise_on_error: false
expect(err).to match(/could not find gem 'missing'/i)
end
it "prints path of all gems in bundle sorted by name" do
bundle "show --paths"
- expect(out).to include(default_bundle_path("gems", "rake-13.0.1").to_s)
+ expect(out).to include(default_bundle_path("gems", "rake-#{rake_version}").to_s)
expect(out).to include(default_bundle_path("gems", "rails-2.3.2").to_s)
# Gem names are the last component of their path.
@@ -100,11 +100,11 @@ RSpec.describe "bundle show", :bundler => "< 3" do
expect(the_bundle).to include_gems "foo 1.0"
bundle :show
- expect(out).to include("foo (1.0 #{@git.ref_for("master", 6)}")
+ expect(out).to include("foo (1.0 #{@git.ref_for("main", 6)}")
end
- it "prints out branch names other than master" do
- update_git "foo", :branch => "omg" do |s|
+ it "prints out branch names other than main" do
+ update_git "foo", branch: "omg" do |s|
s.write "lib/foo.rb", "FOO = '1.0.omg'"
end
@revision = revision_for(lib_path("foo-1.0"))[0...6]
@@ -129,7 +129,7 @@ RSpec.describe "bundle show", :bundler => "< 3" do
end
it "handles when a version is a '-' prerelease" do
- @git = build_git("foo", "1.0.0-beta.1", :path => lib_path("foo"))
+ @git = build_git("foo", "1.0.0-beta.1", path: lib_path("foo"))
install_gemfile <<-G
gem "foo", "1.0.0-beta.1", :git => "#{lib_path("foo")}"
G
@@ -142,13 +142,13 @@ RSpec.describe "bundle show", :bundler => "< 3" do
context "in a fresh gem in a blank git repo" do
before :each do
- build_git "foo", :path => lib_path("foo")
+ build_git "foo", path: lib_path("foo")
File.open(lib_path("foo/Gemfile"), "w") {|f| f.puts "gemspec" }
- sys_exec "rm -rf .git && git init", :dir => lib_path("foo")
+ sys_exec "rm -rf .git && git init", dir: lib_path("foo")
end
it "does not output git errors" do
- bundle :show, :dir => lib_path("foo")
+ bundle :show, dir: lib_path("foo")
expect(err_without_deprecations).to be_empty
end
end
@@ -173,7 +173,7 @@ RSpec.describe "bundle show", :bundler => "< 3" do
G
bundle "show rac"
- expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>)?\z/)
+ expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>.*)?\z/)
end
end
@@ -186,7 +186,7 @@ RSpec.describe "bundle show", :bundler => "< 3" do
invalid_regexp = "[]"
- bundle "show #{invalid_regexp}", :raise_on_error => false
+ bundle "show #{invalid_regexp}", raise_on_error: false
expect(err).to include("Could not find gem '#{invalid_regexp}'.")
end
end
@@ -219,6 +219,6 @@ RSpec.describe "bundle show", :bundler => "< 3" do
end
end
-RSpec.describe "bundle show", :bundler => "3" do
+RSpec.describe "bundle show", bundler: "3" do
pending "shows a friendly error about the command removal"
end
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index 403a48a508..cfb86ebb54 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe "bundle update" do
gem "rack-obama"
exit!
G
- bundle "update", :raise_on_error => false
+ bundle "update", raise_on_error: false
expect(bundled_app_lock).to exist
end
end
@@ -60,7 +60,7 @@ RSpec.describe "bundle update" do
build_gem "activesupport", "3.0"
end
- bundle "update", :all => true
+ bundle "update", all: true
expect(out).to include("Bundle updated!")
expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end
@@ -74,7 +74,7 @@ RSpec.describe "bundle update" do
gem "rack-obama"
exit!
G
- bundle "update", :all => true, :raise_on_error => false
+ bundle "update", all: true, raise_on_error: false
expect(bundled_app_lock).to exist
end
end
@@ -86,7 +86,7 @@ RSpec.describe "bundle update" do
gem "rack", "1.0"
G
- bundle "update --gemfile OmgFile", :all => true
+ bundle "update --gemfile OmgFile", all: true
expect(bundled_app("OmgFile.lock")).to exist
end
@@ -97,13 +97,13 @@ RSpec.describe "bundle update" do
it "errors when passed nothing" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
- bundle :update, :raise_on_error => false
+ bundle :update, raise_on_error: false
expect(err).to eq("To update everything, pass the `--all` flag.")
end
it "errors when passed --all and another option" do
install_gemfile "source \"#{file_uri_for(gem_repo1)}\""
- bundle "update --all foo", :raise_on_error => false
+ bundle "update --all foo", raise_on_error: false
expect(err).to eq("Cannot specify --all along with specific options.")
end
@@ -171,11 +171,11 @@ RSpec.describe "bundle update" do
end
it "should inform the user" do
- bundle "update halting-problem-solver", :raise_on_error => false
+ bundle "update halting-problem-solver", raise_on_error: false
expect(err).to include "Could not find gem 'halting-problem-solver'"
end
it "should suggest alternatives" do
- bundle "update platformspecific", :raise_on_error => false
+ bundle "update platformspecific", raise_on_error: false
expect(err).to include "Did you mean platform_specific?"
end
end
@@ -236,7 +236,7 @@ RSpec.describe "bundle update" do
end
end
- bundle "update", :all => true
+ bundle "update", all: true
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
end
@@ -275,6 +275,11 @@ RSpec.describe "bundle update" do
gem "countries"
G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo4, "countries", "3.1.0")
+ c.checksum(gem_repo4, "country_select", "5.1.0")
+ end
+
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -284,23 +289,145 @@ RSpec.describe "bundle update" do
countries (~> 3.0)
PLATFORMS
- #{specific_local_platform}
+ #{local_platform}
DEPENDENCIES
countries
country_select
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
previous_lockfile = lockfile
- bundle "lock --update"
+ bundle "lock --update", env: { "DEBUG" => "1" }, verbose: true
expect(lockfile).to eq(previous_lockfile)
end
+ it "does not downgrade direct dependencies when run with --conservative" do
+ build_repo4 do
+ build_gem "oauth2", "2.0.6" do |s|
+ s.add_dependency "faraday", ">= 0.17.3", "< 3.0"
+ end
+
+ build_gem "oauth2", "1.4.10" do |s|
+ s.add_dependency "faraday", ">= 0.17.3", "< 3.0"
+ s.add_dependency "multi_json", "~> 1.3"
+ end
+
+ build_gem "faraday", "2.5.2"
+
+ build_gem "multi_json", "1.15.0"
+
+ build_gem "quickbooks-ruby", "1.0.19" do |s|
+ s.add_dependency "oauth2", "~> 1.4"
+ end
+
+ build_gem "quickbooks-ruby", "0.1.9" do |s|
+ s.add_dependency "oauth2"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "oauth2"
+ gem "quickbooks-ruby"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ faraday (2.5.2)
+ multi_json (1.15.0)
+ oauth2 (1.4.10)
+ faraday (>= 0.17.3, < 3.0)
+ multi_json (~> 1.3)
+ quickbooks-ruby (1.0.19)
+ oauth2 (~> 1.4)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ oauth2
+ quickbooks-ruby
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "update --conservative --verbose"
+
+ expect(out).not_to include("Installing quickbooks-ruby 0.1.9")
+ expect(out).to include("Installing quickbooks-ruby 1.0.19").and include("Installing oauth2 1.4.10")
+ end
+
+ it "does not downgrade direct dependencies when using gemspec sources" do
+ create_file("rails.gemspec", <<-G)
+ Gem::Specification.new do |gem|
+ gem.name = "rails"
+ gem.version = "7.1.0.alpha"
+ gem.author = "DHH"
+ gem.summary = "Full-stack web application framework."
+ end
+ G
+
+ build_repo4 do
+ build_gem "rake", "12.3.3"
+ build_gem "rake", "13.0.6"
+
+ build_gem "sneakers", "2.11.0" do |s|
+ s.add_dependency "rake"
+ end
+
+ build_gem "sneakers", "2.12.0" do |s|
+ s.add_dependency "rake", "~> 12.3"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gemspec
+
+ gem "rake"
+ gem "sneakers"
+ G
+
+ lockfile <<~L
+ PATH
+ remote: .
+ specs:
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rake (13.0.6)
+ sneakers (2.11.0)
+ rake
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rake
+ sneakers
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "update --verbose"
+
+ expect(out).not_to include("Installing sneakers 2.12.0")
+ expect(out).not_to include("Installing rake 12.3.3")
+ expect(out).to include("Installing sneakers 2.11.0").and include("Installing rake 13.0.6")
+ end
+
it "does not downgrade indirect dependencies unnecessarily" do
build_repo4 do
build_gem "a" do |s|
@@ -312,7 +439,7 @@ RSpec.describe "bundle update" do
build_gem "c", "2.0"
end
- install_gemfile <<-G, :verbose => true
+ install_gemfile <<-G, verbose: true
source "#{file_uri_for(gem_repo4)}"
gem "a"
G
@@ -325,7 +452,7 @@ RSpec.describe "bundle update" do
end
end
- bundle "update", :all => true, :verbose => true
+ bundle "update", all: true, verbose: true
expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
end
@@ -383,6 +510,11 @@ RSpec.describe "bundle update" do
original_lockfile = lockfile
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo4, "activesupport", "6.0.4.1"
+ c.checksum gem_repo4, "tzinfo", "1.2.9"
+ end
+
expected_lockfile = <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
@@ -396,7 +528,7 @@ RSpec.describe "bundle update" do
DEPENDENCIES
activesupport (~> 6.0.0)
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -405,6 +537,10 @@ RSpec.describe "bundle update" do
expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9")
expect(lockfile).to eq(expected_lockfile)
+ # needed because regressing to versions already present on the system
+ # won't add a checksum
+ expected_lockfile = remove_checksums_from_lockfile(expected_lockfile)
+
lockfile original_lockfile
bundle "update"
expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9")
@@ -421,12 +557,36 @@ RSpec.describe "bundle update" do
before do
build_repo2
- install_gemfile <<-G
+ gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
gem "platform_specific"
G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ activesupport (2.3.5)
+ platform_specific (1.0-#{local_platform})
+ rack (1.0.0)
+ rack-obama (1.0)
+ rack
+
+ PLATFORMS
+ #{local_platform}
+
+ DEPENDENCIES
+ activesupport
+ platform_specific
+ rack-obama
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install"
end
it "doesn't hit repo2" do
@@ -479,7 +639,7 @@ RSpec.describe "bundle update" do
context "when there is a source with the same name as a gem in a group" do
before do
- build_git "foo", :path => lib_path("activesupport")
+ build_git "foo", path: lib_path("activesupport")
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport", :group => :development
@@ -489,7 +649,7 @@ RSpec.describe "bundle update" do
it "should not update the gems from that source" do
update_repo2 { build_gem "activesupport", "3.0" }
- update_git "foo", "2.0", :path => lib_path("activesupport")
+ update_git "foo", "2.0", path: lib_path("activesupport")
bundle "update --group development"
expect(the_bundle).to include_gems "activesupport 3.0"
@@ -531,27 +691,33 @@ RSpec.describe "bundle update" do
G
end
- it "should fail loudly", :bundler => "< 3" do
+ it "should fail loudly", bundler: "< 3" do
bundle "install --deployment"
- bundle "update", :all => true, :raise_on_error => false
+ bundle "update", all: true, raise_on_error: false
expect(last_command).to be_failure
- expect(err).to match(/You are trying to install in deployment mode after changing.your Gemfile/m)
- expect(err).to match(/freeze \nby running `bundle config unset deployment`./m)
+ expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/)
+ expect(err).to match(/freeze by running `bundle config set frozen false`./)
end
- it "should suggest different command when frozen is set globally", :bundler => "< 3" do
+ it "should fail loudly when frozen is set globally" do
bundle "config set --global frozen 1"
- bundle "update", :all => true, :raise_on_error => false
- expect(err).to match(/You are trying to install in deployment mode after changing.your Gemfile/m).
- and match(/freeze \nby running `bundle config unset frozen`./m)
+ bundle "update", all: true, raise_on_error: false
+ expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/).
+ and match(/freeze by running `bundle config set frozen false`./)
end
- it "should suggest different command when frozen is set globally", :bundler => "3" do
+ it "should fail loudly when deployment is set globally" do
bundle "config set --global deployment true"
- bundle "update", :all => true, :raise_on_error => false
- expect(err).to match(/You are trying to install in deployment mode after changing.your Gemfile/m).
- and match(/freeze \nby running `bundle config unset deployment`./m)
+ bundle "update", all: true, raise_on_error: false
+ expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/).
+ and match(/freeze by running `bundle config set frozen false`./)
+ end
+
+ it "should not suggest any command to unfreeze bundler if frozen is set through ENV" do
+ bundle "update", all: true, raise_on_error: false, env: { "BUNDLE_FROZEN" => "true" }
+ expect(err).to match(/Bundler is unlocking, but the lockfile can't be updated because frozen mode is set/)
+ expect(err).not_to match(/by running/)
end
end
@@ -644,7 +810,7 @@ RSpec.describe "bundle update" do
end
end
- it "shows the previous version of the gem when updated from rubygems source", :bundler => "< 3" do
+ it "shows the previous version of the gem when updated from rubygems source" do
build_repo2
install_gemfile <<-G
@@ -652,43 +818,39 @@ RSpec.describe "bundle update" do
gem "activesupport"
G
- bundle "update", :all => true
+ bundle "update", all: true, verbose: true
expect(out).to include("Using activesupport 2.3.5")
update_repo2 do
build_gem "activesupport", "3.0"
end
- bundle "update", :all => true
+ bundle "update", all: true
expect(out).to include("Installing activesupport 3.0 (was 2.3.5)")
end
- context "with suppress_install_using_messages set" do
- before { bundle "config set suppress_install_using_messages true" }
-
- it "only prints `Using` for versions that have changed" do
- build_repo4 do
- build_gem "bar"
- build_gem "foo"
- end
-
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem "bar"
- gem "foo"
- G
+ it "only prints `Using` for versions that have changed" do
+ build_repo4 do
+ build_gem "bar"
+ build_gem "foo"
+ end
- bundle "update", :all => true
- expect(out).to match(/Resolving dependencies\.\.\.\.*\nBundle updated!/)
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "bar"
+ gem "foo"
+ G
- update_repo4 do
- build_gem "foo", "2.0"
- end
+ bundle "update", all: true
+ expect(out).to match(/Resolving dependencies\.\.\.\.*\nBundle updated!/)
- bundle "update", :all => true
- out.sub!("Removing foo (1.0)\n", "")
- expect(out).to match(/Resolving dependencies\.\.\.\.*\nFetching foo 2\.0 \(was 1\.0\)\nInstalling foo 2\.0 \(was 1\.0\)\nBundle updated/)
+ update_repo4 do
+ build_gem "foo", "2.0"
end
+
+ bundle "update", all: true
+ out.sub!("Removing foo (1.0)\n", "")
+ expect(out).to match(/Resolving dependencies\.\.\.\.*\nFetching foo 2\.0 \(was 1\.0\)\nInstalling foo 2\.0 \(was 1\.0\)\nBundle updated/)
end
it "shows error message when Gemfile.lock is not preset and gem is specified" do
@@ -697,12 +859,96 @@ RSpec.describe "bundle update" do
gem "activesupport"
G
- bundle "update nonexisting", :raise_on_error => false
+ bundle "update nonexisting", raise_on_error: false
expect(err).to include("This Bundle hasn't been installed yet. Run `bundle install` to update and install the bundled gems.")
expect(exitstatus).to eq(22)
end
- context "with multiple, duplicated sources, with lockfile in old format", :bundler => "< 3" do
+ context "with multiple sources and caching enabled" do
+ before do
+ build_repo2 do
+ build_gem "rack", "1.0.0"
+
+ build_gem "request_store", "1.0.0" do |s|
+ s.add_dependency "rack", "1.0.0"
+ end
+ end
+
+ build_repo4 do
+ # set up repo with no gems
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo2)}"
+
+ gem "request_store"
+
+ source "#{file_uri_for(gem_repo4)}" do
+ end
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack (1.0.0)
+ request_store (1.0.0)
+ rack (= 1.0.0)
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+
+ PLATFORMS
+ #{local_platform}
+
+ DEPENDENCIES
+ request_store
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "works" do
+ bundle :install
+ bundle :cache
+
+ update_repo2 do
+ build_gem "request_store", "1.1.0" do |s|
+ s.add_dependency "rack", "1.0.0"
+ end
+ end
+
+ bundle "update request_store"
+
+ expect(out).to include("Bundle updated!")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack (1.0.0)
+ request_store (1.1.0)
+ rack (= 1.0.0)
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+
+ PLATFORMS
+ #{local_platform}
+
+ DEPENDENCIES
+ request_store
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "with multiple, duplicated sources, with lockfile in old format", bundler: "< 3" do
before do
build_repo2 do
build_gem "dotenv", "2.7.6"
@@ -743,7 +989,7 @@ RSpec.describe "bundle update" do
vcr (6.0.0)
PLATFORMS
- #{specific_local_platform}
+ #{local_platform}
DEPENDENCIES
dotenv
@@ -756,8 +1002,8 @@ RSpec.describe "bundle update" do
end
it "works" do
- bundle :install, :artifice => "compact_index"
- bundle "update oj", :artifice => "compact_index"
+ bundle :install, artifice: "compact_index"
+ bundle "update oj", artifice: "compact_index"
expect(out).to include("Bundle updated!")
expect(the_bundle).to include_gems "oj 3.11.5"
@@ -893,7 +1139,7 @@ RSpec.describe "bundle update in more complicated situations" do
end
it "allows updating" do
- bundle :update, :all => true
+ bundle :update, all: true
expect(the_bundle).to include_gem "a 1.1"
end
@@ -949,7 +1195,7 @@ RSpec.describe "bundle update without a Gemfile.lock" do
gem "rack", "1.0"
G
- bundle "update", :all => true
+ bundle "update", all: true
expect(the_bundle).to include_gems "rack 1.0.0"
end
@@ -972,7 +1218,7 @@ RSpec.describe "bundle update when a gem depends on a newer version of bundler"
end
it "should explain that bundler conflicted and how to resolve the conflict" do
- bundle "update", :all => true, :raise_on_error => false
+ bundle "update", all: true, raise_on_error: false
expect(last_command.stdboth).not_to match(/in snapshot/i)
expect(err).to match(/current Bundler version/i).
and match(/Install the necessary version with `gem install bundler:#{Bundler::VERSION.succ}`/i)
@@ -980,23 +1226,18 @@ RSpec.describe "bundle update when a gem depends on a newer version of bundler"
end
RSpec.describe "bundle update --ruby" do
- before do
- install_gemfile <<-G
- ::RUBY_VERSION = '2.1.3'
- ::RUBY_PATCHLEVEL = 100
- ruby '~> 2.1.0'
- source "#{file_uri_for(gem_repo1)}"
- G
- end
-
context "when the Gemfile removes the ruby" do
before do
+ install_gemfile <<-G
+ ruby '~> #{Gem.ruby_version}'
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
gemfile <<-G
- ::RUBY_VERSION = '2.1.4'
- ::RUBY_PATCHLEVEL = 222
- source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo1)}"
G
end
+
it "removes the Ruby from the Gemfile.lock" do
bundle "update --ruby"
@@ -1018,60 +1259,85 @@ RSpec.describe "bundle update --ruby" do
context "when the Gemfile specified an updated Ruby version" do
before do
+ install_gemfile <<-G
+ ruby '~> #{Gem.ruby_version}'
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
gemfile <<-G
- ::RUBY_VERSION = '2.1.4'
- ::RUBY_PATCHLEVEL = 222
- ruby '~> 2.1.0'
- source "#{file_uri_for(gem_repo1)}"
+ ruby '~> #{current_ruby_minor}'
+ source "#{file_uri_for(gem_repo1)}"
G
end
+
it "updates the Gemfile.lock with the latest version" do
bundle "update --ruby"
expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo1)}/
- specs:
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
- PLATFORMS
- #{lockfile_platforms}
+ PLATFORMS
+ #{lockfile_platforms}
- DEPENDENCIES
+ DEPENDENCIES
- RUBY VERSION
- ruby 2.1.4p222
+ RUBY VERSION
+ #{Bundler::RubyVersion.system}
- BUNDLED WITH
- #{Bundler::VERSION}
+ BUNDLED WITH
+ #{Bundler::VERSION}
L
end
end
context "when a different Ruby is being used than has been versioned" do
before do
+ install_gemfile <<-G
+ ruby '~> #{Gem.ruby_version}'
+ source "#{file_uri_for(gem_repo1)}"
+ G
+
gemfile <<-G
- ::RUBY_VERSION = '2.2.2'
- ::RUBY_PATCHLEVEL = 505
ruby '~> 2.1.0'
source "#{file_uri_for(gem_repo1)}"
G
end
it "shows a helpful error message" do
- bundle "update --ruby", :raise_on_error => false
+ bundle "update --ruby", raise_on_error: false
- expect(err).to include("Your Ruby version is 2.2.2, but your Gemfile specified ~> 2.1.0")
+ expect(err).to include("Your Ruby version is #{Bundler::RubyVersion.system.gem_version}, but your Gemfile specified ~> 2.1.0")
end
end
context "when updating Ruby version and Gemfile `ruby`" do
before do
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+
+ CHECKSUMS
+
+ RUBY VERSION
+ ruby 2.1.4p222
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
gemfile <<-G
- ::RUBY_VERSION = '1.8.3'
- ::RUBY_PATCHLEVEL = 55
- ruby '~> 1.8.0'
+ ruby '~> #{Gem.ruby_version}'
source "#{file_uri_for(gem_repo1)}"
G
end
+
it "updates the Gemfile.lock with the latest version" do
bundle "update --ruby"
@@ -1085,8 +1351,10 @@ RSpec.describe "bundle update --ruby" do
DEPENDENCIES
+ CHECKSUMS
+
RUBY VERSION
- ruby 1.8.3p55
+ #{Bundler::RubyVersion.system}
BUNDLED WITH
#{Bundler::VERSION}
@@ -1096,24 +1364,355 @@ RSpec.describe "bundle update --ruby" do
end
RSpec.describe "bundle update --bundler" do
- it "updates the bundler version in the lockfile without re-resolving" do
+ it "updates the bundler version in the lockfile" do
build_repo4 do
build_gem "rack", "1.0"
end
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo4, "rack", "1.0")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "rack"
G
- allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2')
- FileUtils.rm_r gem_repo4
+ bundle :update, bundler: true, artifice: "compact_index", verbose: true
+ expect(out).to include("Using bundler #{Bundler::VERSION}")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
- bundle :update, :bundler => true, :verbose => true
expect(the_bundle).to include_gem "rack 1.0"
+ end
+
+ it "updates the bundler version in the lockfile without re-resolving if the highest version is already installed" do
+ system_gems "bundler-2.3.9"
+
+ build_repo4 do
+ build_gem "rack", "1.0"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+ lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
+
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo4, "rack", "1.0")
+ end
+
+ bundle :update, bundler: true, artifice: "compact_index", verbose: true
+ expect(out).to include("Using bundler #{Bundler::VERSION}")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ expect(the_bundle).to include_gem "rack 1.0"
+ end
+
+ it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo do
+ pristine_system_gems "bundler-2.3.9"
+
+ build_repo4 do
+ build_gem "rack", "1.0"
+
+ build_bundler "999.0.0"
+ end
+
+ install_gemfile <<-G, artifice: nil, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+ lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
+
+ bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+
+ # Only updates properly on modern RubyGems.
+
+ if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
+ expect(out).to include("Updating bundler to 999.0.0")
+ expect(out).to include("Using bundler 999.0.0")
+ expect(out).not_to include("Installing Bundler 2.3.9 and restarting using that version.")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ 999.0.0
+ L
+
+ expect(the_bundle).to include_gems "bundler 999.0.0"
+ expect(the_bundle).to include_gems "rack 1.0"
+ else
+ # Old RubyGems versions do not trampoline but they still change BUNDLED
+ # WITH to the latest bundler version. This means the below check fails
+ # because it tries to use bundler 999.0.0 which did not get installed.
+ # Workaround the bug by forcing the version we know is installed.
+ expect(the_bundle).to include_gems "rack 1.0", env: { "BUNDLER_VERSION" => "2.3.9" }
+ end
+ end
+
+ it "does not claim to update to Bundler version to a wrong version when cached gems are present" do
+ pristine_system_gems "bundler-2.99.0"
+
+ build_repo4 do
+ build_gem "rack", "3.0.9.1"
+
+ build_bundler "2.99.0"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (3.0.9.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ 2.99.0
+ L
+
+ bundle :cache, verbose: true
+
+ bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+
+ expect(out).not_to include("Updating bundler to")
+ end
+
+ it "does not update the bundler version in the lockfile if the latest version is not compatible with current ruby", :ruby_repo do
+ pristine_system_gems "bundler-2.3.9"
+
+ build_repo4 do
+ build_gem "rack", "1.0"
+
+ build_bundler "2.3.9"
+ build_bundler "999.0.0" do |s|
+ s.required_ruby_version = "> #{Gem.ruby_version}"
+ end
+ end
+
+ install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+ lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
+
+ bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
- expect(the_bundle.locked_gems.bundler_version).to eq v(Bundler::VERSION)
+ expect(out).to include("Using bundler 2.3.9")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+
+ BUNDLED WITH
+ 2.3.9
+ L
+
+ expect(the_bundle).to include_gems "bundler 2.3.9"
+ expect(the_bundle).to include_gems "rack 1.0"
+ end
+
+ it "errors if the explicit target version does not exist" do
+ pristine_system_gems "bundler-2.3.9"
+
+ build_repo4 do
+ build_gem "rack", "1.0"
+ end
+
+ install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+ lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
+
+ bundle :update, bundler: "999.999.999", artifice: "compact_index", raise_on_error: false
+
+ # Only gives a meaningful error message on modern RubyGems.
+
+ if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
+ expect(last_command).to be_failure
+ expect(err).to include("The `bundle update --bundler` target version (999.999.999) does not exist")
+ end
+ end
+
+ it "allows updating to development versions if already installed locally" do
+ system_gems "bundler-2.3.0.dev"
+
+ build_repo4 do
+ build_gem "rack", "1.0"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+
+ bundle :update, bundler: "2.3.0.dev", verbose: "true"
+
+ # Only updates properly on modern RubyGems.
+ if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo4, "rack", "1.0")
+ end
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+ #{checksums}
+ BUNDLED WITH
+ 2.3.0.dev
+ L
+
+ expect(out).to include("Using bundler 2.3.0.dev")
+ end
+ end
+
+ it "does not touch the network if not necessary" do
+ system_gems "bundler-2.3.9"
+
+ build_repo4 do
+ build_gem "rack", "1.0"
+ end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "rack"
+ G
+
+ bundle :update, bundler: "2.3.9", verbose: true
+
+ expect(out).not_to include("Fetching gem metadata from https://rubygems.org/")
+
+ # Only updates properly on modern RubyGems.
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo4, "rack", "1.0")
+ end
+
+ if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ rack (1.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack
+ #{checksums}
+ BUNDLED WITH
+ 2.3.9
+ L
+
+ expect(out).to include("Using bundler 2.3.9")
+ end
+ end
+
+ it "prints an error when trying to update bundler in frozen mode" do
+ system_gems "bundler-2.3.9"
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo2)}"
+ G
+
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+
+ BUNDLED WITH
+ 2.1.4
+ L
+
+ bundle "update --bundler=2.3.9", env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
+ expect(err).to include("An update to the version of bundler itself was requested, but the lockfile can't be updated because frozen mode is set")
end
end
@@ -1131,7 +1730,10 @@ RSpec.describe "bundle update conservative" do
build_gem "foo", %w[1.5.1] do |s|
s.add_dependency "bar", "~> 3.0"
end
- build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0]
+ build_gem "foo", %w[2.0.0.pre] do |s|
+ s.add_dependency "bar"
+ end
+ build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 2.1.2.pre 3.0.0 3.1.0.pre 4.0.0.pre]
build_gem "qux", %w[1.0.0 1.0.1 1.1.0 2.0.0]
end
@@ -1169,7 +1771,7 @@ RSpec.describe "bundle update conservative" do
end
it "update all" do
- bundle "update --patch", :all => true
+ bundle "update --patch", all: true
expect(the_bundle).to include_gems "foo 1.4.5", "bar 2.1.1", "qux 1.0.1"
end
@@ -1191,11 +1793,37 @@ RSpec.describe "bundle update conservative" do
end
it "minor preferred" do
- bundle "update --minor --strict", :all => true
+ bundle "update --minor --strict", all: true
expect(the_bundle).to include_gems "foo 1.5.0", "bar 2.1.1", "qux 1.1.0"
end
end
+
+ context "pre" do
+ it "defaults to major" do
+ bundle "update --pre foo bar"
+
+ expect(the_bundle).to include_gems "foo 2.0.0.pre", "bar 4.0.0.pre", "qux 1.0.0"
+ end
+
+ it "patch preferred" do
+ bundle "update --patch --pre foo bar"
+
+ expect(the_bundle).to include_gems "foo 1.4.5", "bar 2.1.2.pre", "qux 1.0.0"
+ end
+
+ it "minor preferred" do
+ bundle "update --minor --pre foo bar"
+
+ expect(the_bundle).to include_gems "foo 1.5.1", "bar 3.1.0.pre", "qux 1.0.0"
+ end
+
+ it "major preferred" do
+ bundle "update --major --pre foo bar"
+
+ expect(the_bundle).to include_gems "foo 2.0.0.pre", "bar 4.0.0.pre", "qux 1.0.0"
+ end
+ end
end
context "eager unlocking" do
@@ -1237,13 +1865,15 @@ RSpec.describe "bundle update conservative" do
shared_dep (~> 5.0)
PLATFORMS
- #{specific_local_platform}
+ #{local_platform}
DEPENDENCIES
isolated_owner
shared_owner_a
shared_owner_b
+ CHECKSUMS
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1290,13 +1920,20 @@ RSpec.describe "bundle update conservative" do
shared_dep (~> 5.0)
PLATFORMS
- #{specific_local_platform}
+ #{local_platform}
DEPENDENCIES
isolated_owner
shared_owner_a
shared_owner_b
+ CHECKSUMS
+ isolated_dep (2.0.1)
+ isolated_owner (1.0.2)
+ shared_dep (5.0.1)
+ shared_owner_a (3.0.2)
+ shared_owner_b (4.0.2)
+
BUNDLED WITH
#{Bundler::VERSION}
L
@@ -1323,7 +1960,7 @@ RSpec.describe "bundle update conservative" do
end
it "raises if too many flags are provided" do
- bundle "update --patch --minor", :all => true, :raise_on_error => false
+ bundle "update --patch --minor", all: true, raise_on_error: false
expect(err).to eq "Provide only one of the following options: minor, patch"
end
diff --git a/spec/bundler/commands/version_spec.rb b/spec/bundler/commands/version_spec.rb
index 53d545f5fa..307058a5dd 100644
--- a/spec/bundler/commands/version_spec.rb
+++ b/spec/bundler/commands/version_spec.rb
@@ -4,42 +4,42 @@ require_relative "../support/path"
RSpec.describe "bundle version" do
if Spec::Path.ruby_core?
- COMMIT_HASH = /unknown|[a-fA-F0-9]{7,}/.freeze
+ COMMIT_HASH = /unknown|[a-fA-F0-9]{7,}/
else
- COMMIT_HASH = /[a-fA-F0-9]{7,}/.freeze
+ COMMIT_HASH = /[a-fA-F0-9]{7,}/
end
context "with -v" do
- it "outputs the version", :bundler => "< 3" do
+ it "outputs the version", bundler: "< 3" do
bundle "-v"
expect(out).to eq("Bundler version #{Bundler::VERSION}")
end
- it "outputs the version", :bundler => "3" do
+ it "outputs the version", bundler: "3" do
bundle "-v"
expect(out).to eq(Bundler::VERSION)
end
end
context "with --version" do
- it "outputs the version", :bundler => "< 3" do
+ it "outputs the version", bundler: "< 3" do
bundle "--version"
expect(out).to eq("Bundler version #{Bundler::VERSION}")
end
- it "outputs the version", :bundler => "3" do
+ it "outputs the version", bundler: "3" do
bundle "--version"
expect(out).to eq(Bundler::VERSION)
end
end
context "with version" do
- it "outputs the version with build metadata", :bundler => "< 3" do
+ it "outputs the version with build metadata", bundler: "< 3" do
bundle "version"
expect(out).to match(/\ABundler version #{Regexp.escape(Bundler::VERSION)} \(\d{4}-\d{2}-\d{2} commit #{COMMIT_HASH}\)\z/)
end
- it "outputs the version with build metadata", :bundler => "3" do
+ it "outputs the version with build metadata", bundler: "3" do
bundle "version"
expect(out).to match(/\A#{Regexp.escape(Bundler::VERSION)} \(\d{4}-\d{2}-\d{2} commit #{COMMIT_HASH}\)\z/)
end
diff --git a/spec/bundler/commands/viz_spec.rb b/spec/bundler/commands/viz_spec.rb
index 0efb24b504..f8b5f7836e 100644
--- a/spec/bundler/commands/viz_spec.rb
+++ b/spec/bundler/commands/viz_spec.rb
@@ -1,10 +1,8 @@
# frozen_string_literal: true
-RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do
+RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld: true do
before do
- graphviz_version = RUBY_VERSION >= "2.4" ? "1.2.5" : "1.2.4"
-
- realworld_system_gems "ruby-graphviz --version #{graphviz_version}"
+ realworld_system_gems "ruby-graphviz --version 1.2.5"
end
it "graphs gems from the Gemfile" do
@@ -17,8 +15,8 @@ RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do
bundle "viz"
expect(out).to include("gem_graph.png")
- bundle "viz", :format => "debug"
- expect(out).to eq(strip_whitespace(<<-DOT).strip)
+ bundle "viz", format: "debug"
+ expect(out).to eq(<<~DOT.strip)
digraph Gemfile {
concentrate = "true";
normalize = "true";
@@ -51,8 +49,8 @@ RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do
bundle "viz"
expect(out).to include("gem_graph.png")
- bundle "viz", :format => :debug, :version => true
- expect(out).to eq(strip_whitespace(<<-EOS).strip)
+ bundle "viz", format: :debug, version: true
+ expect(out).to eq(<<~EOS.strip)
digraph Gemfile {
concentrate = "true";
normalize = "true";
@@ -79,7 +77,7 @@ RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do
end
end
- system_gems "graphviz-999", :gem_repo => gem_repo4
+ system_gems "graphviz-999", gem_repo: gem_repo4
end
it "loads the correct ruby-graphviz gem" do
@@ -89,8 +87,8 @@ RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do
gem "rack-obama"
G
- bundle "viz", :format => "debug"
- expect(out).to eq(strip_whitespace(<<-DOT).strip)
+ bundle "viz", format: "debug"
+ expect(out).to eq(<<~DOT.strip)
digraph Gemfile {
concentrate = "true";
normalize = "true";