diff options
Diffstat (limited to 'spec/bundler')
-rw-r--r-- | spec/bundler/bundler/gem_version_promoter_spec.rb | 24 | ||||
-rw-r--r-- | spec/bundler/bundler/shared_helpers_spec.rb | 2 | ||||
-rw-r--r-- | spec/bundler/commands/lock_spec.rb | 283 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/specific_platform_spec.rb | 177 | ||||
-rw-r--r-- | spec/bundler/realworld/edgecases_spec.rb | 2 | ||||
-rw-r--r-- | spec/bundler/realworld/slow_perf_spec.rb | 2 | ||||
-rw-r--r-- | spec/bundler/runtime/inline_spec.rb | 26 | ||||
-rw-r--r-- | spec/bundler/support/indexes.rb | 21 |
8 files changed, 359 insertions, 178 deletions
diff --git a/spec/bundler/bundler/gem_version_promoter_spec.rb b/spec/bundler/bundler/gem_version_promoter_spec.rb index e944f387d3..b5c0f69795 100644 --- a/spec/bundler/bundler/gem_version_promoter_spec.rb +++ b/spec/bundler/bundler/gem_version_promoter_spec.rb @@ -16,6 +16,10 @@ RSpec.describe Bundler::GemVersionPromoter do Bundler::SpecSet.new(build_spec(name, v)) end + def build_package(name, platforms, locked_specs, unlock) + Bundler::Resolver::Package.new(name, platforms, :locked_specs => locked_specs, :unlock => unlock) + end + # Rightmost (highest array index) in result is most preferred. # Leftmost (lowest array index) in result is least preferred. # `build_candidates` has all versions of gem in index. @@ -35,7 +39,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when keeping build_spec, keep current, next release" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), + build_package("foo", [], build_spec_set("foo", "1.7.8"), []), build_candidates(%w[1.7.8 1.7.9 1.8.0]) ) expect(versions(res)).to eq %w[1.7.8 1.7.9] @@ -43,7 +47,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when unlocking prefer next release first" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), + build_package("foo", [], build_spec_set("foo", "1.7.8"), []), build_candidates(%w[1.7.8 1.7.9 1.8.0]) ) expect(versions(res)).to eq %w[1.7.8 1.7.9] @@ -51,7 +55,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when unlocking keep current when already at latest release" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.9"), []), + build_package("foo", [], build_spec_set("foo", "1.7.9"), []), build_candidates(%w[1.7.9 1.8.0 2.0.0]) ) expect(versions(res)).to eq %w[1.7.9] @@ -68,7 +72,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when unlocking favor next releases, remove minor and major increases" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "0.2.0"), []), + build_package("foo", [], build_spec_set("foo", "0.2.0"), []), build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) ) expect(versions(res)).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0] @@ -76,7 +80,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when keep locked, keep current, then favor next release, remove minor and major increases" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "0.2.0"), ["bar"]), + build_package("foo", [], build_spec_set("foo", "0.2.0"), ["bar"]), build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) ) expect(versions(res)).to eq %w[0.3.0 0.3.1 0.9.0 0.2.0] @@ -93,7 +97,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when not unlocking, same order but make sure build_spec version is most preferred to stay put" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.7"), ["bar"]), + build_package("foo", [], build_spec_set("foo", "1.7.7"), ["bar"]), build_candidates(%w[1.5.4 1.6.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 2.0.0 2.0.1]) ) expect(versions(res)).to eq %w[1.5.4 1.6.5 1.7.6 2.0.0 2.0.1 1.8.0 1.8.1 1.7.8 1.7.9 1.7.7] @@ -101,7 +105,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when unlocking favor next release, then current over minor increase" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), + build_package("foo", [], build_spec_set("foo", "1.7.8"), []), build_candidates(%w[1.7.7 1.7.8 1.7.9 1.8.0]) ) expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9] @@ -109,7 +113,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when unlocking do proper integer comparison, not string" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), + build_package("foo", [], build_spec_set("foo", "1.7.8"), []), build_candidates(%w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0]) ) expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9 1.7.15] @@ -117,7 +121,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "leave current when unlocking but already at latest release" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.9"), []), + build_package("foo", [], build_spec_set("foo", "1.7.9"), []), build_candidates(%w[1.7.9 1.8.0 2.0.0]) ) expect(versions(res)).to eq %w[2.0.0 1.8.0 1.7.9] @@ -134,7 +138,7 @@ RSpec.describe Bundler::GemVersionPromoter do it "when unlocking favor next release, then minor increase over current" do res = gvp.sort_versions( - Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "0.2.0"), []), + build_package("foo", [], build_spec_set("foo", "0.2.0"), []), build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) ) expect(versions(res)).to eq %w[2.0.0 2.0.1 1.0.0 0.2.0 0.3.0 0.3.1 0.9.0] diff --git a/spec/bundler/bundler/shared_helpers_spec.rb b/spec/bundler/bundler/shared_helpers_spec.rb index 3d8014b665..3c6536c4eb 100644 --- a/spec/bundler/bundler/shared_helpers_spec.rb +++ b/spec/bundler/bundler/shared_helpers_spec.rb @@ -248,6 +248,8 @@ RSpec.describe Bundler::SharedHelpers do shared_examples_for "ENV['BUNDLER_SETUP'] gets set correctly" do it "ensures bundler/setup is set in ENV['BUNDLER_SETUP']" do + skip "Does not play well with DidYouMean being a bundled gem instead of a default gem in Ruby 2.6" if RUBY_VERSION < "2.7" + subject.set_bundle_environment expect(ENV["BUNDLER_SETUP"]).to eq("#{source_lib_dir}/bundler/setup") end diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index 38bef77eaf..08ac333664 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -768,133 +768,212 @@ RSpec.describe "bundle lock" do #{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 + 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)}" + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" - gem "rails", ">= 7.0.3.1" - gem "activeadmin", "2.13.1" - G + gem "rails", ">= 7.0.3.1" + gem "activeadmin", "2.13.1" + G - bundle "lock", :raise_on_error => false + bundle "lock", :raise_on_error => false - expect(err).to eq <<~ERR.strip - Could not find compatible versions + 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)}/ or installed locally, - version solving has failed. - ERR - end + 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)}/ 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 + 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 + # 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 + %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 + # 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 + 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)}" + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" - gem "rails", ">= 7.0.2.3" - gem "activeadmin", "= 2.13.1" - G + 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) + 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 - #{lockfile_platforms} + PLATFORMS + #{lockfile_platforms} - DEPENDENCIES - activeadmin (= 2.13.1) - ransack (= 3.1.0) + DEPENDENCIES + activeadmin (= 2.13.1) + ransack (= 3.1.0) - BUNDLED WITH - #{Bundler::VERSION} - L + 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 is forbidden. + (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 is forbidden. + So, because 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 + + 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(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 is forbidden. - (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 is forbidden. - So, because Gemfile depends on rails >= 7.0.2.3, - version solving has failed. - ERR + expect(lockfile).not_to include("tzinfo-data (1.2022.7)") end end end diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 8f23b509bd..2f82a9f9f3 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -6,10 +6,8 @@ RSpec.describe "bundle install with specific platforms" do gem "google-protobuf" G - context "when on a darwin machine" do - before { simulate_platform "x86_64-darwin-15" } - - it "locks to the specific darwin platform" do + it "locks to the specific darwin platform" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem install_gemfile(google_protobuf) allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) @@ -19,8 +17,10 @@ RSpec.describe "bundle install with specific platforms" do google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin ]) end + end - it "understands that a non-platform specific gem in a old lockfile doesn't necessarily mean installing the non-specific variant" do + it "understands that a non-platform specific gem in a old lockfile doesn't necessarily mean installing the non-specific variant" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem system_gems "bundler-2.1.4" @@ -53,8 +53,10 @@ RSpec.describe "bundle install with specific platforms" do # make sure the platform that got actually installed with the old bundler is used expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin") end + end - it "understands that a non-platform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do + it "understands that a non-platform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem system_gems "bundler-2.1.4" @@ -103,8 +105,10 @@ RSpec.describe "bundle install with specific platforms" do #{Bundler::VERSION} L end + end - it "still installs the generic RUBY variant if necessary even when running on a legacy lockfile locked only to RUBY" do + context "when running on a legacy lockfile locked only to RUBY" do + around do |example| build_repo4 do build_gem "nokogiri", "1.3.10" build_gem "nokogiri", "1.3.10" do |s| @@ -140,12 +144,20 @@ RSpec.describe "bundle install with specific platforms" do 2.1.4 L - simulate_platform "arm64-darwin-22" do - bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } - end + simulate_platform "arm64-darwin-22", &example end - it "doesn't discard previously installed platform specific gem and fall back to ruby on subsequent bundles" do + it "still installs the generic RUBY variant if necessary" do + bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + end + + it "still installs the generic RUBY variant if necessary, even in frozen mode" do + bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLE_FROZEN" => "true" } + end + end + + it "doesn't discard previously installed platform specific gem and fall back to ruby on subsequent bundles" do + simulate_platform "x86_64-darwin-15" do build_repo2 do build_gem("libv8", "8.4.255.0") build_gem("libv8", "8.4.255.0") {|s| s.platform = "universal-darwin" } @@ -188,8 +200,10 @@ RSpec.describe "bundle install with specific platforms" do bundle "add mini_racer --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)") end + end - it "chooses platform specific gems even when resolving upon materialization and the API returns more specific platforms first" do + it "chooses platform specific gems even when resolving upon materialization and the API returns more specific platforms first" do + simulate_platform "x86_64-darwin-15" do build_repo4 do build_gem("grpc", "1.50.0") build_gem("grpc", "1.50.0") {|s| s.platform = "universal-darwin" } @@ -220,8 +234,10 @@ RSpec.describe "bundle install with specific platforms" do bundle "install --verbose", :artifice => "compact_index_precompiled_before", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } expect(out).to include("Installing grpc 1.50.0 (universal-darwin)") end + end - it "caches the universal-darwin gem when --all-platforms is passed and properly picks it up on further bundler invocations" do + it "caches the universal-darwin gem when --all-platforms is passed and properly picks it up on further bundler invocations" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem gemfile(google_protobuf) bundle "cache --all-platforms" @@ -230,8 +246,10 @@ RSpec.describe "bundle install with specific platforms" do bundle "install --verbose" expect(err).to be_empty end + end - it "caches the universal-darwin gem when cache_all_platforms is configured and properly picks it up on further bundler invocations" do + it "caches the universal-darwin gem when cache_all_platforms is configured and properly picks it up on further bundler invocations" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem gemfile(google_protobuf) bundle "config set --local cache_all_platforms true" @@ -241,44 +259,46 @@ RSpec.describe "bundle install with specific platforms" do bundle "install --verbose" expect(err).to be_empty end + end - it "caches multiplatform git gems with a single gemspec when --all-platforms is passed" do - git = build_git "pg_array_parser", "1.0" + it "caches multiplatform git gems with a single gemspec when --all-platforms is passed" do + git = build_git "pg_array_parser", "1.0" - gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "pg_array_parser", :git => "#{lib_path("pg_array_parser-1.0")}" - G + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem "pg_array_parser", :git => "#{lib_path("pg_array_parser-1.0")}" + G - lockfile <<-L - GIT - remote: #{lib_path("pg_array_parser-1.0")} - revision: #{git.ref_for("main")} - specs: - pg_array_parser (1.0-java) - pg_array_parser (1.0) + lockfile <<-L + GIT + remote: #{lib_path("pg_array_parser-1.0")} + revision: #{git.ref_for("main")} + specs: + pg_array_parser (1.0-java) + pg_array_parser (1.0) - GEM - specs: + GEM + specs: - PLATFORMS - java - #{lockfile_platforms} + PLATFORMS + java + #{lockfile_platforms} - DEPENDENCIES - pg_array_parser! + DEPENDENCIES + pg_array_parser! - BUNDLED WITH - #{Bundler::VERSION} - L + BUNDLED WITH + #{Bundler::VERSION} + L - bundle "config set --local cache_all true" - bundle "cache --all-platforms" + bundle "config set --local cache_all true" + bundle "cache --all-platforms" - expect(err).to be_empty - end + expect(err).to be_empty + end - it "uses the platform-specific gem with extra dependencies" do + it "uses the platform-specific gem with extra dependencies" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem_with_different_dependencies_per_platform install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" @@ -291,13 +311,15 @@ RSpec.describe "bundle install with specific platforms" do expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(["CFPropertyList-1.0", "facter-2.4.6-universal-darwin"]) end + end - context "when adding a platform via lock --add_platform" do - before do - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) - end + context "when adding a platform via lock --add_platform" do + before do + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + end - it "adds the foreign platform" do + it "adds the foreign platform" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem install_gemfile(google_protobuf) bundle "lock --add-platform=#{x64_mingw32}" @@ -308,8 +330,10 @@ RSpec.describe "bundle install with specific platforms" do google-protobuf-3.0.0.alpha.5.0.5.1-x64-mingw32 ]) end + end - it "falls back on plain ruby when that version doesn't have a platform-specific gem" do + it "falls back on plain ruby when that version doesn't have a platform-specific gem" do + simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem install_gemfile(google_protobuf) bundle "lock --add-platform=#{java}" @@ -664,6 +688,63 @@ RSpec.describe "bundle install with specific platforms" do L end + it "automatically fixes the lockfile without removing other variants if it's missing platform gems, but they are installed locally" do + simulate_platform "x86_64-darwin-21" do + build_repo4 do + build_gem("sorbet-static", "0.5.10549") do |s| + s.platform = "universal-darwin-20" + end + + build_gem("sorbet-static", "0.5.10549") do |s| + s.platform = "universal-darwin-21" + end + end + + # Make sure sorbet-static-0.5.10549-universal-darwin-21 is installed + install_gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + + gem "sorbet-static", "= 0.5.10549" + G + + # Make sure the lockfile is missing sorbet-static-0.5.10549-universal-darwin-21 + lockfile <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + sorbet-static (0.5.10549-universal-darwin-20) + + PLATFORMS + x86_64-darwin + + DEPENDENCIES + sorbet-static (= 0.5.10549) + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "install" + + expect(lockfile).to eq <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + sorbet-static (0.5.10549-universal-darwin-20) + sorbet-static (0.5.10549-universal-darwin-21) + + PLATFORMS + x86_64-darwin + + DEPENDENCIES + sorbet-static (= 0.5.10549) + + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile" do build_repo4 do build_gem "nokogiri", "1.13.8" diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index d04da0c334..2f465b7b25 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -323,7 +323,7 @@ RSpec.describe "real world edgecases", :realworld => true do if Bundler.feature_flag.bundler_3_mode? # Conflicts on bundler version, so we count attempts differently bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }, :raise_on_error => false - expect(out.split("\n").grep(/backtracking to/).count).to eq(8) + expect(out.split("\n").grep(/backtracking to/).count).to eq(16) else bundle :lock, :env => { "DEBUG_RESOLVER" => "1" } expect(out).to include("Solution found after 7 attempts") diff --git a/spec/bundler/realworld/slow_perf_spec.rb b/spec/bundler/realworld/slow_perf_spec.rb index 3ef537be0a..aa8a48fcc7 100644 --- a/spec/bundler/realworld/slow_perf_spec.rb +++ b/spec/bundler/realworld/slow_perf_spec.rb @@ -28,6 +28,6 @@ RSpec.describe "bundle install with complex dependencies", :realworld => true do gem 'rspec-rails' G - expect { bundle "lock" }.to take_less_than(18) # seconds + expect { bundle "lock" }.to take_less_than(30) # seconds end end diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb index 8f347dfa68..9567d2a3c3 100644 --- a/spec/bundler/runtime/inline_spec.rb +++ b/spec/bundler/runtime/inline_spec.rb @@ -168,6 +168,29 @@ RSpec.describe "bundler/inline#gemfile" do expect(err).to be_empty end + it "installs subdependencies quietly if necessary when the install option is not set" do + build_repo4 do + build_gem "rack" do |s| + s.add_dependency "rackdep" + end + + build_gem "rackdep", "1.0.0" + end + + script <<-RUBY + gemfile do + source "#{file_uri_for(gem_repo4)}" + gem "rack" + end + + require "rackdep" + puts RACKDEP + RUBY + + expect(out).to eq("1.0.0") + expect(err).to be_empty + end + it "installs quietly from git if necessary when the install option is not set" do build_git "foo", "1.0.0" baz_ref = build_git("baz", "2.0.0").ref_for("HEAD") @@ -207,8 +230,6 @@ RSpec.describe "bundler/inline#gemfile" do expect(err).to be_empty end -<<<<<<< HEAD:spec/bundler/runtime/inline_spec.rb -======= it "doesn't reinstall already installed gems" do system_gems "rack-1.0.0" @@ -316,7 +337,6 @@ RSpec.describe "bundler/inline#gemfile" do expect(err).to be_empty end ->>>>>>> fa6e6ea95c2 (Fix issue with extensions not compiling properly using inline gemfile):bundler/spec/runtime/inline_spec.rb it "installs inline gems when a Gemfile.lock is present" do gemfile <<-G source "https://notaserver.com" diff --git a/spec/bundler/support/indexes.rb b/spec/bundler/support/indexes.rb index 670f3b0230..78372302f1 100644 --- a/spec/bundler/support/indexes.rb +++ b/spec/bundler/support/indexes.rb @@ -18,22 +18,17 @@ module Spec @platforms ||= ["ruby"] default_source = instance_double("Bundler::Source::Rubygems", :specs => @index, :to_s => "locally install gems") source_requirements = { :default => default_source } - args[0] ||= Bundler::SpecSet.new([]) # base - args[0].each {|ls| ls.source = default_source } - args[1] ||= Bundler::GemVersionPromoter.new # gem_version_promoter - args[2] ||= [] # additional_base_requirements - originally_locked = args[3] || Bundler::SpecSet.new([]) - unlock = args[4] || [] - packages = Hash.new do |h, k| - h[k] = Bundler::Resolver::Package.new(k, @platforms, originally_locked, unlock) - end + base = args[0] || Bundler::SpecSet.new([]) + base.each {|ls| ls.source = default_source } + gem_version_promoter = args[1] || Bundler::GemVersionPromoter.new + originally_locked = args[2] || Bundler::SpecSet.new([]) + unlock = args[3] || [] @deps.each do |d| name = d.name - platforms = d.gem_platforms(@platforms) source_requirements[name] = d.source = default_source - packages[name] = Bundler::Resolver::Package.new(name, platforms, originally_locked, unlock, :dependency => d) end - Bundler::Resolver.new(source_requirements, *args[0..2]).start(@deps, packages) + packages = Bundler::Resolver::Base.new(source_requirements, @deps, base, @platforms, :locked_specs => originally_locked, :unlock => unlock) + Bundler::Resolver.new(packages, gem_version_promoter).start end def should_not_resolve @@ -71,7 +66,7 @@ module Spec s.level = opts.first s.strict = opts.include?(:strict) end - should_resolve_and_include specs, [@base, search, [], @locked, unlock] + should_resolve_and_include specs, [@base, search, @locked, unlock] end def an_awesome_index |