diff options
author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2023-12-22 07:01:12 +0900 |
---|---|---|
committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2023-12-22 07:24:04 +0900 |
commit | 82496f2b389278a569fa7680ee6faa55a97410d7 (patch) | |
tree | acce0c98431a9f617be3d5c971b4c684155c5b94 /spec/bundler | |
parent | fc549b2b3a65a95a734ee8679293a30284f84622 (diff) | |
download | ruby-82496f2b389278a569fa7680ee6faa55a97410d7.tar.gz |
Merge RubyGems-3.5.2 and Bundler-2.5.2
Diffstat (limited to 'spec/bundler')
-rw-r--r-- | spec/bundler/bundler/definition_spec.rb | 12 | ||||
-rw-r--r-- | spec/bundler/commands/update_spec.rb | 67 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/specific_platform_spec.rb | 42 | ||||
-rw-r--r-- | spec/bundler/lock/lockfile_spec.rb | 2 | ||||
-rw-r--r-- | spec/bundler/realworld/edgecases_spec.rb | 134 | ||||
-rw-r--r-- | spec/bundler/realworld/slow_perf_spec.rb | 103 | ||||
-rw-r--r-- | spec/bundler/support/artifice/helpers/compact_index.rb | 2 | ||||
-rw-r--r-- | spec/bundler/support/artifice/helpers/endpoint.rb | 2 | ||||
-rw-r--r-- | spec/bundler/support/builders.rb | 47 | ||||
-rw-r--r-- | spec/bundler/support/helpers.rb | 30 | ||||
-rw-r--r-- | spec/bundler/support/matchers.rb | 16 | ||||
-rw-r--r-- | spec/bundler/support/path.rb | 7 |
12 files changed, 285 insertions, 179 deletions
diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb index 2e3c1584b1..a19cf789ee 100644 --- a/spec/bundler/bundler/definition_spec.rb +++ b/spec/bundler/bundler/definition_spec.rb @@ -121,10 +121,7 @@ RSpec.describe Bundler::Definition do gem "foo", :path => "#{lib_path("foo")}" G - bundle :check, env: { "DEBUG" => "1" } - - expect(out).to match(/using resolution from the lockfile/) - expect(lockfile).to eq <<~G + expected_lockfile = <<~G PATH remote: #{lib_path("foo")} specs: @@ -145,6 +142,13 @@ RSpec.describe Bundler::Definition do BUNDLED WITH #{Bundler::VERSION} G + + expect(lockfile).to eq(expected_lockfile) + + bundle :check, env: { "DEBUG" => "1" } + + expect(out).to match(/using resolution from the lockfile/) + expect(lockfile).to eq(expected_lockfile) end it "for a locked gem for another platform" do diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index 013cadd541..59e7c3867c 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -1371,26 +1371,28 @@ RSpec.describe "bundle update --bundler" do expect(the_bundle).to include_gem "rack 1.0" end - it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo, :realworld do + it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo do pristine_system_gems "bundler-2.3.9" build_repo4 do build_gem "rack", "1.0" + + build_bundler "999.0.0" end - install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } + install_gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem "rack" G lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") - bundle :update, bundler: true, artifice: "vcr", verbose: true, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } + bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } # Only updates properly on modern RubyGems. if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev") - expect(out).to include("Updating bundler to 2.3.10") - expect(out).to include("Using bundler 2.3.10") + expect(out).to include("Updating bundler to 999.0.0") + expect(out).to include("Using bundler 999.0.0") expect(out).not_to include("Installing Bundler 2.3.9 and restarting using that version.") expect(lockfile).to eq <<~L @@ -1406,16 +1408,63 @@ RSpec.describe "bundle update --bundler" do rack BUNDLED WITH - 2.3.10 + 999.0.0 L - expect(the_bundle).to include_gems "bundler 2.3.10" + expect(the_bundle).to include_gems "bundler 999.0.0" + expect(the_bundle).to include_gems "rack 1.0" + else + # Old RubyGems versions do not trampoline but they still change BUNDLED + # WITH to the latest bundler version. This means the below check fails + # because it tries to use bundler 999.0.0 which did not get installed. + # Workaround the bug by forcing the version we know is installed. + expect(the_bundle).to include_gems "rack 1.0", env: { "BUNDLER_VERSION" => "2.3.9" } + end + end + + it "does not update the bundler version in the lockfile if the latest version is not compatible with current ruby", :ruby_repo do + pristine_system_gems "bundler-2.3.9" + + build_repo4 do + build_gem "rack", "1.0" + + build_bundler "2.3.9" + build_bundler "999.0.0" do |s| + s.required_ruby_version = "> #{Gem.ruby_version}" + end end + install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } + source "#{file_uri_for(gem_repo4)}" + gem "rack" + G + lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") + + bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } + + expect(out).to include("Using bundler 2.3.9") + + expect(lockfile).to eq <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + rack (1.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + rack + + BUNDLED WITH + 2.3.9 + L + + expect(the_bundle).to include_gems "bundler 2.3.9" expect(the_bundle).to include_gems "rack 1.0" end - it "errors if the explicit target version does not exist", :realworld do + it "errors if the explicit target version does not exist" do pristine_system_gems "bundler-2.3.9" build_repo4 do @@ -1428,7 +1477,7 @@ RSpec.describe "bundle update --bundler" do G lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") - bundle :update, bundler: "999.999.999", artifice: "vcr", raise_on_error: false + bundle :update, bundler: "999.999.999", artifice: "compact_index", raise_on_error: false # Only gives a meaningful error message on modern RubyGems. diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 8b37570793..8344650411 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -1220,6 +1220,48 @@ RSpec.describe "bundle install with specific platforms" do end end + it "does not add ruby platform gem if it brings extra dependencies not resolved originally" do + build_repo4 do + build_gem "nokogiri", "1.15.5" do |s| + s.add_dependency "mini_portile2", "~> 2.8.2" + end + + build_gem "nokogiri", "1.15.5" do |s| + s.platform = "x86_64-linux" + end + end + + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + + gem "nokogiri" + G + + checksums = checksums_section_when_existing do |c| + c.checksum gem_repo4, "nokogiri", "1.15.5", "x86_64-linux" + end + + simulate_platform "x86_64-linux" do + bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + + expect(lockfile).to eq(<<~L) + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.15.5-x86_64-linux) + + PLATFORMS + x86_64-linux + + DEPENDENCIES + nokogiri + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + private def setup_multiplatform_gem diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index 8fe2f37054..5e996f5aac 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -1603,7 +1603,7 @@ RSpec.describe "the lockfile format" do L bundle "install --verbose" - expect(out).to include("re-resolving dependencies because your lock file is missing \"minitest-bisect\"") + expect(out).to include("re-resolving dependencies because your lock file includes \"minitest-bisect\" but not some of its dependencies") expect(lockfile).to eq <<~L GEM diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index c9af686dbe..dc70271b6e 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -219,140 +219,6 @@ RSpec.describe "real world edgecases", realworld: true do expect(err).to include("resque-scheduler 2.2.0 includes a gemspec with `require_paths` set to an array of arrays. Newer versions of this gem might've already fixed this").once end - it "doesn't hang on big gemfile" do - skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7") - - gemfile <<~G - # frozen_string_literal: true - - source "https://rubygems.org" - - ruby "~> 2.7.7" - - gem "rails" - gem "pg", ">= 0.18", "< 2.0" - gem "goldiloader" - gem "awesome_nested_set" - gem "circuitbox" - gem "passenger" - gem "globalid" - gem "rack-cors" - gem "rails-pg-extras" - gem "linear_regression_trend" - gem "rack-protection" - gem "pundit" - gem "remote_ip_proxy_scrubber" - gem "bcrypt" - gem "searchkick" - gem "excon" - gem "faraday_middleware-aws-sigv4" - gem "typhoeus" - gem "sidekiq" - gem "sidekiq-undertaker" - gem "sidekiq-cron" - gem "storext" - gem "appsignal" - gem "fcm" - gem "business_time" - gem "tzinfo" - gem "holidays" - gem "bigdecimal" - gem "progress_bar" - gem "redis" - gem "hiredis" - gem "state_machines" - gem "state_machines-audit_trail" - gem "state_machines-activerecord" - gem "interactor" - gem "ar_transaction_changes" - gem "redis-rails" - gem "seed_migration" - gem "lograge" - gem "graphiql-rails", group: :development - gem "graphql" - gem "pusher" - gem "rbnacl" - gem "jwt" - gem "json-schema" - gem "discard" - gem "money" - gem "strip_attributes" - gem "validates_email_format_of" - gem "audited" - gem "concurrent-ruby" - gem "with_advisory_lock" - - group :test do - gem "rspec-sidekiq" - gem "simplecov", require: false - end - - group :development, :test do - gem "byebug", platform: :mri - gem "guard" - gem "guard-bundler" - gem "guard-rspec" - gem "rb-fsevent" - gem "rspec_junit_formatter" - gem "rspec-collection_matchers" - gem "rspec-rails" - gem "rspec-retry" - gem "state_machines-rspec" - gem "dotenv-rails" - gem "database_cleaner-active_record" - gem "database_cleaner-redis" - gem "timecop" - end - - gem "factory_bot_rails" - gem "faker" - - group :development do - gem "listen" - gem "sql_queries_count" - gem "rubocop" - gem "rubocop-performance" - gem "rubocop-rspec" - gem "rubocop-rails" - gem "brakeman" - gem "bundler-audit" - gem "solargraph" - gem "annotate" - end - G - - 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) - else - bundle :lock, env: { "DEBUG_RESOLVER" => "1" } - expect(out).to include("Solution found after 7 attempts") - end - end - - it "doesn't hang on tricky gemfile" do - skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7") - - gemfile <<~G - source 'https://rubygems.org' - - group :development do - gem "puppet-module-posix-default-r2.7", '~> 0.3' - gem "puppet-module-posix-dev-r2.7", '~> 0.3' - gem "beaker-rspec" - gem "beaker-puppet" - gem "beaker-docker" - gem "beaker-puppet_install_helper" - gem "beaker-module_install_helper" - end - G - - bundle :lock, env: { "DEBUG_RESOLVER" => "1" } - - expect(out).to include("Solution found after 6 attempts") - end - it "doesn't hang on nix gemfile" do skip "Only for ruby 3.0" unless RUBY_VERSION.start_with?("3.0") diff --git a/spec/bundler/realworld/slow_perf_spec.rb b/spec/bundler/realworld/slow_perf_spec.rb index d5ca51975a..be557d3902 100644 --- a/spec/bundler/realworld/slow_perf_spec.rb +++ b/spec/bundler/realworld/slow_perf_spec.rb @@ -30,4 +30,107 @@ RSpec.describe "bundle install with complex dependencies", realworld: true do expect { bundle "lock" }.to take_less_than(30) # seconds end + + it "resolves big gemfile quickly" do + gemfile <<~G + # frozen_string_literal: true + + source "https://rubygems.org" + + gem "rails" + gem "pg", ">= 0.18", "< 2.0" + gem "goldiloader" + gem "awesome_nested_set" + gem "circuitbox" + gem "passenger" + gem "globalid" + gem "rack-cors" + gem "rails-pg-extras" + gem "linear_regression_trend" + gem "rack-protection" + gem "pundit" + gem "remote_ip_proxy_scrubber" + gem "bcrypt" + gem "searchkick" + gem "excon" + gem "faraday_middleware-aws-sigv4" + gem "typhoeus" + gem "sidekiq" + gem "sidekiq-undertaker" + gem "sidekiq-cron" + gem "storext" + gem "appsignal" + gem "fcm" + gem "business_time" + gem "tzinfo" + gem "holidays" + gem "bigdecimal" + gem "progress_bar" + gem "redis" + gem "hiredis" + gem "state_machines" + gem "state_machines-audit_trail" + gem "state_machines-activerecord" + gem "interactor" + gem "ar_transaction_changes" + gem "redis-rails" + gem "seed_migration" + gem "lograge" + gem "graphiql-rails", group: :development + gem "graphql" + gem "pusher" + gem "rbnacl" + gem "jwt" + gem "json-schema" + gem "discard" + gem "money" + gem "strip_attributes" + gem "validates_email_format_of" + gem "audited" + gem "concurrent-ruby" + gem "with_advisory_lock" + + group :test do + gem "rspec-sidekiq" + gem "simplecov", require: false + end + + group :development, :test do + gem "byebug", platform: :mri + gem "guard" + gem "guard-bundler" + gem "guard-rspec" + gem "rb-fsevent" + gem "rspec_junit_formatter" + gem "rspec-collection_matchers" + gem "rspec-rails" + gem "rspec-retry" + gem "state_machines-rspec" + gem "dotenv-rails" + gem "database_cleaner-active_record" + gem "database_cleaner-redis" + gem "timecop" + end + + gem "factory_bot_rails" + gem "faker" + + group :development do + gem "listen" + gem "sql_queries_count" + gem "rubocop" + gem "rubocop-performance" + gem "rubocop-rspec" + gem "rubocop-rails" + gem "brakeman" + gem "bundler-audit" + gem "solargraph" + gem "annotate" + end + G + + expect do + bundle "lock", env: { "DEBUG_RESOLVER" => "1" }, raise_on_error: !Bundler.feature_flag.bundler_3_mode? + end.to take_less_than(30) # seconds + end end diff --git a/spec/bundler/support/artifice/helpers/compact_index.rb b/spec/bundler/support/artifice/helpers/compact_index.rb index 8e7acb41a9..cf8bb34c5a 100644 --- a/spec/bundler/support/artifice/helpers/compact_index.rb +++ b/spec/bundler/support/artifice/helpers/compact_index.rb @@ -77,7 +77,7 @@ class CompactIndexAPI < Endpoint specs.group_by(&:name).map do |name, versions| gem_versions = versions.map do |spec| - deps = spec.dependencies.select {|d| d.type == :runtime }.map do |d| + deps = spec.runtime_dependencies.map do |d| reqs = d.requirement.requirements.map {|r| r.join(" ") }.join(", ") CompactIndex::Dependency.new(d.name, reqs) end diff --git a/spec/bundler/support/artifice/helpers/endpoint.rb b/spec/bundler/support/artifice/helpers/endpoint.rb index 6115e91535..be52df6936 100644 --- a/spec/bundler/support/artifice/helpers/endpoint.rb +++ b/spec/bundler/support/artifice/helpers/endpoint.rb @@ -72,7 +72,7 @@ class Endpoint < Sinatra::Base name: spec.name, number: spec.version.version, platform: spec.platform.to_s, - dependencies: spec.dependencies.select {|dep| dep.type == :runtime }.map do |dep| + dependencies: spec.runtime_dependencies.map do |dep| [dep.name, dep.requirement.requirements.map {|a| a.join(" ") }.join(", ")] end, } diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb index 1763e091fe..68e3bd7c7b 100644 --- a/spec/bundler/support/builders.rb +++ b/spec/bundler/support/builders.rb @@ -297,6 +297,10 @@ module Spec build_with(LibBuilder, name, args, &blk) end + def build_bundler(*args, &blk) + build_with(BundlerBuilder, "bundler", args, &blk) + end + def build_gem(name, *args, &blk) build_with(GemBuilder, name, args, &blk) end @@ -402,6 +406,49 @@ module Spec alias_method :dep, :runtime end + class BundlerBuilder + attr_writer :required_ruby_version + + def initialize(context, name, version) + raise "can only build bundler" unless name == "bundler" + + @context = context + @version = version || Bundler::VERSION + end + + def _build(options = {}) + full_name = "bundler-#{@version}" + build_path = @context.tmp + full_name + bundler_path = build_path + "#{full_name}.gem" + + Dir.mkdir build_path + + @context.shipped_files.each do |shipped_file| + target_shipped_file = shipped_file + target_shipped_file = shipped_file.sub(/\Alibexec/, "exe") if @context.ruby_core? + target_shipped_file = build_path + target_shipped_file + target_shipped_dir = File.dirname(target_shipped_file) + FileUtils.mkdir_p target_shipped_dir unless File.directory?(target_shipped_dir) + FileUtils.cp shipped_file, target_shipped_file, preserve: true + end + + @context.replace_version_file(@version, dir: build_path) + @context.replace_required_ruby_version(@required_ruby_version, dir: build_path) if @required_ruby_version + + Spec::BuildMetadata.write_build_metadata(dir: build_path) + + @context.gem_command "build #{@context.relative_gemspec}", dir: build_path + + if block_given? + yield(bundler_path) + else + FileUtils.mv bundler_path, options[:path] + end + ensure + build_path.rmtree + end + end + class LibBuilder def initialize(context, name, version) @context = context diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb index 5e5a6a6e3b..64ed0553b8 100644 --- a/spec/bundler/support/helpers.rb +++ b/spec/bundler/support/helpers.rb @@ -326,34 +326,8 @@ module Spec gem_command "install #{args} '#{path}'" end - def with_built_bundler(version = nil) - version ||= Bundler::VERSION - full_name = "bundler-#{version}" - build_path = tmp + full_name - bundler_path = build_path + "#{full_name}.gem" - - Dir.mkdir build_path - - begin - shipped_files.each do |shipped_file| - target_shipped_file = shipped_file - target_shipped_file = shipped_file.sub(/\Alibexec/, "exe") if ruby_core? - target_shipped_file = build_path + target_shipped_file - target_shipped_dir = File.dirname(target_shipped_file) - FileUtils.mkdir_p target_shipped_dir unless File.directory?(target_shipped_dir) - FileUtils.cp shipped_file, target_shipped_file, preserve: true - end - - replace_version_file(version, dir: build_path) - - Spec::BuildMetadata.write_build_metadata(dir: build_path) - - gem_command "build #{relative_gemspec}", dir: build_path - - yield(bundler_path) - ensure - build_path.rmtree - end + def with_built_bundler(version = nil, &block) + Builders::BundlerBuilder.new(self, "bundler", version)._build(&block) end def with_gem_path_as(path) diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb index ea7c784683..9d604bec25 100644 --- a/spec/bundler/support/matchers.rb +++ b/spec/bundler/support/matchers.rb @@ -103,7 +103,21 @@ module Spec actual.call - (Time.now - start_time).to_f < seconds + actual_time = (Time.now - start_time).to_f + + acceptable = actual_time < seconds + + @errors = ["took #{actual_time} seconds"] unless acceptable + + acceptable + end + + failure_message do + super() + " but:\n" + @errors.map {|e| indent(e) }.join("\n") + end + + failure_message_when_negated do + super() + " but:\n" + @errors.map {|e| indent(e) }.join("\n") end supports_block_expectations diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb index 3dbc553c01..7352d5a353 100644 --- a/spec/bundler/support/path.rb +++ b/spec/bundler/support/path.rb @@ -250,6 +250,13 @@ module Spec File.open(version_file, "w") {|f| f << contents } end + def replace_required_ruby_version(version, dir:) + gemspec_file = File.expand_path("bundler.gemspec", dir) + contents = File.read(gemspec_file) + contents.sub!(/(^\s+s\.required_ruby_version\s*=\s*)"[^"]+"/, %(\\1"#{version}")) + File.open(gemspec_file, "w") {|f| f << contents } + end + def ruby_core? # avoid to warnings @ruby_core ||= nil |