diff options
author | Hiroshi SHIBATA <[email protected]> | 2019-12-13 20:19:08 +0900 |
---|---|---|
committer | Hiroshi SHIBATA <[email protected]> | 2019-12-13 20:19:33 +0900 |
commit | 82cc2843a92b286cc13afd0860a4e111d4ea2a0b () | |
tree | a517dedd40d35540930cea7732f5a36e76a549e8 /lib | |
parent | 26774351dc5f494253ba031e4bc453dc4dddb2cf (diff) |
Prepare to release RubyGems 3.1.0 final version.
-rw-r--r-- | lib/rubygems.rb | 18 | ||||
-rw-r--r-- | lib/rubygems/command.rb | 34 | ||||
-rw-r--r-- | lib/rubygems/commands/generate_index_command.rb | 3 | ||||
-rw-r--r-- | lib/rubygems/commands/setup_command.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/commands/sources_command.rb | 14 | ||||
-rw-r--r-- | lib/rubygems/core_ext/kernel_warn.rb | 16 | ||||
-rw-r--r-- | lib/rubygems/ext/builder.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/remote_fetcher.rb | 51 | ||||
-rw-r--r-- | lib/rubygems/request.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/source.rb | 8 | ||||
-rw-r--r-- | lib/rubygems/specification_policy.rb | 73 | ||||
-rw-r--r-- | lib/rubygems/uri_formatter.rb | 1 | ||||
-rw-r--r-- | lib/rubygems/uri_parser.rb | 36 | ||||
-rw-r--r-- | lib/rubygems/uri_parsing.rb | 23 |
14 files changed, 193 insertions, 90 deletions
@@ -160,24 +160,14 @@ module Gem ].freeze ## - # Exception classes used in a Gem.read_binary +rescue+ statement. Not all of - # these are defined in Ruby 1.8.7, hence the need for this convoluted setup. - READ_BINARY_ERRORS = begin - read_binary_errors = [Errno::EACCES, Errno::EROFS, Errno::ENOSYS] - read_binary_errors << Errno::ENOTSUP if Errno.const_defined?(:ENOTSUP) - read_binary_errors - end.freeze ## - # Exception classes used in Gem.write_binary +rescue+ statement. Not all of - # these are defined in Ruby 1.8.7. - WRITE_BINARY_ERRORS = begin - write_binary_errors = [Errno::ENOSYS] - write_binary_errors << Errno::ENOTSUP if Errno.const_defined?(:ENOTSUP) - write_binary_errors - end.freeze @@win_platform = nil @@ -369,22 +369,44 @@ class Gem::Command end end - def deprecate_option(short_name: nil, long_name: nil, version: nil) - @deprecated_options[command].merge!({ short_name => { "rg_version_to_expire" => version } }) if short_name - @deprecated_options[command].merge!({ long_name => { "rg_version_to_expire" => version } }) if long_name end def check_deprecated_options(options) options.each do |option| if option_is_deprecated?(option) - version_to_expire = @deprecated_options[command][option]["rg_version_to_expire"] deprecate_option_msg = if version_to_expire - "The \"#{option}\" option has been deprecated and will be removed in Rubygems #{version_to_expire}, its use is discouraged." else - "The \"#{option}\" option has been deprecated and will be removed in future versions of Rubygems, its use is discouraged." end alert_warning(deprecate_option_msg) end end @@ -25,6 +25,9 @@ class Gem::Commands::GenerateIndexCommand < Gem::Command options[:build_modern] = value end add_option '--update', 'Update modern indexes with gems added', 'since the last update' do |value, options| @@ -98,7 +98,7 @@ class Gem::Commands::SetupCommand < Gem::Command end def check_ruby_version - required_version = Gem::Requirement.new '>= 1.8.7' unless required_version.satisfied_by? Gem.ruby_version alert_error "Expected Ruby version #{required_version}, is #{Gem.ruby_version}" @@ -43,6 +43,8 @@ class Gem::Commands::SourcesCommand < Gem::Command source = Gem::Source.new source_uri begin if Gem.sources.include? source say "source #{source_uri} already present in the cache" @@ -62,6 +64,18 @@ class Gem::Commands::SourcesCommand < Gem::Command end end def check_rubygems_https(source_uri) # :nodoc: uri = URI source_uri @@ -6,13 +6,17 @@ if RUBY_VERSION >= "2.5" module Kernel path = "#{__dir__}/" # Frames to be skipped start with this path. - # Suppress "method redefined" warning - original_warn = instance_method(:warn) - Module.new {define_method(:warn, original_warn)} - original_warn = method(:warn) - module_function define_method(:warn) {|*messages, **kw| unless uplevel = kw[:uplevel] if Gem.java_platform? return original_warn.call(*messages) @@ -46,6 +50,6 @@ if RUBY_VERSION >= "2.5" kw[:uplevel] = uplevel original_warn.call(*messages, **kw) - } end end @@ -6,7 +6,6 @@ #++ require 'rubygems/user_interaction' -require "open3" class Gem::Ext::Builder @@ -68,6 +67,7 @@ class Gem::Ext::Builder results << "current directory: #{Dir.pwd}" results << (command.respond_to?(:shelljoin) ? command.shelljoin : command) output, status = Open3.capture2e(*command) if verbose puts output @@ -4,6 +4,7 @@ require 'rubygems/request' require 'rubygems/request/connection_pools' require 'rubygems/s3_uri_signer' require 'rubygems/uri_formatter' require 'rubygems/user_interaction' require 'resolv' require 'rubygems/deprecate' @@ -17,12 +18,16 @@ class Gem::RemoteFetcher include Gem::UserInteraction extend Gem::Deprecate ## # A FetchError exception wraps up the various possible IO and HTTP failures # that could happen while downloading from the internet. class FetchError < Gem::Exception ## # The URI which was being accessed when the exception happened. @@ -30,13 +35,12 @@ class Gem::RemoteFetcher def initialize(message, uri) super message - begin - uri = URI(uri) - uri.password = 'REDACTED' if uri.password - @uri = uri.to_s - rescue URI::InvalidURIError, ArgumentError - @uri = uri - end end def to_s # :nodoc: @@ -107,7 +111,7 @@ class Gem::RemoteFetcher spec, source = found.max_by { |(s,_)| s.version } - download spec, source.uri.to_s end ## @@ -130,18 +134,7 @@ class Gem::RemoteFetcher FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir - # Always escape URI's to deal with potential spaces and such - # It should also be considered that source_uri may already be - # a valid URI with escaped characters. e.g. "{DESede}" is encoded - # as "%7BDESede%7D". If this is escaped again the percentage - # symbols will be escaped. - unless source_uri.is_a?(URI::Generic) - begin - source_uri = URI.parse(source_uri) - rescue - source_uri = URI.parse(URI::DEFAULT_PARSER.escape(source_uri.to_s)) - end - end scheme = source_uri.scheme @@ -159,7 +152,7 @@ class Gem::RemoteFetcher remote_gem_path = source_uri + "gems/#{gem_file_name}" self.cache_update_path remote_gem_path, local_gem_path - rescue Gem::RemoteFetcher::FetchError raise if spec.original_platform == spec.platform alternate_name = "#{spec.original_name}.gem" @@ -236,7 +229,7 @@ class Gem::RemoteFetcher unless location = response['Location'] raise FetchError.new("redirecting but no redirect location was given", uri) end - location = URI.parse response['Location'] if https?(uri) && !https?(location) raise FetchError.new("redirecting to non-https resource: #{location}", uri) @@ -254,9 +247,7 @@ class Gem::RemoteFetcher # Downloads +uri+ and returns it as a String. def fetch_path(uri, mtime = nil, head = false) - uri = URI.parse uri unless URI::Generic === uri - - raise ArgumentError, "bad uri: #{uri}" unless uri unless uri.scheme raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}" @@ -268,21 +259,19 @@ class Gem::RemoteFetcher begin data = Gem::Util.gunzip data rescue Zlib::GzipFile::Error - raise FetchError.new("server did not return a valid file", uri.to_s) end end data - rescue FetchError - raise rescue Timeout::Error - raise UnknownHostError.new('timed out', uri.to_s) rescue IOError, SocketError, SystemCallError, *(OpenSSL::SSL::SSLError if defined?(OpenSSL)) => e if e.message =~ /getaddrinfo/ - raise UnknownHostError.new('no such name', uri.to_s) else - raise FetchError.new("#{e.class}: #{e}", uri.to_s) end end @@ -19,6 +19,7 @@ class Gem::Request end def self.proxy_uri(proxy) # :nodoc: case proxy when :no_proxy then nil when URI::HTTP then proxy @@ -173,6 +174,7 @@ class Gem::Request :no_proxy : get_proxy_from_env('http') end uri = URI(Gem::UriFormatter.new(env_proxy).normalize) if uri and uri.user.nil? and uri.password.nil? @@ -1,7 +1,7 @@ # frozen_string_literal: true autoload :FileUtils, 'fileutils' -autoload :URI, 'uri' ## # A Source knows how to list and fetch gems from a RubyGems marshal index. # @@ -11,6 +11,7 @@ autoload :URI, 'uri' class Gem::Source include Comparable FILES = { # :nodoc: :released => 'specs', @@ -219,6 +220,11 @@ class Gem::Source end end end require 'rubygems/source/git' @@ -1,8 +1,6 @@ -require 'delegate' -require 'uri' require 'rubygems/user_interaction' -class Gem::SpecificationPolicy < SimpleDelegator include Gem::UserInteraction @@ -25,7 +23,7 @@ class Gem::SpecificationPolicy < SimpleDelegator def initialize(specification) @warnings = 0 - super(specification) end ## @@ -51,7 +49,7 @@ class Gem::SpecificationPolicy < SimpleDelegator validate_require_paths - keep_only_files_and_directories validate_non_files @@ -92,6 +90,8 @@ class Gem::SpecificationPolicy < SimpleDelegator # Implementation for Specification#validate_metadata def validate_metadata unless Hash === metadata error 'metadata must be a hash' end @@ -130,7 +130,7 @@ class Gem::SpecificationPolicy < SimpleDelegator error_messages = [] warning_messages = [] - dependencies.each do |dep| if prev = seen[dep.type][dep.name] error_messages << <<-MESSAGE duplicate dependency on #{dep}, (#{prev.requirement}) use: @@ -145,7 +145,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: end warning_messages << "prerelease dependency on #{dep} is not recommended" if - prerelease_dep && !version.prerelease? open_ended = dep.requirement.requirements.all? do |op, version| not version.prerelease? and (op == '>' or op == '>=') @@ -190,14 +190,14 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: def validate_permissions return if Gem.win_platform? - files.each do |file| next unless File.file?(file) next if File.stat(file).mode & 0444 == 0444 warning "#{file} is not world-readable" end - executables.each do |name| - exec = File.join bindir, name next unless File.file?(exec) next if File.stat(exec).executable? warning "#{exec} is not executable" @@ -208,7 +208,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: def validate_nil_attributes nil_attributes = Gem::Specification.non_nil_attributes.select do |attrname| - __getobj__.instance_variable_get("@#{attrname}").nil? end return if nil_attributes.empty? error "#{nil_attributes.join ', '} must not be nil" @@ -216,6 +216,9 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: def validate_rubygems_version return unless packaging return if rubygems_version == Gem::VERSION error "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}" @@ -223,13 +226,15 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: def validate_required_attributes Gem::Specification.required_attributes.each do |symbol| - unless send symbol error "missing value for attribute #{symbol}" end end end def validate_name if !name.is_a?(String) error "invalid value for attribute name: \"#{name.inspect}\" must be a string" elsif name !~ /[a-zA-Z]/ @@ -242,14 +247,15 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: end def validate_require_paths - return unless raw_require_paths.empty? error 'specification must have at least one require_path' end def validate_non_files return unless packaging - non_files = files.reject {|x| File.file?(x) || File.symlink?(x)} unless non_files.empty? error "[\"#{non_files.join "\", \""}\"] are not files" @@ -257,18 +263,22 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: end def validate_self_inclusion_in_files_list - return unless files.include?(file_name) - error "#{full_name} contains itself (#{file_name}), check your files list" end def validate_specification_version - return if specification_version.is_a?(Integer) error 'specification_version must be an Integer (did you mean version?)' end def validate_platform case platform when Gem::Platform, Gem::Platform::RUBY # ok else @@ -283,7 +293,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: end def validate_array_attribute(field) - val = self.send(field) klass = case field when :dependencies then Gem::Dependency @@ -298,12 +308,14 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: end def validate_authors_field - return unless authors.empty? error "authors may not be empty" end def validate_licenses licenses.each do |license| if license.length > 64 error "each license must be 64 characters or less" @@ -331,24 +343,27 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li HOMEPAGE_URI_PATTERN = /\A[a-z][a-z\d+.-]*:/i.freeze def validate_lazy_metadata - unless authors.grep(LAZY_PATTERN).empty? error "#{LAZY} is not an author" end - unless Array(email).grep(LAZY_PATTERN).empty? error "#{LAZY} is not an email" end - if description =~ LAZY_PATTERN error "#{LAZY} is not a description" end - if summary =~ LAZY_PATTERN error "#{LAZY} is not a summary" end # Make sure a homepage is valid HTTP/HTTPS URI if homepage and not homepage.empty? begin homepage_uri = URI.parse(homepage) unless [URI::HTTP, URI::HTTPS].member? homepage_uri.class @@ -365,29 +380,29 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li validate_attribute_present(attribute) end - if description == summary warning "description and summary are identical" end # TODO: raise at some given date - warning "deprecated autorequire specified" if autorequire - executables.each do |executable| validate_shebang_line_in(executable) end - files.select { |f| File.symlink?(f) }.each do |file| warning "#{file} is a symlink, which is not supported on all platforms" end end def validate_attribute_present(attribute) - value = self.send attribute warning("no #{attribute} specified") if value.nil? || value.empty? end def validate_shebang_line_in(executable) - executable_path = File.join(bindir, executable) return if File.read(executable_path, 2) == '#!' warning "#{executable_path} is missing #! line" @@ -1,6 +1,5 @@ # frozen_string_literal: true require 'cgi' -require 'uri' ## # The UriFormatter handles URIs from user-input and escaping. @@ -0,0 +1,36 @@ @@ -0,0 +1,23 @@ |