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:
parent
ff31b35f6a
commit
615ac35934
62 changed files with 386 additions and 410 deletions
|
@ -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'
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
##
|
##
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ||= []
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Gem::Dependency
|
||||||
TYPES = [
|
TYPES = [
|
||||||
:development,
|
:development,
|
||||||
:runtime,
|
:runtime,
|
||||||
]
|
].freeze
|
||||||
|
|
||||||
##
|
##
|
||||||
# Dependency name or regular expression.
|
# Dependency name or regular expression.
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Gem::Doctor
|
||||||
['doc', ''],
|
['doc', ''],
|
||||||
['extensions', ''],
|
['extensions', ''],
|
||||||
['gems', ''],
|
['gems', ''],
|
||||||
]
|
].freeze
|
||||||
|
|
||||||
missing =
|
missing =
|
||||||
Gem::REPOSITORY_SUBDIRECTORIES.sort -
|
Gem::REPOSITORY_SUBDIRECTORIES.sort -
|
||||||
|
|
|
@ -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|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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 ==="
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
#
|
#
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue