1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Merge rubygems master branch from github.com/rubygems/rubygems.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65294 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
hsbt 2018-10-22 00:27:02 +00:00
parent ff31b35f6a
commit 615ac35934
62 changed files with 386 additions and 410 deletions

View file

@ -9,7 +9,7 @@
require 'rbconfig' require 'rbconfig'
module Gem module Gem
VERSION = "3.0.0.beta1" VERSION = "3.0.0.beta1".freeze
end end
# Must be first since it unloads the prelude from 1.9.2 # Must be first since it unloads the prelude from 1.9.2
@ -126,14 +126,14 @@ module Gem
/mingw/i, /mingw/i,
/mswin/i, /mswin/i,
/wince/i, /wince/i,
] ].freeze
GEM_DEP_FILES = %w[ GEM_DEP_FILES = %w[
gem.deps.rb gem.deps.rb
gems.rb gems.rb
Gemfile Gemfile
Isolate Isolate
] ].freeze
## ##
# Subdirectories in a gem repository # Subdirectories in a gem repository
@ -145,7 +145,7 @@ module Gem
extensions extensions
gems gems
specifications specifications
] ].freeze
## ##
# Subdirectories in a gem repository for default gems # Subdirectories in a gem repository for default gems
@ -153,7 +153,7 @@ module Gem
REPOSITORY_DEFAULT_GEM_SUBDIRECTORIES = %w[ REPOSITORY_DEFAULT_GEM_SUBDIRECTORIES = %w[
gems gems
specifications/default specifications/default
] ].freeze
## ##
# Exception classes used in a Gem.read_binary +rescue+ statement. Not all of # Exception classes used in a Gem.read_binary +rescue+ statement. Not all of
@ -1342,7 +1342,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
## ##
# Location of Marshal quick gemspecs on remote repositories # Location of Marshal quick gemspecs on remote repositories
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/" MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/".freeze
autoload :BundlerVersionFinder, 'rubygems/bundler_version_finder' autoload :BundlerVersionFinder, 'rubygems/bundler_version_finder'
autoload :ConfigFile, 'rubygems/config_file' autoload :ConfigFile, 'rubygems/config_file'

View file

@ -570,7 +570,7 @@ class Gem::Command
# :stopdoc: # :stopdoc:
HELP = <<-HELP HELP = <<-HELP.freeze
RubyGems is a sophisticated package manager for Ruby. This is a RubyGems is a sophisticated package manager for Ruby. This is a
basic help message containing pointers to more information. basic help message containing pointers to more information.

View file

@ -69,11 +69,11 @@ class Gem::CommandManager
:update, :update,
:which, :which,
:yank, :yank,
] ].freeze
ALIAS_COMMANDS = { ALIAS_COMMANDS = {
'i' => 'install' 'i' => 'install'
} }.freeze
## ##
# Return the authoritative instance of the command manager. # Return the authoritative instance of the command manager.

View file

@ -55,7 +55,11 @@ with gem spec:
spec = Gem::Specification.load File.basename(gemspec) spec = Gem::Specification.load File.basename(gemspec)
if spec then if spec then
Gem::Package.build spec, options[:force], options[:strict] Gem::Package.build(
spec,
options[:force],
options[:strict]
)
else else
alert_error "Error loading gemspec. Aborting." alert_error "Error loading gemspec. Aborting."
terminate_interaction 1 terminate_interaction 1

View file

@ -149,15 +149,15 @@ class Gem::Commands::CertCommand < Gem::Command
end end
def build_cert email, key # :nodoc: def build_cert email, key # :nodoc:
expiration_length_days = options[:expiration_length_days] expiration_length_days = options[:expiration_length_days] ||
age = Gem.configuration.cert_expiration_length_days
if expiration_length_days.nil? || expiration_length_days == 0
Gem::Security::ONE_YEAR cert = Gem::Security.create_cert_email(
else email,
Gem::Security::ONE_DAY * expiration_length_days key,
end (Gem::Security::ONE_DAY * expiration_length_days)
)
cert = Gem::Security.create_cert_email email, key, age
Gem::Security.write cert, "gem-public_cert.pem" Gem::Security.write cert, "gem-public_cert.pem"
end end

View file

@ -4,7 +4,7 @@ require 'rubygems/command'
class Gem::Commands::HelpCommand < Gem::Command class Gem::Commands::HelpCommand < Gem::Command
# :stopdoc: # :stopdoc:
EXAMPLES = <<-EOF EXAMPLES = <<-EOF.freeze
Some examples of 'gem' usage. Some examples of 'gem' usage.
* Install 'rake', either from local directory or remote server: * Install 'rake', either from local directory or remote server:
@ -53,7 +53,7 @@ Some examples of 'gem' usage.
gem update --system gem update --system
EOF EOF
GEM_DEPENDENCIES = <<-EOF GEM_DEPENDENCIES = <<-EOF.freeze
A gem dependencies file allows installation of a consistent set of gems across A gem dependencies file allows installation of a consistent set of gems across
multiple environments. The RubyGems implementation is designed to be multiple environments. The RubyGems implementation is designed to be
compatible with Bundler's Gemfile format. You can see additional compatible with Bundler's Gemfile format. You can see additional
@ -230,7 +230,7 @@ default. This may be overridden with the :development_group option:
EOF EOF
PLATFORMS = <<-'EOF' PLATFORMS = <<-'EOF'.freeze
RubyGems platforms are composed of three parts, a CPU, an OS, and a RubyGems platforms are composed of three parts, a CPU, an OS, and a
version. These values are taken from values in rbconfig.rb. You can view version. These values are taken from values in rbconfig.rb. You can view
your current platform by running `gem environment`. your current platform by running `gem environment`.
@ -277,7 +277,7 @@ platform.
["examples", EXAMPLES], ["examples", EXAMPLES],
["gem_dependencies", GEM_DEPENDENCIES], ["gem_dependencies", GEM_DEPENDENCIES],
["platforms", PLATFORMS], ["platforms", PLATFORMS],
] ].freeze
# :startdoc: # :startdoc:
def initialize def initialize

View file

@ -9,7 +9,7 @@ class Gem::Commands::SetupCommand < Gem::Command
HISTORY_HEADER = /^===\s*[\d.a-zA-Z]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/ HISTORY_HEADER = /^===\s*[\d.a-zA-Z]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/
VERSION_MATCHER = /^===\s*([\d.a-zA-Z]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/ VERSION_MATCHER = /^===\s*([\d.a-zA-Z]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/
ENV_PATHS = %w[/usr/bin/env /bin/env] ENV_PATHS = %w[/usr/bin/env /bin/env].freeze
def initialize def initialize
require 'tmpdir' require 'tmpdir'

View file

@ -168,12 +168,8 @@ command to remove old versions.
Dir.chdir update_dir do Dir.chdir update_dir do
say "Installing RubyGems #{version}" say "Installing RubyGems #{version}"
# Make sure old rubygems isn't loaded installed = system Gem.ruby, '--disable-gems', 'setup.rb', *args
old = ENV["RUBYOPT"]
ENV.delete("RUBYOPT") if old
installed = system Gem.ruby, 'setup.rb', *args
say "RubyGems system software updated" if installed say "RubyGems system software updated" if installed
ENV["RUBYOPT"] = old if old
end end
end end

View file

@ -22,7 +22,7 @@ module Gem
EXEEXT RUBY_SO_NAME arch bindir datadir libdir ruby_install_name EXEEXT RUBY_SO_NAME arch bindir datadir libdir ruby_install_name
ruby_version rubylibprefix sitedir sitelibdir vendordir vendorlibdir ruby_version rubylibprefix sitedir sitelibdir vendordir vendorlibdir
rubylibdir rubylibdir
] ].freeze
unless defined?(ConfigMap) unless defined?(ConfigMap)
## ##

View file

@ -45,6 +45,7 @@ class Gem::ConfigFile
DEFAULT_VERBOSITY = true DEFAULT_VERBOSITY = true
DEFAULT_UPDATE_SOURCES = true DEFAULT_UPDATE_SOURCES = true
DEFAULT_CONCURRENT_DOWNLOADS = 8 DEFAULT_CONCURRENT_DOWNLOADS = 8
DEFAULT_CERT_EXPIRATION_LENGTH_DAYS = 365
## ##
# For Ruby packagers to set configuration defaults. Set in # For Ruby packagers to set configuration defaults. Set in
@ -135,6 +136,11 @@ class Gem::ConfigFile
# sources to look for gems # sources to look for gems
attr_accessor :sources attr_accessor :sources
##
# Expiration length to sign a certificate
attr_accessor :cert_expiration_length_days
## ##
# Path name of directory or file of openssl client certificate, used for remote https connection with client authentication # Path name of directory or file of openssl client certificate, used for remote https connection with client authentication
@ -185,6 +191,7 @@ class Gem::ConfigFile
@verbose = DEFAULT_VERBOSITY @verbose = DEFAULT_VERBOSITY
@update_sources = DEFAULT_UPDATE_SOURCES @update_sources = DEFAULT_UPDATE_SOURCES
@concurrent_downloads = DEFAULT_CONCURRENT_DOWNLOADS @concurrent_downloads = DEFAULT_CONCURRENT_DOWNLOADS
@cert_expiration_length_days = DEFAULT_CERT_EXPIRATION_LENGTH_DAYS
operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS) operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS) platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
@ -208,9 +215,9 @@ class Gem::ConfigFile
@path = @hash[:gempath] if @hash.key? :gempath @path = @hash[:gempath] if @hash.key? :gempath
@update_sources = @hash[:update_sources] if @hash.key? :update_sources @update_sources = @hash[:update_sources] if @hash.key? :update_sources
@verbose = @hash[:verbose] if @hash.key? :verbose @verbose = @hash[:verbose] if @hash.key? :verbose
@concurrent_downloads = @hash[:concurrent_downloads] if @hash.key? :concurrent_downloads
@disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
@sources = @hash[:sources] if @hash.key? :sources @sources = @hash[:sources] if @hash.key? :sources
@cert_expiration_length_days = @hash[:cert_expiration_length_days] if @hash.key? :cert_expiration_length_days
@ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode @ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
@ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert @ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert

View file

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
module Gem module Gem
DEFAULT_HOST = "https://rubygems.org" DEFAULT_HOST = "https://rubygems.org".freeze
@post_install_hooks ||= [] @post_install_hooks ||= []
@done_installing_hooks ||= [] @done_installing_hooks ||= []

View file

@ -19,7 +19,7 @@ class Gem::Dependency
TYPES = [ TYPES = [
:development, :development,
:runtime, :runtime,
] ].freeze
## ##
# Dependency name or regular expression. # Dependency name or regular expression.

View file

@ -26,7 +26,7 @@ class Gem::Doctor
['doc', ''], ['doc', ''],
['extensions', ''], ['extensions', ''],
['gems', ''], ['gems', ''],
] ].freeze
missing = missing =
Gem::REPOSITORY_SUBDIRECTORIES.sort - Gem::REPOSITORY_SUBDIRECTORIES.sort -

View file

@ -148,9 +148,21 @@ EOF
def build_extension extension, dest_path # :nodoc: def build_extension extension, dest_path # :nodoc:
results = [] results = []
# FIXME: Determine if this line is necessary and, if so, why.
# Notes:
# 1. As far as I can tell, this method is only called by +build_extensions+.
# 2. The existence of this line implies +extension+ is, or previously was,
# sometimes +false+ or +nil+.
# 3. #1 and #2 combined suggests, but does not confirm, that
# +@specs.extensions+ sometimes contained +false+ or +nil+ values.
# 4. Nothing seems to explicitly handle +extension+ being empty,
# which makes me wonder both what it should do and what it does.
#
# - @duckinator
extension ||= '' # I wish I knew why this line existed extension ||= '' # I wish I knew why this line existed
extension_dir = extension_dir =
File.expand_path File.join @gem_dir, File.dirname(extension) File.expand_path File.join(@gem_dir, File.dirname(extension))
lib_dir = File.join @spec.full_gem_path, @spec.raw_require_paths.first lib_dir = File.join @spec.full_gem_path, @spec.raw_require_paths.first
builder = builder_for extension builder = builder_for extension
@ -200,6 +212,7 @@ EOF
FileUtils.rm_f @spec.gem_build_complete_path FileUtils.rm_f @spec.gem_build_complete_path
# FIXME: action at a distance: @ran_rake modified deep in build_extension(). - @duckinator
@ran_rake = false # only run rake once @ran_rake = false # only run rake once
@spec.extensions.each do |extension| @spec.extensions.each do |extension|

View file

@ -38,7 +38,7 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
destdir = ENV["DESTDIR"] destdir = ENV["DESTDIR"]
begin begin
cmd = [Gem.ruby, "-r", get_relative_path(siteconf.path), File.basename(extension), *args].join ' ' cmd = [Gem.ruby, "-I", File.expand_path("../../..", __FILE__), "-r", get_relative_path(siteconf.path), File.basename(extension), *args].join ' '
begin begin
run cmd, results run cmd, results

View file

@ -5,6 +5,8 @@
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require "shellwords"
class Gem::Ext::RakeBuilder < Gem::Ext::Builder class Gem::Ext::RakeBuilder < Gem::Ext::Builder
def self.build(extension, dest_path, results, args=[], lib_dir=nil) def self.build(extension, dest_path, results, args=[], lib_dir=nil)
@ -14,9 +16,6 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
run cmd, results run cmd, results
end end
# Deal with possible spaces in the path, e.g. C:/Program Files
dest_path = '"' + dest_path.to_s + '"' if dest_path.to_s.include?(' ')
rake = ENV['rake'] rake = ENV['rake']
rake ||= begin rake ||= begin
@ -26,9 +25,8 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
rake ||= Gem.default_exec_format % 'rake' rake ||= Gem.default_exec_format % 'rake'
cmd = "#{rake} RUBYARCHDIR=#{dest_path} RUBYLIBDIR=#{dest_path}" # ENV is frozen rake_args = ["RUBYARCHDIR=#{dest_path}", "RUBYLIBDIR=#{dest_path}", *args]
run "#{rake} #{rake_args.shelljoin}", results
run cmd, results
results results
end end

View file

@ -63,30 +63,6 @@ module Gem::InstallUpdateOptions
options[:document] = [] options[:document] = []
end end
add_option(:Deprecated, '--[no-]rdoc',
'Generate RDoc for installed gems',
'Use --document instead') do |value, options|
if value then
options[:document] << 'rdoc'
else
options[:document].delete 'rdoc'
end
options[:document].uniq!
end
add_option(:Deprecated, '--[no-]ri',
'Generate ri data for installed gems.',
'Use --document instead') do |value, options|
if value then
options[:document] << 'ri'
else
options[:document].delete 'ri'
end
options[:document].uniq!
end
add_option(:"Install/Update", '-E', '--[no-]env-shebang', add_option(:"Install/Update", '-E', '--[no-]env-shebang',
"Rewrite the shebang line on installed", "Rewrite the shebang line on installed",
"scripts to use /usr/bin/env") do |value, options| "scripts to use /usr/bin/env") do |value, options|

View file

@ -34,7 +34,7 @@ class Gem::Installer
# Paths where env(1) might live. Some systems are broken and have it in # Paths where env(1) might live. Some systems are broken and have it in
# /bin # /bin
ENV_PATHS = %w[/usr/bin/env /bin/env] ENV_PATHS = %w[/usr/bin/env /bin/env].freeze
## ##
# Deprecated in favor of Gem::Ext::BuildError # Deprecated in favor of Gem::Ext::BuildError

View file

@ -119,7 +119,7 @@ class Gem::Package
# Permission for other files # Permission for other files
attr_accessor :data_mode attr_accessor :data_mode
def self.build spec, skip_validation=false, strict_validation=false def self.build spec, skip_validation = false, strict_validation = false
gem_file = spec.file_name gem_file = spec.file_name
package = new gem_file package = new gem_file
@ -263,7 +263,11 @@ class Gem::Package
@spec.mark_version @spec.mark_version
@spec.validate true, strict_validation unless skip_validation @spec.validate true, strict_validation unless skip_validation
setup_signer setup_signer(
signer_options: {
expiration_length_days: Gem.configuration.cert_expiration_length_days
}
)
@gem.with_write_io do |gem_io| @gem.with_write_io do |gem_io|
Gem::Package::TarWriter.new gem_io do |gem| Gem::Package::TarWriter.new gem_io do |gem|
@ -521,10 +525,17 @@ EOM
# Prepares the gem for signing and checksum generation. If a signing # Prepares the gem for signing and checksum generation. If a signing
# certificate and key are not present only checksum generation is set up. # certificate and key are not present only checksum generation is set up.
def setup_signer def setup_signer(signer_options: {})
passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE'] passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
if @spec.signing_key then if @spec.signing_key then
@signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain, passphrase @signer =
Gem::Security::Signer.new(
@spec.signing_key,
@spec.cert_chain,
passphrase,
signer_options
)
@spec.signing_key = nil @spec.signing_key = nil
@spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s } @spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s }
else else

View file

@ -50,7 +50,7 @@ class Gem::Package::TarHeader
:uid, :uid,
:uname, :uname,
:version, :version,
] ].freeze
## ##
# Pack format for a tar header # Pack format for a tar header

View file

@ -195,12 +195,12 @@ class Gem::Platform
# A pure-Ruby gem that may use Gem::Specification#extensions to build # A pure-Ruby gem that may use Gem::Specification#extensions to build
# binary files. # binary files.
RUBY = 'ruby' RUBY = 'ruby'.freeze
## ##
# A platform-specific gem that is built for the packaging Ruby's platform. # A platform-specific gem that is built for the packaging Ruby's platform.
# This will be replaced with Gem::Platform::local. # This will be replaced with Gem::Platform::local.
CURRENT = 'current' CURRENT = 'current'.freeze
end end

View file

@ -71,13 +71,10 @@ class Gem::RemoteFetcher
# HTTP_PROXY_PASS) # HTTP_PROXY_PASS)
# * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy # * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy
# #
# +dns+: An object to use for DNS resolution of the API endpoint.
# By default, use Resolv::DNS.
#
# +headers+: A set of additional HTTP headers to be sent to the server when # +headers+: A set of additional HTTP headers to be sent to the server when
# fetching the gem. # fetching the gem.
def initialize(proxy=nil, dns=Resolv::DNS.new, headers={}) def initialize(proxy=nil, dns=nil, headers={})
require 'net/http' require 'net/http'
require 'stringio' require 'stringio'
require 'time' require 'time'
@ -90,34 +87,9 @@ class Gem::RemoteFetcher
@pool_lock = Mutex.new @pool_lock = Mutex.new
@cert_files = Gem::Request.get_cert_files @cert_files = Gem::Request.get_cert_files
@dns = dns
@headers = headers @headers = headers
end end
##
# Given a source at +uri+, calculate what hostname to actually
# connect to query the data for it.
def api_endpoint(uri)
host = uri.host
begin
res = @dns.getresource "_rubygems._tcp.#{host}",
Resolv::DNS::Resource::IN::SRV
rescue Resolv::ResolvError => e
verbose "Getting SRV record failed: #{e}"
uri
else
target = res.target.to_s.strip
if URI("http://" + target).host.end_with?(".#{host}")
return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
end
uri
end
end
## ##
# Given a name and requirement, downloads this gem into cache and returns the # Given a name and requirement, downloads this gem into cache and returns the
# filename. Returns nil if the gem cannot be located. # filename. Returns nil if the gem cannot be located.

View file

@ -48,7 +48,7 @@ class Gem::RequestSet::GemDependencyAPI
:ruby_19 => %w[ruby rbx maglev], :ruby_19 => %w[ruby rbx maglev],
:ruby_20 => %w[ruby rbx maglev], :ruby_20 => %w[ruby rbx maglev],
:ruby_21 => %w[ruby rbx maglev], :ruby_21 => %w[ruby rbx maglev],
} }.freeze
mswin = Gem::Platform.new 'x86-mswin32' mswin = Gem::Platform.new 'x86-mswin32'
mswin64 = Gem::Platform.new 'x64-mswin64' mswin64 = Gem::Platform.new 'x64-mswin64'
@ -88,7 +88,7 @@ class Gem::RequestSet::GemDependencyAPI
:x64_mingw => x64_mingw, :x64_mingw => x64_mingw,
:x64_mingw_20 => x64_mingw, :x64_mingw_20 => x64_mingw,
:x64_mingw_21 => x64_mingw :x64_mingw_21 => x64_mingw
} }.freeze
gt_eq_0 = Gem::Requirement.new '>= 0' gt_eq_0 = Gem::Requirement.new '>= 0'
tilde_gt_1_8_0 = Gem::Requirement.new '~> 1.8.0' tilde_gt_1_8_0 = Gem::Requirement.new '~> 1.8.0'
@ -129,7 +129,7 @@ class Gem::RequestSet::GemDependencyAPI
:x64_mingw => gt_eq_0, :x64_mingw => gt_eq_0,
:x64_mingw_20 => tilde_gt_2_0_0, :x64_mingw_20 => tilde_gt_2_0_0,
:x64_mingw_21 => tilde_gt_2_1_0, :x64_mingw_21 => tilde_gt_2_1_0,
} }.freeze
WINDOWS = { # :nodoc: WINDOWS = { # :nodoc:
:mingw => :only, :mingw => :only,
@ -160,7 +160,7 @@ class Gem::RequestSet::GemDependencyAPI
:x64_mingw => :only, :x64_mingw => :only,
:x64_mingw_20 => :only, :x64_mingw_20 => :only,
:x64_mingw_21 => :only, :x64_mingw_21 => :only,
} }.freeze
## ##
# The gems required by #gem statements in the gem.deps.rb file # The gems required by #gem statements in the gem.deps.rb file

View file

@ -22,12 +22,12 @@ class Gem::Requirement
">=" => lambda { |v, r| v >= r }, ">=" => lambda { |v, r| v >= r },
"<=" => lambda { |v, r| v <= r }, "<=" => lambda { |v, r| v <= r },
"~>" => lambda { |v, r| v >= r && v.release < r.bump } "~>" => lambda { |v, r| v >= r && v.release < r.bump }
} }.freeze
SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc: SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
quoted = OPS.keys.map { |k| Regexp.quote k }.join "|" quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*" # :nodoc: PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*".freeze # :nodoc:
## ##
# A regular expression that matches a requirement # A regular expression that matches a requirement
@ -37,7 +37,7 @@ class Gem::Requirement
## ##
# The default requirement matches any version # The default requirement matches any version
DefaultRequirement = [">=", Gem::Version.new(0)] DefaultRequirement = [">=", Gem::Version.new(0)].freeze
## ##
# Raised when a bad requirement is encountered # Raised when a bad requirement is encountered

View file

@ -37,7 +37,7 @@ class Gem::Resolver::SourceSet < Gem::Resolver::Set
@links[name] = source @links[name] = source
end end
private private
def get_set(name) def get_set(name)
link = @links[name] link = @links[name]

View file

@ -32,7 +32,7 @@ class Gem::Resolver::Stats
@iterations += 1 @iterations += 1
end end
PATTERN = "%20s: %d\n" PATTERN = "%20s: %d\n".freeze
def display def display
$stdout.puts "=== Resolver Statistics ===" $stdout.puts "=== Resolver Statistics ==="

View file

@ -19,12 +19,12 @@ module Gem
Gem::Version::Requirement Gem::Version::Requirement
YAML::Syck::DefaultKey YAML::Syck::DefaultKey
Syck::DefaultKey Syck::DefaultKey
) ).freeze
WHITELISTED_SYMBOLS = %w( WHITELISTED_SYMBOLS = %w(
development development
runtime runtime
) ).freeze
if ::YAML.respond_to? :safe_load if ::YAML.respond_to? :safe_load
def self.safe_load input def self.safe_load input

View file

@ -401,7 +401,7 @@ module Gem::Security
'keyUsage' => 'keyUsage' =>
'keyEncipherment,dataEncipherment,digitalSignature', 'keyEncipherment,dataEncipherment,digitalSignature',
'subjectKeyIdentifier' => 'hash', 'subjectKeyIdentifier' => 'hash',
} }.freeze
def self.alt_name_or_x509_entry certificate, x509_entry def self.alt_name_or_x509_entry certificate, x509_entry
alt_name = certificate.extensions.find do |extension| alt_name = certificate.extensions.find do |extension|

View file

@ -110,7 +110,7 @@ module Gem::Security
'MediumSecurity' => MediumSecurity, 'MediumSecurity' => MediumSecurity,
'HighSecurity' => HighSecurity, 'HighSecurity' => HighSecurity,
# SigningPolicy is not intended for use by `gem -P` so do not list it # SigningPolicy is not intended for use by `gem -P` so do not list it
} }.freeze
end end

View file

@ -29,6 +29,15 @@ class Gem::Security::Signer
attr_reader :digest_name # :nodoc: attr_reader :digest_name # :nodoc:
##
# Gem::Security::Signer options
attr_reader :options
DEFAULT_OPTIONS = {
expiration_length_days: 365
}.freeze
## ##
# Attemps to re-sign an expired cert with a given private key # Attemps to re-sign an expired cert with a given private key
def self.re_sign_cert(expired_cert, expired_cert_path, private_key) def self.re_sign_cert(expired_cert, expired_cert_path, private_key)
@ -40,7 +49,11 @@ class Gem::Security::Signer
Gem::Security.write(expired_cert, new_expired_cert_path) Gem::Security.write(expired_cert, new_expired_cert_path)
re_signed_cert = Gem::Security.re_sign(expired_cert, private_key) re_signed_cert = Gem::Security.re_sign(
expired_cert,
private_key,
(Gem::Security::ONE_DAY * Gem.configuration.cert_expiration_length_days)
)
Gem::Security.write(re_signed_cert, expired_cert_path) Gem::Security.write(re_signed_cert, expired_cert_path)
@ -52,10 +65,11 @@ class Gem::Security::Signer
# +chain+ containing X509 certificates, encoding certificates or paths to # +chain+ containing X509 certificates, encoding certificates or paths to
# certificates. # certificates.
def initialize key, cert_chain, passphrase = nil def initialize key, cert_chain, passphrase = nil, options = {}
@cert_chain = cert_chain @cert_chain = cert_chain
@key = key @key = key
@passphrase = passphrase @passphrase = passphrase
@options = DEFAULT_OPTIONS.merge(options)
unless @key then unless @key then
default_key = File.join Gem.default_key_path default_key = File.join Gem.default_key_path
@ -130,7 +144,9 @@ class Gem::Security::Signer
raise Gem::Security::Exception, 'no certs provided' if @cert_chain.empty? raise Gem::Security::Exception, 'no certs provided' if @cert_chain.empty?
if @cert_chain.length == 1 and @cert_chain.last.not_after < Time.now then if @cert_chain.length == 1 and @cert_chain.last.not_after < Time.now then
re_sign_key re_sign_key(
expiration_length: (Gem::Security::ONE_DAY * options[:expiration_length_days])
)
end end
full_name = extract_name @cert_chain.last full_name = extract_name @cert_chain.last
@ -154,7 +170,7 @@ class Gem::Security::Signer
# be saved as ~/.gem/gem-public_cert.pem.expired.%Y%m%d%H%M%S where the # be saved as ~/.gem/gem-public_cert.pem.expired.%Y%m%d%H%M%S where the
# expiry time (not after) is used for the timestamp. # expiry time (not after) is used for the timestamp.
def re_sign_key # :nodoc: def re_sign_key(expiration_length: Gem::Security::ONE_YEAR) # :nodoc:
old_cert = @cert_chain.last old_cert = @cert_chain.last
disk_cert_path = File.join(Gem.default_cert_path) disk_cert_path = File.join(Gem.default_cert_path)
@ -174,7 +190,7 @@ class Gem::Security::Signer
unless File.exist?(old_cert_path) unless File.exist?(old_cert_path)
Gem::Security.write(old_cert, old_cert_path) Gem::Security.write(old_cert, old_cert_path)
cert = Gem::Security.re_sign(old_cert, @key) cert = Gem::Security.re_sign(old_cert, @key, expiration_length)
Gem::Security.write(cert, disk_cert_path) Gem::Security.write(cert, disk_cert_path)

View file

@ -11,7 +11,7 @@ class Gem::Security::TrustDir
DEFAULT_PERMISSIONS = { DEFAULT_PERMISSIONS = {
:trust_dir => 0700, :trust_dir => 0700,
:trusted_cert => 0600, :trusted_cert => 0600,
} }.freeze
## ##
# The directory where trusted certificates will be stored. # The directory where trusted certificates will be stored.

View file

@ -35,7 +35,7 @@ class Gem::Server
include ERB::Util include ERB::Util
include Gem::UserInteraction include Gem::UserInteraction
SEARCH = <<-ERB SEARCH = <<-ERB.freeze
<form class="headerSearch" name="headerSearchForm" method="get" action="/rdoc"> <form class="headerSearch" name="headerSearchForm" method="get" action="/rdoc">
<div id="search" style="float:right"> <div id="search" style="float:right">
<label for="q">Filter/Search</label> <label for="q">Filter/Search</label>
@ -45,7 +45,7 @@ class Gem::Server
</form> </form>
ERB ERB
DOC_TEMPLATE = <<-'ERB' DOC_TEMPLATE = <<-'ERB'.freeze
<?xml version="1.0" encoding="iso-8859-1"?> <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@ -129,7 +129,7 @@ class Gem::Server
ERB ERB
# CSS is copy & paste from rdoc-style.css, RDoc V1.0.1 - 20041108 # CSS is copy & paste from rdoc-style.css, RDoc V1.0.1 - 20041108
RDOC_CSS = <<-CSS RDOC_CSS = <<-CSS.freeze
body { body {
font-family: Verdana,Arial,Helvetica,sans-serif; font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 90%; font-size: 90%;
@ -339,7 +339,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
.ruby-value { color: #7fffd4; background: transparent; } .ruby-value { color: #7fffd4; background: transparent; }
CSS CSS
RDOC_NO_DOCUMENTATION = <<-'ERB' RDOC_NO_DOCUMENTATION = <<-'ERB'.freeze
<?xml version="1.0" encoding="iso-8859-1"?> <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@ -373,7 +373,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
</html> </html>
ERB ERB
RDOC_SEARCH_TEMPLATE = <<-'ERB' RDOC_SEARCH_TEMPLATE = <<-'ERB'.freeze
<?xml version="1.0" encoding="iso-8859-1"?> <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

View file

@ -16,7 +16,7 @@ class Gem::Source
:released => 'specs', :released => 'specs',
:latest => 'latest_specs', :latest => 'latest_specs',
:prerelease => 'prerelease_specs', :prerelease => 'prerelease_specs',
} }.freeze
## ##
# The URI this source will fetch gems from. # The URI this source will fetch gems from.
@ -36,15 +36,6 @@ class Gem::Source
end end
@uri = uri @uri = uri
@api_uri = nil
end
##
# Use an SRV record on the host to look up the true endpoint for the index.
def api_uri # :nodoc:
require 'rubygems/remote_fetcher'
@api_uri ||= Gem::RemoteFetcher.fetcher.api_endpoint uri
end end
## ##
@ -87,9 +78,9 @@ class Gem::Source
# Returns a Set that can fetch specifications from this source. # Returns a Set that can fetch specifications from this source.
def dependency_resolver_set # :nodoc: def dependency_resolver_set # :nodoc:
return Gem::Resolver::IndexSet.new self if 'file' == api_uri.scheme return Gem::Resolver::IndexSet.new self if 'file' == uri.scheme
bundler_api_uri = api_uri + './api/v1/dependencies' bundler_api_uri = uri + './api/v1/dependencies'
begin begin
fetcher = Gem::RemoteFetcher.fetcher fetcher = Gem::RemoteFetcher.fetcher
@ -140,9 +131,9 @@ class Gem::Source
spec_file_name = name_tuple.spec_name spec_file_name = name_tuple.spec_name
uri = api_uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}" source_uri = uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
cache_dir = cache_dir uri cache_dir = cache_dir source_uri
local_spec = File.join cache_dir, spec_file_name local_spec = File.join cache_dir, spec_file_name
@ -152,9 +143,9 @@ class Gem::Source
return spec if spec return spec if spec
end end
uri.path << '.rz' source_uri.path << '.rz'
spec = fetcher.fetch_path uri spec = fetcher.fetch_path source_uri
spec = Gem::Util.inflate spec spec = Gem::Util.inflate spec
if update_cache? then if update_cache? then
@ -184,7 +175,7 @@ class Gem::Source
file = FILES[type] file = FILES[type]
fetcher = Gem::RemoteFetcher.fetcher fetcher = Gem::RemoteFetcher.fetcher
file_name = "#{file}.#{Gem.marshal_version}" file_name = "#{file}.#{Gem.marshal_version}"
spec_path = api_uri + "#{file_name}.gz" spec_path = uri + "#{file_name}.gz"
cache_dir = cache_dir spec_path cache_dir = cache_dir spec_path
local_file = File.join(cache_dir, file_name) local_file = File.join(cache_dir, file_name)
retried = false retried = false
@ -212,7 +203,7 @@ class Gem::Source
def download(spec, dir=Dir.pwd) def download(spec, dir=Dir.pwd)
fetcher = Gem::RemoteFetcher.fetcher fetcher = Gem::RemoteFetcher.fetcher
fetcher.download spec, api_uri.to_s, dir fetcher.download spec, uri.to_s, dir
end end
def pretty_print q # :nodoc: def pretty_print q # :nodoc:
@ -220,7 +211,7 @@ class Gem::Source
q.breakable q.breakable
q.text @uri.to_s q.text @uri.to_s
if api = api_uri if api = uri
q.breakable q.breakable
q.text 'API URI: ' q.text 'API URI: '
q.text api.to_s q.text api.to_s

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true # frozen_string_literal: true
# -*- coding: utf-8 -*-
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -95,7 +95,7 @@ class Gem::Specification < Gem::BasicSpecification
4 => [ 4 => [
'Added sandboxed freeform metadata to the specification version.' 'Added sandboxed freeform metadata to the specification version.'
] ]
} }.freeze
MARSHAL_FIELDS = { # :nodoc: MARSHAL_FIELDS = { # :nodoc:
-1 => 16, -1 => 16,
@ -103,12 +103,14 @@ class Gem::Specification < Gem::BasicSpecification
2 => 16, 2 => 16,
3 => 17, 3 => 17,
4 => 18, 4 => 18,
} }.freeze
today = Time.now.utc today = Time.now.utc
TODAY = Time.utc(today.year, today.month, today.day) # :nodoc: TODAY = Time.utc(today.year, today.month, today.day) # :nodoc:
# rubocop:disable Style/MutableConstant
LOAD_CACHE = {} # :nodoc: LOAD_CACHE = {} # :nodoc:
# rubocop:enable Style/MutableConstant
private_constant :LOAD_CACHE if defined? private_constant private_constant :LOAD_CACHE if defined? private_constant
@ -163,7 +165,9 @@ class Gem::Specification < Gem::BasicSpecification
:version => nil, :version => nil,
}.freeze }.freeze
# rubocop:disable Style/MutableConstant
INITIALIZE_CODE_FOR_DEFAULTS = { } # :nodoc: INITIALIZE_CODE_FOR_DEFAULTS = { } # :nodoc:
# rubocop:enable Style/MutableConstant
@@default_value.each do |k,v| @@default_value.each do |k,v|
INITIALIZE_CODE_FOR_DEFAULTS[k] = case v INITIALIZE_CODE_FOR_DEFAULTS[k] = case v
@ -260,22 +264,11 @@ class Gem::Specification < Gem::BasicSpecification
].flatten.compact.uniq.sort ].flatten.compact.uniq.sort
end end
######################################################################
# :section: Recommended gemspec attributes
## ##
# Singular writer for #authors # A list of authors for this gem.
# #
# Usage: # Alternatively, a single author can be specified by assigning a string to
# # `spec.author`
# spec.author = 'John Jones'
def author= o
self.authors = [o]
end
##
# Sets the list of authors, ensuring it is an array.
# #
# Usage: # Usage:
# #
@ -285,6 +278,9 @@ class Gem::Specification < Gem::BasicSpecification
@authors = Array(value).flatten.grep(String) @authors = Array(value).flatten.grep(String)
end end
######################################################################
# :section: Recommended gemspec attributes
## ##
# A long description of this gem # A long description of this gem
# #
@ -403,6 +399,17 @@ class Gem::Specification < Gem::BasicSpecification
###################################################################### ######################################################################
# :section: Optional gemspec attributes # :section: Optional gemspec attributes
##
# Singular (alternative) writer for #authors
#
# Usage:
#
# spec.author = 'John Jones'
def author= o
self.authors = [o]
end
## ##
# The path in the gem for executable scripts. Usually 'bin' # The path in the gem for executable scripts. Usually 'bin'
# #

View file

@ -4,6 +4,8 @@ require 'uri'
class Gem::SpecificationPolicy < SimpleDelegator class Gem::SpecificationPolicy < SimpleDelegator
VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc: VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:
SPECIAL_CHARACTERS = /\A[#{Regexp.escape('.-_')}]+/ # :nodoc:
VALID_URI_PATTERN = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z} # :nodoc: VALID_URI_PATTERN = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z} # :nodoc:
METADATA_LINK_KEYS = %w[ METADATA_LINK_KEYS = %w[
@ -14,7 +16,7 @@ class Gem::SpecificationPolicy < SimpleDelegator
mailing_list_uri mailing_list_uri
source_code_uri source_code_uri
wiki_uri wiki_uri
] # :nodoc: ].freeze # :nodoc:
def initialize(specification) def initialize(specification)
@warnings = 0 @warnings = 0
@ -219,12 +221,14 @@ open-ended dependency on #{dep} is not recommended
end end
def validate_name def validate_name
if !name.is_a?(String) then if !name.is_a?(String)
error "invalid value for attribute name: \"#{name.inspect}\" must be a string" error "invalid value for attribute name: \"#{name.inspect}\" must be a string"
elsif name !~ /[a-zA-Z]/ then elsif name !~ /[a-zA-Z]/
error "invalid value for attribute name: #{name.dump} must include at least one letter" error "invalid value for attribute name: #{name.dump} must include at least one letter"
elsif name !~ VALID_NAME_PATTERN then elsif name !~ VALID_NAME_PATTERN
error "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores" error "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
elsif name =~ SPECIAL_CHARACTERS
error "invalid value for attribute name: #{name.dump} can not begin with a period, dash, or underscore"
end end
end end

View file

@ -6,10 +6,10 @@
class Gem::StubSpecification < Gem::BasicSpecification class Gem::StubSpecification < Gem::BasicSpecification
# :nodoc: # :nodoc:
PREFIX = "# stub: " PREFIX = "# stub: ".freeze
# :nodoc: # :nodoc:
OPEN_MODE = 'r:UTF-8:-' OPEN_MODE = 'r:UTF-8:-'.freeze
class StubLine # :nodoc: all class StubLine # :nodoc: all
attr_reader :name, :version, :platform, :require_paths, :extensions, attr_reader :name, :version, :platform, :require_paths, :extensions,
@ -22,7 +22,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
'lib' => 'lib'.freeze, 'lib' => 'lib'.freeze,
'test' => 'test'.freeze, 'test' => 'test'.freeze,
'ext' => 'ext'.freeze, 'ext' => 'ext'.freeze,
} }.freeze
# These are common require path lists. This hash is used to optimize # These are common require path lists. This hash is used to optimize
# and consolidate require_path objects. Most specs just specify "lib" # and consolidate require_path objects. Most specs just specify "lib"
@ -30,7 +30,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
# a require path list for that case. # a require path list for that case.
REQUIRE_PATH_LIST = { # :nodoc: REQUIRE_PATH_LIST = { # :nodoc:
'lib' => ['lib'].freeze 'lib' => ['lib'].freeze
} }.freeze
def initialize data, extensions def initialize data, extensions
parts = data[PREFIX.length..-1].split(" ".freeze, 4) parts = data[PREFIX.length..-1].split(" ".freeze, 4)

View file

@ -1540,7 +1540,7 @@ Also, a list:
# :stopdoc: # :stopdoc:
# only available in RubyGems tests # only available in RubyGems tests
PRIVATE_KEY_PASSPHRASE = 'Foo bar' PRIVATE_KEY_PASSPHRASE = 'Foo bar'.freeze
begin begin
PRIVATE_KEY = load_key 'private' PRIVATE_KEY = load_key 'private'

View file

@ -25,17 +25,11 @@ class Gem::FakeFetcher
attr_reader :data attr_reader :data
attr_reader :last_request attr_reader :last_request
attr_reader :api_endpoints
attr_accessor :paths attr_accessor :paths
def initialize def initialize
@data = {} @data = {}
@paths = [] @paths = []
@api_endpoints = {}
end
def api_endpoint(uri)
@api_endpoints[uri] || uri
end end
def find_data(path) def find_data(path)
@ -111,14 +105,6 @@ class Gem::FakeFetcher
q.breakable q.breakable
q.pp @data.keys q.pp @data.keys
unless @api_endpoints.empty? then
q.breakable
q.text 'API endpoints:'
q.breakable
q.pp @api_endpoints.keys
end
end end
end end

View file

@ -154,7 +154,7 @@ class Gem::Version
include Comparable include Comparable
VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc: VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?'.freeze # :nodoc:
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/ # :nodoc: ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/ # :nodoc:
## ##

View file

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
SIMPLE_GEM = <<-GEMDATA SIMPLE_GEM = <<-GEMDATA.freeze
MD5SUM = "989bf34a1cbecd52e0ea66b662b3a405" MD5SUM = "989bf34a1cbecd52e0ea66b662b3a405"
if $0 == __FILE__ if $0 == __FILE__
require 'optparse' require 'optparse'

View file

@ -14,7 +14,7 @@ end
class TestGem < Gem::TestCase class TestGem < Gem::TestCase
PLUGINS_LOADED = [] PLUGINS_LOADED = [] # rubocop:disable Style/MutableConstant
def setup def setup
super super
@ -1494,7 +1494,7 @@ class TestGem < Gem::TestCase
if Gem::USE_BUNDLER_FOR_GEMDEPS if Gem::USE_BUNDLER_FOR_GEMDEPS
BUNDLER_LIB_PATH = File.expand_path $LOAD_PATH.find {|lp| File.file?(File.join(lp, "bundler.rb")) }.dup.untaint BUNDLER_LIB_PATH = File.expand_path $LOAD_PATH.find {|lp| File.file?(File.join(lp, "bundler.rb")) }.dup.untaint
BUNDLER_FULL_NAME = "bundler-#{Bundler::VERSION}" BUNDLER_FULL_NAME = "bundler-#{Bundler::VERSION}".freeze
end end
def add_bundler_full_name(names) def add_bundler_full_name(names)
@ -1757,7 +1757,8 @@ class TestGem < Gem::TestCase
else else
platform = " #{platform}" platform = " #{platform}"
end end
expected = if Gem::USE_BUNDLER_FOR_GEMDEPS expected =
if Gem::USE_BUNDLER_FOR_GEMDEPS
<<-EXPECTED <<-EXPECTED
Could not find gem 'a#{platform}' in any of the gem sources listed in your Gemfile. Could not find gem 'a#{platform}' in any of the gem sources listed in your Gemfile.
You may need to `gem install -g` to install missing gems You may need to `gem install -g` to install missing gems

View file

@ -126,7 +126,7 @@ class TestGemCommandManager < Gem::TestCase
#check settings #check settings
check_options = nil check_options = nil
@command_manager.process_args %w[ @command_manager.process_args %w[
install --force --local --rdoc --install-dir . install --force --local --document=ri,rdoc --install-dir .
--version 3.0 --no-wrapper --bindir . --version 3.0 --no-wrapper --bindir .
] ]
assert_equal %w[rdoc ri], check_options[:document].sort assert_equal %w[rdoc ri], check_options[:document].sort
@ -260,7 +260,7 @@ class TestGemCommandManager < Gem::TestCase
#check settings #check settings
check_options = nil check_options = nil
@command_manager.process_args %w[update --force --rdoc --install-dir .] @command_manager.process_args %w[update --force --document=ri --install-dir .]
assert_includes check_options[:document], 'ri' assert_includes check_options[:document], 'ri'
assert_equal true, check_options[:force] assert_equal true, check_options[:force]
assert_equal Dir.pwd, check_options[:install_dir] assert_equal Dir.pwd, check_options[:install_dir]

View file

@ -6,6 +6,12 @@ require 'rubygems/package'
class TestGemCommandsBuildCommand < Gem::TestCase class TestGemCommandsBuildCommand < Gem::TestCase
CERT_FILE = cert_path 'public3072'
SIGNING_KEY = key_path 'private3072'
EXPIRED_CERT_FILE = cert_path 'expired'
PRIVATE_KEY_FILE = key_path 'private'
def setup def setup
super super
@ -50,6 +56,32 @@ class TestGemCommandsBuildCommand < Gem::TestCase
util_test_build_gem @gem util_test_build_gem @gem
end end
def test_execute_bad_name
[".", "-", "_"].each do |special_char|
gem = util_spec 'some_gem_with_bad_name' do |s|
s.name = "#{special_char}bad_gem_name"
s.license = 'AGPL-3.0'
s.files = ['README.md']
end
gemspec_file = File.join(@tempdir, gem.spec_name)
File.open gemspec_file, 'w' do |gs|
gs.write gem.to_ruby
end
@cmd.options[:args] = [gemspec_file]
use_ui @ui do
Dir.chdir @tempdir do
assert_raises Gem::InvalidSpecificationException do
@cmd.execute
end
end
end
end
end
def test_execute_strict_without_warnings def test_execute_strict_without_warnings
gemspec_file = File.join(@tempdir, @gem.spec_name) gemspec_file = File.join(@tempdir, @gem.spec_name)
@ -221,9 +253,6 @@ class TestGemCommandsBuildCommand < Gem::TestCase
util_test_build_gem @gem util_test_build_gem @gem
end end
CERT_FILE = cert_path 'public3072'
SIGNING_KEY = key_path 'private3072'
def test_build_signed_gem def test_build_signed_gem
skip 'openssl is missing' unless defined?(OpenSSL::SSL) skip 'openssl is missing' unless defined?(OpenSSL::SSL)
@ -251,4 +280,48 @@ class TestGemCommandsBuildCommand < Gem::TestCase
assert gem.verify assert gem.verify
end end
def test_build_signed_gem_with_cert_expiration_length_days
skip 'openssl is missing' unless defined?(OpenSSL::SSL)
gem_path = File.join Gem.user_home, ".gem"
Dir.mkdir gem_path
trust_dir = Gem::Security.trust_dir
tmp_expired_cert_file = File.join gem_path, "gem-public_cert.pem"
File.write(tmp_expired_cert_file, File.read(EXPIRED_CERT_FILE))
tmp_private_key_file = File.join gem_path, "gem-private_key.pem"
File.write(tmp_private_key_file, File.read(PRIVATE_KEY_FILE))
spec = util_spec 'some_gem' do |s|
s.signing_key = tmp_private_key_file
s.cert_chain = [tmp_expired_cert_file]
end
gemspec_file = File.join(@tempdir, spec.spec_name)
File.open gemspec_file, 'w' do |gs|
gs.write spec.to_ruby
end
@cmd.options[:args] = [gemspec_file]
Gem.configuration.cert_expiration_length_days = 28
use_ui @ui do
Dir.chdir @tempdir do
@cmd.execute
end
end
re_signed_cert = OpenSSL::X509::Certificate.new(File.read(tmp_expired_cert_file))
cert_days_to_expire = (re_signed_cert.not_after - re_signed_cert.not_before).to_i / (24 * 60 * 60)
gem_file = File.join @tempdir, File.basename(spec.cache_file)
assert File.exist?(gem_file)
assert_equal(28, cert_days_to_expire)
end
end end

View file

@ -615,6 +615,37 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
assert_equal '', @ui.error assert_equal '', @ui.error
end end
def test_execute_re_sign_with_cert_expiration_length_days
gem_path = File.join Gem.user_home, ".gem"
Dir.mkdir gem_path
path = File.join @tempdir, 'cert.pem'
Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0600
assert_equal '/CN=nobody/DC=example', EXPIRED_PUBLIC_CERT.issuer.to_s
tmp_expired_cert_file = File.join(Dir.tmpdir, File.basename(EXPIRED_PUBLIC_CERT_FILE))
File.write(tmp_expired_cert_file, File.read(EXPIRED_PUBLIC_CERT_FILE))
@cmd.handle_options %W[
--private-key #{PRIVATE_KEY_FILE}
--certificate #{tmp_expired_cert_file}
--re-sign
]
Gem.configuration.cert_expiration_length_days = 28
use_ui @ui do
@cmd.execute
end
re_signed_cert = OpenSSL::X509::Certificate.new(File.read(tmp_expired_cert_file))
cert_days_to_expire = (re_signed_cert.not_after - re_signed_cert.not_before).to_i / (24 * 60 * 60)
assert_equal(28, cert_days_to_expire)
assert_equal '', @ui.error
end
def test_handle_options def test_handle_options
@cmd.handle_options %W[ @cmd.handle_options %W[
--add #{PUBLIC_CERT_FILE} --add #{PUBLIC_CERT_FILE}

View file

@ -55,7 +55,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
a2_pre = specs['a-2.a'] a2_pre = specs['a-2.a']
@cmd.handle_options [a2_pre.name, '--version', a2_pre.version.to_s, @cmd.handle_options [a2_pre.name, '--version', a2_pre.version.to_s,
"--no-ri", "--no-rdoc"] "--no-document"]
assert @cmd.options[:prerelease] assert @cmd.options[:prerelease]
assert @cmd.options[:version].satisfied_by?(a2_pre.version) assert @cmd.options[:version].satisfied_by?(a2_pre.version)

View file

@ -495,11 +495,13 @@ class TestGemCommandsPristineCommand < Gem::TestCase
@cmd.execute @cmd.execute
end end
assert_equal([ assert_equal(
[
"Restoring gems to pristine condition...", "Restoring gems to pristine condition...",
"Skipped default-2.0.0.0, it is a default gem", "Skipped default-2.0.0.0, it is a default gem",
], ],
@ui.output.split("\n")) @ui.output.split("\n")
)
assert_empty(@ui.error) assert_empty(@ui.error)
end end

View file

@ -10,7 +10,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
if File.exist?(bundler_gemspec) if File.exist?(bundler_gemspec)
BUNDLER_VERS = File.read(bundler_gemspec).match(/VERSION = "(#{Gem::Version::VERSION_PATTERN})"/)[1] BUNDLER_VERS = File.read(bundler_gemspec).match(/VERSION = "(#{Gem::Version::VERSION_PATTERN})"/)[1]
else else
BUNDLER_VERS = "1.16.2" BUNDLER_VERS = "1.16.2".freeze
end end
def setup def setup

View file

@ -44,6 +44,7 @@ class TestGemConfigFile < Gem::TestCase
assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold
assert_equal true, @cfg.verbose assert_equal true, @cfg.verbose
assert_equal [@gem_repo], Gem.sources assert_equal [@gem_repo], Gem.sources
assert_equal 365, @cfg.cert_expiration_length_days
File.open @temp_conf, 'w' do |fp| File.open @temp_conf, 'w' do |fp|
fp.puts ":backtrace: true" fp.puts ":backtrace: true"
@ -58,6 +59,7 @@ class TestGemConfigFile < Gem::TestCase
fp.puts "- /var/ruby/1.8/gem_home" fp.puts "- /var/ruby/1.8/gem_home"
fp.puts ":ssl_verify_mode: 0" fp.puts ":ssl_verify_mode: 0"
fp.puts ":ssl_ca_cert: /etc/ssl/certs" fp.puts ":ssl_ca_cert: /etc/ssl/certs"
fp.puts ":cert_expiration_length_days: 28"
end end
util_config_file util_config_file
@ -71,6 +73,7 @@ class TestGemConfigFile < Gem::TestCase
@cfg.path) @cfg.path)
assert_equal 0, @cfg.ssl_verify_mode assert_equal 0, @cfg.ssl_verify_mode
assert_equal '/etc/ssl/certs', @cfg.ssl_ca_cert assert_equal '/etc/ssl/certs', @cfg.ssl_ca_cert
assert_equal 28, @cfg.cert_expiration_length_days
end end
def test_initialize_handle_arguments_config_file def test_initialize_handle_arguments_config_file

View file

@ -26,7 +26,7 @@ class TestGemExtRakeBuilder < Gem::TestCase
refute_match %r%^rake failed:%, output refute_match %r%^rake failed:%, output
assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, output assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, output
assert_match %r%^#{Regexp.escape rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, output assert_match %r%^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}%, output
end end
end end
@ -47,7 +47,22 @@ class TestGemExtRakeBuilder < Gem::TestCase
refute_match %r%^rake failed:%, output refute_match %r%^rake failed:%, output
assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, output assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, output
assert_match %r%^#{Regexp.escape rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, output assert_match %r%^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}%, output
end
end
def test_class_build_no_mkrf_passes_args
output = []
build_rake_in do |rake|
Dir.chdir @ext do
Gem::Ext::RakeBuilder.build "ext/Rakefile", @dest_path, output, ["test1", "test2"]
end
output = output.join "\n"
refute_match %r%^rake failed:%, output
assert_match %r%^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path} test1 test2%, output
end end
end end

View file

@ -21,8 +21,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
--build-root build_root --build-root build_root
--format-exec --format-exec
--ignore-dependencies --ignore-dependencies
--rdoc --document
--ri
-E -E
-f -f
-i /install_to -i /install_to
@ -92,24 +91,6 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
assert_equal %w[ri], @cmd.options[:document] assert_equal %w[ri], @cmd.options[:document]
end end
def test_rdoc
@cmd.handle_options %w[--rdoc]
assert_equal %w[rdoc ri], @cmd.options[:document].sort
end
def test_rdoc_no
@cmd.handle_options %w[--no-rdoc]
assert_equal %w[ri], @cmd.options[:document]
end
def test_ri
@cmd.handle_options %w[--no-ri]
assert_equal %w[], @cmd.options[:document]
end
def test_security_policy def test_security_policy
skip 'openssl is missing' unless defined?(OpenSSL::SSL) skip 'openssl is missing' unless defined?(OpenSSL::SSL)

View file

@ -35,7 +35,7 @@ class TestGemRemoteFetcher < Gem::TestCase
include Gem::DefaultUserInteraction include Gem::DefaultUserInteraction
SERVER_DATA = <<-EOY SERVER_DATA = <<-EOY.freeze
--- !ruby/object:Gem::Cache --- !ruby/object:Gem::Cache
gems: gems:
rake-0.4.11: !ruby/object:Gem::Specification rake-0.4.11: !ruby/object:Gem::Specification
@ -185,106 +185,6 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end end
end end
def test_api_endpoint
uri = URI.parse "http://example.com/foo"
target = MiniTest::Mock.new
target.expect :target, "gems.example.com"
dns = MiniTest::Mock.new
dns.expect :getresource, target, [String, Object]
fetch = Gem::RemoteFetcher.new nil, dns
assert_equal URI.parse("http://gems.example.com/foo"), fetch.api_endpoint(uri)
target.verify
dns.verify
end
def test_api_endpoint_ignores_trans_domain_values
uri = URI.parse "http://gems.example.com/foo"
target = MiniTest::Mock.new
target.expect :target, "blah.com"
dns = MiniTest::Mock.new
dns.expect :getresource, target, [String, Object]
fetch = Gem::RemoteFetcher.new nil, dns
assert_equal URI.parse("http://gems.example.com/foo"), fetch.api_endpoint(uri)
target.verify
dns.verify
end
def test_api_endpoint_ignores_trans_domain_values_that_starts_with_original
uri = URI.parse "http://example.com/foo"
target = MiniTest::Mock.new
target.expect :target, "example.combadguy.com"
dns = MiniTest::Mock.new
dns.expect :getresource, target, [String, Object]
fetch = Gem::RemoteFetcher.new nil, dns
assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri)
target.verify
dns.verify
end
def test_api_endpoint_ignores_trans_domain_values_that_end_with_original
uri = URI.parse "http://example.com/foo"
target = MiniTest::Mock.new
target.expect :target, "badexample.com"
dns = MiniTest::Mock.new
dns.expect :getresource, target, [String, Object]
fetch = Gem::RemoteFetcher.new nil, dns
assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri)
target.verify
dns.verify
end
def test_api_endpoint_ignores_trans_domain_values_that_end_with_original_in_path
uri = URI.parse "http://example.com/foo"
target = MiniTest::Mock.new
target.expect :target, "evil.com/a.example.com"
dns = MiniTest::Mock.new
dns.expect :getresource, target, [String, Object]
fetch = Gem::RemoteFetcher.new nil, dns
assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri)
target.verify
dns.verify
end
def test_api_endpoint_timeout_warning
uri = URI.parse "http://gems.example.com/foo"
dns = MiniTest::Mock.new
def dns.getresource arg, *rest
raise Resolv::ResolvError.new('timeout!')
end
fetch = Gem::RemoteFetcher.new nil, dns
begin
old_verbose, Gem.configuration.verbose = Gem.configuration.verbose, 1
endpoint = use_ui @stub_ui do
fetch.api_endpoint(uri)
end
ensure
Gem.configuration.verbose = old_verbose
end
assert_equal uri, endpoint
assert_equal "Getting SRV record failed: timeout!\n", @stub_ui.output
dns.verify
end
def test_cache_update_path def test_cache_update_path
uri = URI 'http://example/file' uri = URI 'http://example/file'
path = File.join @tempdir, 'file' path = File.join @tempdir, 'file'

View file

@ -36,18 +36,6 @@ class TestGemSource < Gem::TestCase
assert_equal repository, source.uri assert_equal repository, source.uri
end end
def test_api_uri
assert_equal @source.api_uri, @source.uri
end
def test_api_uri_resolved_from_remote_fetcher
uri = URI.parse "http://gem.example/foo"
@fetcher.api_endpoints[uri] = URI.parse "http://api.blah"
src = Gem::Source.new uri
assert_equal URI.parse("http://api.blah"), src.api_uri
end
def test_cache_dir_escapes_windows_paths def test_cache_dir_escapes_windows_paths
uri = URI.parse("file:///C:/WINDOWS/Temp/gem_repo") uri = URI.parse("file:///C:/WINDOWS/Temp/gem_repo")
root = Gem.spec_cache_dir root = Gem.spec_cache_dir

View file

@ -9,7 +9,7 @@ require 'rubygems/installer'
class TestGemSpecification < Gem::TestCase class TestGemSpecification < Gem::TestCase
LEGACY_YAML_SPEC = <<-EOF LEGACY_YAML_SPEC = <<-EOF.freeze
--- !ruby/object:Gem::Specification --- !ruby/object:Gem::Specification
rubygems_version: "1.0" rubygems_version: "1.0"
name: keyedlist name: keyedlist
@ -28,7 +28,7 @@ email: flgr@ccan.de
has_rdoc: true has_rdoc: true
EOF EOF
LEGACY_RUBY_SPEC = <<-EOF LEGACY_RUBY_SPEC = <<-EOF.freeze
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = %q{keyedlist} s.name = %q{keyedlist}
s.version = %q{0.4.0} s.version = %q{0.4.0}

View file

@ -5,7 +5,8 @@ require 'rubygems/util'
class TestGemUtil < Gem::TestCase class TestGemUtil < Gem::TestCase
def test_class_popen def test_class_popen
assert_equal "0\n", Gem::Util.popen(Gem.ruby, '-e', 'p 0') skip "MJIT executes process and it's caught by Process.wait(-1)" if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
assert_equal "0\n", Gem::Util.popen(Gem.ruby, '-I', File.expand_path('../../../lib', __FILE__), '-e', 'p 0')
assert_raises Errno::ECHILD do assert_raises Errno::ECHILD do
Process.wait(-1) Process.wait(-1)
@ -14,7 +15,7 @@ class TestGemUtil < Gem::TestCase
def test_silent_system def test_silent_system
assert_silent do assert_silent do
Gem::Util.silent_system Gem.ruby, '-e', 'puts "hello"; warn "hello"' Gem::Util.silent_system Gem.ruby, '-I', File.expand_path('../../../lib', __FILE__), '-e', 'puts "hello"; warn "hello"'
end end
end end