diff options
author | Hiroshi SHIBATA <[email protected]> | 2022-12-12 09:09:23 +0900 |
---|---|---|
committer | Hiroshi SHIBATA <[email protected]> | 2022-12-12 10:49:43 +0900 |
commit | bbe56a643734025aef6a3cbeb07c5306505040f6 () | |
tree | c6980a39ce6571c032695702bd974431eee4d516 /lib | |
parent | f1cdc129d4d6440168b840fa852fa6c3e28d46a9 (diff) |
Merge RubyGems/Bundler master
from https://.com/rubygems/rubygems/commit/bfb0ae69776069155d2092702bfbb5a12617d85a
Notes: Merged: https://.com/ruby/ruby/pull/6906
30 files changed, 106 insertions, 330 deletions
@@ -29,8 +29,8 @@ Gem::Specification.new do |s| "source_code_uri" => "https://.com/rubygems/rubygems/tree/master/bundler", } - s.required_ruby_version = ">= 2.3.0" - s.required_rubygems_version = ">= 2.5.2" s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) } @@ -40,7 +40,7 @@ module Bundler raise InvalidOption, "Please specify gems to add." if gems.empty? version.to_a.each do |v| - raise InvalidOption, "Invalid gem requirement pattern '#{v}'" unless Gem::Requirement::PATTERN =~ v.to_s end end end @@ -73,12 +73,10 @@ module Bundler definition.specs.each do |spec| bundles_for_gem(spec).each do |bundle| bad_paths = dylibs(bundle).select do |f| - begin - Fiddle.dlopen(f) - false - rescue Fiddle::DLError - true - end end if bad_paths.any? broken_links[spec] ||= [] @@ -270,7 +270,7 @@ module Bundler Bundler.ui.info hint_text("test") result = Bundler.ui.ask "Enter a test framework. rspec/minitest/test-unit/(none):" - if result =~ /rspec|minitest|test-unit/ test_framework = result else test_framework = false @@ -311,7 +311,7 @@ module Bundler Bundler.ui.info hint_text("ci") result = Bundler.ui.ask "Enter a CI service. /travis/gitlab/circle/(none):" - if result =~ /|travis|gitlab|circle/ ci_template = result else ci_template = false @@ -342,7 +342,7 @@ module Bundler Bundler.ui.info hint_text("linter") result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):" - if result =~ /rubocop|standard/ linter_template = result else linter_template = false @@ -389,7 +389,7 @@ module Bundler end def ensure_safe_gem_name(name, constant_array) - if name =~ /^\d/ Bundler.ui.error "Invalid gem name #{name} Please give a name which does not start with numbers." exit 1 end @@ -416,28 +416,15 @@ module Bundler end def required_ruby_version - if Gem.ruby_version < Gem::Version.new("2.4.a") then "2.3.0" - elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "2.4.0" - elsif Gem.ruby_version < Gem::Version.new("2.6.a") then "2.5.0" - else - "2.6.0" - end end def rubocop_version - if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.81.0" - elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.12" - else - "1.21" - end end def standard_version - if Gem.ruby_version < Gem::Version.new("2.4.a") then "0.2.5" - elsif Gem.ruby_version < Gem::Version.new("2.5.a") then "1.0" - else - "1.3" - end end end end @@ -68,7 +68,7 @@ module Bundler def info_path(name) name = name.to_s - if name =~ /[^a-z0-9_-]/ name += "-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}" info_roots.last.join(name) else @@ -20,63 +20,64 @@ module Bundler def initialize(fetcher) @fetcher = fetcher - require_relative "../vendored_tmpdir" end def update(local_path, remote_path, retrying = nil) headers = {} - Bundler::Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir| - local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename) - - # first try to fetch any new bytes on the existing file - if retrying.nil? && local_path.file? - copy_file local_path, local_temp_path - - headers["If-None-Match"] = etag_for(local_temp_path) - headers["Range"] = - if local_temp_path.size.nonzero? - # Subtract a byte to ensure the range won't be empty. - # Avoids 416 (Range Not Satisfiable) responses. - "bytes=#{local_temp_path.size - 1}-" - else - "bytes=#{local_temp_path.size}-" - end - end - response = @fetcher.call(remote_path, headers) - return nil if response.is_a?(Net::HTTPNotModified) - content = response.body - etag = (response["ETag"] || "").gsub(%r{\AW/}, "") - correct_response = SharedHelpers.filesystem_access(local_temp_path) do - if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero? - local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) } - etag_for(local_temp_path) == etag - else - local_temp_path.open("wb") {|f| f << content } - etag.length.zero? || etag_for(local_temp_path) == etag - end - end - if correct_response - SharedHelpers.filesystem_access(local_path) do - FileUtils.mv(local_temp_path, local_path) - end - return nil end - if retrying - raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path)) end - update(local_path, remote_path, :retrying) end rescue Zlib::GzipFile::Error raise Bundler::HTTPError end def etag_for(path) @@ -295,7 +295,7 @@ module Bundler # Convert to \r\n if the existing lock has them # i.e., Windows with `git config core.autocrlf=true` - contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n") if @locked_bundler_version locked_major = @locked_bundler_version.segments.first @@ -324,7 +324,7 @@ module Bundler if name.is_a?(Symbol) raise GemfileError, %(You need to specify gem names as Strings. Use 'gem "#{name}"' instead) end - if name =~ /\s/ raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace) end raise GemfileError, %(an empty gem name is not valid) if name.empty? @@ -12,17 +12,15 @@ module Bundler method = instance_method(method_name) undef_method(method_name) define_method(method_name) do |*args, &blk| - begin - method.bind(self).call(*args, &blk) - rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e - raise HTTPError, e.message - rescue AuthenticationRequiredError - # Fail since we got a 401 from the server. - raise - rescue HTTPError => e - Bundler.ui.trace(e) - nil - end end end @@ -80,7 +80,7 @@ module Bundler private def validate_uri_scheme!(uri) - return if uri.scheme =~ /\Ahttps?\z/ raise InvalidOption, "The request uri `#{uri}` has an invalid scheme (`#{uri.scheme}`). " \ "Did you mean `http` or `https`?" @@ -37,7 +37,7 @@ module Bundler when Thor::Error Bundler.ui.error error.message when LoadError - raise error unless error.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/ Bundler.ui.error "\nCould not load OpenSSL. #{error.class}: #{error}\n#{error.backtrace.join("\n ")}" when Interrupt Bundler.ui.error "\nQuitting..." @@ -235,7 +235,7 @@ module Bundler gemfile.each_with_index do |line, index| next unless !line.nil? && line.strip.start_with?(block_name) - if gemfile[index + 1] =~ /^\s*end\s*$/ gemfile[index] = nil gemfile[index + 1] = nil end @@ -136,11 +136,7 @@ module Bundler mode = Gem.win_platform? ? "wb:UTF-8" : "w" require "erb" - content = if RUBY_VERSION >= "2.6" - ERB.new(template, :trim_mode => "-").result(binding) - else - ERB.new(template, nil, "-").result(binding) - end File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask) if Gem.win_platform? || options[:all_platforms] @@ -183,11 +179,7 @@ module Bundler mode = Gem.win_platform? ? "wb:UTF-8" : "w" require "erb" - content = if RUBY_VERSION >= "2.6" - ERB.new(template, :trim_mode => "-").result(binding) - else - ERB.new(template, nil, "-").result(binding) - end File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755) if Gem.win_platform? || options[:all_platforms] @@ -226,12 +218,10 @@ module Bundler requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) } path_plugin_files = requested_path_gems.map do |spec| - begin - Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}") - rescue TypeError - error_message = "#{spec.name} #{spec.version} has an invalid gemspec" - raise Gem::InvalidSpecificationException, error_message - end end.flatten Bundler.rubygems.load_plugin_files(path_plugin_files) Bundler.rubygems.load_env_plugins @@ -63,7 +63,7 @@ module Bundler @state = nil @specs = {} - if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/) raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \ "Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock." end @@ -80,7 +80,7 @@ module Bundler @state = :ruby elsif line == BUNDLED @state = :bundled_with - elsif line =~ /^[^\s]/ @state = nil elsif @state send("parse_#{@state}", line) @@ -148,13 +148,11 @@ module Bundler class TCPSocketProbe def replies?(mirror) MirrorSockets.new(mirror).any? do |socket, address, timeout| - begin - socket.connect_nonblock(address) - rescue Errno::EINPROGRESS - wait_for_writtable_socket(socket, address, timeout) - rescue RuntimeError # Connection failed somehow, again - false - end end end @@ -338,11 +338,7 @@ module Gem end def glob_files_in_dir(glob, base_path) - if RUBY_VERSION >= "2.5" - Dir.glob(glob, :base => base_path).map! {|f| File.expand_path(f, base_path) } - else - Dir.glob(File.join(base_path.to_s.gsub(/[\[\]]/, '\\\\\\&'), glob)).map! {|f| File.expand_path(f) } - end end end end @@ -64,7 +64,7 @@ module Bundler at = if local? path elsif user_ref = options["ref"] - if ref =~ /\A[a-z0-9]{4,}\z/i shortref_for_display(user_ref) else user_ref @@ -295,7 +295,7 @@ module Bundler end def uri_hash - if uri =~ %r{^\w+://(\w+@)?} # Downcase the domain component of the URI # and strip off a trailing slash, if one is present input = Bundler::URI.parse(uri).normalize.to_s.sub(%r{/$}, "") @@ -250,7 +250,7 @@ module Bundler # Adds credentials to the URI def configured_uri - if /https?:/ =~ uri remote = Bundler::URI(uri) config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host] remote.userinfo ||= config_auth @@ -224,13 +224,13 @@ module Bundler # Some gem authors put absolute paths in their gemspec # and we have to save them from themselves - spec.files = spec.files.map do |p| - next p unless p =~ /\A#{Pathname::SEPARATOR_PAT}/ - next if File.directory?(p) begin - Pathname.new(p).relative_path_from(gem_dir).to_s rescue ArgumentError - p end end.compact @@ -145,7 +145,7 @@ module Bundler end if installed?(spec) && !force - print_using_message "Using #{version_message(spec)}" return nil # no post-install message end @@ -163,8 +163,6 @@ module Bundler install_path = rubygems_dir bin_path = Bundler.system_bindir - Bundler.mkdir_p bin_path unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5") - require_relative "../rubygems_gem_installer" installer = Bundler::RubyGemsGemInstaller.at( @@ -340,7 +338,7 @@ module Bundler def normalize_uri(uri) uri = uri.to_s - uri = "#{uri}/" unless uri =~ %r{/$} require_relative "../vendored_uri" uri = Bundler::URI(uri) raise ArgumentError, "The source must be an absolute URI. For example:\n" \ @@ -383,7 +381,7 @@ module Bundler idx = @allow_local ? installed_specs.dup : Index.new Dir["#{cache_path}/*.gem"].each do |gemfile| - next if gemfile =~ /^bundler\-[\d\.]+?\.gem/ s ||= Bundler.rubygems.spec_from_gem(gemfile) s.source = self idx << s @@ -206,7 +206,7 @@ module Bundler def warn_on_git_protocol(source) return if Bundler.settings["git.allow_insecure"] - if source.uri =~ /^git\:/ Bundler.ui.warn "The git source `#{source.uri}` uses the `git` protocol, " \ "which transmits data without encryption. Disable this warning with " \ "`bundle config set --local git.allow_insecure true`, or switch to the `https` " \ @@ -72,13 +72,7 @@ m = Module.new do bundler_gem_version = Gem::Version.new(version) - requirement = bundler_gem_version.approximate_recommendation - - return requirement unless Gem.rubygems_version < Gem::Version.new("2.7.0") - - requirement += ".a" if bundler_gem_version.prerelease? - - requirement end def load_bundler! @@ -1,154 +0,0 @@ -# frozen_string_literal: true -# -# tmpdir - retrieve temporary directory path -# -# $Id$ -# - -require_relative '../../fileutils/lib/fileutils' -begin - require 'etc.so' -rescue LoadError # rescue LoadError for miniruby -end - -class Bundler::Dir < Dir - - @systmpdir ||= defined?(Etc.systmpdir) ? Etc.systmpdir : '/tmp' - - ## - # Returns the operating system's temporary file path. - - def self.tmpdir - tmp = nil - ['TMPDIR', 'TMP', 'TEMP', ['system temporary path', @systmpdir], ['/tmp']*2, ['.']*2].each do |name, dir = ENV[name]| - next if !dir - dir = File.expand_path(dir) - stat = File.stat(dir) rescue next - case - when !stat.directory? - warn "#{name} is not a directory: #{dir}" - when !stat.writable? - warn "#{name} is not writable: #{dir}" - when stat.world_writable? && !stat.sticky? - warn "#{name} is world-writable: #{dir}" - else - tmp = dir - break - end - end - raise ArgumentError, "could not find a temporary directory" unless tmp - tmp - end - - # Bundler::Dir.mktmpdir creates a temporary directory. - # - # The directory is created with 0700 permission. - # Application should not change the permission to make the temporary directory accessible from other users. - # - # The prefix and suffix of the name of the directory is specified by - # the optional first argument, <i>prefix_suffix</i>. - # - If it is not specified or nil, "d" is used as the prefix and no suffix is used. - # - If it is a string, it is used as the prefix and no suffix is used. - # - If it is an array, first element is used as the prefix and second element is used as a suffix. - # - # Bundler::Dir.mktmpdir {|dir| dir is ".../d..." } - # Bundler::Dir.mktmpdir("foo") {|dir| dir is ".../foo..." } - # Bundler::Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" } - # - # The directory is created under Bundler::Dir.tmpdir or - # the optional second argument <i>tmpdir</i> if non-nil value is given. - # - # Bundler::Dir.mktmpdir {|dir| dir is "#{Bundler::Dir.tmpdir}/d..." } - # Bundler::Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." } - # - # If a block is given, - # it is yielded with the path of the directory. - # The directory and its contents are removed - # using Bundler::FileUtils.remove_entry before Bundler::Dir.mktmpdir returns. - # The value of the block is returned. - # - # Bundler::Dir.mktmpdir {|dir| - # # use the directory... - # open("#{dir}/foo", "w") { ... } - # } - # - # If a block is not given, - # The path of the directory is returned. - # In this case, Bundler::Dir.mktmpdir doesn't remove the directory. - # - # dir = Bundler::Dir.mktmpdir - # begin - # # use the directory... - # open("#{dir}/foo", "w") { ... } - # ensure - # # remove the directory. - # Bundler::FileUtils.remove_entry dir - # end - # - def self.mktmpdir(prefix_suffix=nil, *rest, **options) - base = nil - path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|p, _, _, d| - base = d - mkdir(p, 0700) - } - if block_given? - begin - yield path.dup - ensure - unless base - stat = File.stat(File.dirname(path)) - if stat.world_writable? and !stat.sticky? - raise ArgumentError, "parent directory is world writable but not sticky" - end - end - Bundler::FileUtils.remove_entry path - end - else - path - end - end - - module Tmpname # :nodoc: - module_function - - def tmpdir - Bundler::Dir.tmpdir - end - - UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~" - - class << (RANDOM = Random.new) - MAX = 36**6 # < 0x100000000 - def next - rand(MAX).to_s(36) - end - end - private_constant :RANDOM - - def create(basename, tmpdir=nil, max_try: nil, **opts) - origdir = tmpdir - tmpdir ||= tmpdir() - n = nil - prefix, suffix = basename - prefix = (String.try_convert(prefix) or - raise ArgumentError, "unexpected prefix: #{prefix.inspect}") - prefix = prefix.delete(UNUSABLE_CHARS) - suffix &&= (String.try_convert(suffix) or - raise ArgumentError, "unexpected suffix: #{suffix.inspect}") - suffix &&= suffix.delete(UNUSABLE_CHARS) - begin - t = Time.now.strftime("%Y%m%d") - path = "#{prefix}#{t}-#{$$}-#{RANDOM.next}"\ - "#{n ? %[-#{n}] : ''}#{suffix||''}" - path = File.join(tmpdir, path) - yield(path, n, opts, origdir) - rescue Errno::EEXIST - n ||= 0 - n += 1 - retry if !max_try or n < max_try - raise "cannot generate temporary name using `#{basename}' under `#{tmpdir}'" - end - path - end - end -end @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -module Bundler; end -require_relative "vendor/tmpdir/lib/tmpdir" @@ -87,14 +87,12 @@ module Bundler creation_errors = [] @threads = Array.new(@size) do |i| - begin - Thread.start { process_queue(i) }.tap do |thread| - thread.name = "#{name} Worker ##{i}" if thread.respond_to?(:name=) - end - rescue ThreadError => e - creation_errors << e - nil end end.compact add_interrupt_handler unless @threads.empty? @@ -107,7 +107,7 @@ class Gem::Commands::SetupCommand < Gem::Command end def check_ruby_version - required_version = Gem::Requirement.new ">= 2.3.0" unless required_version.satisfied_by? Gem.ruby_version alert_error "Expected Ruby version #{required_version}, is #{Gem.ruby_version}" @@ -329,14 +329,8 @@ command to remove old versions. Gem::Version.new("3.2.3") elsif Gem.ruby_version > Gem::Version.new("2.7.a") Gem::Version.new("3.1.2") - elsif Gem.ruby_version > Gem::Version.new("2.6.a") - Gem::Version.new("3.0.1") - elsif Gem.ruby_version > Gem::Version.new("2.5.a") - Gem::Version.new("2.7.3") - elsif Gem.ruby_version > Gem::Version.new("2.4.a") - Gem::Version.new("2.6.8") else - Gem::Version.new("2.5.2") end end end @@ -1,7 +1,6 @@ # frozen_string_literal: true -# `uplevel` keyword argument of Kernel#warn is available since ruby 2.5. -if RUBY_VERSION >= "2.5" && !Gem::KERNEL_WARN_IGNORES_INTERNAL_ENTRIES module Kernel rubygems_path = "#{__dir__}/" # Frames to be skipped start with this path. @@ -434,13 +434,6 @@ module Gem::Security end ## - # In Ruby 2.3 EC doesn't implement the private_key? but not the private? method - - if defined?(OpenSSL::PKey::EC) && Gem::Version.new(String.new(RUBY_VERSION)) < Gem::Version.new("2.4.0") - OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?) - end - - ## # Creates a self-signed certificate with an issuer and subject from +email+, # a subject alternative name of +email+ and the given +extensions+ for the # +key+. @@ -492,13 +485,7 @@ module Gem::Security when "rsa" OpenSSL::PKey::RSA.new(RSA_DSA_KEY_LENGTH) when "ec" - 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." @@ -97,11 +97,7 @@ module Gem::Util # returning absolute paths to the matching files. def self.glob_files_in_dir(glob, base_path) - if RUBY_VERSION >= "2.5" - Dir.glob(glob, base: base_path).map! {|f| File.expand_path(f, base_path) } - else - Dir.glob(File.expand_path(glob, base_path)) - end end ## |