diff options
Diffstat (limited to 'spec/bundler/install/gems/resolving_spec.rb')
-rw-r--r-- | spec/bundler/install/gems/resolving_spec.rb | 289 |
1 files changed, 208 insertions, 81 deletions
diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index 279d3422c1..694bc7c131 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -66,7 +66,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs gems with implicit rake dependencies" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "with_implicit_rake_dep" gem "another_implicit_rake_dep" gem "rake" @@ -84,7 +84,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs gems with implicit rake dependencies without rake previously installed" do with_path_as("") do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "with_implicit_rake_dep" gem "another_implicit_rake_dep" gem "rake" @@ -100,30 +100,32 @@ RSpec.describe "bundle install with install-time dependencies" do expect(out).to eq("YES\nYES") end - it "installs gems with a dependency with no type" do + it "does not install gems with a dependency with no type" do build_repo2 path = "#{gem_repo2}/#{Gem::MARSHAL_SPEC_DIR}/actionpack-2.3.2.gemspec.rz" spec = Marshal.load(Bundler.rubygems.inflate(File.binread(path))) spec.dependencies.each do |d| - d.instance_variable_set(:@type, :fail) + d.instance_variable_set(:@type, "fail") end File.open(path, "wb") do |f| f.write Gem.deflate(Marshal.dump(spec)) end - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo2" gem "actionpack", "2.3.2" G - expect(the_bundle).to include_gems "actionpack 2.3.2", "activesupport 2.3.2" + expect(err).to include("Downloading actionpack-2.3.2 revealed dependencies not in the API or the lockfile (activesupport (= 2.3.2)).") + + expect(the_bundle).not_to include_gems "actionpack 2.3.2", "activesupport 2.3.2" end describe "with crazy rubygem plugin stuff" do it "installs plugins" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_b" G @@ -131,8 +133,8 @@ RSpec.describe "bundle install with install-time dependencies" do end it "installs plugins depended on by other plugins" do - install_gemfile <<-G, :env => { "DEBUG" => "1" } - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G, env: { "DEBUG" => "1" } + source "https://gem.repo2" gem "net_a" G @@ -140,8 +142,8 @@ RSpec.describe "bundle install with install-time dependencies" do end it "installs multiple levels of dependencies" do - install_gemfile <<-G, :env => { "DEBUG" => "1" } - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G, env: { "DEBUG" => "1" } + source "https://gem.repo2" gem "net_c" gem "net_e" G @@ -152,12 +154,12 @@ RSpec.describe "bundle install with install-time dependencies" do context "with ENV['BUNDLER_DEBUG_RESOLVER'] set" do it "produces debug output" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_c" gem "net_e" G - bundle :install, :env => { "BUNDLER_DEBUG_RESOLVER" => "1", "DEBUG" => "1" } + bundle :install, env: { "BUNDLER_DEBUG_RESOLVER" => "1", "DEBUG" => "1" } expect(out).to include("Resolving dependencies...") end @@ -166,12 +168,12 @@ RSpec.describe "bundle install with install-time dependencies" do context "with ENV['DEBUG_RESOLVER'] set" do it "produces debug output" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_c" gem "net_e" G - bundle :install, :env => { "DEBUG_RESOLVER" => "1", "DEBUG" => "1" } + bundle :install, env: { "DEBUG_RESOLVER" => "1", "DEBUG" => "1" } expect(out).to include("Resolving dependencies...") end @@ -180,17 +182,17 @@ RSpec.describe "bundle install with install-time dependencies" do context "with ENV['DEBUG_RESOLVER_TREE'] set" do it "produces debug output" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_c" gem "net_e" G - bundle :install, :env => { "DEBUG_RESOLVER_TREE" => "1", "DEBUG" => "1" } + bundle :install, env: { "DEBUG_RESOLVER_TREE" => "1", "DEBUG" => "1" } expect(out).to include(" net_b"). and include("Resolving dependencies..."). and include("Solution found after 1 attempts:"). - and include("selecting net_b 1.0") + and include("selected net_b 1.0") end end end @@ -199,44 +201,44 @@ RSpec.describe "bundle install with install-time dependencies" do context "allows only an older version" do it "installs the older version" do build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end end - install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + install_gemfile <<-G ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' G - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end it "installs the older version when using servers not implementing the compact index API" do build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end end - install_gemfile <<-G, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + install_gemfile <<-G, artifice: "endpoint" ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' G - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end context "when there is a lockfile using the newer incompatible version" do @@ -252,13 +254,17 @@ RSpec.describe "bundle install with install-time dependencies" do end gemfile <<-G - source "http://localgemserver.test/" + source "https://gem.repo2" gem 'parallel_tests' G + checksums = checksums_section do |c| + c.checksum gem_repo2, "parallel_tests", "3.8.0" + end + lockfile <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: parallel_tests (3.8.0) @@ -267,18 +273,22 @@ RSpec.describe "bundle install with install-time dependencies" do DEPENDENCIES parallel_tests - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L end it "automatically updates lockfile to use the older version" do - bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + bundle "install --verbose" + + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo2, "parallel_tests", "3.7.0" + end expect(lockfile).to eq <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: parallel_tests (3.7.0) @@ -287,7 +297,7 @@ RSpec.describe "bundle install with install-time dependencies" do DEPENDENCIES parallel_tests - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -295,7 +305,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "gives a meaningful error if we're in frozen mode" do expect do - bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s, "BUNDLE_FROZEN" => "true" }, :raise_on_error => false + bundle "install --verbose", env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false end.not_to change { lockfile } expect(err).to include("parallel_tests-3.8.0 requires ruby version >= #{next_ruby_minor}") @@ -328,13 +338,18 @@ RSpec.describe "bundle install with install-time dependencies" do end gemfile <<-G - source "http://localgemserver.test/" + source "https://gem.repo2" gem 'rubocop' G + checksums = checksums_section do |c| + c.checksum gem_repo2, "rubocop", "1.35.0" + c.checksum gem_repo2, "rubocop-ast", "1.21.0" + end + lockfile <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: rubocop (1.35.0) rubocop-ast (>= 1.20.1, < 2.0) @@ -345,18 +360,23 @@ RSpec.describe "bundle install with install-time dependencies" do DEPENDENCIES parallel_tests - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L end it "automatically updates lockfile to use the older compatible versions" do - bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + bundle "install --verbose" + + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo2, "rubocop", "1.28.2" + c.checksum gem_repo2, "rubocop-ast", "1.17.0" + end expect(lockfile).to eq <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: rubocop (1.28.2) rubocop-ast (>= 1.17.0, < 2.0) @@ -367,7 +387,7 @@ RSpec.describe "bundle install with install-time dependencies" do DEPENDENCIES rubocop - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -387,13 +407,13 @@ RSpec.describe "bundle install with install-time dependencies" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'sorbet', '= 0.5.10554' G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet (0.5.10554) sorbet-static (= 0.5.10554) @@ -412,11 +432,11 @@ RSpec.describe "bundle install with install-time dependencies" do it "raises a proper error" do simulate_platform "aarch64-linux" do - bundle "install", :raise_on_error => false + bundle "install", raise_on_error: false end - nice_error = strip_whitespace(<<-E).strip - Could not find gem 'sorbet-static (= 0.5.10554)' with platforms 'arm64-darwin-21', 'aarch64-linux' in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally. + nice_error = <<~E.strip + Could not find gems matching 'sorbet-static (= 0.5.10554)' valid for all resolution platforms (arm64-darwin-21, aarch64-linux) in rubygems repository https://gem.repo4/ or installed locally. The source contains the following gems matching 'sorbet-static (= 0.5.10554)': * sorbet-static-0.5.10554-universal-darwin-21 @@ -425,6 +445,62 @@ RSpec.describe "bundle install with install-time dependencies" do end end + context "when adding a new gem that does not resolve under all locked platforms" do + before do + simulate_platform "x86_64-linux" do + build_repo4 do + build_gem "nokogiri", "1.14.0" do |s| + s.platform = "x86_64-linux" + end + build_gem "nokogiri", "1.14.0" do |s| + s.platform = "arm-linux" + end + + build_gem "sorbet-static", "0.5.10696" do |s| + s.platform = "x86_64-linux" + end + end + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + nokogiri (1.14.0-arm-linux) + nokogiri (1.14.0-x86_64-linux) + + PLATFORMS + arm-linux + x86_64-linux + + DEPENDENCIES + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L + + gemfile <<~G + source "https://gem.repo4" + + gem "nokogiri" + gem "sorbet-static" + G + + bundle "lock", raise_on_error: false + end + end + + it "raises a proper error" do + nice_error = <<~E.strip + Could not find gems matching 'sorbet-static' valid for all resolution platforms (arm-linux, x86_64-linux) in rubygems repository https://gem.repo4/ or installed locally. + + The source contains the following gems matching 'sorbet-static': + * sorbet-static-0.5.10696-x86_64-linux + E + expect(err).to end_with(nice_error) + end + end + it "gives a meaningful error on ruby version mismatches between dependencies" do build_repo4 do build_gem "requires-old-ruby" do |s| @@ -432,14 +508,14 @@ RSpec.describe "bundle install with install-time dependencies" do end end - build_lib("foo", :path => bundled_app) do |s| + build_lib("foo", path: bundled_app) do |s| s.required_ruby_version = ">= #{Gem.ruby_version}" s.add_dependency "requires-old-ruby" end - install_gemfile <<-G, :raise_on_error => false - source "#{file_uri_for(gem_repo4)}" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo4" gemspec G @@ -457,47 +533,47 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs the older version under rate limiting conditions" do build_repo4 do - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end - build_gem "rack", "1.2" + build_gem "myrack", "1.2" build_gem "foo1", "1.0" end - install_gemfile <<-G, :artifice => "compact_index_rate_limited", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + install_gemfile <<-G, artifice: "compact_index_rate_limited" ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo4" + gem 'myrack' gem 'foo1' G - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end it "installs the older not platform specific version" do build_repo4 do - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end - build_gem "rack", "1.2" do |s| + build_gem "myrack", "1.2" do |s| s.platform = x86_mingw32 s.required_ruby_version = "> 9000" end - build_gem "rack", "1.2" + build_gem "myrack", "1.2" end simulate_platform x86_mingw32 do - install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + install_gemfile <<-G, artifice: "compact_index" ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo4" + gem 'myrack' G end - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(err).to_not include("rack-1.2-#{Bundler.local_platform} requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(err).to_not include("myrack-1.2-#{Bundler.local_platform} requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end end @@ -514,14 +590,14 @@ RSpec.describe "bundle install with install-time dependencies" do let(:error_message_requirement) { "= #{Gem.ruby_version}" } it "raises a proper error that mentions the current Ruby version during resolution" do - install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false - source "http://localgemserver.test/" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo2" gem 'require_ruby' G expect(out).to_not include("Gem::InstallError: require_ruby requires Ruby version > 9000") - nice_error = strip_whitespace(<<-E).strip + nice_error = <<~E.strip Could not find compatible versions Because every version of require_ruby depends on Ruby > 9000 @@ -535,15 +611,15 @@ RSpec.describe "bundle install with install-time dependencies" do shared_examples_for "ruby version conflicts" do it "raises an error during resolution" do - install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :raise_on_error => false - source "http://localgemserver.test/" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo2" ruby #{ruby_requirement} gem 'require_ruby' G expect(out).to_not include("Gem::InstallError: require_ruby requires Ruby version > 9000") - nice_error = strip_whitespace(<<-E).strip + nice_error = <<~E.strip Could not find compatible versions Because every version of require_ruby depends on Ruby > 9000 @@ -581,13 +657,13 @@ RSpec.describe "bundle install with install-time dependencies" do end end - install_gemfile <<-G, :raise_on_error => false - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo2" gem 'require_rubygems' G expect(err).to_not include("Gem::InstallError: require_rubygems requires RubyGems version > 9000") - nice_error = strip_whitespace(<<-E).strip + nice_error = <<~E.strip Because every version of require_rubygems depends on RubyGems > 9000 and Gemfile depends on require_rubygems >= 0, RubyGems > 9000 is required. @@ -597,4 +673,55 @@ RSpec.describe "bundle install with install-time dependencies" do expect(err).to end_with(nice_error) end end + + context "when non platform specific gems bring more dependencies", :truffleruby_only do + before do + build_repo4 do + build_gem "foo", "1.0" do |s| + s.add_dependency "bar" + end + + build_gem "foo", "2.0" do |s| + s.platform = "x86_64-linux" + end + + build_gem "bar" + end + + gemfile <<-G + source "https://gem.repo4" + gem "foo" + G + end + + it "locks both ruby and current platform, and resolve to ruby variants that install on truffleruby" do + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "foo", "1.0" + c.checksum gem_repo4, "bar", "1.0" + end + + simulate_platform "x86_64-linux" do + bundle "install" + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + bar (1.0) + foo (1.0) + bar + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + foo + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + end end |