aboutsummaryrefslogtreecommitdiffstats
path: root/spec/bundler
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2023-12-22 07:01:12 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2023-12-22 07:24:04 +0900
commit82496f2b389278a569fa7680ee6faa55a97410d7 (patch)
treeacce0c98431a9f617be3d5c971b4c684155c5b94 /spec/bundler
parentfc549b2b3a65a95a734ee8679293a30284f84622 (diff)
downloadruby-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.rb12
-rw-r--r--spec/bundler/commands/update_spec.rb67
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb42
-rw-r--r--spec/bundler/lock/lockfile_spec.rb2
-rw-r--r--spec/bundler/realworld/edgecases_spec.rb134
-rw-r--r--spec/bundler/realworld/slow_perf_spec.rb103
-rw-r--r--spec/bundler/support/artifice/helpers/compact_index.rb2
-rw-r--r--spec/bundler/support/artifice/helpers/endpoint.rb2
-rw-r--r--spec/bundler/support/builders.rb47
-rw-r--r--spec/bundler/support/helpers.rb30
-rw-r--r--spec/bundler/support/matchers.rb16
-rw-r--r--spec/bundler/support/path.rb7
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