summaryrefslogtreecommitdiff
path: root/spec/bundler/lock/lockfile_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/bundler/lock/lockfile_spec.rb')
-rw-r--r--spec/bundler/lock/lockfile_spec.rb830
1 files changed, 604 insertions, 226 deletions
diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb
index 976db33b0e..4fd081e7d0 100644
--- a/spec/bundler/lock/lockfile_spec.rb
+++ b/spec/bundler/lock/lockfile_spec.rb
@@ -1,28 +1,22 @@
# frozen_string_literal: true
RSpec.describe "the lockfile format" do
- include Bundler::GemHelpers
-
before do
- build_repo2 do
- # Capistrano did this (at least until version 2.5.10)
- # RubyGems 2.2 doesn't allow the specifying of a dependency twice
- # See https://github.com/rubygems/rubygems/commit/03dbac93a3396a80db258d9bc63500333c25bd2f
- build_gem "double_deps", "1.0", :skip_validation => true do |s|
- s.add_dependency "net-ssh", ">= 1.0.0"
- s.add_dependency "net-ssh"
- end
- end
+ build_repo2
end
it "generates a simple lockfile for a single source, gem" do
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo2, "rack", "1.0.0")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -33,13 +27,13 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
- it "updates the lockfile's bundler version if current ver. is newer" do
+ it "updates the lockfile's bundler version if current ver. is newer, and version was forced through BUNDLER_VERSION" do
system_gems "bundler-1.8.2"
lockfile <<-L
@@ -64,13 +58,16 @@ RSpec.describe "the lockfile format" do
1.8.2
L
- install_gemfile <<-G, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
+ install_gemfile <<-G, verbose: true, env: { "BUNDLER_VERSION" => Bundler::VERSION }
source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with 1.8.2.")
+ expect(out).to include("Using bundler #{Bundler::VERSION}")
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -87,8 +84,8 @@ RSpec.describe "the lockfile format" do
G
end
- it "does not update the lockfile's bundler version if nothing changed during bundle install" do
- version = "#{Bundler::VERSION.split(".").first}.0.0.a"
+ it "does not update the lockfile's bundler version if nothing changed during bundle install, but uses the locked version", rubygems: ">= 3.3.0.a", realworld: true do
+ version = "2.3.0"
lockfile <<-L
GEM
@@ -106,13 +103,16 @@ RSpec.describe "the lockfile format" do
#{version}
L
- install_gemfile <<-G
+ install_gemfile <<-G, verbose: true, artifice: "vcr"
source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{version}.")
+ expect(out).to include("Using bundler #{version}")
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -129,7 +129,13 @@ RSpec.describe "the lockfile format" do
G
end
- it "updates the lockfile's bundler version if not present" do
+ it "does not update the lockfile's bundler version if nothing changed during bundle install, and uses the latest version", rubygems: "< 3.3.0.a" do
+ version = "#{Bundler::VERSION.split(".").first}.0.0.a"
+
+ checksums = checksums_section do |c|
+ c.checksum(gem_repo2, "rack", "1.0.0")
+ end
+
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -141,15 +147,21 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
+ #{checksums}
+ BUNDLED WITH
+ #{version}
L
- install_gemfile <<-G
+ install_gemfile <<-G, verbose: true
source "#{file_uri_for(gem_repo2)}"
- gem "rack", "> 0"
+ gem "rack"
G
- lockfile_should_be <<-G
+ expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{version}.")
+ expect(out).to include("Using bundler #{Bundler::VERSION}")
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -159,17 +171,14 @@ RSpec.describe "the lockfile format" do
#{lockfile_platforms}
DEPENDENCIES
- rack (> 0)
-
+ rack
+ #{checksums}
BUNDLED WITH
- #{Bundler::VERSION}
+ #{version}
G
end
- it "warns if the current is older than lockfile's bundler version" do
- current_version = Bundler::VERSION
- newer_minor = bump_minor(current_version)
-
+ it "adds the BUNDLED WITH section if not present" do
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -181,25 +190,15 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
-
- BUNDLED WITH
- #{newer_minor}
L
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
- gem "rack"
+ gem "rack", "> 0"
G
- pre_flag = prerelease?(newer_minor) ? " --pre" : ""
- warning_message = "the running version of Bundler (#{current_version}) is older " \
- "than the version that created the lockfile (#{newer_minor}). " \
- "We suggest you to upgrade to the version that created the " \
- "lockfile by running `gem install bundler:#{newer_minor}#{pre_flag}`."
- expect(err).to include warning_message
-
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -209,14 +208,14 @@ RSpec.describe "the lockfile format" do
#{lockfile_platforms}
DEPENDENCIES
- rack
+ rack (> 0)
BUNDLED WITH
- #{newer_minor}
+ #{Bundler::VERSION}
G
end
- it "warns when updating bundler major version" do
+ it "update the bundler major version just fine" do
current_version = Bundler::VERSION
older_major = previous_major(current_version)
@@ -238,18 +237,15 @@ RSpec.describe "the lockfile format" do
#{older_major}
L
- install_gemfile <<-G, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
+ install_gemfile <<-G, env: { "BUNDLER_VERSION" => Bundler::VERSION }
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
G
- expect(err).to include(
- "Warning: the lockfile is being updated to Bundler " \
- "#{current_version.split(".").first}, after which you will be unable to return to Bundler #{older_major.split(".").first}."
- )
+ expect(err).to be_empty
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -273,7 +269,12 @@ RSpec.describe "the lockfile format" do
gem "rack-obama"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "rack", "1.0.0"
+ c.checksum gem_repo2, "rack-obama", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -286,7 +287,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -299,7 +300,12 @@ RSpec.describe "the lockfile format" do
gem "rack-obama", ">= 1.0"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "rack", "1.0.0"
+ c.checksum gem_repo2, "rack-obama", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -312,49 +318,18 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
- it "generates a lockfile without credentials for a configured source", :bundler => "< 3" do
+ it "generates a lockfile without credentials" do
bundle "config set http://localgemserver.test/ user:pass"
- install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
- source "http://localgemserver.test/" do
-
- end
-
- source "http://user:pass@othergemserver.test/" do
- gem "rack-obama", ">= 1.0"
- end
- G
-
- lockfile_should_be <<-G
- GEM
- remote: http://localgemserver.test/
- remote: http://user:pass@othergemserver.test/
- specs:
- rack (1.0.0)
- rack-obama (1.0)
- rack
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- rack-obama (>= 1.0)!
+ install_gemfile(<<-G, artifice: "endpoint_strict_basic_authentication", quiet: true)
+ source "#{file_uri_for(gem_repo1)}"
- BUNDLED WITH
- #{Bundler::VERSION}
- G
- end
-
- it "generates a lockfile without credentials for a configured source", :bundler => "3" do
- bundle "config set http://localgemserver.test/ user:pass"
-
- install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
source "http://localgemserver.test/" do
end
@@ -364,8 +339,14 @@ RSpec.describe "the lockfile format" do
end
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "rack", "1.0.0"
+ c.checksum gem_repo2, "rack-obama", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
GEM
@@ -373,7 +354,7 @@ RSpec.describe "the lockfile format" do
specs:
GEM
- remote: http://user:pass@othergemserver.test/
+ remote: http://othergemserver.test/
specs:
rack (1.0.0)
rack-obama (1.0)
@@ -384,7 +365,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -396,7 +377,12 @@ RSpec.describe "the lockfile format" do
gem "net-sftp"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "net-sftp", "1.1.1"
+ c.checksum gem_repo2, "net-ssh", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -409,7 +395,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
net-sftp
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -421,17 +407,23 @@ RSpec.describe "the lockfile format" do
git = build_git "foo"
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
- revision: #{git.ref_for("master")}
+ revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -439,14 +431,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not asplode when a platform specific dependency is present and the Gemfile has not been resolved on that platform" do
- build_lib "omg", :path => lib_path("omg")
+ build_lib "omg", path: lib_path("omg")
gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
@@ -487,20 +479,26 @@ RSpec.describe "the lockfile format" do
it "serializes global git sources" do
git = build_git "foo"
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
git "#{lib_path("foo-1.0")}" do
gem "foo"
end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
- revision: #{git.ref_for("master")}
+ revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -508,7 +506,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -516,13 +514,18 @@ RSpec.describe "the lockfile format" do
it "generates a lockfile with a ref for a single pinned source, git gem with a branch requirement" do
git = build_git "foo"
- update_git "foo", :branch => "omg"
+ update_git "foo", branch: "omg"
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "omg"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
@@ -531,6 +534,7 @@ RSpec.describe "the lockfile format" do
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -538,7 +542,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -546,13 +550,18 @@ RSpec.describe "the lockfile format" do
it "generates a lockfile with a ref for a single pinned source, git gem with a tag requirement" do
git = build_git "foo"
- update_git "foo", :tag => "omg"
+ update_git "foo", tag: "omg"
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :git => "#{lib_path("foo-1.0")}", :tag => "omg"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
@@ -561,6 +570,7 @@ RSpec.describe "the lockfile format" do
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -568,26 +578,118 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
+ it "is conservative with dependencies of git gems" do
+ build_repo4 do
+ build_gem "orm_adapter", "0.4.1"
+ build_gem "orm_adapter", "0.5.0"
+ end
+
+ FileUtils.mkdir_p lib_path("ckeditor/lib")
+
+ @remote = build_git("ckeditor_remote", bare: true)
+
+ build_git "ckeditor", path: lib_path("ckeditor") do |s|
+ s.write "lib/ckeditor.rb", "CKEDITOR = '4.0.7'"
+ s.version = "4.0.7"
+ s.add_dependency "orm_adapter"
+ end
+
+ update_git "ckeditor", path: lib_path("ckeditor"), remote: file_uri_for(@remote.path)
+ update_git "ckeditor", path: lib_path("ckeditor"), tag: "v4.0.7"
+ old_git = update_git "ckeditor", path: lib_path("ckeditor"), push: "v4.0.7"
+
+ update_git "ckeditor", path: lib_path("ckeditor"), gemspec: true do |s|
+ s.write "lib/ckeditor.rb", "CKEDITOR = '4.0.8'"
+ s.version = "4.0.8"
+ s.add_dependency "orm_adapter"
+ end
+ update_git "ckeditor", path: lib_path("ckeditor"), tag: "v4.0.8"
+
+ new_git = update_git "ckeditor", path: lib_path("ckeditor"), push: "v4.0.8"
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "ckeditor", :git => "#{@remote.path}", :tag => "v4.0.8"
+ G
+
+ lockfile <<~L
+ GIT
+ remote: #{@remote.path}
+ revision: #{old_git.ref_for("v4.0.7")}
+ tag: v4.0.7
+ specs:
+ ckeditor (4.0.7)
+ orm_adapter
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ orm_adapter (0.4.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ ckeditor!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "lock"
+
+ # Bumps the git gem, but keeps its dependency locked
+ expect(lockfile).to eq <<~L
+ GIT
+ remote: #{@remote.path}
+ revision: #{new_git.ref_for("v4.0.8")}
+ tag: v4.0.8
+ specs:
+ ckeditor (4.0.8)
+ orm_adapter
+
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ orm_adapter (0.4.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ ckeditor!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
it "serializes pinned path sources to the lockfile" do
build_lib "foo"
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -595,7 +697,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -604,21 +706,27 @@ RSpec.describe "the lockfile format" do
it "serializes pinned path sources to the lockfile even when packaging" do
build_lib "foo"
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
+
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
bundle "config set cache_all true"
bundle :cache
- bundle :install, :local => true
+ bundle :install, local: true
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -626,7 +734,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -636,6 +744,12 @@ RSpec.describe "the lockfile format" do
build_lib "foo"
bar = build_git "bar"
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ c.no_checksum "bar", "1.0"
+ c.checksum gem_repo2, "rack", "1.0.0"
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
@@ -644,10 +758,10 @@ RSpec.describe "the lockfile format" do
gem "bar", :git => "#{lib_path("bar-1.0")}"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("bar-1.0")}
- revision: #{bar.ref_for("master")}
+ revision: #{bar.ref_for("main")}
specs:
bar (1.0)
@@ -668,7 +782,35 @@ RSpec.describe "the lockfile format" do
bar!
foo!
rack
+ #{checksums}
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
+ it "removes redundant sources" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}/"
+
+ gem "rack", :source => "#{file_uri_for(gem_repo2)}/"
+ G
+
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "rack", "1.0.0"
+ end
+ expect(lockfile).to eq <<~G
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack (1.0.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack!
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -683,7 +825,15 @@ RSpec.describe "the lockfile format" do
gem "rack-obama"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "actionpack", "2.3.2"
+ c.checksum gem_repo2, "activesupport", "2.3.2"
+ c.checksum gem_repo2, "rack", "1.0.0"
+ c.checksum gem_repo2, "rack-obama", "1.0"
+ c.checksum gem_repo2, "thin", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -703,7 +853,7 @@ RSpec.describe "the lockfile format" do
actionpack
rack-obama
thin
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -716,7 +866,17 @@ RSpec.describe "the lockfile format" do
gem "rails"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "actionmailer", "2.3.2"
+ c.checksum gem_repo2, "actionpack", "2.3.2"
+ c.checksum gem_repo2, "activerecord", "2.3.2"
+ c.checksum gem_repo2, "activeresource", "2.3.2"
+ c.checksum gem_repo2, "activesupport", "2.3.2"
+ c.checksum gem_repo2, "rails", "2.3.2"
+ c.checksum gem_repo2, "rake", rake_version
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -734,27 +894,42 @@ RSpec.describe "the lockfile format" 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})
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rails
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "orders dependencies by version" do
+ update_repo2 do
+ # Capistrano did this (at least until version 2.5.10)
+ # RubyGems 2.2 doesn't allow the specifying of a dependency twice
+ # See https://github.com/rubygems/rubygems/commit/03dbac93a3396a80db258d9bc63500333c25bd2f
+ build_gem "double_deps", "1.0", skip_validation: true do |s|
+ s.add_dependency "net-ssh", ">= 1.0.0"
+ s.add_dependency "net-ssh"
+ end
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem 'double_deps'
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "double_deps", "1.0"
+ c.checksum gem_repo2, "net-ssh", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -768,7 +943,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
double_deps
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -781,7 +956,12 @@ RSpec.describe "the lockfile format" do
gem "rack-obama", ">= 1.0", :require => "rack/obama"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "rack", "1.0.0"
+ c.checksum gem_repo2, "rack-obama", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -794,7 +974,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -807,7 +987,12 @@ RSpec.describe "the lockfile format" do
gem "rack-obama", ">= 1.0", :group => :test
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "rack", "1.0.0"
+ c.checksum gem_repo2, "rack-obama", "1.0"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -820,28 +1005,34 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack-obama (>= 1.0)
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided in a relative fashion and in Gemfile dir" do
- build_lib "foo", :path => bundled_app("foo")
+ build_lib "foo", path: bundled_app("foo")
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
path "foo" do
gem "foo"
end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -849,28 +1040,34 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided in a relative fashion and is above Gemfile dir" do
- build_lib "foo", :path => bundled_app(File.join("..", "foo"))
+ build_lib "foo", path: bundled_app(File.join("..", "foo"))
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
path "../foo" do
gem "foo"
end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: ../foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -878,28 +1075,34 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided in an absolute fashion but is relative" do
- build_lib "foo", :path => bundled_app("foo")
+ build_lib "foo", path: bundled_app("foo")
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
install_gemfile <<-G
- path File.expand_path("../foo", __FILE__) do
+ source "#{file_uri_for(gem_repo1)}"
+ path File.expand_path("foo", __dir__) do
gem "foo"
end
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -907,26 +1110,32 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided for gemspec" do
- build_lib("foo", :path => tmp.join("foo"))
+ build_lib("foo", path: tmp.join("foo"))
+
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "foo", "1.0"
+ end
install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
gemspec :path => "../foo"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
PATH
remote: ../foo
specs:
foo (1.0)
GEM
+ remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
@@ -934,13 +1143,17 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
foo!
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "keeps existing platforms in the lockfile" do
+ checksums = checksums_section_when_existing do |c|
+ c.no_checksum "rack", "1.0.0"
+ end
+
lockfile <<-G
GEM
remote: #{file_uri_for(gem_repo2)}/
@@ -952,7 +1165,7 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
@@ -963,24 +1176,65 @@ RSpec.describe "the lockfile format" do
gem "rack"
G
- lockfile_should_be <<-G
+ checksums.checksum(gem_repo2, "rack", "1.0.0")
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
- java
- #{lockfile_platforms}
+ #{lockfile_platforms("java", local_platform, defaults: [])}
DEPENDENCIES
rack
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
+ it "adds compatible platform specific variants to the lockfile, even if resolution fallback to RUBY due to some other incompatible platform specific variant" do
+ simulate_platform "arm64-darwin-23" do
+ build_repo4 do
+ build_gem "google-protobuf", "3.25.1"
+ build_gem "google-protobuf", "3.25.1" do |s|
+ s.platform = "arm64-darwin-23"
+ end
+ build_gem "google-protobuf", "3.25.1" do |s|
+ s.platform = "x64-mingw-ucrt"
+ s.required_ruby_version = "> #{Gem.ruby_version}"
+ end
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "google-protobuf"
+ G
+ bundle "lock --add-platform x64-mingw-ucrt"
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ google-protobuf (3.25.1)
+ google-protobuf (3.25.1-arm64-darwin-23)
+
+ PLATFORMS
+ arm64-darwin-23
+ ruby
+ x64-mingw-ucrt
+
+ DEPENDENCIES
+ google-protobuf
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
it "persists the spec's specific platform to the lockfile" do
build_repo2 do
build_gem "platform_specific", "1.0" do |s|
@@ -995,7 +1249,11 @@ RSpec.describe "the lockfile format" do
gem "platform_specific"
G
- lockfile_should_be <<-G
+ checksums = checksums_section_when_existing do |c|
+ c.checksum gem_repo2, "platform_specific", "1.0", "universal-java-16"
+ end
+
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -1006,13 +1264,18 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
platform_specific
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate gems" do
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo2, "activesupport", "2.3.5")
+ c.checksum(gem_repo2, "rack", "1.0.0")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
@@ -1024,7 +1287,7 @@ RSpec.describe "the lockfile format" do
gem "activesupport"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -1037,20 +1300,24 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
activesupport
rack
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies" do
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo2, "rack", "1.0.0")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
gem "rack"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -1061,20 +1328,24 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies with versions" do
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo2, "rack", "1.0.0")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0"
gem "rack", "1.0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -1085,20 +1356,24 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (= 1.0)
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies in different groups" do
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo2, "rack", "1.0.0")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack", "1.0", :group => :one
gem "rack", "1.0", :group => :two
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -1109,14 +1384,14 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (= 1.0)
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "raises if two different versions are used" 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"
@@ -1127,7 +1402,7 @@ RSpec.describe "the lockfile format" do
end
it "raises if two different sources are used" 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", :git => "git://hubz.com"
@@ -1138,12 +1413,16 @@ RSpec.describe "the lockfile format" do
end
it "works correctly with multiple version dependencies" do
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo2, "rack", "0.9.1")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack", "> 0.9", "< 1.0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -1154,20 +1433,24 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (> 0.9, < 1.0)
-
+ #{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "captures the Ruby version in the lockfile" do
+ checksums = checksums_section_when_existing do |c|
+ c.checksum(gem_repo2, "rack", "0.9.1")
+ end
+
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
- ruby '#{RUBY_VERSION}'
+ ruby '#{Gem.ruby_version}'
gem "rack", "> 0.9", "< 1.0"
G
- lockfile_should_be <<-G
+ expect(lockfile).to eq <<~G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
@@ -1178,113 +1461,207 @@ RSpec.describe "the lockfile format" do
DEPENDENCIES
rack (> 0.9, < 1.0)
-
+ #{checksums}
RUBY VERSION
- ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}
+ #{Bundler::RubyVersion.system}
BUNDLED WITH
#{Bundler::VERSION}
G
end
- # Some versions of the Bundler 1.1 RC series introduced corrupted
- # lockfiles. There were two major problems:
- #
- # * multiple copies of the same GIT section appeared in the lockfile
- # * when this happened, those sections got multiple copies of gems
- # in those sections.
- it "fixes corrupted lockfiles" do
- build_git "omg", :path => lib_path("omg")
- revision = revision_for(lib_path("omg"))
+ it "raises a helpful error message when the lockfile is missing deps" do
+ lockfile <<-L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack_middleware (1.0)
- gemfile <<-G
- source "#{file_uri_for(gem_repo2)}/"
- gem "omg", :git => "#{lib_path("omg")}", :branch => 'master'
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack_middleware
+ L
+
+ install_gemfile <<-G, raise_on_error: false
+ source "#{file_uri_for(gem_repo2)}"
+ gem "rack_middleware"
G
- bundle "config set --local path vendor"
- bundle :install
- expect(the_bundle).to include_gems "omg 1.0"
+ expect(err).to include("Downloading rack_middleware-1.0 revealed dependencies not in the API or the lockfile (#{Gem::Dependency.new("rack", "= 0.9.1")}).").
+ and include("Running `bundle update rack_middleware` should fix the problem.")
+ end
- # Create a Gemfile.lock that has duplicate GIT sections
- lockfile <<-L
- GIT
- remote: #{lib_path("omg")}
- revision: #{revision}
- branch: master
- specs:
- omg (1.0)
+ it "regenerates a lockfile with no specs" do
+ build_repo4 do
+ build_gem "indirect_dependency", "1.2.3" do |s|
+ s.metadata["funding_uri"] = "https://example.com/donate"
+ end
- GIT
- remote: #{lib_path("omg")}
- revision: #{revision}
- branch: master
- specs:
- omg (1.0)
+ build_gem "direct_dependency", "4.5.6" do |s|
+ s.add_dependency "indirect_dependency", ">= 0"
+ end
+ end
+ lockfile <<-G
GEM
- remote: #{file_uri_for(gem_repo2)}/
+ remote: #{file_uri_for(gem_repo4)}/
specs:
PLATFORMS
- #{lockfile_platforms}
+ ruby
DEPENDENCIES
- omg!
+ direct_dependency
BUNDLED WITH
#{Bundler::VERSION}
- L
+ G
- FileUtils.rm_rf(bundled_app("vendor"))
- bundle "install"
- expect(the_bundle).to include_gems "omg 1.0"
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
- # Confirm that duplicate specs do not appear
- lockfile_should_be(<<-L)
- GIT
- remote: #{lib_path("omg")}
- revision: #{revision}
- branch: master
- specs:
- omg (1.0)
+ gem "direct_dependency"
+ G
+ expect(lockfile).to eq <<~G
GEM
- remote: #{file_uri_for(gem_repo2)}/
+ remote: #{file_uri_for(gem_repo4)}/
specs:
+ direct_dependency (4.5.6)
+ indirect_dependency
+ indirect_dependency (1.2.3)
PLATFORMS
- #{lockfile_platforms}
+ #{lockfile_platforms("ruby", generic_local_platform, defaults: [])}
DEPENDENCIES
- omg!
+ direct_dependency
BUNDLED WITH
#{Bundler::VERSION}
- L
+ G
end
- it "raises a helpful error message when the lockfile is missing deps" do
- lockfile <<-L
+ shared_examples_for "a lockfile missing dependent specs" do
+ it "auto-heals" do
+ build_repo4 do
+ build_gem "minitest-bisect", "1.6.0" do |s|
+ s.add_dependency "path_expander", "~> 1.1"
+ end
+
+ build_gem "path_expander", "1.1.1"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "minitest-bisect"
+ G
+
+ # Corrupt lockfile (completely missing path_expander)
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ minitest-bisect (1.6.0)
+
+ PLATFORMS
+ #{platforms}
+
+ DEPENDENCIES
+ minitest-bisect
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ cache_gems "minitest-bisect-1.6.0", "path_expander-1.1.1", gem_repo: gem_repo4
+ bundle :install
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ minitest-bisect (1.6.0)
+ path_expander (~> 1.1)
+ path_expander (1.1.1)
+
+ PLATFORMS
+ #{platforms}
+
+ DEPENDENCIES
+ minitest-bisect
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "with just specific platform" do
+ let(:platforms) { lockfile_platforms }
+
+ it_behaves_like "a lockfile missing dependent specs"
+ end
+
+ context "with both ruby and specific platform" do
+ let(:platforms) { lockfile_platforms("ruby") }
+
+ it_behaves_like "a lockfile missing dependent specs"
+ end
+
+ it "auto-heals when the lockfile is missing specs" do
+ build_repo4 do
+ build_gem "minitest-bisect", "1.6.0" do |s|
+ s.add_dependency "path_expander", "~> 1.1"
+ end
+
+ build_gem "path_expander", "1.1.1"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "minitest-bisect"
+ G
+
+ lockfile <<~L
GEM
- remote: #{file_uri_for(gem_repo2)}/
+ remote: #{file_uri_for(gem_repo4)}/
specs:
- rack_middleware (1.0)
+ minitest-bisect (1.6.0)
+ path_expander (~> 1.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
- rack_middleware
+ minitest-bisect
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
L
- install_gemfile <<-G, :raise_on_error => false
- source "#{file_uri_for(gem_repo2)}"
- gem "rack_middleware"
- G
+ bundle "install --verbose"
+ expect(out).to include("re-resolving dependencies because your lock file includes \"minitest-bisect\" but not some of its dependencies")
- expect(err).to include("Downloading rack_middleware-1.0 revealed dependencies not in the API or the lockfile (#{Gem::Dependency.new("rack", "= 0.9.1")}).").
- and include("Either installing with `--full-index` or running `bundle update rack_middleware` should fix the problem.")
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ minitest-bisect (1.6.0)
+ path_expander (~> 1.1)
+ path_expander (1.1.1)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ minitest-bisect
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
describe "a line ending" do
@@ -1315,7 +1692,7 @@ RSpec.describe "the lockfile format" do
end
end
- expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
+ expect { bundle "update", all: true }.to change { File.mtime(bundled_app_lock) }
expect(File.read(bundled_app_lock)).not_to match("\r\n")
expect(the_bundle).to include_gems "rack 1.2"
end
@@ -1333,8 +1710,9 @@ RSpec.describe "the lockfile format" do
File.open(bundled_app_lock, "wb") {|f| f.puts(win_lock) }
set_lockfile_mtime_to_known_value
- expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
+ expect { bundle "update", all: true }.to change { File.mtime(bundled_app_lock) }
expect(File.read(bundled_app_lock)).to match("\r\n")
+
expect(the_bundle).to include_gems "rack 1.2"
end
end
@@ -1356,7 +1734,7 @@ RSpec.describe "the lockfile format" do
expect do
ruby <<-RUBY
- require '#{lib_dir}/bundler'
+ require 'bundler'
Bundler.setup
RUBY
end.not_to change { File.mtime(bundled_app_lock) }
@@ -1385,7 +1763,7 @@ RSpec.describe "the lockfile format" do
#{Bundler::VERSION}
L
- install_gemfile <<-G, :raise_on_error => false
+ install_gemfile <<-G, raise_on_error: false
source "#{file_uri_for(gem_repo2)}/"
gem "rack"
G