diff options
38 files changed, 170 insertions, 253 deletions
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb index bb9f1cb3f5..452583617b 100644 --- a/lib/bundler/rubygems_gem_installer.rb +++ b/lib/bundler/rubygems_gem_installer.rb @@ -67,7 +67,7 @@ module Bundler def build_extensions extension_cache_path = options[:bundler_extension_cache_path] unless extension_cache_path && extension_dir = spec.extension_dir - require "shellwords" # compensate missing require in rubygems before version 3.2.25 + require "shellwords" unless Bundler.rubygems.provides?(">= 3.2.25") return super end diff --git a/lib/bundler/self_manager.rb b/lib/bundler/self_manager.rb index bda2eb51f3..d62ef6ca12 100644 --- a/lib/bundler/self_manager.rb +++ b/lib/bundler/self_manager.rb @@ -39,10 +39,13 @@ module Bundler configured_gem_home = ENV["GEM_HOME"] configured_gem_path = ENV["GEM_PATH"] + cmd = [$PROGRAM_NAME, *ARGV] + cmd.unshift(Gem.ruby) unless File.executable?($PROGRAM_NAME) + Bundler.with_original_env do Kernel.exec( { "GEM_HOME" => configured_gem_home, "GEM_PATH" => configured_gem_path, "BUNDLER_VERSION" => lockfile_version }, - $PROGRAM_NAME, *ARGV + *cmd ) end end diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb index de9323b2db..de9b3b4c86 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions.rb @@ -161,6 +161,8 @@ class Bundler::Thor # to the block you provide. The path is set back to the previous path when # the method exits. # + # Returns the value yielded by the block. + # # ==== Parameters # dir<String>:: the directory to move to. # config<Hash>:: give :verbose => true to log and use padding. @@ -179,16 +181,18 @@ class Bundler::Thor FileUtils.mkdir_p(destination_root) end + result = nil if pretend # In pretend mode, just yield down to the block - block.arity == 1 ? yield(destination_root) : yield + result = block.arity == 1 ? yield(destination_root) : yield else require "fileutils" - FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield } + FileUtils.cd(destination_root) { result = block.arity == 1 ? yield(destination_root) : yield } end @destination_stack.pop shell.padding -= 1 if verbose + result end # Goes to the root and execute the given block. diff --git a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb index 90a8d2e847..bf2a737c84 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb @@ -210,9 +210,9 @@ class Bundler::Thor # # ==== Examples # - # inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n" + # inject_into_class "app/controllers/application_controller.rb", "ApplicationController", " filter_parameter :password\n" # - # inject_into_class "app/controllers/application_controller.rb", ApplicationController do + # inject_into_class "app/controllers/application_controller.rb", "ApplicationController" do # " filter_parameter :password\n" # end # @@ -233,9 +233,9 @@ class Bundler::Thor # # ==== Examples # - # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper, " def help; 'help'; end\n" + # inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper", " def help; 'help'; end\n" # - # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper do + # inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper" do # " def help; 'help'; end\n" # end # @@ -252,7 +252,7 @@ class Bundler::Thor # flag<Regexp|String>:: the regexp or string to be replaced # replacement<String>:: the replacement, can be also given as a block # config<Hash>:: give :verbose => false to not log the status, and - # :force => true, to force the replacement regardless of runner behavior. + # :force => true, to force the replacement regardles of runner behavior. # # ==== Example # @@ -331,7 +331,7 @@ class Bundler::Thor path = File.expand_path(path, destination_root) say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) - if !options[:pretend] && File.exist?(path) + if !options[:pretend] && (File.exist?(path) || File.symlink?(path)) require "fileutils" ::FileUtils.rm_rf(path) end diff --git a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb index 09ce0864f0..f52ced2bcd 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb @@ -106,12 +106,14 @@ class Bundler::Thor # Adds the content to the file. # def replace!(regexp, string, force) - return if pretend? content = File.read(destination) - if force || !content.include?(replacement) + before, after = content.split(regexp, 2) + snippet = (behavior == :after ? after : before).to_s + + if force || !snippet.include?(replacement) success = content.gsub!(regexp, string) - File.open(destination, "wb") { |file| file.write(content) } + File.open(destination, "wb") { |file| file.write(content) } unless pretend? success end end diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb index c167aa33b8..3c4483e5dd 100644 --- a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +++ b/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb @@ -28,6 +28,12 @@ class Bundler::Thor super(convert_key(key)) end + def except(*keys) + dup.tap do |hash| + keys.each { |key| hash.delete(convert_key(key)) } + end + end + def fetch(key, *args) super(convert_key(key), *args) end diff --git a/lib/bundler/vendor/thor/lib/thor/error.rb b/lib/bundler/vendor/thor/lib/thor/error.rb index 7d57129b83..03f2ce85bb 100644 --- a/lib/bundler/vendor/thor/lib/thor/error.rb +++ b/lib/bundler/vendor/thor/lib/thor/error.rb @@ -102,9 +102,14 @@ class Bundler::Thor end if Correctable - DidYouMean::SPELL_CHECKERS.merge!( - 'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker, - 'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker - ) + if DidYouMean.respond_to?(:correct_error) + DidYouMean.correct_error(Bundler::Thor::UndefinedCommandError, UndefinedCommandError::SpellChecker) + DidYouMean.correct_error(Bundler::Thor::UnknownArgumentError, UnknownArgumentError::SpellChecker) + else + DidYouMean::SPELL_CHECKERS.merge!( + 'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker, + 'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker + ) + end end end diff --git a/lib/bundler/vendor/thor/lib/thor/parser/options.rb b/lib/bundler/vendor/thor/lib/thor/parser/options.rb index 3a8927d09c..5bd97aba6f 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/options.rb @@ -45,6 +45,7 @@ class Bundler::Thor @switches = {} @extra = [] @stopped_parsing_after_extra_index = nil + @is_treated_as_value = false options.each do |option| @switches[option.switch_name] = option @@ -74,8 +75,19 @@ class Bundler::Thor end end + def shift + @is_treated_as_value = false + super + end + + def unshift(arg, is_value: false) + @is_treated_as_value = is_value + super(arg) + end + def parse(args) # rubocop:disable MethodLength @pile = args.dup + @is_treated_as_value = false @parsing_options = true while peek @@ -88,7 +100,10 @@ class Bundler::Thor when SHORT_SQ_RE unshift($1.split("").map { |f| "-#{f}" }) next - when EQ_RE, SHORT_NUM + when EQ_RE + unshift($2, is_value: true) + switch = $1 + when SHORT_NUM unshift($2) switch = $1 when LONG_RE, SHORT_RE @@ -148,6 +163,7 @@ class Bundler::Thor # Two booleans are returned. The first is true if the current value # starts with a hyphen; the second is true if it is a registered switch. def current_is_switch? + return [false, false] if @is_treated_as_value case peek when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM [true, switch?($1)] @@ -159,6 +175,7 @@ class Bundler::Thor end def current_is_switch_formatted? + return false if @is_treated_as_value case peek when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM, SHORT_SQ_RE true @@ -168,6 +185,7 @@ class Bundler::Thor end def current_is_value? + return true if @is_treated_as_value peek && (!parsing_options? || super) end diff --git a/lib/bundler/vendor/thor/lib/thor/shell.rb b/lib/bundler/vendor/thor/lib/thor/shell.rb index e36fa472d6..a4137d1bde 100644 --- a/lib/bundler/vendor/thor/lib/thor/shell.rb +++ b/lib/bundler/vendor/thor/lib/thor/shell.rb @@ -21,7 +21,7 @@ class Bundler::Thor end module Shell - SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width] + SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_error, :say_status, :print_in_columns, :print_table, :print_wrapped, :file_collision, :terminal_width] attr_writer :shell autoload :Basic, File.expand_path("shell/basic", __dir__) diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb index 2dddd4a53a..8eff00bf3d 100644 --- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +++ b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb @@ -103,6 +103,23 @@ class Bundler::Thor stdout.flush end + # Say (print) an error to the user. If the sentence ends with a whitespace + # or tab character, a new line is not appended (print + flush). Otherwise + # are passed straight to puts (behavior got from Highline). + # + # ==== Example + # say_error("error: something went wrong") + # + def say_error(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/)) + return if quiet? + + buffer = prepare_message(message, *color) + buffer << "\n" if force_new_line && !message.to_s.end_with?("\n") + + stderr.print(buffer) + stderr.flush + end + # Say a status with the given color and appends the message. Since this # method is used frequently by actions, it allows nil or false to be given # in log_status, avoiding the message from being shown. If a Symbol is @@ -111,13 +128,14 @@ class Bundler::Thor def say_status(status, message, log_status = true) return if quiet? || log_status == false spaces = " " * (padding + 1) - color = log_status.is_a?(Symbol) ? log_status : :green - status = status.to_s.rjust(12) + margin = " " * status.length + spaces + + color = log_status.is_a?(Symbol) ? log_status : :green status = set_color status, color, true if color - buffer = "#{status}#{spaces}#{message}" - buffer = "#{buffer}\n" unless buffer.end_with?("\n") + message = message.to_s.chomp.gsub(/(?<!\A)^/, margin) + buffer = "#{status}#{spaces}#{message}\n" stdout.print(buffer) stdout.flush diff --git a/lib/bundler/vendor/thor/lib/thor/util.rb b/lib/bundler/vendor/thor/lib/thor/util.rb index ddf4d21b90..d2572a4249 100644 --- a/lib/bundler/vendor/thor/lib/thor/util.rb +++ b/lib/bundler/vendor/thor/lib/thor/util.rb @@ -211,7 +211,7 @@ class Bundler::Thor # def globs_for(path) path = escape_globs(path) - ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"] + ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/**/*.thor"] end # Return the path to the ruby interpreter taking into account multiple diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index d987722f78..bfe7ae7f7c 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.3.0".freeze + VERSION = "2.3.1".freeze def self.bundler_major_version @bundler_major_version ||= VERSION.split(".").first.to_i diff --git a/lib/rubygems.rb b/lib/rubygems.rb index a956e06bdb..2e13c589b3 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = "3.3.0".freeze + VERSION = "3.3.1".freeze end # Must be first since it unloads the prelude from 1.9.2 @@ -272,9 +272,6 @@ module Gem unless spec = specs.first msg = "can't find gem #{dep} with executable #{exec_name}" - if dep.filters_bundler? && bundler_message = Gem::BundlerVersionFinder.missing_version_message - msg = bundler_message - end raise Gem::GemNotFoundException, msg end diff --git a/lib/rubygems/bundler_version_finder.rb b/lib/rubygems/bundler_version_finder.rb index 9ce0a2378e..14179aebf3 100644 --- a/lib/rubygems/bundler_version_finder.rb +++ b/lib/rubygems/bundler_version_finder.rb @@ -2,48 +2,18 @@ module Gem::BundlerVersionFinder def self.bundler_version - version, _ = bundler_version_with_reason + v = ENV["BUNDLER_VERSION"] - return unless version + v ||= bundle_update_bundler_version + return if v == true - Gem::Version.new(version) - end - - def self.bundler_version_with_reason - if v = ENV["BUNDLER_VERSION"] - return [v, "`$BUNDLER_VERSION`"] - end - if v = bundle_update_bundler_version - return if v == true - return [v, "`bundle update --bundler`"] - end - v, lockfile = lockfile_version - if v - return [v, "your #{lockfile}"] - end - end + v ||= lockfile_version + return unless v - def self.missing_version_message - return unless vr = bundler_version_with_reason - <<-EOS -Could not find 'bundler' (#{vr.first}) required by #{vr.last}. -To update to the latest version installed on your system, run `bundle update --bundler`. -To install the missing version, run `gem install bundler:#{vr.first}` - EOS + Gem::Version.new(v) end - def self.compatible?(spec) - return true unless spec.name == "bundler".freeze - return true unless bundler_version = self.bundler_version - - spec.version.segments.first == bundler_version.segments.first - end - - def self.filter!(specs) - return unless bundler_version = self.bundler_version - - specs.reject! {|spec| spec.version.segments.first != bundler_version.segments.first } - + def self.prioritize!(specs) exact_match_index = specs.find_index {|spec| spec.version == bundler_version } return unless exact_match_index @@ -68,12 +38,10 @@ To install the missing version, run `gem install bundler:#{vr.first}` private_class_method :bundle_update_bundler_version def self.lockfile_version - return unless lockfile = lockfile_contents - lockfile, contents = lockfile - lockfile ||= "lockfile" + return unless contents = lockfile_contents regexp = /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ return unless contents =~ regexp - [$1, lockfile] + $1 end private_class_method :lockfile_version @@ -103,7 +71,7 @@ To install the missing version, run `gem install bundler:#{vr.first}` return unless File.file?(lockfile) - [lockfile, File.read(lockfile)] + File.read(lockfile) end private_class_method :lockfile_contents end diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb index 3721204ab2..3640362364 100644 --- a/lib/rubygems/dependency.rb +++ b/lib/rubygems/dependency.rb @@ -277,7 +277,7 @@ class Gem::Dependency requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version) end.map(&:to_spec) - Gem::BundlerVersionFinder.filter!(matches) if filters_bundler? + Gem::BundlerVersionFinder.prioritize!(matches) if prioritizes_bundler? if platform_only matches.reject! do |spec| @@ -295,7 +295,7 @@ class Gem::Dependency @requirement.specific? end - def filters_bundler? + def prioritizes_bundler? name == "bundler".freeze && !specific? end @@ -325,11 +325,11 @@ class Gem::Dependency active = matches.find {|spec| spec.activated? } return active if active - return matches.first if prerelease? - - # Move prereleases to the end of the list for >= 0 requirements - pre, matches = matches.partition {|spec| spec.version.prerelease? } - matches += pre if requirement == Gem::Requirement.default + unless prerelease? + # Move prereleases to the end of the list for >= 0 requirements + pre, matches = matches.partition {|spec| spec.version.prerelease? } + matches += pre if requirement == Gem::Requirement.default + end matches.first end diff --git a/lib/rubygems/errors.rb b/lib/rubygems/errors.rb index 86f0d1da14..f115ce23d0 100644 --- a/lib/rubygems/errors.rb +++ b/lib/rubygems/errors.rb @@ -59,9 +59,6 @@ module Gem private def build_message - if name == "bundler" && message = Gem::BundlerVersionFinder.missing_version_message - return message - end names = specs.map(&:full_name) "Could not find '#{name}' (#{requirement}) - did find: [#{names.join ','}]\n" end diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb index 2275997207..f21c175642 100644 --- a/lib/rubygems/security.rb +++ b/lib/rubygems/security.rb @@ -424,6 +424,8 @@ module Gem::Security # Gets the right public key from a PKey instance def self.get_public_key(key) + # Ruby 3.0 (Ruby/OpenSSL 2.2) or later + return OpenSSL::PKey.read(key.public_to_der) if key.respond_to?(:public_to_der) return key.public_key unless key.is_a?(OpenSSL::PKey::EC) ec_key = OpenSSL::PKey::EC.new(key.group.curve_name) @@ -490,9 +492,13 @@ module Gem::Security when 'rsa' OpenSSL::PKey::RSA.new(RSA_DSA_KEY_LENGTH) when 'ec' - domain_key = OpenSSL::PKey::EC.new(EC_NAME) - domain_key.generate_key - domain_key + if RUBY_VERSION >= "2.4.0" + OpenSSL::PKey::EC.generate(EC_NAME) + else + domain_key = OpenSSL::PKey::EC.new(EC_NAME) + domain_key.generate_key + domain_key + end else raise Gem::Security::Exception, "#{algorithm} algorithm not found. RSA, DSA, and EC algorithms are supported." @@ -527,7 +533,7 @@ module Gem::Security raise Gem::Security::Exception, "incorrect signing key for re-signing " + "#{expired_certificate.subject}" unless - expired_certificate.public_key.to_pem == get_public_key(private_key).to_pem + expired_certificate.check_private_key(private_key) unless expired_certificate.subject.to_s == expired_certificate.issuer.to_s diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb index 3c3cb647ee..06eae073f4 100644 --- a/lib/rubygems/security/policy.rb +++ b/lib/rubygems/security/policy.rb @@ -115,11 +115,9 @@ class Gem::Security::Policy raise Gem::Security::Exception, 'missing key or signature' end - public_key = Gem::Security.get_public_key(key) - raise Gem::Security::Exception, "certificate #{signer.subject} does not match the signing key" unless - signer.public_key.to_pem == public_key.to_pem + signer.check_private_key(key) true end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index dc5e5ba013..f162eb4a84 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -995,7 +995,6 @@ class Gem::Specification < Gem::BasicSpecification def self.find_by_path(path) path = path.dup.freeze spec = @@spec_with_requirable_file[path] ||= (stubs.find do |s| - next unless Gem::BundlerVersionFinder.compatible?(s) s.contains_requirable_file? path end || NOT_FOUND) spec.to_spec @@ -1008,7 +1007,6 @@ class Gem::Specification < Gem::BasicSpecification def self.find_inactive_by_path(path) stub = stubs.find do |s| next if s.activated? - next unless Gem::BundlerVersionFinder.compatible?(s) s.contains_requirable_file? path end stub && stub.to_spec diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb index faefda25f4..337d5f021c 100644 --- a/spec/bundler/install/gems/standalone_spec.rb +++ b/spec/bundler/install/gems/standalone_spec.rb @@ -116,7 +116,7 @@ RSpec.shared_examples "bundle install --standalone" do realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0" necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"] - necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a") + necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.a") realworld_system_gems(*necessary_system_gems, :path => scoped_gem_path(bundled_app("bundle"))) build_gem "foo", "1.0.0", :to_system => true, :default => true do |s| diff --git a/spec/bundler/realworld/mirror_probe_spec.rb b/spec/bundler/realworld/mirror_probe_spec.rb index b5aaf676e9..241424d4d6 100644 --- a/spec/bundler/realworld/mirror_probe_spec.rb +++ b/spec/bundler/realworld/mirror_probe_spec.rb @@ -74,25 +74,12 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld = bundle :install, :artifice => nil, :raise_on_error => false expect(out).to include("Fetching source index from #{mirror}") - expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") - expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") - expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") - expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") - end - it "prints each error and warning on a new line" do - gemfile <<-G - source "#{original}" - gem 'weakling' - G - - bundle :install, :artifice => nil, :raise_on_error => false - - expect(out).to include "Fetching source index from #{mirror}/" - expect(err).to include "Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)" - expect(err).to include "Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)" - expect(err).to include "Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)" - expect(err).to include "Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)" + err_lines = err.split("\n") + expect(err_lines).to include(%r{\ARetrying fetcher due to error \(2/4\): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <}) + expect(err_lines).to include(%r{\ARetrying fetcher due to error \(3/4\): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <}) + expect(err_lines).to include(%r{\ARetrying fetcher due to error \(4/4\): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <}) + expect(err_lines).to include(%r{\ACould not fetch specs from #{mirror}/ due to underlying error <}) end end @@ -110,10 +97,12 @@ RSpec.describe "fetching dependencies with a not available mirror", :realworld = bundle :install, :artifice => nil, :raise_on_error => false expect(out).to include("Fetching source index from #{mirror}") - expect(err).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") - expect(err).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") - expect(err).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") - expect(err).to include("Could not fetch specs from #{mirror}/ due to underlying error <Errno::ECONNREFUSED: Failed to open TCP connection to #{host}:#{@mirror_port} (Connection refused - connect(2)") + + err_lines = err.split("\n") + expect(err_lines).to include(%r{\ARetrying fetcher due to error \(2/4\): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <}) + expect(err_lines).to include(%r{\ARetrying fetcher due to error \(3/4\): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <}) + expect(err_lines).to include(%r{\ARetrying fetcher due to error \(4/4\): Bundler::HTTPError Could not fetch specs from #{mirror}/ due to underlying error <}) + expect(err_lines).to include(%r{\ACould not fetch specs from #{mirror}/ due to underlying error <}) end end diff --git a/spec/bundler/runtime/gem_tasks_spec.rb b/spec/bundler/runtime/gem_tasks_spec.rb index b0ef0cc144..b89fdf2cb1 100644 --- a/spec/bundler/runtime/gem_tasks_spec.rb +++ b/spec/bundler/runtime/gem_tasks_spec.rb @@ -27,7 +27,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do end it "includes the relevant tasks" do - with_gem_path_as(base_system_gems.to_s) do + with_gem_path_as(base_system_gem_path.to_s) do sys_exec "#{rake} -T", :env => { "GEM_HOME" => system_gem_path.to_s } end @@ -44,7 +44,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do end it "defines a working `rake install` task", :ruby_repo do - with_gem_path_as(base_system_gems.to_s) do + with_gem_path_as(base_system_gem_path.to_s) do sys_exec "#{rake} install", :env => { "GEM_HOME" => system_gem_path.to_s } end @@ -98,7 +98,7 @@ RSpec.describe "require 'bundler/gem_tasks'" do end it "adds 'pkg' to rake/clean's CLOBBER" do - with_gem_path_as(base_system_gems.to_s) do + with_gem_path_as(base_system_gem_path.to_s) do sys_exec %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect'), :env => { "GEM_HOME" => system_gem_path.to_s } end expect(out).to eq '["pkg"]' diff --git a/spec/bundler/support/artifice/compact_index.rb b/spec/bundler/support/artifice/compact_index.rb index 1b314e89ef..fb068fa9b5 100644 --- a/spec/bundler/support/artifice/compact_index.rb +++ b/spec/bundler/support/artifice/compact_index.rb @@ -2,7 +2,7 @@ require_relative "endpoint" -$LOAD_PATH.unshift Dir[Spec::Path.base_system_gems.join("gems/compact_index*/lib")].first.to_s +$LOAD_PATH.unshift Dir[Spec::Path.base_system_gem_path.join("gems/compact_index*/lib")].first.to_s require "compact_index" class CompactIndexAPI < Endpoint diff --git a/spec/bundler/support/artifice/endpoint.rb b/spec/bundler/support/artifice/endpoint.rb index 4a820e5a3f..c00113b28f 100644 --- a/spec/bundler/support/artifice/endpoint.rb +++ b/spec/bundler/support/artifice/endpoint.rb @@ -2,7 +2,7 @@ require_relative "../path" -$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s)) +$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s)) require "artifice" require "sinatra/base" diff --git a/spec/bundler/support/artifice/endpoint_500.rb b/spec/bundler/support/artifice/endpoint_500.rb index 0ce8dfeaad..a0d850a44d 100644 --- a/spec/bundler/support/artifice/endpoint_500.rb +++ b/spec/bundler/support/artifice/endpoint_500.rb @@ -2,7 +2,7 @@ require_relative "../path" -$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s)) +$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s)) require "artifice" require "sinatra/base" diff --git a/spec/bundler/support/artifice/windows.rb b/spec/bundler/support/artifice/windows.rb index ddbbd62b96..674470688d 100644 --- a/spec/bundler/support/artifice/windows.rb +++ b/spec/bundler/support/artifice/windows.rb @@ -2,7 +2,7 @@ require_relative "../path" -$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gems.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s)) +$LOAD_PATH.unshift(*Dir[Spec::Path.base_system_gem_path.join("gems/{artifice,mustermann,rack,tilt,sinatra,ruby2_keywords}-*/lib")].map(&:to_s)) require "artifice" require "sinatra/base" diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb index 90e9cbb242..aca31638ac 100644 --- a/spec/bundler/support/builders.rb +++ b/spec/bundler/support/builders.rb @@ -259,7 +259,7 @@ module Spec @_build_path = "#{path}/gems" @_build_repo = File.basename(path) yield - with_gem_path_as Path.base_system_gems do + with_gem_path_as Path.base_system_gem_path do gem_command :generate_index, :dir => path end ensure diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb index 5238c8b980..99baec24d4 100644 --- a/spec/bundler/support/helpers.rb +++ b/spec/bundler/support/helpers.rb @@ -545,7 +545,7 @@ module Spec def require_rack # need to hack, so we can require rack old_gem_home = ENV["GEM_HOME"] - ENV["GEM_HOME"] = Spec::Path.base_system_gems.to_s + ENV["GEM_HOME"] = Spec::Path.base_system_gem_path.to_s require "rack" ENV["GEM_HOME"] = old_gem_home end diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb index a73b3e699e..3304c69c78 100644 --- a/spec/bundler/support/path.rb +++ b/spec/bundler/support/path.rb @@ -146,6 +146,10 @@ module Spec bundled_app("Gemfile.lock") end + def base_system_gem_path + scoped_gem_path(base_system_gems) + end + def base_system_gems tmp.join("gems/base") end diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb index 9389543a0f..62ba4d56c4 100644 --- a/spec/bundler/support/rubygems_ext.rb +++ b/spec/bundler/support/rubygems_ext.rb @@ -59,15 +59,13 @@ module Spec Gem.clear_paths ENV["BUNDLE_PATH"] = nil - ENV["GEM_HOME"] = ENV["GEM_PATH"] = Path.base_system_gems.to_s + ENV["GEM_HOME"] = ENV["GEM_PATH"] = Path.base_system_gem_path.to_s ENV["PATH"] = [Path.system_gem_path.join("bin"), ENV["PATH"]].join(File::PATH_SEPARATOR) ENV["PATH"] = [Path.bindir, ENV["PATH"]].join(File::PATH_SEPARATOR) if Path.ruby_core? end def install_test_deps - setup_test_paths - - install_gems(test_gemfile) + install_gems(test_gemfile, Path.base_system_gems.to_s) install_gems(rubocop_gemfile, Path.rubocop_gems.to_s) install_gems(standard_gemfile, Path.standard_gems.to_s) end @@ -109,7 +107,9 @@ module Spec def install_gems(gemfile, path = nil) old_gemfile = ENV["BUNDLE_GEMFILE"] + old_orig_gemfile = ENV["BUNDLER_ORIG_BUNDLE_GEMFILE"] ENV["BUNDLE_GEMFILE"] = gemfile.to_s + ENV["BUNDLER_ORIG_BUNDLE_GEMFILE"] = nil if path old_path = ENV["BUNDLE_PATH"] @@ -128,6 +128,7 @@ module Spec ENV["BUNDLE_PATH__SYSTEM"] = old_path__system end + ENV["BUNDLER_ORIG_BUNDLE_GEMFILE"] = old_orig_gemfile ENV["BUNDLE_GEMFILE"] = old_gemfile end diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index f0f36b5561..970b3b70dd 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -354,41 +354,6 @@ class TestGem < Gem::TestCase assert status.success?, output end - def test_activate_bin_path_gives_proper_error_for_bundler - bundler = util_spec 'bundler', '2' do |s| - s.executables = ['bundle'] - end - - install_specs bundler - - File.open("Gemfile.lock", "w") do |f| - f.write <<-L.gsub(/ {8}/, "") - GEM - remote: https://rubygems.org/ - specs: - - PLATFORMS - ruby - - DEPENDENCIES - - BUNDLED WITH - 9999 - L - end - - File.open("Gemfile", "w") {|f| f.puts('source "https://rubygems.org"') } - - e = assert_raise Gem::GemNotFoundException do - load Gem.activate_bin_path("bundler", "bundle", ">= 0.a") - end - - assert_includes e.message, "Could not find 'bundler' (9999) required by your #{File.expand_path("Gemfile.lock")}." - assert_includes e.message, "To update to the latest version installed on your system, run `bundle update --bundler`." - assert_includes e.message, "To install the missing version, run `gem install bundler:9999`" - refute_includes e.message, "can't find gem bundler (>= 0.a) with executable bundle" - end - def test_activate_bin_path_selects_exact_bundler_version_if_present bundler_latest = util_spec 'bundler', '2.0.1' do |s| s.executables = ['bundle'] diff --git a/test/rubygems/test_gem_bundler_version_finder.rb b/test/rubygems/test_gem_bundler_version_finder.rb index e971e6ae29..7494a94d6e 100644 --- a/test/rubygems/test_gem_bundler_version_finder.rb +++ b/test/rubygems/test_gem_bundler_version_finder.rb @@ -48,30 +48,31 @@ class TestGemBundlerVersionFinder < Gem::TestCase end def test_bundler_version_with_lockfile - bvf.stub(:lockfile_contents, [nil, ""]) do + bvf.stub(:lockfile_contents, "") do assert_nil bvf.bundler_version end - bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do + bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n 1.1.1.1\n") do assert_equal v("1.1.1.1"), bvf.bundler_version end - bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n fjdkslfjdkslfjsldk\n"]) do + bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n fjdkslfjdkslfjsldk\n") do assert_nil bvf.bundler_version end end - def test_bundler_version_with_reason - assert_nil bvf.bundler_version_with_reason - bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do - assert_equal ["1.1.1.1", "your lockfile"], bvf.bundler_version_with_reason + def test_bundler_version + assert_nil bvf.bundler_version + bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n 1.1.1.1\n") do + assert_equal "1.1.1.1", bvf.bundler_version.to_s $0 = "bundle" ARGV.replace %w[update --bundler] - assert_nil bvf.bundler_version_with_reason + assert_nil bvf.bundler_version + ARGV.replace %w[update --bundler=1.1.1.2] - assert_equal ["1.1.1.2", "`bundle update --bundler`"], bvf.bundler_version_with_reason + assert_equal "1.1.1.2", bvf.bundler_version.to_s ENV["BUNDLER_VERSION"] = "1.1.1.3" - assert_equal ["1.1.1.3", "`$BUNDLER_VERSION`"], bvf.bundler_version_with_reason + assert_equal "1.1.1.3", bvf.bundler_version.to_s end end @@ -90,57 +91,35 @@ class TestGemBundlerVersionFinder < Gem::TestCase Dir.chdir(orig_dir) end - assert_nil bvf.bundler_version_with_reason - end - - def test_compatible - assert bvf.compatible?(util_spec("foo")) - assert bvf.compatible?(util_spec("bundler", 1.1)) - - bvf.stub(:bundler_version, v("1.1.1.1")) do - assert bvf.compatible?(util_spec("foo")) - assert bvf.compatible?(util_spec("bundler", "1.1.1.1")) - assert bvf.compatible?(util_spec("bundler", "1.1.1.a")) - assert bvf.compatible?(util_spec("bundler", "1.999")) - refute bvf.compatible?(util_spec("bundler", "2.999")) - end - - bvf.stub(:bundler_version, v("2.1.1.1")) do - assert bvf.compatible?(util_spec("foo")) - assert bvf.compatible?(util_spec("bundler", "2.1.1.1")) - assert bvf.compatible?(util_spec("bundler", "2.1.1.a")) - assert bvf.compatible?(util_spec("bundler", "2.999")) - refute bvf.compatible?(util_spec("bundler", "1.999")) - refute bvf.compatible?(util_spec("bundler", "3.0.0")) - end + assert_nil bvf.bundler_version end - def test_filter + def test_prioritize versions = %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1] specs = versions.map {|v| util_spec("bundler", v) } - assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) bvf.stub(:bundler_version, v("2.1.1.1")) do - assert_equal %w[2 2.a 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("1.1.1.1")) do - assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("1")) do - assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("2.a")) do - assert_equal %w[2.a 2 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[2.a 1 1.0 1.0.1.1 2 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("3")) do - assert_equal %w[3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[3 1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3.a 3.0 3.1.1], util_prioritize_specs(specs) end end - def util_filter_specs(specs) + def util_prioritize_specs(specs) specs = specs.dup - bvf.filter!(specs) - specs + bvf.prioritize!(specs) + specs.map(&:version).map(&:to_s) end end diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb index 1ca0fc378c..5551966da2 100644 --- a/test/rubygems/test_gem_dependency.rb +++ b/test/rubygems/test_gem_dependency.rb @@ -358,16 +358,12 @@ class TestGemDependency < Gem::TestCase assert_equal [b, b_1], dep.to_specs - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["3.5", "reason"]) do - e = assert_raise Gem::MissingSpecVersionError do - dep.to_specs - end - - assert_match "Could not find 'bundler' (3.5) required by reason.\nTo update to the latest version installed on your system, run `bundle update --bundler`.\nTo install the missing version, run `gem install bundler:3.5`\n", e.message + Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do + assert_equal [b_1, b], dep.to_specs end - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["2.0.0.pre.1", "reason"]) do - assert_equal [b], dep.to_specs + Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("2.0.0.pre.1")) do + assert_equal [b, b_1], dep.to_specs end end diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb index dee36d05ee..4efa7e075d 100644 --- a/test/rubygems/test_kernel.rb +++ b/test/rubygems/test_kernel.rb @@ -117,20 +117,8 @@ class TestKernel < Gem::TestCase assert $:.any? {|p| %r{bundler-1/lib} =~ p } end - def test_gem_bundler_missing_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do - quick_gem 'bundler', '1' - quick_gem 'bundler', '2.a' - - e = assert_raise Gem::MissingSpecVersionError do - gem('bundler') - end - assert_match "Could not find 'bundler' (55) required by reason.", e.message - end - end - def test_gem_bundler_inferred_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do + Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do quick_gem 'bundler', '1' quick_gem 'bundler', '2.a' diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index 80c95b26a3..5b826d052b 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -596,31 +596,6 @@ class TestGemRequire < Gem::TestCase assert_empty unresolved_names end - def test_require_bundler_missing_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do - b1 = util_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb") - b2a = util_spec('bundler', '2.a', nil, "lib/bundler/setup.rb") - install_specs b1, b2a - - e = assert_raise Gem::MissingSpecVersionError do - gem('bundler') - end - assert_match "Could not find 'bundler' (55) required by reason.", e.message - end - end - - def test_require_bundler_with_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do - b1 = util_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb") - b2 = util_spec('bundler', '2', nil, "lib/bundler/setup.rb") - install_specs b1, b2 - - $:.clear - assert_require 'bundler/setup' - assert_equal %w[bundler-1.999999999], loaded_spec_names - end - end - # uplevel is 2.5+ only if RUBY_VERSION >= "2.5" ["", "Kernel."].each do |prefix| diff --git a/tool/bundler/rubocop_gems.rb.lock b/tool/bundler/rubocop_gems.rb.lock index 4c33191c9e..56f6b9873d 100644 --- a/tool/bundler/rubocop_gems.rb.lock +++ b/tool/bundler/rubocop_gems.rb.lock @@ -60,4 +60,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.0 + 2.3.1 diff --git a/tool/bundler/standard_gems.rb.lock b/tool/bundler/standard_gems.rb.lock index b29129ed57..f0c009898d 100644 --- a/tool/bundler/standard_gems.rb.lock +++ b/tool/bundler/standard_gems.rb.lock @@ -66,4 +66,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.0 + 2.3.1 diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock index d53195b0c9..98cc8eab22 100644 --- a/tool/bundler/test_gems.rb.lock +++ b/tool/bundler/test_gems.rb.lock @@ -41,4 +41,4 @@ DEPENDENCIES webrick (= 1.7.0) BUNDLED WITH - 2.3.0 + 2.3.1 |