summaryrefslogtreecommitdiff
path: root/spec/bundler/commands/lock_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/bundler/commands/lock_spec.rb')
-rw-r--r--spec/bundler/commands/lock_spec.rb286
1 files changed, 277 insertions, 9 deletions
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index 08ac333664..126853e35f 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -140,6 +140,62 @@ RSpec.describe "bundle lock" do
expect(read_lockfile).to eq(@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 (13.0.1)")
+ end
+
it "errors when updating a missing specific gems using --update" do
lockfile @lockfile
@@ -266,7 +322,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([java, x86_mingw32, specific_local_platform].uniq)
+ expect(lockfile.platforms).to match_array([java, x86_mingw32, local_platform].uniq)
end
it "supports adding new platforms with force_ruby_platform = true" do
@@ -275,11 +331,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
@@ -298,7 +354,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(["ruby", specific_local_platform].uniq)
+ expect(lockfile.platforms).to match_array(["ruby", local_platform].uniq)
end
it "warns when adding an unknown platform" do
@@ -311,12 +367,12 @@ 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([java, x86_mingw32, specific_local_platform].uniq)
+ expect(lockfile.platforms).to match_array([java, x86_mingw32, local_platform].uniq)
bundle "lock --remove-platform java"
lockfile = Bundler::LockfileParser.new(read_lockfile)
- expect(lockfile.platforms).to match_array([x86_mingw32, specific_local_platform].uniq)
+ expect(lockfile.platforms).to match_array([x86_mingw32, local_platform].uniq)
end
it "also cleans up redundant platform gems when removing platforms" do
@@ -375,7 +431,7 @@ RSpec.describe "bundle lock" do
end
it "errors when removing all platforms" do
- bundle "lock --remove-platform #{specific_local_platform}", :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
@@ -644,6 +700,62 @@ RSpec.describe "bundle lock" do
bundle "lock --add-platform x86_64-linux", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
end
+ 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"
+
+ 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|
@@ -880,7 +992,7 @@ RSpec.describe "bundle lock" do
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 is forbidden.
+ 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.
@@ -892,7 +1004,7 @@ RSpec.describe "bundle lock" do
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 is forbidden.
+ rails >= 7.0.2.3 cannot be used.
So, because Gemfile depends on rails >= 7.0.2.3,
version solving has failed.
ERR
@@ -924,6 +1036,31 @@ RSpec.describe "bundle lock" do
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"
@@ -976,4 +1113,135 @@ RSpec.describe "bundle lock" do
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
+ 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
+ x86_64-linux
+
+ DEPENDENCIES
+ foo!
+
+ 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
+ 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
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
end