mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Merge rubygems master.
This is RC version of Rubygems 2.7.0.
688fb7e83c
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60133 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6b05153a3a
commit
c00e84327f
96 changed files with 2021 additions and 701 deletions
113
lib/rubygems.rb
113
lib/rubygems.rb
|
@ -39,7 +39,7 @@ require 'rubygems/errors'
|
||||||
# Further RubyGems documentation can be found at:
|
# Further RubyGems documentation can be found at:
|
||||||
#
|
#
|
||||||
# * {RubyGems Guides}[http://guides.rubygems.org]
|
# * {RubyGems Guides}[http://guides.rubygems.org]
|
||||||
# * {RubyGems API}[http://rubygems.rubyforge.org/rdoc] (also available from
|
# * {RubyGems API}[http://www.rubydoc.info/github/rubygems/rubygems] (also available from
|
||||||
# <tt>gem server</tt>)
|
# <tt>gem server</tt>)
|
||||||
#
|
#
|
||||||
# == RubyGems Plugins
|
# == RubyGems Plugins
|
||||||
|
@ -47,15 +47,16 @@ require 'rubygems/errors'
|
||||||
# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or
|
# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or
|
||||||
# $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and
|
# $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and
|
||||||
# placed at the root of your gem's #require_path. Plugins are discovered via
|
# placed at the root of your gem's #require_path. Plugins are discovered via
|
||||||
# Gem::find_files then loaded. Take care when implementing a plugin as your
|
# Gem::find_files and then loaded. Take care when implementing a plugin as your
|
||||||
# plugin file may be loaded multiple times if multiple versions of your gem
|
# plugin file may be loaded multiple times if multiple versions of your gem
|
||||||
# are installed.
|
# are installed.
|
||||||
#
|
#
|
||||||
# For an example plugin, see the graph gem which adds a `gem graph` command.
|
# For an example plugin, see the {Graph gem}[https://github.com/seattlerb/graph]
|
||||||
|
# which adds a `gem graph` command.
|
||||||
#
|
#
|
||||||
# == RubyGems Defaults, Packaging
|
# == RubyGems Defaults, Packaging
|
||||||
#
|
#
|
||||||
# RubyGems defaults are stored in rubygems/defaults.rb. If you're packaging
|
# RubyGems defaults are stored in lib/rubygems/defaults.rb. If you're packaging
|
||||||
# RubyGems or implementing Ruby you can change RubyGems' defaults.
|
# RubyGems or implementing Ruby you can change RubyGems' defaults.
|
||||||
#
|
#
|
||||||
# For RubyGems packagers, provide lib/rubygems/defaults/operating_system.rb
|
# For RubyGems packagers, provide lib/rubygems/defaults/operating_system.rb
|
||||||
|
@ -65,7 +66,7 @@ require 'rubygems/errors'
|
||||||
# override any defaults from lib/rubygems/defaults.rb.
|
# override any defaults from lib/rubygems/defaults.rb.
|
||||||
#
|
#
|
||||||
# If you need RubyGems to perform extra work on install or uninstall, your
|
# If you need RubyGems to perform extra work on install or uninstall, your
|
||||||
# defaults override file can set pre and post install and uninstall hooks.
|
# defaults override file can set pre/post install and uninstall hooks.
|
||||||
# See Gem::pre_install, Gem::pre_uninstall, Gem::post_install,
|
# See Gem::pre_install, Gem::pre_uninstall, Gem::post_install,
|
||||||
# Gem::post_uninstall.
|
# Gem::post_uninstall.
|
||||||
#
|
#
|
||||||
|
@ -106,6 +107,8 @@ require 'rubygems/errors'
|
||||||
#
|
#
|
||||||
# (If your name is missing, PLEASE let us know!)
|
# (If your name is missing, PLEASE let us know!)
|
||||||
#
|
#
|
||||||
|
# == License
|
||||||
|
#
|
||||||
# See {LICENSE.txt}[rdoc-ref:lib/rubygems/LICENSE.txt] for permissions.
|
# See {LICENSE.txt}[rdoc-ref:lib/rubygems/LICENSE.txt] for permissions.
|
||||||
#
|
#
|
||||||
# Thanks!
|
# Thanks!
|
||||||
|
@ -130,6 +133,7 @@ module Gem
|
||||||
|
|
||||||
GEM_DEP_FILES = %w[
|
GEM_DEP_FILES = %w[
|
||||||
gem.deps.rb
|
gem.deps.rb
|
||||||
|
gems.rb
|
||||||
Gemfile
|
Gemfile
|
||||||
Isolate
|
Isolate
|
||||||
]
|
]
|
||||||
|
@ -159,7 +163,7 @@ module Gem
|
||||||
# these are defined in Ruby 1.8.7, hence the need for this convoluted setup.
|
# these are defined in Ruby 1.8.7, hence the need for this convoluted setup.
|
||||||
|
|
||||||
READ_BINARY_ERRORS = begin
|
READ_BINARY_ERRORS = begin
|
||||||
read_binary_errors = [Errno::EACCES]
|
read_binary_errors = [Errno::EACCES, Errno::EROFS]
|
||||||
read_binary_errors << Errno::ENOTSUP if Errno.const_defined?(:ENOTSUP)
|
read_binary_errors << Errno::ENOTSUP if Errno.const_defined?(:ENOTSUP)
|
||||||
read_binary_errors
|
read_binary_errors
|
||||||
end.freeze
|
end.freeze
|
||||||
|
@ -174,6 +178,8 @@ module Gem
|
||||||
write_binary_errors
|
write_binary_errors
|
||||||
end.freeze
|
end.freeze
|
||||||
|
|
||||||
|
USE_BUNDLER_FOR_GEMDEPS = true # :nodoc:
|
||||||
|
|
||||||
@@win_platform = nil
|
@@win_platform = nil
|
||||||
|
|
||||||
@configuration = nil
|
@configuration = nil
|
||||||
|
@ -266,17 +272,22 @@ module Gem
|
||||||
|
|
||||||
return loaded if loaded && dep.matches_spec?(loaded)
|
return loaded if loaded && dep.matches_spec?(loaded)
|
||||||
|
|
||||||
specs = dep.matching_specs(true)
|
find_specs = proc { dep.matching_specs(true) }
|
||||||
|
if dep.to_s == "bundler (>= 0.a)"
|
||||||
raise Gem::GemNotFoundException,
|
specs = Gem::BundlerVersionFinder.without_filtering(&find_specs)
|
||||||
"can't find gem #{dep}" if specs.empty?
|
else
|
||||||
|
specs = find_specs.call
|
||||||
|
end
|
||||||
|
|
||||||
specs = specs.find_all { |spec|
|
specs = specs.find_all { |spec|
|
||||||
spec.executables.include? exec_name
|
spec.executables.include? exec_name
|
||||||
} if exec_name
|
} if exec_name
|
||||||
|
|
||||||
unless spec = specs.first
|
unless spec = specs.first
|
||||||
msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
|
msg = "can't find gem #{dep} with executable #{exec_name}"
|
||||||
|
if name == "bundler" && bundler_message = Gem::BundlerVersionFinder.missing_version_message
|
||||||
|
msg = bundler_message
|
||||||
|
end
|
||||||
raise Gem::GemNotFoundException, msg
|
raise Gem::GemNotFoundException, msg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -297,7 +308,10 @@ module Gem
|
||||||
|
|
||||||
def self.activate_bin_path name, exec_name, requirement # :nodoc:
|
def self.activate_bin_path name, exec_name, requirement # :nodoc:
|
||||||
spec = find_spec_for_exe name, exec_name, [requirement]
|
spec = find_spec_for_exe name, exec_name, [requirement]
|
||||||
Gem::LOADED_SPECS_MUTEX.synchronize { spec.activate }
|
Gem::LOADED_SPECS_MUTEX.synchronize do
|
||||||
|
spec.activate
|
||||||
|
finish_resolve
|
||||||
|
end
|
||||||
spec.bin_file exec_name
|
spec.bin_file exec_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -356,12 +370,16 @@ module Gem
|
||||||
# package is not available as a gem, return nil.
|
# package is not available as a gem, return nil.
|
||||||
|
|
||||||
def self.datadir(gem_name)
|
def self.datadir(gem_name)
|
||||||
# TODO: deprecate
|
|
||||||
spec = @loaded_specs[gem_name]
|
spec = @loaded_specs[gem_name]
|
||||||
return nil if spec.nil?
|
return nil if spec.nil?
|
||||||
spec.datadir
|
spec.datadir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
extend Gem::Deprecate
|
||||||
|
deprecate :datadir, "spec.datadir", 2016, 10
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# A Zlib::Deflate.deflate wrapper
|
# A Zlib::Deflate.deflate wrapper
|
||||||
|
|
||||||
|
@ -594,7 +612,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
# Zlib::GzipReader wrapper that unzips +data+.
|
# Zlib::GzipReader wrapper that unzips +data+.
|
||||||
|
|
||||||
def self.gunzip(data)
|
def self.gunzip(data)
|
||||||
require 'rubygems/util'
|
|
||||||
Gem::Util.gunzip data
|
Gem::Util.gunzip data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -602,7 +619,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
# Zlib::GzipWriter wrapper that zips +data+.
|
# Zlib::GzipWriter wrapper that zips +data+.
|
||||||
|
|
||||||
def self.gzip(data)
|
def self.gzip(data)
|
||||||
require 'rubygems/util'
|
|
||||||
Gem::Util.gzip data
|
Gem::Util.gzip data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -610,7 +626,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
# A Zlib::Inflate#inflate wrapper
|
# A Zlib::Inflate#inflate wrapper
|
||||||
|
|
||||||
def self.inflate(data)
|
def self.inflate(data)
|
||||||
require 'rubygems/util'
|
|
||||||
Gem::Util.inflate data
|
Gem::Util.inflate data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -715,9 +730,20 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
|
|
||||||
##
|
##
|
||||||
# The file name and line number of the caller of the caller of this method.
|
# The file name and line number of the caller of the caller of this method.
|
||||||
|
#
|
||||||
|
# +depth+ is how many layers up the call stack it should go.
|
||||||
|
#
|
||||||
|
# e.g.,
|
||||||
|
#
|
||||||
|
# def a; Gem.location_of_caller; end
|
||||||
|
# a #=> ["x.rb", 2] # (it'll vary depending on file name and line number)
|
||||||
|
#
|
||||||
|
# def b; c; end
|
||||||
|
# def c; Gem.location_of_caller(2); end
|
||||||
|
# b #=> ["x.rb", 6] # (it'll vary depending on file name and line number)
|
||||||
|
|
||||||
def self.location_of_caller
|
def self.location_of_caller(depth = 1)
|
||||||
caller[1] =~ /(.*?):(\d+).*?$/i
|
caller[depth] =~ /(.*?):(\d+).*?$/i
|
||||||
file = $1
|
file = $1
|
||||||
lineno = $2.to_i
|
lineno = $2.to_i
|
||||||
|
|
||||||
|
@ -1148,8 +1174,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
path = path.dup
|
path = path.dup
|
||||||
|
|
||||||
if path == "-" then
|
if path == "-" then
|
||||||
require 'rubygems/util'
|
|
||||||
|
|
||||||
Gem::Util.traverse_parents Dir.pwd do |directory|
|
Gem::Util.traverse_parents Dir.pwd do |directory|
|
||||||
dep_file = GEM_DEP_FILES.find { |f| File.file?(f) }
|
dep_file = GEM_DEP_FILES.find { |f| File.file?(f) }
|
||||||
|
|
||||||
|
@ -1168,18 +1192,36 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
raise ArgumentError, "Unable to find gem dependencies file at #{path}"
|
raise ArgumentError, "Unable to find gem dependencies file at #{path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
rs = Gem::RequestSet.new
|
if USE_BUNDLER_FOR_GEMDEPS
|
||||||
@gemdeps = rs.load_gemdeps path
|
|
||||||
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path(path)
|
||||||
|
require 'rubygems/user_interaction'
|
||||||
|
Gem::DefaultUserInteraction.use_ui(ui) do
|
||||||
|
require "bundler"
|
||||||
|
@gemdeps = Bundler.setup
|
||||||
|
Bundler.ui = nil
|
||||||
|
@gemdeps.requested_specs.map(&:to_spec).sort_by(&:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
rs = Gem::RequestSet.new
|
||||||
|
@gemdeps = rs.load_gemdeps path
|
||||||
|
|
||||||
|
rs.resolve_current.map do |s|
|
||||||
|
s.full_spec.tap(&:activate)
|
||||||
|
end
|
||||||
|
|
||||||
rs.resolve_current.map do |s|
|
|
||||||
sp = s.full_spec
|
|
||||||
sp.activate
|
|
||||||
sp
|
|
||||||
end
|
end
|
||||||
rescue Gem::LoadError, Gem::UnsatisfiableDependencyError => e
|
rescue => e
|
||||||
warn e.message
|
case e
|
||||||
warn "You may need to `gem install -g` to install missing gems"
|
when Gem::LoadError, Gem::UnsatisfiableDependencyError, (defined?(Bundler::GemNotFound) ? Bundler::GemNotFound : Gem::LoadError)
|
||||||
warn ""
|
warn e.message
|
||||||
|
warn "You may need to `gem install -g` to install missing gems"
|
||||||
|
warn ""
|
||||||
|
else
|
||||||
|
raise
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
@ -1225,6 +1267,8 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
prefix_pattern = /^(#{prefix_group})/
|
prefix_pattern = /^(#{prefix_group})/
|
||||||
end
|
end
|
||||||
|
|
||||||
|
suffix_pattern = /#{Regexp.union(Gem.suffixes)}\z/
|
||||||
|
|
||||||
spec.files.each do |file|
|
spec.files.each do |file|
|
||||||
if new_format
|
if new_format
|
||||||
file = file.sub(prefix_pattern, "")
|
file = file.sub(prefix_pattern, "")
|
||||||
|
@ -1232,6 +1276,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
end
|
end
|
||||||
|
|
||||||
@path_to_default_spec_map[file] = spec
|
@path_to_default_spec_map[file] = spec
|
||||||
|
@path_to_default_spec_map[file.sub(suffix_pattern, "")] = spec
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1239,11 +1284,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
# Find a Gem::Specification of default gem from +path+
|
# Find a Gem::Specification of default gem from +path+
|
||||||
|
|
||||||
def find_unresolved_default_spec(path)
|
def find_unresolved_default_spec(path)
|
||||||
Gem.suffixes.each do |suffix|
|
@path_to_default_spec_map[path]
|
||||||
spec = @path_to_default_spec_map["#{path}#{suffix}"]
|
|
||||||
return spec if spec
|
|
||||||
end
|
|
||||||
nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -1314,6 +1355,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
|
|
||||||
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
|
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
|
||||||
|
|
||||||
|
autoload :BundlerVersionFinder, 'rubygems/bundler_version_finder'
|
||||||
autoload :ConfigFile, 'rubygems/config_file'
|
autoload :ConfigFile, 'rubygems/config_file'
|
||||||
autoload :Dependency, 'rubygems/dependency'
|
autoload :Dependency, 'rubygems/dependency'
|
||||||
autoload :DependencyList, 'rubygems/dependency_list'
|
autoload :DependencyList, 'rubygems/dependency_list'
|
||||||
|
@ -1329,6 +1371,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
||||||
autoload :SourceList, 'rubygems/source_list'
|
autoload :SourceList, 'rubygems/source_list'
|
||||||
autoload :SpecFetcher, 'rubygems/spec_fetcher'
|
autoload :SpecFetcher, 'rubygems/spec_fetcher'
|
||||||
autoload :Specification, 'rubygems/specification'
|
autoload :Specification, 'rubygems/specification'
|
||||||
|
autoload :Util, 'rubygems/util'
|
||||||
autoload :Version, 'rubygems/version'
|
autoload :Version, 'rubygems/version'
|
||||||
|
|
||||||
require "rubygems/specification"
|
require "rubygems/specification"
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Gem::BasicSpecification
|
||||||
elsif missing_extensions? then
|
elsif missing_extensions? then
|
||||||
@ignored = true
|
@ignored = true
|
||||||
|
|
||||||
warn "Ignoring #{full_name} because its extensions are not built. " +
|
warn "Ignoring #{full_name} because its extensions are not built. " +
|
||||||
"Try: gem pristine #{name} --version #{version}"
|
"Try: gem pristine #{name} --version #{version}"
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -275,10 +275,10 @@ class Gem::BasicSpecification
|
||||||
# for this spec.
|
# for this spec.
|
||||||
|
|
||||||
def lib_dirs_glob
|
def lib_dirs_glob
|
||||||
dirs = if self.require_paths.size > 1 then
|
dirs = if self.raw_require_paths.size > 1 then
|
||||||
"{#{self.require_paths.join(',')}}"
|
"{#{self.raw_require_paths.join(',')}}"
|
||||||
else
|
else
|
||||||
self.require_paths.first
|
self.raw_require_paths.first
|
||||||
end
|
end
|
||||||
|
|
||||||
"#{self.full_gem_path}/#{dirs}".dup.untaint
|
"#{self.full_gem_path}/#{dirs}".dup.untaint
|
||||||
|
|
112
lib/rubygems/bundler_version_finder.rb
Normal file
112
lib/rubygems/bundler_version_finder.rb
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
module Gem::BundlerVersionFinder
|
||||||
|
@without_filtering = false
|
||||||
|
|
||||||
|
def self.without_filtering
|
||||||
|
without_filtering, @without_filtering = true, @without_filtering
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
@without_filtering = without_filtering
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.bundler_version
|
||||||
|
version, _ = bundler_version_with_reason
|
||||||
|
|
||||||
|
return unless version
|
||||||
|
|
||||||
|
Gem::Version.new(version)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.bundler_version_with_reason
|
||||||
|
return if @without_filtering
|
||||||
|
|
||||||
|
if v = ENV["BUNDLER_VERSION"]
|
||||||
|
return [v, "`$BUNDLER_VERSION`"]
|
||||||
|
end
|
||||||
|
if v = bundle_update_bundler_version
|
||||||
|
return if v == true
|
||||||
|
return [v, "`bundle update --bundler`"]
|
||||||
|
end
|
||||||
|
v, lockfile = lockfile_version
|
||||||
|
if v
|
||||||
|
return [v, "your #{lockfile}"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.missing_version_message
|
||||||
|
return unless vr = bundler_version_with_reason
|
||||||
|
<<-EOS
|
||||||
|
Could not find 'bundler' (#{vr.first}) required by #{vr.last}.
|
||||||
|
To update to the lastest version installed on your system, run `bundle update --bundler`.
|
||||||
|
To install the missing version, run `gem install bundler:#{vr.first}`
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.compatible?(spec)
|
||||||
|
return true unless spec.name == "bundler".freeze
|
||||||
|
return true unless bundler_version = self.bundler_version
|
||||||
|
if bundler_version.segments.first >= 2
|
||||||
|
spec.version == bundler_version
|
||||||
|
else # 1.x
|
||||||
|
spec.version.segments.first < 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.filter!(specs)
|
||||||
|
return unless bundler_version = self.bundler_version
|
||||||
|
if bundler_version.segments.first >= 2
|
||||||
|
specs.reject! { |spec| spec.version != bundler_version }
|
||||||
|
else # 1.x
|
||||||
|
specs.reject! { |spec| spec.version.segments.first >= 2}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.bundle_update_bundler_version
|
||||||
|
return unless File.basename($0) == "bundle".freeze
|
||||||
|
return unless "update".start_with?(ARGV.first || " ")
|
||||||
|
bundler_version = nil
|
||||||
|
update_index = nil
|
||||||
|
ARGV.each_with_index do |a, i|
|
||||||
|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
||||||
|
bundler_version = a
|
||||||
|
end
|
||||||
|
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
||||||
|
bundler_version = $1 || true
|
||||||
|
update_index = i
|
||||||
|
end
|
||||||
|
bundler_version
|
||||||
|
end
|
||||||
|
private_class_method :bundle_update_bundler_version
|
||||||
|
|
||||||
|
def self.lockfile_version
|
||||||
|
return unless lockfile = lockfile_contents
|
||||||
|
lockfile, contents = lockfile
|
||||||
|
lockfile ||= "lockfile"
|
||||||
|
regexp = /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
||||||
|
return unless contents =~ regexp
|
||||||
|
[$1, lockfile]
|
||||||
|
end
|
||||||
|
private_class_method :lockfile_version
|
||||||
|
|
||||||
|
def self.lockfile_contents
|
||||||
|
gemfile = ENV["BUNDLE_GEMFILE"]
|
||||||
|
gemfile = nil if gemfile && gemfile.empty?
|
||||||
|
Gem::Util.traverse_parents Dir.pwd do |directory|
|
||||||
|
next unless gemfile = Gem::GEM_DEP_FILES.find { |f| File.file?(f.untaint) }
|
||||||
|
|
||||||
|
gemfile = File.join directory, gemfile
|
||||||
|
break
|
||||||
|
end unless gemfile
|
||||||
|
|
||||||
|
return unless gemfile
|
||||||
|
|
||||||
|
lockfile = case gemfile
|
||||||
|
when "gems.rb" then "gems.locked"
|
||||||
|
else "#{gemfile}.lock"
|
||||||
|
end.untaint
|
||||||
|
|
||||||
|
return unless File.file?(lockfile)
|
||||||
|
|
||||||
|
[lockfile, File.read(lockfile)]
|
||||||
|
end
|
||||||
|
private_class_method :lockfile_contents
|
||||||
|
end
|
|
@ -527,7 +527,7 @@ class Gem::Command
|
||||||
end
|
end
|
||||||
|
|
||||||
add_common_option("--silent",
|
add_common_option("--silent",
|
||||||
"Silence rubygems output") do |value, options|
|
"Silence RubyGems output") do |value, options|
|
||||||
options[:silent] = true
|
options[:silent] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,8 @@ class Gem::CommandManager
|
||||||
:rdoc,
|
:rdoc,
|
||||||
:search,
|
:search,
|
||||||
:server,
|
:server,
|
||||||
|
:signin,
|
||||||
|
:signout,
|
||||||
:sources,
|
:sources,
|
||||||
:specification,
|
:specification,
|
||||||
:stale,
|
:stale,
|
||||||
|
@ -161,7 +163,7 @@ class Gem::CommandManager
|
||||||
say Gem::VERSION
|
say Gem::VERSION
|
||||||
terminate_interaction 0
|
terminate_interaction 0
|
||||||
when /^-/ then
|
when /^-/ then
|
||||||
alert_error "Invalid option: #{args.first}. See 'gem --help'."
|
alert_error "Invalid option: #{args.first}. See 'gem --help'."
|
||||||
terminate_interaction 1
|
terminate_interaction 1
|
||||||
else
|
else
|
||||||
cmd_name = args.shift.downcase
|
cmd_name = args.shift.downcase
|
||||||
|
|
|
@ -84,6 +84,11 @@ class Gem::Commands::CertCommand < Gem::Command
|
||||||
|
|
||||||
options[:sign] << cert_file
|
options[:sign] << cert_file
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_option('-d', '--days NUMBER_OF_DAYS',
|
||||||
|
'Days before the certificate expires') do |days, options|
|
||||||
|
options[:expiration_length_days] = days.to_i
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_certificate certificate # :nodoc:
|
def add_certificate certificate # :nodoc:
|
||||||
|
@ -105,16 +110,20 @@ class Gem::Commands::CertCommand < Gem::Command
|
||||||
list_certificates_matching filter
|
list_certificates_matching filter
|
||||||
end
|
end
|
||||||
|
|
||||||
options[:build].each do |name|
|
options[:build].each do |email|
|
||||||
build name
|
build email
|
||||||
end
|
end
|
||||||
|
|
||||||
sign_certificates unless options[:sign].empty?
|
sign_certificates unless options[:sign].empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def build name
|
def build email
|
||||||
|
if !valid_email?(email)
|
||||||
|
raise Gem::CommandLineError, "Invalid email address #{email}"
|
||||||
|
end
|
||||||
|
|
||||||
key, key_path = build_key
|
key, key_path = build_key
|
||||||
cert_path = build_cert name, key
|
cert_path = build_cert email, key
|
||||||
|
|
||||||
say "Certificate: #{cert_path}"
|
say "Certificate: #{cert_path}"
|
||||||
|
|
||||||
|
@ -124,8 +133,16 @@ class Gem::Commands::CertCommand < Gem::Command
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_cert name, key # :nodoc:
|
def build_cert email, key # :nodoc:
|
||||||
cert = Gem::Security.create_cert_email name, key
|
expiration_length_days = options[:expiration_length_days]
|
||||||
|
age =
|
||||||
|
if expiration_length_days.nil? || expiration_length_days == 0
|
||||||
|
Gem::Security::ONE_YEAR
|
||||||
|
else
|
||||||
|
Gem::Security::ONE_DAY * expiration_length_days
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
@ -273,5 +290,13 @@ For further reading on signing gems see `ri Gem::Security`.
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def valid_email? email
|
||||||
|
# It's simple, but is all we need
|
||||||
|
email =~ /\A.+@.+\z/
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
end if defined?(OpenSSL::SSL)
|
end if defined?(OpenSSL::SSL)
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ If no gems are named all gems in GEM_HOME are cleaned.
|
||||||
clean_gems
|
clean_gems
|
||||||
end
|
end
|
||||||
|
|
||||||
say "Clean Up Complete"
|
say "Clean up complete"
|
||||||
|
|
||||||
verbose do
|
verbose do
|
||||||
skipped = @default_gems.map { |spec| spec.full_name }
|
skipped = @default_gems.map { |spec| spec.full_name }
|
||||||
|
|
|
@ -367,7 +367,7 @@ platform.
|
||||||
elsif possibilities.size > 1 then
|
elsif possibilities.size > 1 then
|
||||||
alert_warning "Ambiguous command #{command_name} (#{possibilities.join(', ')})"
|
alert_warning "Ambiguous command #{command_name} (#{possibilities.join(', ')})"
|
||||||
else
|
else
|
||||||
alert_warning "Unknown command #{command_name}. Try: gem help commands"
|
alert_warning "Unknown command #{command_name}. Try: gem help commands"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,9 @@ permission to.
|
||||||
options[:remove] << value
|
options[:remove] << value
|
||||||
end
|
end
|
||||||
|
|
||||||
add_option '-h', '--host HOST', 'Use another gemcutter-compatible host' do |value, options|
|
add_option '-h', '--host HOST',
|
||||||
|
'Use another gemcutter-compatible host',
|
||||||
|
' (e.g. https://rubygems.org)' do |value, options|
|
||||||
options[:host] = value
|
options[:host] = value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -125,14 +125,14 @@ extensions will be restored.
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
unless spec.extensions.empty? or options[:extensions] then
|
unless spec.extensions.empty? or options[:extensions] or options[:only_executables] then
|
||||||
say "Skipped #{spec.full_name}, it needs to compile an extension"
|
say "Skipped #{spec.full_name}, it needs to compile an extension"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
gem = spec.cache_file
|
gem = spec.cache_file
|
||||||
|
|
||||||
unless File.exist? gem then
|
unless File.exist? gem or options[:only_executables] then
|
||||||
require 'rubygems/remote_fetcher'
|
require 'rubygems/remote_fetcher'
|
||||||
|
|
||||||
say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
|
say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
|
||||||
|
@ -157,16 +157,19 @@ extensions will be restored.
|
||||||
install_defaults.to_s['--env-shebang']
|
install_defaults.to_s['--env-shebang']
|
||||||
end
|
end
|
||||||
|
|
||||||
installer = Gem::Installer.at(gem,
|
installer_options = {
|
||||||
:wrappers => true,
|
:wrappers => true,
|
||||||
:force => true,
|
:force => true,
|
||||||
:install_dir => spec.base_dir,
|
:install_dir => spec.base_dir,
|
||||||
:env_shebang => env_shebang,
|
:env_shebang => env_shebang,
|
||||||
:build_args => spec.build_args)
|
:build_args => spec.build_args,
|
||||||
|
}
|
||||||
|
|
||||||
if options[:only_executables] then
|
if options[:only_executables] then
|
||||||
|
installer = Gem::Installer.for_spec(spec, installer_options)
|
||||||
installer.generate_bin
|
installer.generate_bin
|
||||||
else
|
else
|
||||||
|
installer = Gem::Installer.at(gem, installer_options)
|
||||||
installer.install
|
installer.install
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ command. For further discussion see the help for the yank command.
|
||||||
add_key_option
|
add_key_option
|
||||||
|
|
||||||
add_option('--host HOST',
|
add_option('--host HOST',
|
||||||
'Push to another gemcutter-compatible host') do |value, options|
|
'Push to another gemcutter-compatible host',
|
||||||
|
' (e.g. https://rubygems.org)') do |value, options|
|
||||||
options[:host] = value
|
options[:host] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -255,22 +255,21 @@ is too hard to use.
|
||||||
name_tuples.map { |n| n.version }.uniq
|
name_tuples.map { |n| n.version }.uniq
|
||||||
else
|
else
|
||||||
platforms.sort.reverse.map do |version, pls|
|
platforms.sort.reverse.map do |version, pls|
|
||||||
if pls == [Gem::Platform::RUBY] then
|
out = version.to_s
|
||||||
if options[:domain] == :remote || specs.all? { |spec| spec.is_a? Gem::Source }
|
|
||||||
version
|
if options[:domain] == :local
|
||||||
else
|
default = specs.any? do |s|
|
||||||
spec = specs.select { |s| s.version == version }
|
!s.is_a?(Gem::Source) && s.version == version && s.default_gem?
|
||||||
if spec.first.default_gem?
|
|
||||||
"default: #{version}"
|
|
||||||
else
|
|
||||||
version
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
else
|
out = "default: #{out}" if default
|
||||||
ruby = pls.delete Gem::Platform::RUBY
|
|
||||||
platform_list = [ruby, *pls.sort].compact
|
|
||||||
"#{version} #{platform_list.join ' '}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if pls != [Gem::Platform::RUBY] then
|
||||||
|
platform_list = [pls.delete(Gem::Platform::RUBY), *pls.sort].compact
|
||||||
|
out = platform_list.unshift(out).join(' ')
|
||||||
|
end
|
||||||
|
|
||||||
|
out
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,11 @@ class Gem::Commands::SetupCommand < Gem::Command
|
||||||
super 'setup', 'Install RubyGems',
|
super 'setup', 'Install RubyGems',
|
||||||
:format_executable => true, :document => %w[ri],
|
:format_executable => true, :document => %w[ri],
|
||||||
:site_or_vendor => 'sitelibdir',
|
:site_or_vendor => 'sitelibdir',
|
||||||
:destdir => '', :prefix => '', :previous_version => ''
|
:destdir => '', :prefix => '', :previous_version => '',
|
||||||
|
:regenerate_binstubs => true
|
||||||
|
|
||||||
add_option '--previous-version=VERSION',
|
add_option '--previous-version=VERSION',
|
||||||
'Previous version of rubygems',
|
'Previous version of RubyGems',
|
||||||
'Used for changelog processing' do |version, options|
|
'Used for changelog processing' do |version, options|
|
||||||
options[:previous_version] = version
|
options[:previous_version] = version
|
||||||
end
|
end
|
||||||
|
@ -42,7 +43,7 @@ class Gem::Commands::SetupCommand < Gem::Command
|
||||||
|
|
||||||
add_option '--[no-]format-executable',
|
add_option '--[no-]format-executable',
|
||||||
'Makes `gem` match ruby',
|
'Makes `gem` match ruby',
|
||||||
'If ruby is ruby18, gem will be gem18' do |value, options|
|
'If Ruby is ruby18, gem will be gem18' do |value, options|
|
||||||
options[:format_executable] = value
|
options[:format_executable] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -79,6 +80,15 @@ class Gem::Commands::SetupCommand < Gem::Command
|
||||||
options[:document].uniq!
|
options[:document].uniq!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_option '--[no-]regenerate-binstubs',
|
||||||
|
'Regenerate gem binstubs' do |value, options|
|
||||||
|
if value then
|
||||||
|
options[:regenerate_binstubs] = true
|
||||||
|
else
|
||||||
|
options.delete(:regenerate_binstubs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@verbose = nil
|
@verbose = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -92,7 +102,7 @@ class Gem::Commands::SetupCommand < Gem::Command
|
||||||
end
|
end
|
||||||
|
|
||||||
def defaults_str # :nodoc:
|
def defaults_str # :nodoc:
|
||||||
"--format-executable --document ri"
|
"--format-executable --document ri --regenerate-binstubs"
|
||||||
end
|
end
|
||||||
|
|
||||||
def description # :nodoc:
|
def description # :nodoc:
|
||||||
|
@ -142,8 +152,12 @@ By default, this RubyGems will install gem as:
|
||||||
|
|
||||||
remove_old_lib_files lib_dir
|
remove_old_lib_files lib_dir
|
||||||
|
|
||||||
|
install_default_bundler_gem
|
||||||
|
|
||||||
say "RubyGems #{Gem::VERSION} installed"
|
say "RubyGems #{Gem::VERSION} installed"
|
||||||
|
|
||||||
|
regenerate_binstubs
|
||||||
|
|
||||||
uninstall_old_gemcutter
|
uninstall_old_gemcutter
|
||||||
|
|
||||||
documentation_success = install_rdoc
|
documentation_success = install_rdoc
|
||||||
|
@ -190,7 +204,7 @@ By default, this RubyGems will install gem as:
|
||||||
|
|
||||||
if options[:document].include? 'ri' then
|
if options[:document].include? 'ri' then
|
||||||
say "Ruby Interactive (ri) documentation was installed. ri is kind of like man "
|
say "Ruby Interactive (ri) documentation was installed. ri is kind of like man "
|
||||||
say "pages for ruby libraries. You may access it like this:"
|
say "pages for Ruby libraries. You may access it like this:"
|
||||||
say " ri Classname"
|
say " ri Classname"
|
||||||
say " ri Classname.class_method"
|
say " ri Classname.class_method"
|
||||||
say " ri Classname#instance_method"
|
say " ri Classname#instance_method"
|
||||||
|
@ -202,59 +216,64 @@ By default, this RubyGems will install gem as:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def install_executables(bin_dir)
|
|
||||||
say "Installing gem executable" if @verbose
|
|
||||||
|
|
||||||
|
def install_executables(bin_dir)
|
||||||
@bin_file_names = []
|
@bin_file_names = []
|
||||||
|
|
||||||
Dir.chdir 'bin' do
|
executables = { 'gem' => 'bin' }
|
||||||
bin_files = Dir['*']
|
executables['bundler'] = 'bundler/exe' if Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
executables.each do |tool, path|
|
||||||
|
say "Installing #{tool} executable" if @verbose
|
||||||
|
|
||||||
bin_files.delete 'update_rubygems'
|
Dir.chdir path do
|
||||||
|
bin_files = Dir['*']
|
||||||
|
|
||||||
bin_files.each do |bin_file|
|
bin_files -= %w[update_rubygems bundler bundle_ruby]
|
||||||
bin_file_formatted = if options[:format_executable] then
|
|
||||||
Gem.default_exec_format % bin_file
|
|
||||||
else
|
|
||||||
bin_file
|
|
||||||
end
|
|
||||||
|
|
||||||
dest_file = File.join bin_dir, bin_file_formatted
|
bin_files.each do |bin_file|
|
||||||
bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
|
bin_file_formatted = if options[:format_executable] then
|
||||||
|
Gem.default_exec_format % bin_file
|
||||||
|
else
|
||||||
|
bin_file
|
||||||
|
end
|
||||||
|
|
||||||
begin
|
dest_file = File.join bin_dir, bin_file_formatted
|
||||||
bin = File.readlines bin_file
|
bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
|
||||||
bin[0] = "#!#{Gem.ruby}\n"
|
|
||||||
|
|
||||||
File.open bin_tmp_file, 'w' do |fp|
|
begin
|
||||||
fp.puts bin.join
|
bin = File.readlines bin_file
|
||||||
|
bin[0] = "#!#{Gem.ruby}\n"
|
||||||
|
|
||||||
|
File.open bin_tmp_file, 'w' do |fp|
|
||||||
|
fp.puts bin.join
|
||||||
|
end
|
||||||
|
|
||||||
|
install bin_tmp_file, dest_file, :mode => 0755
|
||||||
|
@bin_file_names << dest_file
|
||||||
|
ensure
|
||||||
|
rm bin_tmp_file
|
||||||
end
|
end
|
||||||
|
|
||||||
install bin_tmp_file, dest_file, :mode => 0755
|
next unless Gem.win_platform?
|
||||||
@bin_file_names << dest_file
|
|
||||||
ensure
|
|
||||||
rm bin_tmp_file
|
|
||||||
end
|
|
||||||
|
|
||||||
next unless Gem.win_platform?
|
begin
|
||||||
|
bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"
|
||||||
|
|
||||||
begin
|
File.open bin_cmd_file, 'w' do |file|
|
||||||
bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"
|
file.puts <<-TEXT
|
||||||
|
@ECHO OFF
|
||||||
|
IF NOT "%~f0" == "~f0" GOTO :WinNT
|
||||||
|
@"#{File.basename(Gem.ruby).chomp('"')}" "#{dest_file}" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||||
|
GOTO :EOF
|
||||||
|
:WinNT
|
||||||
|
@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
|
||||||
|
TEXT
|
||||||
|
end
|
||||||
|
|
||||||
File.open bin_cmd_file, 'w' do |file|
|
install bin_cmd_file, "#{dest_file}.bat", :mode => 0755
|
||||||
file.puts <<-TEXT
|
ensure
|
||||||
@ECHO OFF
|
rm bin_cmd_file
|
||||||
IF NOT "%~f0" == "~f0" GOTO :WinNT
|
|
||||||
@"#{File.basename(Gem.ruby).chomp('"')}" "#{dest_file}" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
|
||||||
GOTO :EOF
|
|
||||||
:WinNT
|
|
||||||
@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
|
|
||||||
TEXT
|
|
||||||
end
|
end
|
||||||
|
|
||||||
install bin_cmd_file, "#{dest_file}.bat", :mode => 0755
|
|
||||||
ensure
|
|
||||||
rm bin_cmd_file
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -269,18 +288,22 @@ TEXT
|
||||||
end
|
end
|
||||||
|
|
||||||
def install_lib(lib_dir)
|
def install_lib(lib_dir)
|
||||||
say "Installing RubyGems" if @verbose
|
libs = { 'RubyGems' => 'lib' }
|
||||||
|
libs['Bundler'] = 'bundler/lib' if Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
libs.each do |tool, path|
|
||||||
|
say "Installing #{tool}" if @verbose
|
||||||
|
|
||||||
lib_files = rb_files_in 'lib'
|
lib_files = rb_files_in path
|
||||||
pem_files = pem_files_in 'lib'
|
pem_files = pem_files_in path
|
||||||
|
|
||||||
Dir.chdir 'lib' do
|
Dir.chdir path do
|
||||||
lib_files.each do |lib_file|
|
lib_files.each do |lib_file|
|
||||||
install_file lib_file, lib_dir
|
install_file lib_file, lib_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
pem_files.each do |pem_file|
|
pem_files.each do |pem_file|
|
||||||
install_file pem_file, lib_dir
|
install_file pem_file, lib_dir
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -326,6 +349,29 @@ TEXT
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def install_default_bundler_gem
|
||||||
|
return unless Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
|
||||||
|
bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
|
||||||
|
bundler_spec.files = Dir["bundler/{*.md,{lib,exe,man}/**/*}"]
|
||||||
|
bundler_spec.executables -= %w[bundler bundle_ruby]
|
||||||
|
Dir.entries(Gem::Specification.default_specifications_dir).
|
||||||
|
select {|gs| gs.start_with?("bundler-") }.
|
||||||
|
each {|gs| File.delete(File.join(Gem::Specification.default_specifications_dir, gs)) }
|
||||||
|
|
||||||
|
default_spec_path = File.join(Gem::Specification.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
|
||||||
|
Gem.write_binary(default_spec_path, bundler_spec.to_ruby)
|
||||||
|
|
||||||
|
bundler_spec = Gem::Specification.load(default_spec_path)
|
||||||
|
|
||||||
|
Dir.entries(bundler_spec.gems_dir).
|
||||||
|
select {|default_gem| default_gem.start_with?("bundler-") }.
|
||||||
|
each {|default_gem| rm_r File.join(bundler_spec.gems_dir, default_gem) }
|
||||||
|
|
||||||
|
mkdir_p bundler_spec.bin_dir
|
||||||
|
bundler_spec.executables.each {|e| cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_spec.bin_dir, e) }
|
||||||
|
end
|
||||||
|
|
||||||
def make_destination_dirs(install_destdir)
|
def make_destination_dirs(install_destdir)
|
||||||
lib_dir, bin_dir = Gem.default_rubygems_dirs
|
lib_dir, bin_dir = Gem.default_rubygems_dirs
|
||||||
|
|
||||||
|
@ -397,7 +443,7 @@ TEXT
|
||||||
old_bin_path = File.join bin_dir, old_bin_file
|
old_bin_path = File.join bin_dir, old_bin_file
|
||||||
next unless File.exist? old_bin_path
|
next unless File.exist? old_bin_path
|
||||||
|
|
||||||
deprecation_message = "`#{old_bin_file}` has been deprecated. Use `#{new_name}` instead."
|
deprecation_message = "`#{old_bin_file}` has been deprecated. Use `#{new_name}` instead."
|
||||||
|
|
||||||
File.open old_bin_path, 'w' do |fp|
|
File.open old_bin_path, 'w' do |fp|
|
||||||
fp.write <<-EOF
|
fp.write <<-EOF
|
||||||
|
@ -416,23 +462,26 @@ abort "#{deprecation_message}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_old_lib_files lib_dir
|
def remove_old_lib_files lib_dir
|
||||||
rubygems_dir = File.join lib_dir, 'rubygems'
|
lib_dirs = { File.join(lib_dir, 'rubygems') => 'lib/rubygems' }
|
||||||
lib_files = rb_files_in 'lib/rubygems'
|
lib_dirs[File.join(lib_dir, 'bundler')] = 'bundler/lib/bundler' if Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
lib_dirs.each do |old_lib_dir, new_lib_dir|
|
||||||
|
lib_files = rb_files_in(new_lib_dir)
|
||||||
|
|
||||||
old_lib_files = rb_files_in rubygems_dir
|
old_lib_files = rb_files_in(old_lib_dir)
|
||||||
|
|
||||||
to_remove = old_lib_files - lib_files
|
to_remove = old_lib_files - lib_files
|
||||||
|
|
||||||
to_remove.delete_if do |file|
|
to_remove.delete_if do |file|
|
||||||
file.start_with? 'defaults'
|
file.start_with? 'defaults'
|
||||||
end
|
end
|
||||||
|
|
||||||
Dir.chdir rubygems_dir do
|
Dir.chdir old_lib_dir do
|
||||||
to_remove.each do |file|
|
to_remove.each do |file|
|
||||||
FileUtils.rm_f file
|
FileUtils.rm_f file
|
||||||
|
|
||||||
warn "unable to remove old file #{file} please remove it by hand" if
|
warn "unable to remove old file #{file} please remove it by hand" if
|
||||||
File.exist? file
|
File.exist? file
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -480,5 +529,11 @@ abort "#{deprecation_message}"
|
||||||
rescue Gem::InstallError
|
rescue Gem::InstallError
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
def regenerate_binstubs
|
||||||
|
require "rubygems/commands/pristine_command"
|
||||||
|
say "Regenerating binstubs"
|
||||||
|
command = Gem::Commands::PristineCommand.new
|
||||||
|
command.invoke(*%w[--all --only-executables --silent])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
33
lib/rubygems/commands/signin_command.rb
Normal file
33
lib/rubygems/commands/signin_command.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require 'rubygems/command'
|
||||||
|
require 'rubygems/gemcutter_utilities'
|
||||||
|
|
||||||
|
class Gem::Commands::SigninCommand < Gem::Command
|
||||||
|
include Gem::GemcutterUtilities
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super 'signin', 'Sign in to any gemcutter-compatible host. '\
|
||||||
|
'It defaults to https://rubygems.org'
|
||||||
|
|
||||||
|
add_option('--host HOST', 'Push to another gemcutter-compatible host') do |value, options|
|
||||||
|
options[:host] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def description # :nodoc:
|
||||||
|
'The signin command executes host sign in for a push server (the default is'\
|
||||||
|
' https://rubygems.org). The host can be provided with the host flag or can'\
|
||||||
|
' be inferred from the provided gem. Host resolution matches the resolution'\
|
||||||
|
' strategy for the push command.'
|
||||||
|
end
|
||||||
|
|
||||||
|
def usage # :nodoc:
|
||||||
|
program_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute
|
||||||
|
sign_in options[:host]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
33
lib/rubygems/commands/signout_command.rb
Normal file
33
lib/rubygems/commands/signout_command.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require 'rubygems/command'
|
||||||
|
|
||||||
|
class Gem::Commands::SignoutCommand < Gem::Command
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super 'signout', 'Sign out from all the current sessions.'
|
||||||
|
end
|
||||||
|
|
||||||
|
def description # :nodoc:
|
||||||
|
'The `signout` command is used to sign out from all current sessions,'\
|
||||||
|
' allowing you to sign in using a different set of credentials.'
|
||||||
|
end
|
||||||
|
|
||||||
|
def usage # :nodoc:
|
||||||
|
program_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute
|
||||||
|
credentials_path = Gem.configuration.credentials_path
|
||||||
|
|
||||||
|
if !File.exist?(credentials_path) then
|
||||||
|
alert_error 'You are not currently signed in.'
|
||||||
|
elsif !File.writable?(credentials_path) then
|
||||||
|
alert_error "File '#{Gem.configuration.credentials_path}' is read-only."\
|
||||||
|
' Please make sure it is writable.'
|
||||||
|
else
|
||||||
|
Gem.configuration.unset_api_key!
|
||||||
|
say 'You have successfully signed out from all sessions.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -30,7 +30,7 @@ class Gem::Commands::UninstallCommand < Gem::Command
|
||||||
options[:ignore] = value
|
options[:ignore] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
add_option('-D', '--[no-]-check-development',
|
add_option('-D', '--[no-]check-development',
|
||||||
'Check development dependencies while uninstalling',
|
'Check development dependencies while uninstalling',
|
||||||
'(default: false)') do |value, options|
|
'(default: false)') do |value, options|
|
||||||
options[:check_dev] = value
|
options[:check_dev] = value
|
||||||
|
@ -143,7 +143,9 @@ that is a dependency of an existing gem. You can use the
|
||||||
deplist = Gem::DependencyList.new
|
deplist = Gem::DependencyList.new
|
||||||
|
|
||||||
get_all_gem_names.uniq.each do |name|
|
get_all_gem_names.uniq.each do |name|
|
||||||
Gem::Specification.find_all_by_name(name).each do |spec|
|
gem_specs = Gem::Specification.find_all_by_name(name)
|
||||||
|
say("Gem '#{name}' is not installed") if gem_specs.empty?
|
||||||
|
gem_specs.each do |spec|
|
||||||
deplist.add spec
|
deplist.add spec
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -162,4 +164,3 @@ that is a dependency of an existing gem. You can use the
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,20 @@
|
||||||
require 'rubygems/command'
|
require 'rubygems/command'
|
||||||
require 'rubygems/installer'
|
require 'rubygems/installer'
|
||||||
require 'rubygems/version_option'
|
require 'rubygems/version_option'
|
||||||
|
require 'rubygems/security_option'
|
||||||
require 'rubygems/remote_fetcher'
|
require 'rubygems/remote_fetcher'
|
||||||
|
|
||||||
|
# forward-declare
|
||||||
|
|
||||||
|
module Gem::Security # :nodoc:
|
||||||
|
class Policy # :nodoc:
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Gem::Commands::UnpackCommand < Gem::Command
|
class Gem::Commands::UnpackCommand < Gem::Command
|
||||||
|
|
||||||
include Gem::VersionOption
|
include Gem::VersionOption
|
||||||
|
include Gem::SecurityOption
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
|
@ -24,6 +33,7 @@ class Gem::Commands::UnpackCommand < Gem::Command
|
||||||
options[:spec] = true
|
options[:spec] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_security_option
|
||||||
add_version_option
|
add_version_option
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,6 +73,8 @@ command help for an example.
|
||||||
# at the same time.)
|
# at the same time.)
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
security_policy = options[:security_policy]
|
||||||
|
|
||||||
get_all_gem_names.each do |name|
|
get_all_gem_names.each do |name|
|
||||||
dependency = Gem::Dependency.new name, options[:version]
|
dependency = Gem::Dependency.new name, options[:version]
|
||||||
path = get_path dependency
|
path = get_path dependency
|
||||||
|
@ -73,7 +85,7 @@ command help for an example.
|
||||||
end
|
end
|
||||||
|
|
||||||
if @options[:spec] then
|
if @options[:spec] then
|
||||||
spec, metadata = get_metadata path
|
spec, metadata = get_metadata path, security_policy
|
||||||
|
|
||||||
if metadata.nil? then
|
if metadata.nil? then
|
||||||
alert_error "--spec is unsupported on '#{name}' (old format gem)"
|
alert_error "--spec is unsupported on '#{name}' (old format gem)"
|
||||||
|
@ -89,7 +101,7 @@ command help for an example.
|
||||||
basename = File.basename path, '.gem'
|
basename = File.basename path, '.gem'
|
||||||
target_dir = File.expand_path basename, options[:target]
|
target_dir = File.expand_path basename, options[:target]
|
||||||
|
|
||||||
package = Gem::Package.new path
|
package = Gem::Package.new path, security_policy
|
||||||
package.extract_files target_dir
|
package.extract_files target_dir
|
||||||
|
|
||||||
say "Unpacked gem: '#{target_dir}'"
|
say "Unpacked gem: '#{target_dir}'"
|
||||||
|
@ -158,8 +170,8 @@ command help for an example.
|
||||||
#--
|
#--
|
||||||
# TODO move to Gem::Package as #raw_spec or something
|
# TODO move to Gem::Package as #raw_spec or something
|
||||||
|
|
||||||
def get_metadata path
|
def get_metadata path, security_policy = nil
|
||||||
format = Gem::Package.new path
|
format = Gem::Package.new path, security_policy
|
||||||
spec = format.spec
|
spec = format.spec
|
||||||
|
|
||||||
metadata = nil
|
metadata = nil
|
||||||
|
|
|
@ -70,7 +70,7 @@ command to remove old versions.
|
||||||
|
|
||||||
def check_latest_rubygems version # :nodoc:
|
def check_latest_rubygems version # :nodoc:
|
||||||
if Gem.rubygems_version == version then
|
if Gem.rubygems_version == version then
|
||||||
say "Latest version currently installed. Aborting."
|
say "Latest version already installed. Done."
|
||||||
terminate_interaction
|
terminate_interaction
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ requiring to see why it does not behave as you expect.
|
||||||
paths = find_paths arg, dirs
|
paths = find_paths arg, dirs
|
||||||
|
|
||||||
if paths.empty? then
|
if paths.empty? then
|
||||||
alert_error "Can't find ruby library file or shared library #{arg}"
|
alert_error "Can't find Ruby library file or shared library #{arg}"
|
||||||
|
|
||||||
found &&= false
|
found &&= false
|
||||||
else
|
else
|
||||||
|
|
|
@ -11,19 +11,11 @@ class Gem::Commands::YankCommand < Gem::Command
|
||||||
|
|
||||||
def description # :nodoc:
|
def description # :nodoc:
|
||||||
<<-EOF
|
<<-EOF
|
||||||
The yank command removes a gem you pushed to a server from the server's
|
The yank command permanently removes a gem you pushed to a server.
|
||||||
index.
|
|
||||||
|
|
||||||
Note that if you push a gem to rubygems.org the yank command does not
|
|
||||||
prevent other people from downloading the gem via the download link.
|
|
||||||
|
|
||||||
Once you have pushed a gem several downloads will happen automatically
|
Once you have pushed a gem several downloads will happen automatically
|
||||||
via the webhooks. If you accidentally pushed passwords or other sensitive
|
via the webhooks. If you accidentally pushed passwords or other sensitive
|
||||||
data you will need to change them immediately and yank your gem.
|
data you will need to change them immediately and yank your gem.
|
||||||
|
|
||||||
If you are yanking a gem due to intellectual property reasons contact
|
|
||||||
http://help.rubygems.org for permanent removal. Be sure to mention this
|
|
||||||
as the reason for the removal request.
|
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -42,7 +34,8 @@ as the reason for the removal request.
|
||||||
add_platform_option("remove")
|
add_platform_option("remove")
|
||||||
|
|
||||||
add_option('--host HOST',
|
add_option('--host HOST',
|
||||||
'Yank from another gemcutter-compatible host') do |value, options|
|
'Yank from another gemcutter-compatible host',
|
||||||
|
' (e.g. https://rubygems.org)') do |value, options|
|
||||||
options[:host] = value
|
options[:host] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,15 @@ if you believe they were disclosed to a third party.
|
||||||
load_api_keys # reload
|
load_api_keys # reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Remove the +~/.gem/credentials+ file to clear all the current sessions.
|
||||||
|
|
||||||
|
def unset_api_key!
|
||||||
|
return false unless File.exist?(credentials_path)
|
||||||
|
|
||||||
|
File.delete(credentials_path)
|
||||||
|
end
|
||||||
|
|
||||||
def load_file(filename)
|
def load_file(filename)
|
||||||
Gem.load_yaml
|
Gem.load_yaml
|
||||||
|
|
||||||
|
@ -419,31 +428,11 @@ if you believe they were disclosed to a third party.
|
||||||
# to_yaml only overwrites things you can't override on the command line.
|
# to_yaml only overwrites things you can't override on the command line.
|
||||||
def to_yaml # :nodoc:
|
def to_yaml # :nodoc:
|
||||||
yaml_hash = {}
|
yaml_hash = {}
|
||||||
yaml_hash[:backtrace] = if @hash.key?(:backtrace)
|
yaml_hash[:backtrace] = @hash.fetch(:backtrace, DEFAULT_BACKTRACE)
|
||||||
@hash[:backtrace]
|
yaml_hash[:bulk_threshold] = @hash.fetch(:bulk_threshold, DEFAULT_BULK_THRESHOLD)
|
||||||
else
|
|
||||||
DEFAULT_BACKTRACE
|
|
||||||
end
|
|
||||||
|
|
||||||
yaml_hash[:bulk_threshold] = if @hash.key?(:bulk_threshold)
|
|
||||||
@hash[:bulk_threshold]
|
|
||||||
else
|
|
||||||
DEFAULT_BULK_THRESHOLD
|
|
||||||
end
|
|
||||||
|
|
||||||
yaml_hash[:sources] = Gem.sources.to_a
|
yaml_hash[:sources] = Gem.sources.to_a
|
||||||
|
yaml_hash[:update_sources] = @hash.fetch(:update_sources, DEFAULT_UPDATE_SOURCES)
|
||||||
yaml_hash[:update_sources] = if @hash.key?(:update_sources)
|
yaml_hash[:verbose] = @hash.fetch(:verbose, DEFAULT_VERBOSITY)
|
||||||
@hash[:update_sources]
|
|
||||||
else
|
|
||||||
DEFAULT_UPDATE_SOURCES
|
|
||||||
end
|
|
||||||
|
|
||||||
yaml_hash[:verbose] = if @hash.key?(:verbose)
|
|
||||||
@hash[:verbose]
|
|
||||||
else
|
|
||||||
DEFAULT_VERBOSITY
|
|
||||||
end
|
|
||||||
|
|
||||||
yaml_hash[:ssl_verify_mode] =
|
yaml_hash[:ssl_verify_mode] =
|
||||||
@hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
|
@hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
|
||||||
|
|
|
@ -41,8 +41,7 @@ module Kernel
|
||||||
|
|
||||||
path = path.to_path if path.respond_to? :to_path
|
path = path.to_path if path.respond_to? :to_path
|
||||||
|
|
||||||
spec = Gem.find_unresolved_default_spec(path)
|
if spec = Gem.find_unresolved_default_spec(path)
|
||||||
if spec
|
|
||||||
Gem.remove_unresolved_default_spec(spec)
|
Gem.remove_unresolved_default_spec(spec)
|
||||||
begin
|
begin
|
||||||
Kernel.send(:gem, spec.name)
|
Kernel.send(:gem, spec.name)
|
||||||
|
@ -66,12 +65,10 @@ module Kernel
|
||||||
#--
|
#--
|
||||||
# TODO request access to the C implementation of this to speed up RubyGems
|
# TODO request access to the C implementation of this to speed up RubyGems
|
||||||
|
|
||||||
spec = Gem::Specification.find_active_stub_by_path path
|
if Gem::Specification.find_active_stub_by_path(path)
|
||||||
|
|
||||||
begin
|
|
||||||
RUBYGEMS_ACTIVATION_MONITOR.exit
|
RUBYGEMS_ACTIVATION_MONITOR.exit
|
||||||
return gem_original_require(path)
|
return gem_original_require(path)
|
||||||
end if spec
|
end
|
||||||
|
|
||||||
# Attempt to find +path+ in any unresolved gems...
|
# Attempt to find +path+ in any unresolved gems...
|
||||||
|
|
||||||
|
@ -109,7 +106,7 @@ module Kernel
|
||||||
|
|
||||||
# Ok, now find a gem that has no conflicts, starting
|
# Ok, now find a gem that has no conflicts, starting
|
||||||
# at the highest version.
|
# at the highest version.
|
||||||
valid = found_specs.reject { |s| s.has_conflicts? }.first
|
valid = found_specs.find { |s| !s.has_conflicts? }
|
||||||
|
|
||||||
unless valid then
|
unless valid then
|
||||||
le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate"
|
le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate"
|
||||||
|
@ -143,4 +140,3 @@ module Kernel
|
||||||
private :require
|
private :require
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,8 @@ class Gem::Dependency
|
||||||
requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
|
requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
|
||||||
}.map(&:to_spec)
|
}.map(&:to_spec)
|
||||||
|
|
||||||
|
Gem::BundlerVersionFinder.filter!(matches) if name == "bundler".freeze
|
||||||
|
|
||||||
if platform_only
|
if platform_only
|
||||||
matches.reject! { |spec|
|
matches.reject! { |spec|
|
||||||
spec.nil? || !Gem::Platform.match(spec.platform)
|
spec.nil? || !Gem::Platform.match(spec.platform)
|
||||||
|
|
|
@ -7,6 +7,7 @@ require 'rubygems/spec_fetcher'
|
||||||
require 'rubygems/user_interaction'
|
require 'rubygems/user_interaction'
|
||||||
require 'rubygems/source'
|
require 'rubygems/source'
|
||||||
require 'rubygems/available_set'
|
require 'rubygems/available_set'
|
||||||
|
require 'rubygems/deprecate'
|
||||||
|
|
||||||
##
|
##
|
||||||
# Installs a gem along with all its dependencies from local and remote gems.
|
# Installs a gem along with all its dependencies from local and remote gems.
|
||||||
|
@ -46,6 +47,9 @@ class Gem::DependencyInstaller
|
||||||
|
|
||||||
attr_reader :gems_to_install # :nodoc:
|
attr_reader :gems_to_install # :nodoc:
|
||||||
|
|
||||||
|
extend Gem::Deprecate
|
||||||
|
deprecate :gems_to_install, :none, 2016, 10
|
||||||
|
|
||||||
##
|
##
|
||||||
# List of gems installed by #install in alphabetic order
|
# List of gems installed by #install in alphabetic order
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,9 @@ module Gem
|
||||||
private
|
private
|
||||||
|
|
||||||
def build_message
|
def build_message
|
||||||
|
if name == "bundler" && message = Gem::BundlerVersionFinder.missing_version_message
|
||||||
|
return message
|
||||||
|
end
|
||||||
names = specs.map(&:full_name)
|
names = specs.map(&:full_name)
|
||||||
"Could not find '#{name}' (#{requirement}) - did find: [#{names.join ','}]\n"
|
"Could not find '#{name}' (#{requirement}) - did find: [#{names.join ','}]\n"
|
||||||
end
|
end
|
||||||
|
|
|
@ -154,6 +154,12 @@ class Gem::ImpossibleDependenciesError < Gem::Exception
|
||||||
end
|
end
|
||||||
|
|
||||||
class Gem::InstallError < Gem::Exception; end
|
class Gem::InstallError < Gem::Exception; end
|
||||||
|
class Gem::RuntimeRequirementNotMetError < Gem::InstallError
|
||||||
|
attr_accessor :suggestion
|
||||||
|
def message
|
||||||
|
[suggestion, super].compact.join("\n\t")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Potentially raised when a specification is validated.
|
# Potentially raised when a specification is validated.
|
||||||
|
|
|
@ -183,7 +183,7 @@ EOF
|
||||||
return if @spec.extensions.empty?
|
return if @spec.extensions.empty?
|
||||||
|
|
||||||
if @build_args.empty?
|
if @build_args.empty?
|
||||||
say "Building native extensions. This could take a while..."
|
say "Building native extensions. This could take a while..."
|
||||||
else
|
else
|
||||||
say "Building native extensions with: '#{@build_args.join ' '}'"
|
say "Building native extensions with: '#{@build_args.join ' '}'"
|
||||||
say "This could take a while..."
|
say "This could take a while..."
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
require 'rubygems/command_manager'
|
require 'rubygems/command_manager'
|
||||||
require 'rubygems/config_file'
|
require 'rubygems/config_file'
|
||||||
|
require 'rubygems/deprecate'
|
||||||
|
|
||||||
##
|
##
|
||||||
# Load additional plugins from $LOAD_PATH
|
# Load additional plugins from $LOAD_PATH
|
||||||
|
@ -26,7 +27,10 @@ Gem.load_env_plugins rescue nil
|
||||||
class Gem::GemRunner
|
class Gem::GemRunner
|
||||||
|
|
||||||
def initialize(options={})
|
def initialize(options={})
|
||||||
# TODO: nuke these options
|
if !options.empty? && !Gem::Deprecate.skip
|
||||||
|
Kernel.warn "NOTE: passing options to Gem::GemRunner.new is deprecated with no replacement. It will be removed on or after 2016-10-01."
|
||||||
|
end
|
||||||
|
|
||||||
@command_manager_class = options[:command_manager] || Gem::CommandManager
|
@command_manager_class = options[:command_manager] || Gem::CommandManager
|
||||||
@config_file_class = options[:config_file] || Gem::ConfigFile
|
@config_file_class = options[:config_file] || Gem::ConfigFile
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,37 +6,18 @@
|
||||||
#++
|
#++
|
||||||
|
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
require 'rubygems/security_option'
|
||||||
# forward-declare
|
|
||||||
|
|
||||||
module Gem::Security # :nodoc:
|
|
||||||
class Policy # :nodoc:
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Mixin methods for install and update options for Gem::Commands
|
# Mixin methods for install and update options for Gem::Commands
|
||||||
|
|
||||||
module Gem::InstallUpdateOptions
|
module Gem::InstallUpdateOptions
|
||||||
|
include Gem::SecurityOption
|
||||||
|
|
||||||
##
|
##
|
||||||
# Add the install/update options to the option parser.
|
# Add the install/update options to the option parser.
|
||||||
|
|
||||||
def add_install_update_options
|
def add_install_update_options
|
||||||
# TODO: use @parser.accept
|
|
||||||
OptionParser.accept Gem::Security::Policy do |value|
|
|
||||||
require 'rubygems/security'
|
|
||||||
|
|
||||||
raise OptionParser::InvalidArgument, 'OpenSSL not installed' unless
|
|
||||||
defined?(Gem::Security::HighSecurity)
|
|
||||||
|
|
||||||
value = Gem::Security::Policies[value]
|
|
||||||
valid = Gem::Security::Policies.keys.sort
|
|
||||||
message = "#{value} (#{valid.join ', '} are valid)"
|
|
||||||
raise OptionParser::InvalidArgument, message if value.nil?
|
|
||||||
value
|
|
||||||
end
|
|
||||||
|
|
||||||
add_option(:"Install/Update", '-i', '--install-dir DIR',
|
add_option(:"Install/Update", '-i', '--install-dir DIR',
|
||||||
'Gem repository directory to get installed',
|
'Gem repository directory to get installed',
|
||||||
'gems') do |value, options|
|
'gems') do |value, options|
|
||||||
|
@ -124,11 +105,7 @@ module Gem::InstallUpdateOptions
|
||||||
options[:wrappers] = value
|
options[:wrappers] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
add_option(:"Install/Update", '-P', '--trust-policy POLICY',
|
add_security_option
|
||||||
Gem::Security::Policy,
|
|
||||||
'Specify gem trust policy') do |value, options|
|
|
||||||
options[:security_policy] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
add_option(:"Install/Update", '--ignore-dependencies',
|
add_option(:"Install/Update", '--ignore-dependencies',
|
||||||
'Do not install any required dependent gems') do |value, options|
|
'Do not install any required dependent gems') do |value, options|
|
||||||
|
@ -136,8 +113,8 @@ module Gem::InstallUpdateOptions
|
||||||
end
|
end
|
||||||
|
|
||||||
add_option(:"Install/Update", '--[no-]format-executable',
|
add_option(:"Install/Update", '--[no-]format-executable',
|
||||||
'Make installed executable names match ruby.',
|
'Make installed executable names match Ruby.',
|
||||||
'If ruby is ruby18, foo_exec will be',
|
'If Ruby is ruby18, foo_exec will be',
|
||||||
'foo_exec18') do |value, options|
|
'foo_exec18') do |value, options|
|
||||||
options[:format_executable] = value
|
options[:format_executable] = value
|
||||||
end
|
end
|
||||||
|
|
|
@ -136,8 +136,9 @@ class Gem::Installer
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Constructs an Installer instance that will install the gem located at
|
# Constructs an Installer instance that will install the gem at +package+ which
|
||||||
# +gem+. +options+ is a Hash with the following keys:
|
# can either be a path or an instance of Gem::Package. +options+ is a Hash
|
||||||
|
# with the following keys:
|
||||||
#
|
#
|
||||||
# :bin_dir:: Where to put a bin wrapper if needed.
|
# :bin_dir:: Where to put a bin wrapper if needed.
|
||||||
# :development:: Whether or not development dependencies should be installed.
|
# :development:: Whether or not development dependencies should be installed.
|
||||||
|
@ -157,6 +158,7 @@ class Gem::Installer
|
||||||
# :wrappers:: Install wrappers if true, symlinks if false.
|
# :wrappers:: Install wrappers if true, symlinks if false.
|
||||||
# :build_args:: An Array of arguments to pass to the extension builder
|
# :build_args:: An Array of arguments to pass to the extension builder
|
||||||
# process. If not set, then Gem::Command.build_args is used
|
# process. If not set, then Gem::Command.build_args is used
|
||||||
|
# :post_install_message:: Print gem post install message if true
|
||||||
|
|
||||||
def initialize(package, options={})
|
def initialize(package, options={})
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
|
@ -471,7 +473,7 @@ class Gem::Installer
|
||||||
|
|
||||||
unless File.exist? bin_path then
|
unless File.exist? bin_path then
|
||||||
# TODO change this to a more useful warning
|
# TODO change this to a more useful warning
|
||||||
warn "#{bin_path} maybe `gem pristine #{spec.name}` will fix it?"
|
warn "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -608,7 +610,9 @@ class Gem::Installer
|
||||||
def ensure_required_ruby_version_met # :nodoc:
|
def ensure_required_ruby_version_met # :nodoc:
|
||||||
if rrv = spec.required_ruby_version then
|
if rrv = spec.required_ruby_version then
|
||||||
unless rrv.satisfied_by? Gem.ruby_version then
|
unless rrv.satisfied_by? Gem.ruby_version then
|
||||||
raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}."
|
ruby_version = Gem.ruby_api_version
|
||||||
|
raise Gem::RuntimeRequirementNotMetError,
|
||||||
|
"#{spec.name} requires Ruby version #{rrv}. The current ruby version is #{ruby_version}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -616,8 +620,9 @@ class Gem::Installer
|
||||||
def ensure_required_rubygems_version_met # :nodoc:
|
def ensure_required_rubygems_version_met # :nodoc:
|
||||||
if rrgv = spec.required_rubygems_version then
|
if rrgv = spec.required_rubygems_version then
|
||||||
unless rrgv.satisfied_by? Gem.rubygems_version then
|
unless rrgv.satisfied_by? Gem.rubygems_version then
|
||||||
raise Gem::InstallError,
|
rg_version = Gem::VERSION
|
||||||
"#{spec.name} requires RubyGems version #{rrgv}. " +
|
raise Gem::RuntimeRequirementNotMetError,
|
||||||
|
"#{spec.name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " +
|
||||||
"Try 'gem update --system' to update RubyGems itself."
|
"Try 'gem update --system' to update RubyGems itself."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -821,7 +826,7 @@ TEXT
|
||||||
#
|
#
|
||||||
# Version and dependency checks are skipped if this install is forced.
|
# Version and dependency checks are skipped if this install is forced.
|
||||||
#
|
#
|
||||||
# The dependent check will be skipped this install is ignoring dependencies.
|
# The dependent check will be skipped if the install is ignoring dependencies.
|
||||||
|
|
||||||
def pre_install_checks
|
def pre_install_checks
|
||||||
verify_gem_home options[:unpack]
|
verify_gem_home options[:unpack]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require 'rubygems/test_case'
|
require 'rubygems/test_case'
|
||||||
require 'rubygems/installer'
|
require 'rubygems/installer'
|
||||||
|
require 'rubygems/deprecate'
|
||||||
|
|
||||||
class Gem::Installer
|
class Gem::Installer
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ class Gem::InstallerTestCase < Gem::TestCase
|
||||||
# a spec named 'a', intended for regular installs
|
# a spec named 'a', intended for regular installs
|
||||||
# @user_spec::
|
# @user_spec::
|
||||||
# a spec named 'b', intended for user installs
|
# a spec named 'b', intended for user installs
|
||||||
|
#
|
||||||
# @gem::
|
# @gem::
|
||||||
# the path to a built gem from @spec
|
# the path to a built gem from @spec
|
||||||
# @user_spec::
|
# @user_spec::
|
||||||
|
@ -107,15 +108,17 @@ class Gem::InstallerTestCase < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def util_gem_bindir spec = @spec # :nodoc:
|
def util_gem_bindir spec = @spec # :nodoc:
|
||||||
# TODO: deprecate
|
|
||||||
spec.bin_dir
|
spec.bin_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
def util_gem_dir spec = @spec # :nodoc:
|
def util_gem_dir spec = @spec # :nodoc:
|
||||||
# TODO: deprecate
|
|
||||||
spec.gem_dir
|
spec.gem_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
extend Gem::Deprecate
|
||||||
|
deprecate :util_gem_bindir, "@spec.bin_dir", 2016, 10
|
||||||
|
deprecate :util_gem_dir, "@spec.gem_dir", 2016, 10
|
||||||
|
|
||||||
##
|
##
|
||||||
# The path where installed executables live
|
# The path where installed executables live
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ class Gem::Package::Old < Gem::Package
|
||||||
break unless line
|
break unless line
|
||||||
end
|
end
|
||||||
|
|
||||||
raise Gem::Exception, "Failed to find end of ruby script while reading gem"
|
raise Gem::Exception, "Failed to find end of Ruby script while reading gem"
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -83,7 +83,7 @@ class Gem::Request
|
||||||
e.message =~ / -- openssl$/
|
e.message =~ / -- openssl$/
|
||||||
|
|
||||||
raise Gem::Exception.new(
|
raise Gem::Exception.new(
|
||||||
'Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources')
|
'Unable to require openssl, install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources')
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.verify_certificate store_context
|
def self.verify_certificate store_context
|
||||||
|
|
|
@ -163,9 +163,26 @@ class Gem::RequestSet
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
spec = req.spec.install options do |installer|
|
spec =
|
||||||
yield req, installer if block_given?
|
begin
|
||||||
end
|
req.spec.install options do |installer|
|
||||||
|
yield req, installer if block_given?
|
||||||
|
end
|
||||||
|
rescue Gem::RuntimeRequirementNotMetError => e
|
||||||
|
recent_match = req.spec.set.find_all(req.request).sort_by(&:version).reverse_each.find do |s|
|
||||||
|
s = s.spec
|
||||||
|
s.required_ruby_version.satisfied_by?(Gem.ruby_version) && s.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
|
||||||
|
end
|
||||||
|
if recent_match
|
||||||
|
suggestion = "The last version of #{req.request} to support your Ruby & RubyGems was #{recent_match.version}. Try installing it with `gem install #{recent_match.name} -v #{recent_match.version}`"
|
||||||
|
suggestion += " and then running the current command again" unless @always_install.include?(req.spec.spec)
|
||||||
|
else
|
||||||
|
suggestion = "There are no versions of #{req.request} compatible with your Ruby & RubyGems"
|
||||||
|
suggestion += ". Maybe try installing an older version of the gem you're looking for?" unless @always_install.include?(req.spec.spec)
|
||||||
|
end
|
||||||
|
e.suggestion = suggestion
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
|
||||||
requests << spec
|
requests << spec
|
||||||
end
|
end
|
||||||
|
|
|
@ -786,7 +786,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
|
||||||
engine_version = options[:engine_version]
|
engine_version = options[:engine_version]
|
||||||
|
|
||||||
raise ArgumentError,
|
raise ArgumentError,
|
||||||
'you must specify engine_version along with the ruby engine' if
|
'You must specify engine_version along with the Ruby engine' if
|
||||||
engine and not engine_version
|
engine and not engine_version
|
||||||
|
|
||||||
return true if @installing
|
return true if @installing
|
||||||
|
@ -799,7 +799,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
|
||||||
end
|
end
|
||||||
|
|
||||||
if engine and engine != Gem.ruby_engine then
|
if engine and engine != Gem.ruby_engine then
|
||||||
message = "Your ruby engine is #{Gem.ruby_engine}, " +
|
message = "Your Ruby engine is #{Gem.ruby_engine}, " +
|
||||||
"but your #{gem_deps_file} requires #{engine}"
|
"but your #{gem_deps_file} requires #{engine}"
|
||||||
|
|
||||||
raise Gem::RubyVersionMismatch, message
|
raise Gem::RubyVersionMismatch, message
|
||||||
|
@ -810,7 +810,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
|
||||||
|
|
||||||
if engine_version != my_engine_version then
|
if engine_version != my_engine_version then
|
||||||
message =
|
message =
|
||||||
"Your ruby engine version is #{Gem.ruby_engine} #{my_engine_version}, " +
|
"Your Ruby engine version is #{Gem.ruby_engine} #{my_engine_version}, " +
|
||||||
"but your #{gem_deps_file} requires #{engine} #{engine_version}"
|
"but your #{gem_deps_file} requires #{engine} #{engine_version}"
|
||||||
|
|
||||||
raise Gem::RubyVersionMismatch, message
|
raise Gem::RubyVersionMismatch, message
|
||||||
|
|
|
@ -51,7 +51,11 @@ class Gem::Requirement
|
||||||
# If the input is "weird", the default version requirement is
|
# If the input is "weird", the default version requirement is
|
||||||
# returned.
|
# returned.
|
||||||
|
|
||||||
def self.create input
|
def self.create *inputs
|
||||||
|
return new inputs if inputs.length > 1
|
||||||
|
|
||||||
|
input = inputs.shift
|
||||||
|
|
||||||
case input
|
case input
|
||||||
when Gem::Requirement then
|
when Gem::Requirement then
|
||||||
input
|
input
|
||||||
|
|
|
@ -230,8 +230,28 @@ class Gem::Resolver
|
||||||
exc.errors = @set.errors
|
exc.errors = @set.errors
|
||||||
raise exc
|
raise exc
|
||||||
end
|
end
|
||||||
possibles.sort_by { |s| [s.source, s.version, Gem::Platform.local =~ s.platform ? 1 : 0] }.
|
|
||||||
map { |s| ActivationRequest.new s, dependency, [] }
|
sources = []
|
||||||
|
|
||||||
|
groups = Hash.new { |hash, key| hash[key] = [] }
|
||||||
|
|
||||||
|
# create groups & sources in the same loop
|
||||||
|
sources = possibles.map { |spec|
|
||||||
|
source = spec.source
|
||||||
|
groups[source] << spec
|
||||||
|
source
|
||||||
|
}.uniq.reverse
|
||||||
|
|
||||||
|
activation_requests = []
|
||||||
|
|
||||||
|
sources.each do |source|
|
||||||
|
groups[source].
|
||||||
|
sort_by { |spec| [spec.version, Gem::Platform.local =~ spec.platform ? 1 : 0] }.
|
||||||
|
map { |spec| ActivationRequest.new spec, dependency, [] }.
|
||||||
|
each { |activation_request| activation_requests << activation_request }
|
||||||
|
end
|
||||||
|
|
||||||
|
activation_requests
|
||||||
end
|
end
|
||||||
|
|
||||||
def dependencies_for(specification)
|
def dependencies_for(specification)
|
||||||
|
|
|
@ -41,6 +41,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
||||||
@ignore_dependencies = false
|
@ignore_dependencies = false
|
||||||
@ignore_installed = false
|
@ignore_installed = false
|
||||||
@local = {}
|
@local = {}
|
||||||
|
@local_source = Gem::Source::Local.new
|
||||||
@remote_set = Gem::Resolver::BestSet.new
|
@remote_set = Gem::Resolver::BestSet.new
|
||||||
@specs = {}
|
@specs = {}
|
||||||
end
|
end
|
||||||
|
@ -136,13 +137,11 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
||||||
|
|
||||||
res.concat matching_local
|
res.concat matching_local
|
||||||
|
|
||||||
local_source = Gem::Source::Local.new
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if local_spec = local_source.find_gem(name, dep.requirement) then
|
if local_spec = @local_source.find_gem(name, dep.requirement) then
|
||||||
res << Gem::Resolver::IndexSpecification.new(
|
res << Gem::Resolver::IndexSpecification.new(
|
||||||
self, local_spec.name, local_spec.version,
|
self, local_spec.name, local_spec.version,
|
||||||
local_source, local_spec.platform)
|
@local_source, local_spec.platform)
|
||||||
end
|
end
|
||||||
rescue Gem::Package::FormatError
|
rescue Gem::Package::FormatError
|
||||||
# ignore
|
# ignore
|
||||||
|
@ -194,7 +193,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
||||||
# Has a local gem for +dep_name+ been added to this set?
|
# Has a local gem for +dep_name+ been added to this set?
|
||||||
|
|
||||||
def local? dep_name # :nodoc:
|
def local? dep_name # :nodoc:
|
||||||
spec, = @local[dep_name]
|
spec, _ = @local[dep_name]
|
||||||
|
|
||||||
spec
|
spec
|
||||||
end
|
end
|
||||||
|
@ -226,4 +225,3 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -340,7 +340,9 @@ module Gem::Security
|
||||||
# Digest algorithm used to sign gems
|
# Digest algorithm used to sign gems
|
||||||
|
|
||||||
DIGEST_ALGORITHM =
|
DIGEST_ALGORITHM =
|
||||||
if defined?(OpenSSL::Digest::SHA1) then
|
if defined?(OpenSSL::Digest::SHA256) then
|
||||||
|
OpenSSL::Digest::SHA256
|
||||||
|
elsif defined?(OpenSSL::Digest::SHA1) then
|
||||||
OpenSSL::Digest::SHA1
|
OpenSSL::Digest::SHA1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -363,7 +365,7 @@ module Gem::Security
|
||||||
##
|
##
|
||||||
# Length of keys created by KEY_ALGORITHM
|
# Length of keys created by KEY_ALGORITHM
|
||||||
|
|
||||||
KEY_LENGTH = 2048
|
KEY_LENGTH = 3072
|
||||||
|
|
||||||
##
|
##
|
||||||
# Cipher used to encrypt the key pair used to sign gems.
|
# Cipher used to encrypt the key pair used to sign gems.
|
||||||
|
@ -371,10 +373,15 @@ module Gem::Security
|
||||||
|
|
||||||
KEY_CIPHER = OpenSSL::Cipher.new('AES-256-CBC') if defined?(OpenSSL::Cipher)
|
KEY_CIPHER = OpenSSL::Cipher.new('AES-256-CBC') if defined?(OpenSSL::Cipher)
|
||||||
|
|
||||||
|
##
|
||||||
|
# One day in seconds
|
||||||
|
|
||||||
|
ONE_DAY = 86400
|
||||||
|
|
||||||
##
|
##
|
||||||
# One year in seconds
|
# One year in seconds
|
||||||
|
|
||||||
ONE_YEAR = 86400 * 365
|
ONE_YEAR = ONE_DAY * 365
|
||||||
|
|
||||||
##
|
##
|
||||||
# The default set of extensions are:
|
# The default set of extensions are:
|
||||||
|
|
43
lib/rubygems/security_option.rb
Normal file
43
lib/rubygems/security_option.rb
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
#--
|
||||||
|
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
||||||
|
# All rights reserved.
|
||||||
|
# See LICENSE.txt for permissions.
|
||||||
|
#++
|
||||||
|
|
||||||
|
require 'rubygems'
|
||||||
|
|
||||||
|
# forward-declare
|
||||||
|
|
||||||
|
module Gem::Security # :nodoc:
|
||||||
|
class Policy # :nodoc:
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Mixin methods for security option for Gem::Commands
|
||||||
|
|
||||||
|
module Gem::SecurityOption
|
||||||
|
def add_security_option
|
||||||
|
# TODO: use @parser.accept
|
||||||
|
OptionParser.accept Gem::Security::Policy do |value|
|
||||||
|
require 'rubygems/security'
|
||||||
|
|
||||||
|
raise OptionParser::InvalidArgument, 'OpenSSL not installed' unless
|
||||||
|
defined?(Gem::Security::HighSecurity)
|
||||||
|
|
||||||
|
policy = Gem::Security::Policies[value]
|
||||||
|
unless policy
|
||||||
|
valid = Gem::Security::Policies.keys.sort
|
||||||
|
raise OptionParser::InvalidArgument, "#{value} (#{valid.join ', '} are valid)"
|
||||||
|
end
|
||||||
|
policy
|
||||||
|
end
|
||||||
|
|
||||||
|
add_option(:"Install/Update", '-P', '--trust-policy POLICY',
|
||||||
|
Gem::Security::Policy,
|
||||||
|
'Specify gem trust policy') do |value, options|
|
||||||
|
options[:security_policy] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -573,19 +573,11 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
||||||
add_date res
|
add_date res
|
||||||
|
|
||||||
case req.request_uri.path
|
case req.request_uri.path
|
||||||
when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+[^-]*?)(-.*?)?\.gemspec\.rz$| then
|
when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)\.gemspec\.rz$| then
|
||||||
marshal_format, name, version, platform = $1, $2, $3, $4
|
marshal_format, full_name = $1, $2
|
||||||
specs = Gem::Specification.find_all_by_name name, version
|
specs = Gem::Specification.find_all_by_full_name(full_name)
|
||||||
|
|
||||||
selector = [name, version, platform].map(&:inspect).join ' '
|
selector = full_name.inspect
|
||||||
|
|
||||||
platform = if platform then
|
|
||||||
Gem::Platform.new platform.sub(/^-/, '')
|
|
||||||
else
|
|
||||||
Gem::Platform::RUBY
|
|
||||||
end
|
|
||||||
|
|
||||||
specs = specs.select { |s| s.platform == platform }
|
|
||||||
|
|
||||||
if specs.empty? then
|
if specs.empty? then
|
||||||
res.status = 404
|
res.status = 404
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require 'uri'
|
autoload :FileUtils, 'fileutils'
|
||||||
require 'fileutils'
|
autoload :URI, 'uri'
|
||||||
|
|
||||||
##
|
##
|
||||||
# A Source knows how to list and fetch gems from a RubyGems marshal index.
|
# A Source knows how to list and fetch gems from a RubyGems marshal index.
|
||||||
|
@ -67,7 +67,11 @@ class Gem::Source
|
||||||
|
|
||||||
return -1 if !other.uri
|
return -1 if !other.uri
|
||||||
|
|
||||||
@uri.to_s <=> other.uri.to_s
|
# Returning 1 here ensures that when sorting a list of sources, the
|
||||||
|
# original ordering of sources supplied by the user is preserved.
|
||||||
|
return 1 unless @uri.to_s == other.uri.to_s
|
||||||
|
|
||||||
|
0
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -232,4 +236,3 @@ require 'rubygems/source/specific_file'
|
||||||
require 'rubygems/source/local'
|
require 'rubygems/source/local'
|
||||||
require 'rubygems/source/lock'
|
require 'rubygems/source/lock'
|
||||||
require 'rubygems/source/vendor'
|
require 'rubygems/source/vendor'
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require 'digest'
|
|
||||||
require 'rubygems/util'
|
require 'rubygems/util'
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -226,6 +225,8 @@ class Gem::Source::Git < Gem::Source
|
||||||
# A hash for the git gem based on the git repository URI.
|
# A hash for the git gem based on the git repository URI.
|
||||||
|
|
||||||
def uri_hash # :nodoc:
|
def uri_hash # :nodoc:
|
||||||
|
require 'digest' # required here to avoid deadlocking in Gem.activate_bin_path (because digest is a gem on 2.5+)
|
||||||
|
|
||||||
normalized =
|
normalized =
|
||||||
if @repository =~ %r%^\w+://(\w+@)?% then
|
if @repository =~ %r%^\w+://(\w+@)?% then
|
||||||
uri = URI(@repository).normalize.to_s.sub %r%/$%,''
|
uri = URI(@repository).normalize.to_s.sub %r%/$%,''
|
||||||
|
|
|
@ -9,6 +9,7 @@ class Gem::Source::Local < Gem::Source
|
||||||
@specs = nil
|
@specs = nil
|
||||||
@api_uri = nil
|
@api_uri = nil
|
||||||
@uri = nil
|
@uri = nil
|
||||||
|
@load_specs_names = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -34,45 +35,47 @@ class Gem::Source::Local < Gem::Source
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_specs type # :nodoc:
|
def load_specs type # :nodoc:
|
||||||
names = []
|
@load_specs_names[type] ||= begin
|
||||||
|
names = []
|
||||||
|
|
||||||
@specs = {}
|
@specs = {}
|
||||||
|
|
||||||
Dir["*.gem"].each do |file|
|
Dir["*.gem"].each do |file|
|
||||||
begin
|
begin
|
||||||
pkg = Gem::Package.new(file)
|
pkg = Gem::Package.new(file)
|
||||||
rescue SystemCallError, Gem::Package::FormatError
|
rescue SystemCallError, Gem::Package::FormatError
|
||||||
# ignore
|
# ignore
|
||||||
else
|
|
||||||
tup = pkg.spec.name_tuple
|
|
||||||
@specs[tup] = [File.expand_path(file), pkg]
|
|
||||||
|
|
||||||
case type
|
|
||||||
when :released
|
|
||||||
unless pkg.spec.version.prerelease?
|
|
||||||
names << pkg.spec.name_tuple
|
|
||||||
end
|
|
||||||
when :prerelease
|
|
||||||
if pkg.spec.version.prerelease?
|
|
||||||
names << pkg.spec.name_tuple
|
|
||||||
end
|
|
||||||
when :latest
|
|
||||||
tup = pkg.spec.name_tuple
|
|
||||||
|
|
||||||
cur = names.find { |x| x.name == tup.name }
|
|
||||||
if !cur
|
|
||||||
names << tup
|
|
||||||
elsif cur.version < tup.version
|
|
||||||
names.delete cur
|
|
||||||
names << tup
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
names << pkg.spec.name_tuple
|
tup = pkg.spec.name_tuple
|
||||||
|
@specs[tup] = [File.expand_path(file), pkg]
|
||||||
|
|
||||||
|
case type
|
||||||
|
when :released
|
||||||
|
unless pkg.spec.version.prerelease?
|
||||||
|
names << pkg.spec.name_tuple
|
||||||
|
end
|
||||||
|
when :prerelease
|
||||||
|
if pkg.spec.version.prerelease?
|
||||||
|
names << pkg.spec.name_tuple
|
||||||
|
end
|
||||||
|
when :latest
|
||||||
|
tup = pkg.spec.name_tuple
|
||||||
|
|
||||||
|
cur = names.find { |x| x.name == tup.name }
|
||||||
|
if !cur
|
||||||
|
names << tup
|
||||||
|
elsif cur.version < tup.version
|
||||||
|
names.delete cur
|
||||||
|
names << tup
|
||||||
|
end
|
||||||
|
else
|
||||||
|
names << pkg.spec.name_tuple
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
names
|
names
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
|
def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
|
||||||
|
@ -88,7 +91,7 @@ class Gem::Source::Local < Gem::Source
|
||||||
if version.satisfied_by?(s.version)
|
if version.satisfied_by?(s.version)
|
||||||
if prerelease
|
if prerelease
|
||||||
found << s
|
found << s
|
||||||
elsif !s.version.prerelease?
|
elsif !s.version.prerelease? || version.prerelease?
|
||||||
found << s
|
found << s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,6 +34,10 @@ class Gem::Source::Lock < Gem::Source
|
||||||
0 == (self <=> other)
|
0 == (self <=> other)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def hash # :nodoc:
|
||||||
|
@wrapped.hash ^ 3
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Delegates to the wrapped source's fetch_spec method.
|
# Delegates to the wrapped source's fetch_spec method.
|
||||||
|
|
||||||
|
@ -46,4 +50,3 @@ class Gem::Source::Lock < Gem::Source
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,5 +2,7 @@
|
||||||
require 'rubygems/source'
|
require 'rubygems/source'
|
||||||
require 'rubygems/source_local'
|
require 'rubygems/source_local'
|
||||||
|
|
||||||
# TODO warn upon require, this file is deprecated.
|
unless Gem::Deprecate.skip
|
||||||
|
Kernel.warn "#{Gem.location_of_caller(3).join(':')}: Warning: Requiring rubygems/source_local is deprecated; please use rubygems/source/local instead."
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require 'rubygems/source/specific_file'
|
require 'rubygems/source/specific_file'
|
||||||
|
|
||||||
# TODO warn upon require, this file is deprecated.
|
unless Gem::Deprecate.skip
|
||||||
|
Kernel.warn "#{Gem.location_of_caller(3).join(':')}: Warning: Requiring rubygems/source_specific_file is deprecated; please use rubygems/source/specific_file instead."
|
||||||
|
end
|
||||||
|
|
|
@ -184,10 +184,10 @@ class Gem::SpecFetcher
|
||||||
# Suggests gems based on the supplied +gem_name+. Returns an array of
|
# Suggests gems based on the supplied +gem_name+. Returns an array of
|
||||||
# alternative gem names.
|
# alternative gem names.
|
||||||
|
|
||||||
def suggest_gems_from_name gem_name
|
def suggest_gems_from_name(gem_name, type = :latest)
|
||||||
gem_name = gem_name.downcase.tr('_-', '')
|
gem_name = gem_name.downcase.tr('_-', '')
|
||||||
max = gem_name.size / 2
|
max = gem_name.size / 2
|
||||||
names = available_specs(:latest).first.values.flatten(1)
|
names = available_specs(type).first.values.flatten(1)
|
||||||
|
|
||||||
matches = names.map { |n|
|
matches = names.map { |n|
|
||||||
next unless n.match_platform?
|
next unless n.match_platform?
|
||||||
|
@ -201,7 +201,11 @@ class Gem::SpecFetcher
|
||||||
[n.name, distance]
|
[n.name, distance]
|
||||||
}.compact
|
}.compact
|
||||||
|
|
||||||
matches = matches.uniq.sort_by { |name, dist| dist }
|
matches = if matches.empty? && type != :prerelease
|
||||||
|
suggest_gems_from_name gem_name, :prerelease
|
||||||
|
else
|
||||||
|
matches.uniq.sort_by { |name, dist| dist }
|
||||||
|
end
|
||||||
|
|
||||||
matches.first(5).map { |name, dist| name }
|
matches.first(5).map { |name, dist| name }
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,6 +30,7 @@ require 'stringio'
|
||||||
# s.email = 'rubycoder@example.com'
|
# s.email = 'rubycoder@example.com'
|
||||||
# s.files = ["lib/example.rb"]
|
# s.files = ["lib/example.rb"]
|
||||||
# s.homepage = 'https://rubygems.org/gems/example'
|
# s.homepage = 'https://rubygems.org/gems/example'
|
||||||
|
# s.metadata = { "source_code_uri" => "https://github.com/example/example" }
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# Starting in RubyGems 2.0, a Specification can hold arbitrary
|
# Starting in RubyGems 2.0, a Specification can hold arbitrary
|
||||||
|
@ -157,16 +158,20 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
:summary => nil,
|
:summary => nil,
|
||||||
:test_files => [],
|
:test_files => [],
|
||||||
:version => nil,
|
:version => nil,
|
||||||
}
|
}.freeze
|
||||||
|
|
||||||
Dupable = { } # :nodoc:
|
INITIALIZE_CODE_FOR_DEFAULTS = { } # :nodoc:
|
||||||
|
|
||||||
@@default_value.each do |k,v|
|
@@default_value.each do |k,v|
|
||||||
case v
|
INITIALIZE_CODE_FOR_DEFAULTS[k] = case v
|
||||||
when Time, Numeric, Symbol, true, false, nil
|
when [], {}, true, false, nil, Numeric, Symbol
|
||||||
Dupable[k] = false
|
v.inspect
|
||||||
|
when String
|
||||||
|
v.dump
|
||||||
|
when Numeric
|
||||||
|
"default_value(:#{k})"
|
||||||
else
|
else
|
||||||
Dupable[k] = true
|
"default_value(:#{k}).dup"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -208,34 +213,6 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
|
|
||||||
attr_reader :version
|
attr_reader :version
|
||||||
|
|
||||||
##
|
|
||||||
# Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
|
|
||||||
# activated.
|
|
||||||
#--
|
|
||||||
# See also #require_paths
|
|
||||||
#++
|
|
||||||
# If you have an extension you do not need to add <code>"ext"</code> to the
|
|
||||||
# require path, the extension build process will copy the extension files
|
|
||||||
# into "lib" for you.
|
|
||||||
#
|
|
||||||
# The default value is <code>"lib"</code>
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
|
||||||
# # If all library files are in the root directory...
|
|
||||||
# spec.require_paths = ['.']
|
|
||||||
|
|
||||||
def require_paths=(val)
|
|
||||||
@require_paths = Array(val)
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# The version of RubyGems used to create this gem.
|
|
||||||
#
|
|
||||||
# Do not set this, it is set automatically when the gem is packaged.
|
|
||||||
|
|
||||||
attr_accessor :rubygems_version
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# A short summary of this gem's description. Displayed in `gem list -d`.
|
# A short summary of this gem's description. Displayed in `gem list -d`.
|
||||||
#
|
#
|
||||||
|
@ -247,6 +224,42 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
|
|
||||||
attr_reader :summary
|
attr_reader :summary
|
||||||
|
|
||||||
|
##
|
||||||
|
# Files included in this gem. You cannot append to this accessor, you must
|
||||||
|
# assign to it.
|
||||||
|
#
|
||||||
|
# Only add files you can require to this list, not directories, etc.
|
||||||
|
#
|
||||||
|
# Directories are automatically stripped from this list when building a gem,
|
||||||
|
# other non-files cause an error.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# require 'rake'
|
||||||
|
# spec.files = FileList['lib/**/*.rb',
|
||||||
|
# 'bin/*',
|
||||||
|
# '[A-Z]*',
|
||||||
|
# 'test/**/*'].to_a
|
||||||
|
#
|
||||||
|
# # or without Rake...
|
||||||
|
# spec.files = Dir['lib/**/*.rb'] + Dir['bin/*']
|
||||||
|
# spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
|
||||||
|
# spec.files.reject! { |fn| fn.include? "CVS" }
|
||||||
|
|
||||||
|
def files
|
||||||
|
# DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks)
|
||||||
|
# DOC: Why isn't it normal? Why does it suck? How can we fix this?
|
||||||
|
@files = [@files,
|
||||||
|
@test_files,
|
||||||
|
add_bindir(@executables),
|
||||||
|
@extra_rdoc_files,
|
||||||
|
@extensions,
|
||||||
|
].flatten.compact.uniq.sort
|
||||||
|
end
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# :section: Recommended gemspec attributes
|
||||||
|
|
||||||
##
|
##
|
||||||
# Singular writer for #authors
|
# Singular writer for #authors
|
||||||
#
|
#
|
||||||
|
@ -269,6 +282,148 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
@authors = Array(value).flatten.grep(String)
|
@authors = Array(value).flatten.grep(String)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# A long description of this gem
|
||||||
|
#
|
||||||
|
# The description should be more detailed than the summary but not
|
||||||
|
# excessively long. A few paragraphs is a recommended length with no
|
||||||
|
# examples or formatting.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# spec.description = <<-EOF
|
||||||
|
# Rake is a Make-like program implemented in Ruby. Tasks and
|
||||||
|
# dependencies are specified in standard Ruby syntax.
|
||||||
|
# EOF
|
||||||
|
|
||||||
|
attr_reader :description
|
||||||
|
|
||||||
|
##
|
||||||
|
# A contact email address (or addresses) for this gem
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# spec.email = 'john.jones@example.com'
|
||||||
|
# spec.email = ['jack@example.com', 'jill@example.com']
|
||||||
|
|
||||||
|
attr_accessor :email
|
||||||
|
|
||||||
|
##
|
||||||
|
# The URL of this gem's home page
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# spec.homepage = 'https://github.com/ruby/rake'
|
||||||
|
|
||||||
|
attr_accessor :homepage
|
||||||
|
|
||||||
|
##
|
||||||
|
# The license for this gem.
|
||||||
|
#
|
||||||
|
# The license must be no more than 64 characters.
|
||||||
|
#
|
||||||
|
# This should just be the name of your license. The full text of the license
|
||||||
|
# should be inside of the gem (at the top level) when you build it.
|
||||||
|
#
|
||||||
|
# The simplest way, is to specify the standard SPDX ID
|
||||||
|
# https://spdx.org/licenses/ for the license.
|
||||||
|
# Ideally you should pick one that is OSI (Open Source Initiative)
|
||||||
|
# http://opensource.org/licenses/alphabetical approved.
|
||||||
|
#
|
||||||
|
# The most commonly used OSI approved licenses are MIT and Apache-2.0.
|
||||||
|
# GitHub also provides a license picker at http://choosealicense.com/.
|
||||||
|
#
|
||||||
|
# You should specify a license for your gem so that people know how they are
|
||||||
|
# permitted to use it, and any restrictions you're placing on it. Not
|
||||||
|
# specifying a license means all rights are reserved; others have no rights
|
||||||
|
# to use the code for any purpose.
|
||||||
|
#
|
||||||
|
# You can set multiple licenses with #licenses=
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# spec.license = 'MIT'
|
||||||
|
|
||||||
|
def license=o
|
||||||
|
self.licenses = [o]
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# The license(s) for the library.
|
||||||
|
#
|
||||||
|
# Each license must be a short name, no more than 64 characters.
|
||||||
|
#
|
||||||
|
# This should just be the name of your license. The full
|
||||||
|
# text of the license should be inside of the gem when you build it.
|
||||||
|
#
|
||||||
|
# See #license= for more discussion
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# spec.licenses = ['MIT', 'GPL-2.0']
|
||||||
|
|
||||||
|
def licenses= licenses
|
||||||
|
@licenses = Array licenses
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# The metadata holds extra data for this gem that may be useful to other
|
||||||
|
# consumers and is settable by gem authors without requiring an update to
|
||||||
|
# the rubygems software.
|
||||||
|
#
|
||||||
|
# Metadata items have the following restrictions:
|
||||||
|
#
|
||||||
|
# * The metadata must be a Hash object
|
||||||
|
# * All keys and values must be Strings
|
||||||
|
# * Keys can be a maximum of 128 bytes and values can be a maximum of 1024
|
||||||
|
# bytes
|
||||||
|
# * All strings must be UTF-8, no binary data is allowed
|
||||||
|
#
|
||||||
|
# You can use metadata to specify links to your gem's homepage, codebase,
|
||||||
|
# documentation, wiki, mailing list, issue tracker and changelog.
|
||||||
|
#
|
||||||
|
# s.metadata = {
|
||||||
|
# "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
|
||||||
|
# "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
|
||||||
|
# "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
|
||||||
|
# "homepage_uri" => "https://bestgemever.example.io",
|
||||||
|
# "mailing_list_uri" => "https://groups.example.com/bestgemever",
|
||||||
|
# "source_code_uri" => "https://example.com/user/bestgemever",
|
||||||
|
# "wiki_uri" => "https://example.com/user/bestgemever/wiki"
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# These links will be used on your gem's page on rubygems.org and must pass
|
||||||
|
# validation against following regex.
|
||||||
|
#
|
||||||
|
# %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}
|
||||||
|
|
||||||
|
attr_accessor :metadata
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# :section: Optional gemspec attributes
|
||||||
|
|
||||||
|
##
|
||||||
|
# The path in the gem for executable scripts. Usually 'bin'
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# spec.bindir = 'bin'
|
||||||
|
|
||||||
|
attr_accessor :bindir
|
||||||
|
|
||||||
|
##
|
||||||
|
# The certificate chain used to sign this gem. See Gem::Security for
|
||||||
|
# details.
|
||||||
|
|
||||||
|
attr_accessor :cert_chain
|
||||||
|
|
||||||
|
##
|
||||||
|
# A message that gets displayed after the gem is installed.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# spec.post_install_message = "Thanks for installing!"
|
||||||
|
|
||||||
|
attr_accessor :post_install_message
|
||||||
|
|
||||||
##
|
##
|
||||||
# The platform this gem runs on.
|
# The platform this gem runs on.
|
||||||
#
|
#
|
||||||
|
@ -327,104 +482,26 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Files included in this gem. You cannot append to this accessor, you must
|
# Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
|
||||||
# assign to it.
|
# activated.
|
||||||
|
#--
|
||||||
|
# See also #require_paths
|
||||||
|
#++
|
||||||
|
# If you have an extension you do not need to add <code>"ext"</code> to the
|
||||||
|
# require path, the extension build process will copy the extension files
|
||||||
|
# into "lib" for you.
|
||||||
#
|
#
|
||||||
# Only add files you can require to this list, not directories, etc.
|
# The default value is <code>"lib"</code>
|
||||||
#
|
|
||||||
# Directories are automatically stripped from this list when building a gem,
|
|
||||||
# other non-files cause an error.
|
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
#
|
#
|
||||||
# require 'rake'
|
# # If all library files are in the root directory...
|
||||||
# spec.files = FileList['lib/**/*.rb',
|
# spec.require_paths = ['.']
|
||||||
# 'bin/*',
|
|
||||||
# '[A-Z]*',
|
|
||||||
# 'test/**/*'].to_a
|
|
||||||
#
|
|
||||||
# # or without Rake...
|
|
||||||
# spec.files = Dir['lib/**/*.rb'] + Dir['bin/*']
|
|
||||||
# spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
|
|
||||||
# spec.files.reject! { |fn| fn.include? "CVS" }
|
|
||||||
|
|
||||||
def files
|
def require_paths=(val)
|
||||||
# DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks)
|
@require_paths = Array(val)
|
||||||
# DOC: Why isn't it normal? Why does it suck? How can we fix this?
|
|
||||||
@files = [@files,
|
|
||||||
@test_files,
|
|
||||||
add_bindir(@executables),
|
|
||||||
@extra_rdoc_files,
|
|
||||||
@extensions,
|
|
||||||
].flatten.compact.uniq.sort
|
|
||||||
end
|
end
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# :section: Optional gemspec attributes
|
|
||||||
|
|
||||||
##
|
|
||||||
# The path in the gem for executable scripts. Usually 'bin'
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
|
||||||
# spec.bindir = 'bin'
|
|
||||||
|
|
||||||
attr_accessor :bindir
|
|
||||||
|
|
||||||
##
|
|
||||||
# The certificate chain used to sign this gem. See Gem::Security for
|
|
||||||
# details.
|
|
||||||
|
|
||||||
attr_accessor :cert_chain
|
|
||||||
|
|
||||||
##
|
|
||||||
# A long description of this gem
|
|
||||||
#
|
|
||||||
# The description should be more detailed than the summary but not
|
|
||||||
# excessively long. A few paragraphs is a recommended length with no
|
|
||||||
# examples or formatting.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
|
||||||
# spec.description = <<-EOF
|
|
||||||
# Rake is a Make-like program implemented in Ruby. Tasks and
|
|
||||||
# dependencies are specified in standard Ruby syntax.
|
|
||||||
# EOF
|
|
||||||
|
|
||||||
attr_reader :description
|
|
||||||
|
|
||||||
##
|
|
||||||
# :category: Recommended gemspec attributes
|
|
||||||
#
|
|
||||||
# A contact email address (or addresses) for this gem
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
|
||||||
# spec.email = 'john.jones@example.com'
|
|
||||||
# spec.email = ['jack@example.com', 'jill@example.com']
|
|
||||||
|
|
||||||
attr_accessor :email
|
|
||||||
|
|
||||||
##
|
|
||||||
# :category: Recommended gemspec attributes
|
|
||||||
#
|
|
||||||
# The URL of this gem's home page
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
|
||||||
# spec.homepage = 'https://github.com/ruby/rake'
|
|
||||||
|
|
||||||
attr_accessor :homepage
|
|
||||||
|
|
||||||
##
|
|
||||||
# A message that gets displayed after the gem is installed.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
|
||||||
# spec.post_install_message = "Thanks for installing!"
|
|
||||||
|
|
||||||
attr_accessor :post_install_message
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# The version of Ruby required by this gem
|
# The version of Ruby required by this gem
|
||||||
|
|
||||||
|
@ -435,32 +512,18 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
|
|
||||||
attr_reader :required_rubygems_version
|
attr_reader :required_rubygems_version
|
||||||
|
|
||||||
|
##
|
||||||
|
# The version of RubyGems used to create this gem.
|
||||||
|
#
|
||||||
|
# Do not set this, it is set automatically when the gem is packaged.
|
||||||
|
|
||||||
|
attr_accessor :rubygems_version
|
||||||
|
|
||||||
##
|
##
|
||||||
# The key used to sign this gem. See Gem::Security for details.
|
# The key used to sign this gem. See Gem::Security for details.
|
||||||
|
|
||||||
attr_accessor :signing_key
|
attr_accessor :signing_key
|
||||||
|
|
||||||
##
|
|
||||||
# :attr_accessor: metadata
|
|
||||||
#
|
|
||||||
# The metadata holds extra data for this gem that may be useful to other
|
|
||||||
# consumers and is settable by gem authors without requiring an update to
|
|
||||||
# the rubygems software.
|
|
||||||
#
|
|
||||||
# Metadata items have the following restrictions:
|
|
||||||
#
|
|
||||||
# * The metadata must be a Hash object
|
|
||||||
# * All keys and values must be Strings
|
|
||||||
# * Keys can be a maximum of 128 bytes and values can be a maximum of 1024
|
|
||||||
# bytes
|
|
||||||
# * All strings must be UTF-8, no binary data is allowed
|
|
||||||
#
|
|
||||||
# To add metadata for the location of a issue tracker:
|
|
||||||
#
|
|
||||||
# s.metadata = { "issue_tracker" => "https://example/issues" }
|
|
||||||
|
|
||||||
attr_accessor :metadata
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Adds a development dependency named +gem+ with +requirements+ to this
|
# Adds a development dependency named +gem+ with +requirements+ to this
|
||||||
# gem.
|
# gem.
|
||||||
|
@ -473,7 +536,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
# activated when a gem is required.
|
# activated when a gem is required.
|
||||||
|
|
||||||
def add_development_dependency(gem, *requirements)
|
def add_development_dependency(gem, *requirements)
|
||||||
add_dependency_with_type(gem, :development, *requirements)
|
add_dependency_with_type(gem, :development, requirements)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -484,7 +547,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
# spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
|
# spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
|
||||||
|
|
||||||
def add_runtime_dependency(gem, *requirements)
|
def add_runtime_dependency(gem, *requirements)
|
||||||
add_dependency_with_type(gem, :runtime, *requirements)
|
add_dependency_with_type(gem, :runtime, requirements)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -556,56 +619,6 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
@installed_by_version = Gem::Version.new version
|
@installed_by_version = Gem::Version.new version
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
|
||||||
# :category: Recommended gemspec attributes
|
|
||||||
#
|
|
||||||
# The license for this gem.
|
|
||||||
#
|
|
||||||
# The license must be no more than 64 characters.
|
|
||||||
#
|
|
||||||
# This should just be the name of your license. The full text of the license
|
|
||||||
# should be inside of the gem (at the top level) when you build it.
|
|
||||||
#
|
|
||||||
# The simplest way, is to specify the standard SPDX ID
|
|
||||||
# https://spdx.org/licenses/ for the license.
|
|
||||||
# Ideally you should pick one that is OSI (Open Source Initiative)
|
|
||||||
# http://opensource.org/licenses/alphabetical approved.
|
|
||||||
#
|
|
||||||
# The most commonly used OSI approved licenses are MIT and Apache-2.0.
|
|
||||||
# GitHub also provides a license picker at http://choosealicense.com/.
|
|
||||||
#
|
|
||||||
# You should specify a license for your gem so that people know how they are
|
|
||||||
# permitted to use it, and any restrictions you're placing on it. Not
|
|
||||||
# specifying a license means all rights are reserved; others have no rights
|
|
||||||
# to use the code for any purpose.
|
|
||||||
#
|
|
||||||
# You can set multiple licenses with #licenses=
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# spec.license = 'MIT'
|
|
||||||
|
|
||||||
def license=o
|
|
||||||
self.licenses = [o]
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# :category: Recommended gemspec attributes
|
|
||||||
# The license(s) for the library.
|
|
||||||
#
|
|
||||||
# Each license must be a short name, no more than 64 characters.
|
|
||||||
#
|
|
||||||
# This should just be the name of your license. The full
|
|
||||||
# text of the license should be inside of the gem when you build it.
|
|
||||||
#
|
|
||||||
# See #license= for more discussion
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# spec.licenses = ['MIT', 'GPL-2.0']
|
|
||||||
|
|
||||||
def licenses= licenses
|
|
||||||
@licenses = Array licenses
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Specifies the rdoc options to be used when generating API documentation.
|
# Specifies the rdoc options to be used when generating API documentation.
|
||||||
#
|
#
|
||||||
|
@ -885,7 +898,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
# properly sorted.
|
# properly sorted.
|
||||||
|
|
||||||
def self.add_spec spec
|
def self.add_spec spec
|
||||||
warn "Gem::Specification.add_spec is deprecated and will be removed in Rubygems 3.0" unless Gem::Deprecate.skip
|
warn "Gem::Specification.add_spec is deprecated and will be removed in RubyGems 3.0" unless Gem::Deprecate.skip
|
||||||
# TODO: find all extraneous adds
|
# TODO: find all extraneous adds
|
||||||
# puts
|
# puts
|
||||||
# p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }]
|
# p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }]
|
||||||
|
@ -910,7 +923,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
# Adds multiple specs to the known specifications.
|
# Adds multiple specs to the known specifications.
|
||||||
|
|
||||||
def self.add_specs *specs
|
def self.add_specs *specs
|
||||||
warn "Gem::Specification.add_specs is deprecated and will be removed in Rubygems 3.0" unless Gem::Deprecate.skip
|
warn "Gem::Specification.add_specs is deprecated and will be removed in RubyGems 3.0" unless Gem::Deprecate.skip
|
||||||
|
|
||||||
raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy
|
raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy
|
||||||
|
|
||||||
|
@ -1022,6 +1035,13 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
Gem::Dependency.new(name, *requirements).matching_specs
|
Gem::Dependency.new(name, *requirements).matching_specs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns every spec that has the given +full_name+
|
||||||
|
|
||||||
|
def self.find_all_by_full_name(full_name)
|
||||||
|
stubs.select {|s| s.full_name == full_name }.map(&:to_spec)
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Find the best specification matching a +name+ and +requirements+. Raises
|
# Find the best specification matching a +name+ and +requirements+. Raises
|
||||||
# if the dependency doesn't resolve to a valid specification.
|
# if the dependency doesn't resolve to a valid specification.
|
||||||
|
@ -1040,6 +1060,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
def self.find_by_path path
|
def self.find_by_path path
|
||||||
path = path.dup.freeze
|
path = path.dup.freeze
|
||||||
spec = @@spec_with_requirable_file[path] ||= (stubs.find { |s|
|
spec = @@spec_with_requirable_file[path] ||= (stubs.find { |s|
|
||||||
|
next unless Gem::BundlerVersionFinder.compatible?(s)
|
||||||
s.contains_requirable_file? path
|
s.contains_requirable_file? path
|
||||||
} || NOT_FOUND)
|
} || NOT_FOUND)
|
||||||
spec.to_spec
|
spec.to_spec
|
||||||
|
@ -1051,7 +1072,9 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
|
|
||||||
def self.find_inactive_by_path path
|
def self.find_inactive_by_path path
|
||||||
stub = stubs.find { |s|
|
stub = stubs.find { |s|
|
||||||
s.contains_requirable_file? path unless s.activated?
|
next if s.activated?
|
||||||
|
next unless Gem::BundlerVersionFinder.compatible?(s)
|
||||||
|
s.contains_requirable_file? path
|
||||||
}
|
}
|
||||||
stub && stub.to_spec
|
stub && stub.to_spec
|
||||||
end
|
end
|
||||||
|
@ -1250,7 +1273,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
# Removes +spec+ from the known specs.
|
# Removes +spec+ from the known specs.
|
||||||
|
|
||||||
def self.remove_spec spec
|
def self.remove_spec spec
|
||||||
warn "Gem::Specification.remove_spec is deprecated and will be removed in Rubygems 3.0" unless Gem::Deprecate.skip
|
warn "Gem::Specification.remove_spec is deprecated and will be removed in RubyGems 3.0" unless Gem::Deprecate.skip
|
||||||
_all.delete spec
|
_all.delete spec
|
||||||
stubs.delete_if { |s| s.full_name == spec.full_name }
|
stubs.delete_if { |s| s.full_name == spec.full_name }
|
||||||
(@@stubs_by_name[spec.name] || []).delete_if { |s| s.full_name == spec.full_name }
|
(@@stubs_by_name[spec.name] || []).delete_if { |s| s.full_name == spec.full_name }
|
||||||
|
@ -1520,7 +1543,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
# +requirements+. Valid types are currently <tt>:runtime</tt> and
|
# +requirements+. Valid types are currently <tt>:runtime</tt> and
|
||||||
# <tt>:development</tt>.
|
# <tt>:development</tt>.
|
||||||
|
|
||||||
def add_dependency_with_type(dependency, type, *requirements)
|
def add_dependency_with_type(dependency, type, requirements)
|
||||||
requirements = if requirements.empty? then
|
requirements = if requirements.empty? then
|
||||||
Gem::Requirement.default
|
Gem::Requirement.default
|
||||||
else
|
else
|
||||||
|
@ -2026,6 +2049,20 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
yaml_initialize coder.tag, coder.map
|
yaml_initialize coder.tag, coder.map
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
eval <<-RB, binding, __FILE__, __LINE__ + 1
|
||||||
|
def set_nil_attributes_to_nil
|
||||||
|
#{@@nil_attributes.map {|key| "@#{key} = nil" }.join "; "}
|
||||||
|
end
|
||||||
|
private :set_nil_attributes_to_nil
|
||||||
|
|
||||||
|
def set_not_nil_attributes_to_default_values
|
||||||
|
#{@@non_nil_attributes.map {|key| "@#{key} = #{INITIALIZE_CODE_FOR_DEFAULTS[key]}" }.join ";"}
|
||||||
|
end
|
||||||
|
private :set_not_nil_attributes_to_default_values
|
||||||
|
RB
|
||||||
|
|
||||||
##
|
##
|
||||||
# Specification constructor. Assigns the default values to the attributes
|
# Specification constructor. Assigns the default values to the attributes
|
||||||
# and yields itself for further initialization. Optionally takes +name+ and
|
# and yields itself for further initialization. Optionally takes +name+ and
|
||||||
|
@ -2041,15 +2078,8 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
@original_platform = nil
|
@original_platform = nil
|
||||||
@installed_by_version = nil
|
@installed_by_version = nil
|
||||||
|
|
||||||
@@nil_attributes.each do |key|
|
set_nil_attributes_to_nil
|
||||||
instance_variable_set "@#{key}", nil
|
set_not_nil_attributes_to_default_values
|
||||||
end
|
|
||||||
|
|
||||||
@@non_nil_attributes.each do |key|
|
|
||||||
default = default_value(key)
|
|
||||||
value = Dupable[key] ? default.dup : default
|
|
||||||
instance_variable_set "@#{key}", value
|
|
||||||
end
|
|
||||||
|
|
||||||
@new_platform = Gem::Platform::RUBY
|
@new_platform = Gem::Platform::RUBY
|
||||||
|
|
||||||
|
@ -2746,29 +2776,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
'metadata must be a hash'
|
'metadata must be a hash'
|
||||||
end
|
end
|
||||||
|
|
||||||
metadata.keys.each do |k|
|
validate_metadata
|
||||||
if !k.kind_of?(String)
|
|
||||||
raise Gem::InvalidSpecificationException,
|
|
||||||
'metadata keys must be a String'
|
|
||||||
end
|
|
||||||
|
|
||||||
if k.size > 128
|
|
||||||
raise Gem::InvalidSpecificationException,
|
|
||||||
"metadata key too large (#{k.size} > 128)"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
metadata.values.each do |k|
|
|
||||||
if !k.kind_of?(String)
|
|
||||||
raise Gem::InvalidSpecificationException,
|
|
||||||
'metadata values must be a String'
|
|
||||||
end
|
|
||||||
|
|
||||||
if k.size > 1024
|
|
||||||
raise Gem::InvalidSpecificationException,
|
|
||||||
"metadata value too large (#{k.size} > 1024)"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
licenses.each { |license|
|
licenses.each { |license|
|
||||||
if license.length > 64
|
if license.length > 64
|
||||||
|
@ -2822,7 +2830,7 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li
|
||||||
|
|
||||||
# Warnings
|
# Warnings
|
||||||
|
|
||||||
%w[author email homepage summary].each do |attribute|
|
%w[author homepage summary files].each do |attribute|
|
||||||
value = self.send attribute
|
value = self.send attribute
|
||||||
warning "no #{attribute} specified" if value.nil? or value.empty?
|
warning "no #{attribute} specified" if value.nil? or value.empty?
|
||||||
end
|
end
|
||||||
|
@ -2855,6 +2863,48 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_metadata
|
||||||
|
url_validation_regex = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}
|
||||||
|
link_keys = %w(
|
||||||
|
bug_tracker_uri
|
||||||
|
changelog_uri
|
||||||
|
documentation_uri
|
||||||
|
homepage_uri
|
||||||
|
mailing_list_uri
|
||||||
|
source_code_uri
|
||||||
|
wiki_uri
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata.each do|key, value|
|
||||||
|
if !key.kind_of?(String)
|
||||||
|
raise Gem::InvalidSpecificationException,
|
||||||
|
"metadata keys must be a String"
|
||||||
|
end
|
||||||
|
|
||||||
|
if key.size > 128
|
||||||
|
raise Gem::InvalidSpecificationException,
|
||||||
|
"metadata key too large (#{key.size} > 128)"
|
||||||
|
end
|
||||||
|
|
||||||
|
if !value.kind_of?(String)
|
||||||
|
raise Gem::InvalidSpecificationException,
|
||||||
|
"metadata values must be a String"
|
||||||
|
end
|
||||||
|
|
||||||
|
if value.size > 1024
|
||||||
|
raise Gem::InvalidSpecificationException,
|
||||||
|
"metadata value too large (#{value.size} > 1024)"
|
||||||
|
end
|
||||||
|
|
||||||
|
if link_keys.include? key
|
||||||
|
if value !~ url_validation_regex
|
||||||
|
raise Gem::InvalidSpecificationException,
|
||||||
|
"metadata['#{key}'] has invalid link: #{value.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Checks that dependencies use requirements as we recommend. Warnings are
|
# Checks that dependencies use requirements as we recommend. Warnings are
|
||||||
# issued when dependencies are open-ended or overly strict for semantic
|
# issued when dependencies are open-ended or overly strict for semantic
|
||||||
|
|
|
@ -188,9 +188,8 @@ class Gem::StubSpecification < Gem::BasicSpecification
|
||||||
|
|
||||||
def to_spec
|
def to_spec
|
||||||
@spec ||= if @data then
|
@spec ||= if @data then
|
||||||
Gem.loaded_specs.values.find { |spec|
|
loaded = Gem.loaded_specs[name]
|
||||||
spec.name == name and spec.version == version
|
loaded if loaded && loaded.version == version
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec ||= Gem::Specification.load(loaded_from)
|
@spec ||= Gem::Specification.load(loaded_from)
|
||||||
|
|
|
@ -25,6 +25,7 @@ unless Gem::Dependency.new('rdoc', '>= 3.10').matching_specs.empty?
|
||||||
gem 'json'
|
gem 'json'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
require 'bundler'
|
||||||
require 'minitest/autorun'
|
require 'minitest/autorun'
|
||||||
|
|
||||||
require 'rubygems/deprecate'
|
require 'rubygems/deprecate'
|
||||||
|
@ -222,6 +223,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
|
||||||
@orig_gem_vendor = ENV['GEM_VENDOR']
|
@orig_gem_vendor = ENV['GEM_VENDOR']
|
||||||
@orig_gem_spec_cache = ENV['GEM_SPEC_CACHE']
|
@orig_gem_spec_cache = ENV['GEM_SPEC_CACHE']
|
||||||
@orig_rubygems_gemdeps = ENV['RUBYGEMS_GEMDEPS']
|
@orig_rubygems_gemdeps = ENV['RUBYGEMS_GEMDEPS']
|
||||||
|
@orig_bundle_gemfile = ENV['BUNDLE_GEMFILE']
|
||||||
@orig_rubygems_host = ENV['RUBYGEMS_HOST']
|
@orig_rubygems_host = ENV['RUBYGEMS_HOST']
|
||||||
ENV.keys.find_all { |k| k.start_with?('GEM_REQUIREMENT_') }.each do |k|
|
ENV.keys.find_all { |k| k.start_with?('GEM_REQUIREMENT_') }.each do |k|
|
||||||
ENV.delete k
|
ENV.delete k
|
||||||
|
@ -232,7 +234,12 @@ class Gem::TestCase < MiniTest::Unit::TestCase
|
||||||
|
|
||||||
@current_dir = Dir.pwd
|
@current_dir = Dir.pwd
|
||||||
@fetcher = nil
|
@fetcher = nil
|
||||||
@ui = Gem::MockGemUi.new
|
|
||||||
|
Bundler.ui = Bundler::UI::Silent.new
|
||||||
|
@ui = Gem::MockGemUi.new
|
||||||
|
# This needs to be a new instance since we call use_ui(@ui) when we want to
|
||||||
|
# capture output
|
||||||
|
Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new
|
||||||
|
|
||||||
tmpdir = File.expand_path Dir.tmpdir
|
tmpdir = File.expand_path Dir.tmpdir
|
||||||
tmpdir.untaint
|
tmpdir.untaint
|
||||||
|
@ -323,6 +330,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
|
||||||
Gem.loaded_specs.clear
|
Gem.loaded_specs.clear
|
||||||
Gem.clear_default_specs
|
Gem.clear_default_specs
|
||||||
Gem::Specification.unresolved_deps.clear
|
Gem::Specification.unresolved_deps.clear
|
||||||
|
Bundler.reset!
|
||||||
|
|
||||||
Gem.configuration.verbose = true
|
Gem.configuration.verbose = true
|
||||||
Gem.configuration.update_sources = true
|
Gem.configuration.update_sources = true
|
||||||
|
@ -394,6 +402,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
|
||||||
ENV['GEM_VENDOR'] = @orig_gem_vendor
|
ENV['GEM_VENDOR'] = @orig_gem_vendor
|
||||||
ENV['GEM_SPEC_CACHE'] = @orig_gem_spec_cache
|
ENV['GEM_SPEC_CACHE'] = @orig_gem_spec_cache
|
||||||
ENV['RUBYGEMS_GEMDEPS'] = @orig_rubygems_gemdeps
|
ENV['RUBYGEMS_GEMDEPS'] = @orig_rubygems_gemdeps
|
||||||
|
ENV['BUNDLE_GEMFILE'] = @orig_bundle_gemfile
|
||||||
ENV['RUBYGEMS_HOST'] = @orig_rubygems_host
|
ENV['RUBYGEMS_HOST'] = @orig_rubygems_host
|
||||||
|
|
||||||
Gem.ruby = @orig_ruby if @orig_ruby
|
Gem.ruby = @orig_ruby if @orig_ruby
|
||||||
|
|
|
@ -7,11 +7,6 @@
|
||||||
|
|
||||||
require 'rubygems/util'
|
require 'rubygems/util'
|
||||||
|
|
||||||
begin
|
|
||||||
require 'io/console'
|
|
||||||
rescue LoadError
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Module that defines the default UserInteraction. Any class including this
|
# Module that defines the default UserInteraction. Any class including this
|
||||||
# module will have access to the +ui+ method that returns the default UI.
|
# module will have access to the +ui+ method that returns the default UI.
|
||||||
|
@ -314,12 +309,21 @@ class Gem::StreamUI
|
||||||
password
|
password
|
||||||
end
|
end
|
||||||
|
|
||||||
if IO.method_defined?(:noecho) then
|
def require_io_console
|
||||||
def _gets_noecho
|
@require_io_console ||= begin
|
||||||
@ins.noecho {@ins.gets}
|
begin
|
||||||
|
require 'io/console'
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
|
true
|
||||||
end
|
end
|
||||||
elsif Gem.win_platform?
|
end
|
||||||
def _gets_noecho
|
|
||||||
|
def _gets_noecho
|
||||||
|
require_io_console
|
||||||
|
if IO.method_defined?(:noecho) then
|
||||||
|
@ins.noecho {@ins.gets}
|
||||||
|
elsif Gem.win_platform?
|
||||||
require "Win32API"
|
require "Win32API"
|
||||||
password = ''
|
password = ''
|
||||||
|
|
||||||
|
@ -332,9 +336,7 @@ class Gem::StreamUI
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
password
|
password
|
||||||
end
|
else
|
||||||
else
|
|
||||||
def _gets_noecho
|
|
||||||
system "stty -echo"
|
system "stty -echo"
|
||||||
begin
|
begin
|
||||||
@ins.gets
|
@ins.gets
|
||||||
|
|
|
@ -109,26 +109,15 @@ module Gem::Util
|
||||||
##
|
##
|
||||||
# Enumerates the parents of +directory+.
|
# Enumerates the parents of +directory+.
|
||||||
|
|
||||||
def self.traverse_parents directory
|
def self.traverse_parents directory, &block
|
||||||
return enum_for __method__, directory unless block_given?
|
return enum_for __method__, directory unless block_given?
|
||||||
|
|
||||||
here = File.expand_path directory
|
here = File.expand_path directory
|
||||||
start = here
|
loop do
|
||||||
|
Dir.chdir here, &block
|
||||||
Dir.chdir start
|
new_here = File.expand_path('..', here)
|
||||||
|
return if new_here == here # toplevel
|
||||||
begin
|
here = new_here
|
||||||
loop do
|
|
||||||
yield here
|
|
||||||
|
|
||||||
Dir.chdir '..'
|
|
||||||
|
|
||||||
return if Dir.pwd == here # toplevel
|
|
||||||
|
|
||||||
here = Dir.pwd
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
Dir.chdir start
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ class Gem::Version
|
||||||
# True if the +version+ string matches RubyGems' requirements.
|
# True if the +version+ string matches RubyGems' requirements.
|
||||||
|
|
||||||
def self.correct? version
|
def self.correct? version
|
||||||
version.to_s =~ ANCHORED_VERSION_PATTERN
|
!!(version.to_s =~ ANCHORED_VERSION_PATTERN)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -241,7 +241,7 @@ class Gem::Version
|
||||||
end
|
end
|
||||||
|
|
||||||
def hash # :nodoc:
|
def hash # :nodoc:
|
||||||
@version.hash
|
canonical_segments.hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def init_with coder # :nodoc:
|
def init_with coder # :nodoc:
|
||||||
|
@ -335,7 +335,7 @@ class Gem::Version
|
||||||
|
|
||||||
def <=> other
|
def <=> other
|
||||||
return unless Gem::Version === other
|
return unless Gem::Version === other
|
||||||
return 0 if @version == other._version
|
return 0 if @version == other._version || canonical_segments == other.canonical_segments
|
||||||
|
|
||||||
lhsegments = _segments
|
lhsegments = _segments
|
||||||
rhsegments = other._segments
|
rhsegments = other._segments
|
||||||
|
@ -360,6 +360,13 @@ class Gem::Version
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def canonical_segments
|
||||||
|
@canonical_segments ||=
|
||||||
|
_split_segments.map! do |segments|
|
||||||
|
segments.reverse_each.drop_while {|s| s == 0 }.reverse
|
||||||
|
end.reduce(&:concat)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def _version
|
def _version
|
||||||
|
@ -375,4 +382,11 @@ class Gem::Version
|
||||||
/^\d+$/ =~ s ? s.to_i : s
|
/^\d+$/ =~ s ? s.to_i : s
|
||||||
end.freeze
|
end.freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def _split_segments
|
||||||
|
string_start = _segments.index {|s| s.is_a?(String) }
|
||||||
|
string_segments = segments
|
||||||
|
numeric_segments = string_segments.slice!(0, string_start || string_segments.size)
|
||||||
|
return numeric_segments, string_segments
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,7 +58,12 @@ module Gem::VersionOption
|
||||||
add_option('-v', '--version VERSION', Gem::Requirement,
|
add_option('-v', '--version VERSION', Gem::Requirement,
|
||||||
"Specify version of gem to #{task}", *wrap) do
|
"Specify version of gem to #{task}", *wrap) do
|
||||||
|value, options|
|
|value, options|
|
||||||
options[:version] = value
|
# Allow handling for multiple --version operators
|
||||||
|
if options[:version] && !options[:version].none?
|
||||||
|
options[:version].concat([value])
|
||||||
|
else
|
||||||
|
options[:version] = value
|
||||||
|
end
|
||||||
|
|
||||||
explicit_prerelease_set = !options[:explicit_prerelease].nil?
|
explicit_prerelease_set = !options[:explicit_prerelease].nil?
|
||||||
options[:explicit_prerelease] = false unless explicit_prerelease_set
|
options[:explicit_prerelease] = false unless explicit_prerelease_set
|
||||||
|
|
40
test/rubygems/private3072_key.pem
Normal file
40
test/rubygems/private3072_key.pem
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDIl6Ne1eCreYAe
|
||||||
|
j+Qkbygv06KqtcarwjNpSPJFq+G/R6xzGfbiuJDGePnlzqyAN6sti8r/tDD8orMS
|
||||||
|
l3EUSQTvFAVJKxbBDnklHUozdaX+giw+fi7onRJ3sQE2j7GhjahXZB0vmx20wU9v
|
||||||
|
sazZ0IU/x7k8X7WbVRCYig99UVn28zsq586LN5u/w7qXo50156bfmeDS8tt+TKSK
|
||||||
|
PkQQYuO+AulWDVdwHycKSzCE7SPWiZ/scFUirN4Stfw0bJZbr8VQ6QBAhHcHgd6B
|
||||||
|
tcZ1vBDC656zsWgpGWNTCU9mSBWV3UMk8mdwkO/jz8mXYSBfbyLESkhc8slf47zd
|
||||||
|
dqs1iZZOmVVlz/TXYc9N9d8DTl3OR/YYy04mdrysf4ijB6HV9U7NrRbjcKqKwTjW
|
||||||
|
xMWsFDdc1d5WCTsXzKjvB582LspGYxv9zgs0KkhSChGTA0qCqGdl0ZVx1Q0suW5O
|
||||||
|
7XlcEWAp9gSww0RW3E1zkrUARcB4mQgyC89kvE4y9RW4/KzZDcsCAwEAAQKCAYEA
|
||||||
|
uhQJBkGLgCZe1nsO3UmMUwmVPZ0QpmapgIKd1EnFScb4T3IHl3w1ORgiYa9eUDbU
|
||||||
|
AZVLg/co9kMLsTRxPqsZ+5pr6Nsi6YY+lVJdce0yRi2FU5eEdl63MfcuM+oKkt4x
|
||||||
|
CpihhnbzkKk+wlNlEE2iPm9NA5eZhXXcxlRUWCEuPqqV+ZA+BuFYBwVPw7mQbd/t
|
||||||
|
6kD50VZejQQWIvPt+fFyaOKUiDIqKaWMdr0XTkgZ1bunchMmttr7ywms4wjUVktv
|
||||||
|
LWMmI8wEMXfxR+xOtigwolSuFn+djWgh02KEc4gSQD3KGKshps5cMrLxxkwIoaC8
|
||||||
|
rDxKfdUtixBx6JzrN0Wmq7f/oLpvzxTXoQTu30BvpUOr9evZjE/3ZYXiGCxoSDEL
|
||||||
|
cvdZHvd+4r0TEkuxNBebq5106bJCBTuq6awwiwAodrsH5DCnqkkrv9tnkVi71NnV
|
||||||
|
UfnF/C4i5clpJK+Rx4bub9SiqJuyEfQBDlEHdCDwKVASk6B3gXD2mgkJu+EdShkp
|
||||||
|
AoHBAPx27s3iBN1gRGzD9GU0x2z7uMrgXzXh71kCvzzkfOli5fpIvCyoOR8CIfok
|
||||||
|
Ph8Kth4c+Bz4bmp6c859yxm5aBdQb3y34LDvCkqEeFCs9XX31QTMjJ1Y3R6Iyun5
|
||||||
|
nJzzZ5BtJbLFTHw9/p/pCUmJscUP8nQLwBMLIk4HzmrVXVLKJyaakK4LbsCChBc5
|
||||||
|
XwCqzWFKbMRZM3X8PaZp3DCo9iA5/TyzkQMTucLSYaxDDG+YNtYQPB8J5wkFWTD8
|
||||||
|
5//WZQKBwQDLZr9CnPR8HcrG46+rDzoZO1nXqaaEQMZhmm25lpL5oSHLrm4elGDp
|
||||||
|
vH5SRcCPz986InRszMROI3xvYpGtFsAzff3UVY0M8uDQcEKucHtd4wmFHefzYmKo
|
||||||
|
cvR9PuGmotk6yYpb+cMITT6sCzC4OHPz3DQAclmswRZchHYd2Zkv7tjgE0dXS9nw
|
||||||
|
XKaH5vQC4wjWBc857scHz0WYJLlj8s8UM9Fludz7kuagXczrsFIONxvrFKNJXeYl
|
||||||
|
muFCQl8hOG8CgcEA4ZZkTBNpxWX/vjBacRR4HinPNXjHmp4IAMEzoHWKKAD2/m1/
|
||||||
|
t2eZotuFAL7hw1sO4FmCWmCiSQKh+CDvGk1RdYOqGwcy/uaZi3xTBcOGkaKh9WfR
|
||||||
|
PcfpzR7uMaOZDaVxJNxikxs4/MtoefsBEXS4JB3bx1W4i0unm5HeIBgHC7MWyKfU
|
||||||
|
H7CXhe0Zmqbo/O+iFQ0ro0cRdJuvesOcvN49Dw7B+Tt6mAVIN41FOWev9QdN+HkJ
|
||||||
|
P7LZfnYI/Hz/0NsBAoHADm2+eZI6wac3YD58kqzk2S9doy/UsSMLL5dN21F0IaMt
|
||||||
|
i45XH3I1Ib+OUnXCQDFly3DwQ1uPPV/FDv22CcpIXh6859gdxmJgUkj0Yf12suVN
|
||||||
|
IpVJg/lhuENXVp8kULbSpBnx565jCG66WGf+z8Kpbw4a3kE+XUPhOzTmUB3EgSL3
|
||||||
|
XYXglK+7yRI5egCHJMFIOi51Uc2/bq1kaXOJdy6dQ/idDRNPOsVj+NJOnBWI7Js6
|
||||||
|
LsXrA2RW1CoVeqbMqsWfAoHAAabWXkQ74BuTo+P7lbfnFa6qLfTRnkWBkKKpWSAZ
|
||||||
|
ZBLfGsw2F5ZzrfwXtLriPcQJNA+3q3u1WPiGZkjV4QnFMt+Kgcg8ahW94vDEgfex
|
||||||
|
OSQyrlioT2m9DLJNXXHxo3+0ePNQkmoMQbNRUwdYjBuK7dqNDmFQ8Oo8SxtlV2sL
|
||||||
|
ntLc47NvFaxDlOvnj9ftQv6ZhdzXQmKGiuZWxtrrjFgHJm8KhMS8IF9xHM3d0uYb
|
||||||
|
sbykscVdmz3lOmUZrxCeIJvk
|
||||||
|
-----END PRIVATE KEY-----
|
25
test/rubygems/public3072_cert.pem
Normal file
25
test/rubygems/public3072_cert.pem
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIENDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
|
||||||
|
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTE2MDEwMTAwMDAwMFoYDzk5
|
||||||
|
OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ
|
||||||
|
FgdleGFtcGxlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAyJejXtXg
|
||||||
|
q3mAHo/kJG8oL9OiqrXGq8IzaUjyRavhv0escxn24riQxnj55c6sgDerLYvK/7Qw
|
||||||
|
/KKzEpdxFEkE7xQFSSsWwQ55JR1KM3Wl/oIsPn4u6J0Sd7EBNo+xoY2oV2QdL5sd
|
||||||
|
tMFPb7Gs2dCFP8e5PF+1m1UQmIoPfVFZ9vM7KufOizebv8O6l6OdNeem35ng0vLb
|
||||||
|
fkykij5EEGLjvgLpVg1XcB8nCkswhO0j1omf7HBVIqzeErX8NGyWW6/FUOkAQIR3
|
||||||
|
B4HegbXGdbwQwuues7FoKRljUwlPZkgVld1DJPJncJDv48/Jl2EgX28ixEpIXPLJ
|
||||||
|
X+O83XarNYmWTplVZc/012HPTfXfA05dzkf2GMtOJna8rH+Ioweh1fVOza0W43Cq
|
||||||
|
isE41sTFrBQ3XNXeVgk7F8yo7wefNi7KRmMb/c4LNCpIUgoRkwNKgqhnZdGVcdUN
|
||||||
|
LLluTu15XBFgKfYEsMNEVtxNc5K1AEXAeJkIMgvPZLxOMvUVuPys2Q3LAgMBAAGj
|
||||||
|
YzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSf
|
||||||
|
hxDG5kMk4VhQNMcuLhULi3gMpTAfBgNVHSMEGDAWgBSfhxDG5kMk4VhQNMcuLhUL
|
||||||
|
i3gMpTANBgkqhkiG9w0BAQsFAAOCAYEAuvY1Nc8lkjCWEnVlAB0yfx85+xa/6zoQ
|
||||||
|
9w4cG/Nk+M2XNXRmp0c6FQgy7Y/aRxIobJnJfo2S1yJIPfzBuxb/oOy4ikYGmrYV
|
||||||
|
JUJFs4KaMPz8nM13YVI+KtskNEs0Pb8kcb0ZO640f0ptkgFDN/rvezu2uxqTlaD+
|
||||||
|
NSy+O+2Xr5T1Qq2eT2ui3mint26sA2g2cZqkqIdeEWHz/wf5ECMANvgCvE4efduI
|
||||||
|
oSwFbdb32UKKzppGW+usUbCgEH++EVNWN7VG8F7bvsnPDmuW2J2p2jjvg76H5eK2
|
||||||
|
OtnI180JV2Qb80d2lKOS24Mq9edhCzh9AUFsTAfaQ1iBUE4P353G67RF88ZNvV1A
|
||||||
|
n9DIgbMBf97bByUmp+5MWMXWJ9AcqyXQFsQutEQMudor8P9UqwpCVUkxijpfFxvM
|
||||||
|
HOBVArYRsdhbjNRGpVAVHdzpJ2AQNTQVeSS7YdzHAzGIVksKHL3K5QJuUJCgNa52
|
||||||
|
9H5201wSTxSAhlhoPTT06OHmIGiTvXZS
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -8,7 +8,7 @@ class TestConfig < Gem::TestCase
|
||||||
util_make_gems
|
util_make_gems
|
||||||
spec = Gem::Specification.find_by_name("a")
|
spec = Gem::Specification.find_by_name("a")
|
||||||
spec.activate
|
spec.activate
|
||||||
assert_equal "#{spec.full_gem_path}/data/a", Gem.datadir('a')
|
assert_equal "#{spec.full_gem_path}/data/a", spec.datadir
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_good_rake_path_is_escaped
|
def test_good_rake_path_is_escaped
|
||||||
|
|
|
@ -180,6 +180,35 @@ class TestGem < Gem::TestCase
|
||||||
assert_match 'a-2/bin/exec', Gem.bin_path('a', 'exec', '>= 0')
|
assert_match 'a-2/bin/exec', Gem.bin_path('a', 'exec', '>= 0')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_activate_bin_path_resolves_eagerly
|
||||||
|
a1 = util_spec 'a', '1' do |s|
|
||||||
|
s.executables = ['exec']
|
||||||
|
s.add_dependency 'b'
|
||||||
|
end
|
||||||
|
|
||||||
|
b1 = util_spec 'b', '1' do |s|
|
||||||
|
s.add_dependency 'c', '2'
|
||||||
|
end
|
||||||
|
|
||||||
|
b2 = util_spec 'b', '2' do |s|
|
||||||
|
s.add_dependency 'c', '1'
|
||||||
|
end
|
||||||
|
|
||||||
|
c1 = util_spec 'c', '1'
|
||||||
|
c2 = util_spec 'c', '2'
|
||||||
|
|
||||||
|
install_specs c1, c2, b1, b2, a1
|
||||||
|
|
||||||
|
Gem.activate_bin_path("a", "exec", ">= 0")
|
||||||
|
|
||||||
|
# If we didn't eagerly resolve, this would activate c-2 and then the
|
||||||
|
# finish_resolve would cause a conflict
|
||||||
|
gem 'c'
|
||||||
|
Gem.finish_resolve
|
||||||
|
|
||||||
|
assert_equal %w(a-1 b-2 c-1), loaded_spec_names
|
||||||
|
end
|
||||||
|
|
||||||
def test_self_bin_path_no_exec_name
|
def test_self_bin_path_no_exec_name
|
||||||
e = assert_raises ArgumentError do
|
e = assert_raises ArgumentError do
|
||||||
Gem.bin_path 'a'
|
Gem.bin_path 'a'
|
||||||
|
@ -275,11 +304,13 @@ class TestGem < Gem::TestCase
|
||||||
|
|
||||||
expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo'
|
expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo'
|
||||||
|
|
||||||
assert_equal expected, Gem.datadir('foo')
|
assert_equal expected, Gem::Specification.find_by_name("foo").datadir
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_self_datadir_nonexistent_package
|
def test_self_datadir_nonexistent_package
|
||||||
assert_nil Gem.datadir('xyzzy')
|
assert_raises(Gem::MissingSpecError) do
|
||||||
|
Gem::Specification.find_by_name("xyzzy").datadir
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_self_default_exec_format
|
def test_self_default_exec_format
|
||||||
|
@ -368,7 +399,7 @@ class TestGem < Gem::TestCase
|
||||||
begin
|
begin
|
||||||
Dir.chdir 'detect/a/b'
|
Dir.chdir 'detect/a/b'
|
||||||
|
|
||||||
assert_empty Gem.detect_gemdeps
|
assert_equal add_bundler_full_name([]), Gem.detect_gemdeps.map(&:full_name)
|
||||||
ensure
|
ensure
|
||||||
Dir.chdir @tempdir
|
Dir.chdir @tempdir
|
||||||
end
|
end
|
||||||
|
@ -1068,7 +1099,7 @@ class TestGem < Gem::TestCase
|
||||||
refute Gem.try_activate 'nonexistent'
|
refute Gem.try_activate 'nonexistent'
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = "Ignoring ext-1 because its extensions are not built. " +
|
expected = "Ignoring ext-1 because its extensions are not built. " +
|
||||||
"Try: gem pristine ext --version 1\n"
|
"Try: gem pristine ext --version 1\n"
|
||||||
|
|
||||||
assert_equal expected, err
|
assert_equal expected, err
|
||||||
|
@ -1079,7 +1110,8 @@ class TestGem < Gem::TestCase
|
||||||
orig_path = ENV.delete 'GEM_PATH'
|
orig_path = ENV.delete 'GEM_PATH'
|
||||||
Gem.use_paths nil, nil
|
Gem.use_paths nil, nil
|
||||||
assert_equal Gem.default_dir, Gem.paths.home
|
assert_equal Gem.default_dir, Gem.paths.home
|
||||||
assert_equal (Gem.default_path + [Gem.paths.home]).uniq, Gem.paths.path
|
path = (Gem.default_path + [Gem.paths.home]).uniq
|
||||||
|
assert_equal path, Gem.paths.path
|
||||||
ensure
|
ensure
|
||||||
ENV['GEM_HOME'] = orig_home
|
ENV['GEM_HOME'] = orig_home
|
||||||
ENV['GEM_PATH'] = orig_path
|
ENV['GEM_PATH'] = orig_path
|
||||||
|
@ -1420,7 +1452,7 @@ class TestGem < Gem::TestCase
|
||||||
|
|
||||||
Gem.detect_gemdeps
|
Gem.detect_gemdeps
|
||||||
|
|
||||||
assert_equal %w!a-1 b-1 c-1!, loaded_spec_names
|
assert_equal add_bundler_full_name(%W(a-1 b-1 c-1)), loaded_spec_names
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_auto_activation_of_detected_gemdeps_file
|
def test_auto_activation_of_detected_gemdeps_file
|
||||||
|
@ -1443,10 +1475,20 @@ class TestGem < Gem::TestCase
|
||||||
|
|
||||||
ENV['RUBYGEMS_GEMDEPS'] = "-"
|
ENV['RUBYGEMS_GEMDEPS'] = "-"
|
||||||
|
|
||||||
assert_equal [a,b,c], Gem.detect_gemdeps.sort_by { |s| s.name }
|
expected_specs = [a, b, (Gem::USE_BUNDLER_FOR_GEMDEPS || nil) && util_spec("bundler", Bundler::VERSION), c].compact
|
||||||
|
assert_equal expected_specs, Gem.detect_gemdeps.sort_by { |s| s.name }
|
||||||
end
|
end
|
||||||
|
|
||||||
LIB_PATH = File.expand_path "../../../lib".dup.untaint, __FILE__.dup.untaint
|
LIB_PATH = File.expand_path "../../../lib".dup.untaint, __FILE__.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}"
|
||||||
|
|
||||||
|
def add_bundler_full_name(names)
|
||||||
|
return names unless Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
names << BUNDLER_FULL_NAME
|
||||||
|
names.sort!
|
||||||
|
names
|
||||||
|
end
|
||||||
|
|
||||||
def test_looks_for_gemdeps_files_automatically_on_start
|
def test_looks_for_gemdeps_files_automatically_on_start
|
||||||
util_clear_gems
|
util_clear_gems
|
||||||
|
@ -1466,7 +1508,8 @@ class TestGem < Gem::TestCase
|
||||||
ENV['RUBYGEMS_GEMDEPS'] = "-"
|
ENV['RUBYGEMS_GEMDEPS'] = "-"
|
||||||
|
|
||||||
path = File.join @tempdir, "gem.deps.rb"
|
path = File.join @tempdir, "gem.deps.rb"
|
||||||
cmd = [Gem.ruby.dup.untaint, "-I#{LIB_PATH.untaint}", "-rrubygems"]
|
cmd = [Gem.ruby.dup.untaint, "-I#{LIB_PATH.untaint}",
|
||||||
|
"-I#{BUNDLER_LIB_PATH.untaint}", "-rrubygems"]
|
||||||
if RUBY_VERSION < '1.9'
|
if RUBY_VERSION < '1.9'
|
||||||
cmd << "-e 'puts Gem.loaded_specs.values.map(&:full_name).sort'"
|
cmd << "-e 'puts Gem.loaded_specs.values.map(&:full_name).sort'"
|
||||||
cmd = cmd.join(' ')
|
cmd = cmd.join(' ')
|
||||||
|
@ -1508,7 +1551,8 @@ class TestGem < Gem::TestCase
|
||||||
Dir.mkdir "sub1"
|
Dir.mkdir "sub1"
|
||||||
|
|
||||||
path = File.join @tempdir, "gem.deps.rb"
|
path = File.join @tempdir, "gem.deps.rb"
|
||||||
cmd = [Gem.ruby.dup.untaint, "-Csub1", "-I#{LIB_PATH.untaint}", "-rrubygems"]
|
cmd = [Gem.ruby.dup.untaint, "-Csub1", "-I#{LIB_PATH.untaint}",
|
||||||
|
"-I#{BUNDLER_LIB_PATH.untaint}", "-rrubygems"]
|
||||||
if RUBY_VERSION < '1.9'
|
if RUBY_VERSION < '1.9'
|
||||||
cmd << "-e 'puts Gem.loaded_specs.values.map(&:full_name).sort'"
|
cmd << "-e 'puts Gem.loaded_specs.values.map(&:full_name).sort'"
|
||||||
cmd = cmd.join(' ')
|
cmd = cmd.join(' ')
|
||||||
|
@ -1603,7 +1647,7 @@ class TestGem < Gem::TestCase
|
||||||
|
|
||||||
Gem.use_gemdeps gem_deps_file
|
Gem.use_gemdeps gem_deps_file
|
||||||
|
|
||||||
assert spec.activated?
|
assert_equal add_bundler_full_name(%W(a-1)), loaded_spec_names
|
||||||
refute_nil Gem.gemdeps
|
refute_nil Gem.gemdeps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1664,7 +1708,7 @@ class TestGem < Gem::TestCase
|
||||||
|
|
||||||
Gem.use_gemdeps
|
Gem.use_gemdeps
|
||||||
|
|
||||||
assert spec.activated?
|
assert_equal add_bundler_full_name(%W(a-1)), loaded_spec_names
|
||||||
ensure
|
ensure
|
||||||
ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
|
ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
|
||||||
end
|
end
|
||||||
|
@ -1706,11 +1750,25 @@ class TestGem < Gem::TestCase
|
||||||
io.write 'gem "a"'
|
io.write 'gem "a"'
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = <<-EXPECTED
|
platform = Bundler::GemHelpers.generic_local_platform
|
||||||
|
if platform == Gem::Platform::RUBY
|
||||||
|
platform = ''
|
||||||
|
else
|
||||||
|
platform = " #{platform}"
|
||||||
|
end
|
||||||
|
expected = if Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
<<-EXPECTED
|
||||||
|
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
|
||||||
|
|
||||||
|
EXPECTED
|
||||||
|
else
|
||||||
|
<<-EXPECTED
|
||||||
Unable to resolve dependency: user requested 'a (>= 0)'
|
Unable to resolve dependency: user requested 'a (>= 0)'
|
||||||
You may need to `gem install -g` to install missing gems
|
You may need to `gem install -g` to install missing gems
|
||||||
|
|
||||||
EXPECTED
|
EXPECTED
|
||||||
|
end
|
||||||
|
|
||||||
assert_output nil, expected do
|
assert_output nil, expected do
|
||||||
Gem.use_gemdeps
|
Gem.use_gemdeps
|
||||||
|
@ -1735,7 +1793,7 @@ You may need to `gem install -g` to install missing gems
|
||||||
|
|
||||||
Gem.use_gemdeps
|
Gem.use_gemdeps
|
||||||
|
|
||||||
assert spec.activated?
|
assert_equal add_bundler_full_name(%W(a-1)), loaded_spec_names
|
||||||
ensure
|
ensure
|
||||||
ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
|
ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
|
||||||
end
|
end
|
||||||
|
|
125
test/rubygems/test_gem_bundler_version_finder.rb
Normal file
125
test/rubygems/test_gem_bundler_version_finder.rb
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require 'rubygems/test_case'
|
||||||
|
|
||||||
|
class TestGemBundlerVersionFinder < Gem::TestCase
|
||||||
|
def setup
|
||||||
|
@argv = ARGV.dup
|
||||||
|
@env = ENV.to_hash.clone
|
||||||
|
ENV.delete("BUNDLER_VERSION")
|
||||||
|
@dollar_0 = $0
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
ARGV.replace @argv
|
||||||
|
ENV.replace @env
|
||||||
|
$0 = @dollar_0
|
||||||
|
end
|
||||||
|
|
||||||
|
def bvf
|
||||||
|
Gem::BundlerVersionFinder
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_bundler_version_defaults_to_nil
|
||||||
|
assert_nil bvf.bundler_version
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_bundler_version_with_env_var
|
||||||
|
ENV["BUNDLER_VERSION"] = "1.1.1.1"
|
||||||
|
assert_equal v("1.1.1.1"), bvf.bundler_version
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_bundler_version_with_bundle_update_bundler
|
||||||
|
ARGV.replace %w[update --bundler]
|
||||||
|
assert_nil bvf.bundler_version
|
||||||
|
$0 = "/foo/bar/bundle"
|
||||||
|
assert_nil bvf.bundler_version
|
||||||
|
ARGV.replace %w[update --bundler=1.1.1.1 gem_name]
|
||||||
|
assert_equal v("1.1.1.1"), bvf.bundler_version
|
||||||
|
ARGV.replace %w[update --bundler 1.1.1.1 gem_name]
|
||||||
|
assert_equal v("1.1.1.1"), bvf.bundler_version
|
||||||
|
ARGV.replace %w[update --bundler\ 1.1.1.1 gem_name]
|
||||||
|
assert_equal v("1.1.1.1"), bvf.bundler_version
|
||||||
|
ARGV.replace %w[update --bundler\ 1.1.1.2 --bundler --bundler 1.1.1.1 gem_name]
|
||||||
|
assert_equal v("1.1.1.1"), bvf.bundler_version
|
||||||
|
$0 = "other"
|
||||||
|
assert_nil bvf.bundler_version
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_bundler_version_with_lockfile
|
||||||
|
bvf.stub(:lockfile_contents, [nil, ""]) do
|
||||||
|
assert_nil bvf.bundler_version
|
||||||
|
end
|
||||||
|
bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do
|
||||||
|
assert_equal v("1.1.1.1"), bvf.bundler_version
|
||||||
|
end
|
||||||
|
bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n fjdkslfjdkslfjsldk\n"]) do
|
||||||
|
assert_nil bvf.bundler_version
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_bundler_version_with_reason
|
||||||
|
assert_nil bvf.bundler_version_with_reason
|
||||||
|
bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do
|
||||||
|
assert_equal ["1.1.1.1", "your lockfile"], bvf.bundler_version_with_reason
|
||||||
|
|
||||||
|
$0 = "bundle"
|
||||||
|
ARGV.replace %w[update --bundler]
|
||||||
|
assert_nil bvf.bundler_version_with_reason
|
||||||
|
ARGV.replace %w[update --bundler=1.1.1.2]
|
||||||
|
assert_equal ["1.1.1.2", "`bundle update --bundler`"], bvf.bundler_version_with_reason
|
||||||
|
|
||||||
|
ENV["BUNDLER_VERSION"] = "1.1.1.3"
|
||||||
|
assert_equal ["1.1.1.3", "`$BUNDLER_VERSION`"], bvf.bundler_version_with_reason
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_compatible
|
||||||
|
assert bvf.compatible?(util_spec("foo"))
|
||||||
|
assert bvf.compatible?(util_spec("bundler", 1.1))
|
||||||
|
|
||||||
|
bvf.stub(:bundler_version, v("1.1.1.1")) do
|
||||||
|
assert bvf.compatible?(util_spec("foo"))
|
||||||
|
assert bvf.compatible?(util_spec("bundler", "1.1.1.1"))
|
||||||
|
assert bvf.compatible?(util_spec("bundler", "1.1.1.a"))
|
||||||
|
assert bvf.compatible?(util_spec("bundler", "1.999"))
|
||||||
|
refute bvf.compatible?(util_spec("bundler", "2.999"))
|
||||||
|
end
|
||||||
|
|
||||||
|
bvf.stub(:bundler_version, v("2.1.1.1")) do
|
||||||
|
assert bvf.compatible?(util_spec("foo"))
|
||||||
|
assert bvf.compatible?(util_spec("bundler", "2.1.1.1"))
|
||||||
|
refute bvf.compatible?(util_spec("bundler", "2.1.1.a"))
|
||||||
|
refute bvf.compatible?(util_spec("bundler", "1.999"))
|
||||||
|
refute bvf.compatible?(util_spec("bundler", "2.999"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_filter
|
||||||
|
versions = %w[1 1.0 1.0.1.1 2.a 3 3.0]
|
||||||
|
specs = versions.map { |v| util_spec("bundler", v) }
|
||||||
|
|
||||||
|
assert_equal %w[1 1.0 1.0.1.1 2.a 3 3.0], util_filter_specs(specs).map(&:version).map(&:to_s)
|
||||||
|
|
||||||
|
bvf.stub(:bundler_version, v("2.1.1.1")) do
|
||||||
|
assert_empty util_filter_specs(specs).map(&:version).map(&:to_s)
|
||||||
|
end
|
||||||
|
bvf.stub(:bundler_version, v("1.1.1.1")) do
|
||||||
|
assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
|
||||||
|
end
|
||||||
|
bvf.stub(:bundler_version, v("1")) do
|
||||||
|
assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
|
||||||
|
end
|
||||||
|
bvf.stub(:bundler_version, v("2.a")) do
|
||||||
|
assert_equal %w[2.a], util_filter_specs(specs).map(&:version).map(&:to_s)
|
||||||
|
end
|
||||||
|
bvf.stub(:bundler_version, v("3")) do
|
||||||
|
assert_equal %w[3 3.0], util_filter_specs(specs).map(&:version).map(&:to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def util_filter_specs(specs)
|
||||||
|
specs = specs.dup
|
||||||
|
bvf.filter!(specs)
|
||||||
|
specs
|
||||||
|
end
|
||||||
|
end
|
|
@ -170,7 +170,7 @@ class TestGemCommand < Gem::TestCase
|
||||||
@cmd.add_option('-f', '--file FILE', 'File option') do |value, options|
|
@cmd.add_option('-f', '--file FILE', 'File option') do |value, options|
|
||||||
options[:help] = true
|
options[:help] = true
|
||||||
end
|
end
|
||||||
@cmd.add_option('--silent', 'Silence rubygems output') do |value, options|
|
@cmd.add_option('--silent', 'Silence RubyGems output') do |value, options|
|
||||||
options[:silent] = true
|
options[:silent] = true
|
||||||
end
|
end
|
||||||
assert @cmd.handles?(['-x'])
|
assert @cmd.handles?(['-x'])
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require 'rubygems/test_case'
|
require 'rubygems/test_case'
|
||||||
require 'rubygems/commands/build_command'
|
require 'rubygems/commands/build_command'
|
||||||
|
@ -117,5 +118,30 @@ class TestGemCommandsBuildCommand < Gem::TestCase
|
||||||
util_test_build_gem @gem, gemspec_file, false
|
util_test_build_gem @gem, gemspec_file, false
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
CERT_FILE = cert_path 'public3072'
|
||||||
|
SIGNING_KEY = key_path 'private3072'
|
||||||
|
|
||||||
|
def test_build_signed_gem
|
||||||
|
trust_dir = Gem::Security.trust_dir
|
||||||
|
|
||||||
|
spec = util_spec 'some_gem' do |s|
|
||||||
|
s.signing_key = SIGNING_KEY
|
||||||
|
s.cert_chain = [CERT_FILE]
|
||||||
|
end
|
||||||
|
|
||||||
|
gemspec_file = File.join(@tempdir, spec.spec_name)
|
||||||
|
|
||||||
|
File.open gemspec_file, 'w' do |gs|
|
||||||
|
gs.write spec.to_ruby
|
||||||
|
end
|
||||||
|
|
||||||
|
util_test_build_gem spec, gemspec_file
|
||||||
|
|
||||||
|
trust_dir.trust_cert OpenSSL::X509::Certificate.new(File.read(CERT_FILE))
|
||||||
|
|
||||||
|
gem = Gem::Package.new(File.join(@tempdir, spec.file_name),
|
||||||
|
Gem::Security::HighSecurity)
|
||||||
|
assert gem.verify
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -130,6 +130,70 @@ Added '/CN=alternate/DC=example'
|
||||||
assert_path_exists File.join(@tempdir, 'gem-public_cert.pem')
|
assert_path_exists File.join(@tempdir, 'gem-public_cert.pem')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_execute_build_bad_email_address
|
||||||
|
passphrase = 'Foo bar'
|
||||||
|
email = "nobody@"
|
||||||
|
|
||||||
|
@cmd.handle_options %W[--build #{email}]
|
||||||
|
|
||||||
|
@build_ui = Gem::MockGemUi.new "#{passphrase}\n#{passphrase}"
|
||||||
|
|
||||||
|
use_ui @build_ui do
|
||||||
|
|
||||||
|
e = assert_raises Gem::CommandLineError do
|
||||||
|
@cmd.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "Invalid email address #{email}",
|
||||||
|
e.message
|
||||||
|
|
||||||
|
refute_path_exists File.join(@tempdir, 'gem-private_key.pem')
|
||||||
|
refute_path_exists File.join(@tempdir, 'gem-public_cert.pem')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_build_expiration_days
|
||||||
|
passphrase = 'Foo bar'
|
||||||
|
|
||||||
|
@cmd.handle_options %W[
|
||||||
|
--build nobody@example.com
|
||||||
|
--days 26
|
||||||
|
]
|
||||||
|
|
||||||
|
@build_ui = Gem::MockGemUi.new "#{passphrase}\n#{passphrase}"
|
||||||
|
|
||||||
|
use_ui @build_ui do
|
||||||
|
@cmd.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
output = @build_ui.output.squeeze("\n").split "\n"
|
||||||
|
|
||||||
|
assert_equal "Passphrase for your Private Key: ",
|
||||||
|
output.shift
|
||||||
|
assert_equal "Please repeat the passphrase for your Private Key: ",
|
||||||
|
output.shift
|
||||||
|
assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
|
||||||
|
output.shift
|
||||||
|
assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}",
|
||||||
|
output.shift
|
||||||
|
|
||||||
|
assert_equal "Don't forget to move the key file to somewhere private!",
|
||||||
|
output.shift
|
||||||
|
|
||||||
|
assert_empty output
|
||||||
|
assert_empty @build_ui.error
|
||||||
|
|
||||||
|
assert_path_exists File.join(@tempdir, 'gem-private_key.pem')
|
||||||
|
assert_path_exists File.join(@tempdir, 'gem-public_cert.pem')
|
||||||
|
|
||||||
|
pem = File.read("#{@tempdir}/gem-public_cert.pem")
|
||||||
|
cert = OpenSSL::X509::Certificate.new(pem)
|
||||||
|
|
||||||
|
test = (cert.not_after - cert.not_before).to_i / (24 * 60 * 60)
|
||||||
|
assert_equal(test, 26)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def test_execute_build_bad_passphrase_confirmation
|
def test_execute_build_bad_passphrase_confirmation
|
||||||
passphrase = 'Foo bar'
|
passphrase = 'Foo bar'
|
||||||
passphrase_confirmation = 'Fu bar'
|
passphrase_confirmation = 'Fu bar'
|
||||||
|
|
|
@ -96,6 +96,39 @@ class TestGemCommandsInstallCommand < Gem::TestCase
|
||||||
assert_match "1 gem installed", @ui.output
|
assert_match "1 gem installed", @ui.output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_execute_local_transitive_prerelease
|
||||||
|
specs = spec_fetcher do |fetcher|
|
||||||
|
fetcher.download 'a', 2, 'b' => "2.a", 'c' => '3'
|
||||||
|
fetcher.download 'b', '2.a'
|
||||||
|
fetcher.download 'c', '3'
|
||||||
|
end
|
||||||
|
|
||||||
|
@cmd.options[:domain] = :local
|
||||||
|
|
||||||
|
FileUtils.mv specs['a-2'].cache_file, @tempdir
|
||||||
|
FileUtils.mv specs['b-2.a'].cache_file, @tempdir
|
||||||
|
FileUtils.mv specs['c-3'].cache_file, @tempdir
|
||||||
|
|
||||||
|
@cmd.options[:args] = %w[a]
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
orig_dir = Dir.pwd
|
||||||
|
begin
|
||||||
|
Dir.chdir @tempdir
|
||||||
|
FileUtils.rm_r [@gemhome, "gems"]
|
||||||
|
assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
|
||||||
|
@cmd.execute
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
Dir.chdir orig_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal %w[a-2 b-2.a c-3], @cmd.installed_specs.map { |spec| spec.full_name }.sort
|
||||||
|
|
||||||
|
assert_match "3 gems installed", @ui.output
|
||||||
|
end
|
||||||
|
|
||||||
def test_execute_no_user_install
|
def test_execute_no_user_install
|
||||||
skip 'skipped on MS Windows (chmod has no effect)' if win_platform?
|
skip 'skipped on MS Windows (chmod has no effect)' if win_platform?
|
||||||
|
|
||||||
|
@ -588,7 +621,7 @@ ERROR: Possible alternatives: non_existent_with_hint
|
||||||
done_installing = true
|
done_installing = true
|
||||||
end
|
end
|
||||||
|
|
||||||
spec = quick_spec 'a', 2
|
spec = util_spec 'a', 2
|
||||||
|
|
||||||
util_build_gem spec
|
util_build_gem spec
|
||||||
|
|
||||||
|
@ -616,7 +649,7 @@ ERROR: Possible alternatives: non_existent_with_hint
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_install_gem_ignore_dependencies_specific_file
|
def test_install_gem_ignore_dependencies_specific_file
|
||||||
spec = quick_spec 'a', 2
|
spec = util_spec 'a', 2
|
||||||
|
|
||||||
util_build_gem spec
|
util_build_gem spec
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
|
||||||
out = @ui.output.split "\n"
|
out = @ui.output.split "\n"
|
||||||
|
|
||||||
assert_equal 'Restoring gems to pristine condition...', out.shift
|
assert_equal 'Restoring gems to pristine condition...', out.shift
|
||||||
assert_equal 'Building native extensions. This could take a while...',
|
assert_equal 'Building native extensions. This could take a while...',
|
||||||
out.shift
|
out.shift
|
||||||
assert_equal "Restored #{a.full_name}", out.shift
|
assert_equal "Restored #{a.full_name}", out.shift
|
||||||
assert_empty out, out.inspect
|
assert_empty out, out.inspect
|
||||||
|
|
|
@ -637,6 +637,25 @@ EOF
|
||||||
assert_equal expected, @ui.output
|
assert_equal expected, @ui.output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_execute_show_default_gems_with_platform
|
||||||
|
a1 = new_default_spec 'a', 1
|
||||||
|
a1.platform = 'java'
|
||||||
|
install_default_specs a1
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
@cmd.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
expected = <<-EOF
|
||||||
|
|
||||||
|
*** LOCAL GEMS ***
|
||||||
|
|
||||||
|
a (default: 1 java)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
assert_equal expected, @ui.output
|
||||||
|
end
|
||||||
|
|
||||||
def test_execute_default_details
|
def test_execute_default_details
|
||||||
spec_fetcher do |fetcher|
|
spec_fetcher do |fetcher|
|
||||||
fetcher.spec 'a', 2
|
fetcher.spec 'a', 2
|
||||||
|
|
|
@ -20,6 +20,13 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
||||||
open 'lib/rubygems.rb', 'w' do |io| io.puts '# rubygems.rb' end
|
open 'lib/rubygems.rb', 'w' do |io| io.puts '# rubygems.rb' end
|
||||||
open 'lib/rubygems/test_case.rb', 'w' do |io| io.puts '# test_case.rb' end
|
open 'lib/rubygems/test_case.rb', 'w' do |io| io.puts '# test_case.rb' end
|
||||||
open 'lib/rubygems/ssl_certs/rubygems.org/foo.pem', 'w' do |io| io.puts 'PEM' end
|
open 'lib/rubygems/ssl_certs/rubygems.org/foo.pem', 'w' do |io| io.puts 'PEM' end
|
||||||
|
|
||||||
|
FileUtils.mkdir_p 'bundler/exe'
|
||||||
|
FileUtils.mkdir_p 'bundler/lib/bundler'
|
||||||
|
|
||||||
|
open 'bundler/exe/bundle', 'w' do |io| io.puts '# bundle' end
|
||||||
|
open 'bundler/lib/bundler.rb', 'w' do |io| io.puts '# bundler.rb' end
|
||||||
|
open 'bundler/lib/bundler/b.rb', 'w' do |io| io.puts '# b.rb' end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_pem_files_in
|
def test_pem_files_in
|
||||||
|
@ -40,12 +47,18 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
||||||
|
|
||||||
assert_path_exists File.join(dir, 'rubygems.rb')
|
assert_path_exists File.join(dir, 'rubygems.rb')
|
||||||
assert_path_exists File.join(dir, 'rubygems/ssl_certs/rubygems.org/foo.pem')
|
assert_path_exists File.join(dir, 'rubygems/ssl_certs/rubygems.org/foo.pem')
|
||||||
|
|
||||||
|
if Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
assert_path_exists File.join(dir, 'bundler.rb')
|
||||||
|
assert_path_exists File.join(dir, 'bundler/b.rb')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_remove_old_lib_files
|
def test_remove_old_lib_files
|
||||||
lib = File.join @install_dir, 'lib'
|
lib = File.join @install_dir, 'lib'
|
||||||
lib_rubygems = File.join lib, 'rubygems'
|
lib_rubygems = File.join lib, 'rubygems'
|
||||||
|
lib_bundler = File.join lib, 'bundler'
|
||||||
lib_rubygems_defaults = File.join lib_rubygems, 'defaults'
|
lib_rubygems_defaults = File.join lib_rubygems, 'defaults'
|
||||||
|
|
||||||
securerandom_rb = File.join lib, 'securerandom.rb'
|
securerandom_rb = File.join lib, 'securerandom.rb'
|
||||||
|
@ -55,13 +68,16 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
||||||
|
|
||||||
old_builder_rb = File.join lib_rubygems, 'builder.rb'
|
old_builder_rb = File.join lib_rubygems, 'builder.rb'
|
||||||
old_format_rb = File.join lib_rubygems, 'format.rb'
|
old_format_rb = File.join lib_rubygems, 'format.rb'
|
||||||
|
old_bundler_c_rb = File.join lib_bundler, 'c.rb'
|
||||||
|
|
||||||
FileUtils.mkdir_p lib_rubygems_defaults
|
FileUtils.mkdir_p lib_rubygems_defaults
|
||||||
|
FileUtils.mkdir_p lib_bundler
|
||||||
|
|
||||||
open securerandom_rb, 'w' do |io| io.puts '# securerandom.rb' end
|
open securerandom_rb, 'w' do |io| io.puts '# securerandom.rb' end
|
||||||
|
|
||||||
open old_builder_rb, 'w' do |io| io.puts '# builder.rb' end
|
open old_builder_rb, 'w' do |io| io.puts '# builder.rb' end
|
||||||
open old_format_rb, 'w' do |io| io.puts '# format.rb' end
|
open old_format_rb, 'w' do |io| io.puts '# format.rb' end
|
||||||
|
open old_bundler_c_rb, 'w' do |io| io.puts '# c.rb' end
|
||||||
|
|
||||||
open engine_defaults_rb, 'w' do |io| io.puts '# jruby.rb' end
|
open engine_defaults_rb, 'w' do |io| io.puts '# jruby.rb' end
|
||||||
open os_defaults_rb, 'w' do |io| io.puts '# operating_system.rb' end
|
open os_defaults_rb, 'w' do |io| io.puts '# operating_system.rb' end
|
||||||
|
@ -70,6 +86,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
||||||
|
|
||||||
refute_path_exists old_builder_rb
|
refute_path_exists old_builder_rb
|
||||||
refute_path_exists old_format_rb
|
refute_path_exists old_format_rb
|
||||||
|
refute_path_exists old_bundler_c_rb if Gem::USE_BUNDLER_FOR_GEMDEPS
|
||||||
|
|
||||||
assert_path_exists securerandom_rb
|
assert_path_exists securerandom_rb
|
||||||
assert_path_exists engine_defaults_rb
|
assert_path_exists engine_defaults_rb
|
||||||
|
|
95
test/rubygems/test_gem_commands_signin_command.rb
Normal file
95
test/rubygems/test_gem_commands_signin_command.rb
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require 'rubygems/test_case'
|
||||||
|
require 'rubygems/commands/signin_command'
|
||||||
|
require 'rubygems/installer'
|
||||||
|
|
||||||
|
class TestGemCommandsSigninCommand < Gem::TestCase
|
||||||
|
|
||||||
|
def setup
|
||||||
|
super
|
||||||
|
|
||||||
|
Gem.configuration.rubygems_api_key = nil
|
||||||
|
Gem.configuration.api_keys.clear
|
||||||
|
|
||||||
|
@cmd = Gem::Commands::SigninCommand.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
credentials_path = Gem.configuration.credentials_path
|
||||||
|
File.delete(credentials_path) if File.exist?(credentials_path)
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_when_not_already_signed_in
|
||||||
|
sign_in_ui = util_capture() { @cmd.execute }
|
||||||
|
assert_match %r{Signed in.}, sign_in_ui.output
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_when_already_signed_in_with_same_host
|
||||||
|
host = 'http://some-gemcutter-compatible-host.org'
|
||||||
|
sign_in_ui = util_capture(nil, host) { @cmd.execute }
|
||||||
|
old_credentials = YAML.load_file Gem.configuration.credentials_path
|
||||||
|
|
||||||
|
sign_in_ui = util_capture(nil, host) { @cmd.execute }
|
||||||
|
new_credentials = YAML.load_file Gem.configuration.credentials_path
|
||||||
|
|
||||||
|
assert_equal old_credentials[host], new_credentials[host]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_when_already_signed_in_with_different_host
|
||||||
|
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf04045xxxx'
|
||||||
|
sign_in_ui = util_capture(nil, nil, api_key) { @cmd.execute }
|
||||||
|
host = 'http://some-gemcutter-compatible-host.org'
|
||||||
|
sign_in_ui = util_capture(nil, host, api_key) { @cmd.execute }
|
||||||
|
credentials = YAML.load_file Gem.configuration.credentials_path
|
||||||
|
|
||||||
|
assert_equal credentials[:rubygems_api_key], api_key
|
||||||
|
|
||||||
|
assert_equal credentials[host], nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_with_host_supplied
|
||||||
|
host = 'http://some-gemcutter-compatible-host.org'
|
||||||
|
|
||||||
|
sign_in_ui = util_capture(nil, host) { @cmd.execute }
|
||||||
|
assert_match %r{Enter your #{host} credentials.}, sign_in_ui.output
|
||||||
|
assert_match %r{Signed in.}, sign_in_ui.output
|
||||||
|
|
||||||
|
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
||||||
|
credentials = YAML.load_file Gem.configuration.credentials_path
|
||||||
|
assert_equal api_key, credentials[host]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_with_valid_creds_set_for_default_host
|
||||||
|
util_capture {@cmd.execute}
|
||||||
|
|
||||||
|
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
||||||
|
credentials = YAML.load_file Gem.configuration.credentials_path
|
||||||
|
|
||||||
|
assert_equal api_key, credentials[:rubygems_api_key]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Utility method to capture IO/UI within the block passed
|
||||||
|
|
||||||
|
def util_capture ui_stub = nil, host = nil, api_key = nil
|
||||||
|
api_key ||= 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
||||||
|
response = [api_key, 200, 'OK']
|
||||||
|
email = 'you@example.com'
|
||||||
|
password = 'secret'
|
||||||
|
fetcher = Gem::FakeFetcher.new
|
||||||
|
|
||||||
|
# Set the expected response for the Web-API supplied
|
||||||
|
ENV['RUBYGEMS_HOST'] = host || Gem::DEFAULT_HOST
|
||||||
|
data_key = "#{ENV['RUBYGEMS_HOST']}/api/v1/api_key"
|
||||||
|
fetcher.data[data_key] = response
|
||||||
|
Gem::RemoteFetcher.fetcher = fetcher
|
||||||
|
|
||||||
|
sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n")
|
||||||
|
|
||||||
|
use_ui sign_in_ui do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
|
||||||
|
sign_in_ui
|
||||||
|
end
|
||||||
|
end
|
37
test/rubygems/test_gem_commands_signout_command.rb
Normal file
37
test/rubygems/test_gem_commands_signout_command.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rubygems/test_case'
|
||||||
|
require 'rubygems/commands/signout_command'
|
||||||
|
require 'rubygems/installer'
|
||||||
|
|
||||||
|
class TestGemCommandsSignoutCommand < Gem::TestCase
|
||||||
|
|
||||||
|
def setup
|
||||||
|
super
|
||||||
|
@cmd = Gem::Commands::SignoutCommand.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
super
|
||||||
|
File.delete Gem.configuration.credentials_path if File.exist?(Gem.configuration.credentials_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_when_user_is_signed_in
|
||||||
|
FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path)
|
||||||
|
FileUtils::touch Gem.configuration.credentials_path
|
||||||
|
|
||||||
|
@sign_out_ui = Gem::MockGemUi.new
|
||||||
|
use_ui(@sign_out_ui) { @cmd.execute }
|
||||||
|
|
||||||
|
assert_match %r{You have successfully signed out}, @sign_out_ui.output
|
||||||
|
assert_equal false, File.exist?(Gem.configuration.credentials_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_execute_when_not_signed_in # i.e. no credential file created
|
||||||
|
@sign_out_ui = Gem::MockGemUi.new
|
||||||
|
use_ui(@sign_out_ui) { @cmd.execute }
|
||||||
|
|
||||||
|
assert_match %r{You are not currently signed in}, @sign_out_ui.error
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -279,5 +279,17 @@ WARNING: Use your OS package manager to uninstall vendor gems
|
||||||
RbConfig::CONFIG['vendordir'] = orig_vendordir
|
RbConfig::CONFIG['vendordir'] = orig_vendordir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_execute_with_gem_not_installed
|
||||||
|
@cmd.options[:args] = ['d']
|
||||||
|
|
||||||
|
use_ui ui do
|
||||||
|
@cmd.execute
|
||||||
|
end
|
||||||
|
|
||||||
|
output = ui.output.split "\n"
|
||||||
|
|
||||||
|
assert_equal output.first, "Gem 'd' is not installed"
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
out = @ui.output.split "\n"
|
out = @ui.output.split "\n"
|
||||||
assert_equal "Latest version currently installed. Aborting.", out.shift
|
assert_equal "Latest version already installed. Done.", out.shift
|
||||||
assert_empty out
|
assert_empty out
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal '', @ui.output
|
assert_equal '', @ui.output
|
||||||
assert_match %r%Can.t find ruby library file or shared library directory\n%,
|
assert_match %r%Can.t find Ruby library file or shared library directory\n%,
|
||||||
@ui.error
|
@ui.error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
|
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
|
||||||
assert_match %r%Can.t find ruby library file or shared library missinglib\n%,
|
assert_match %r%Can.t find Ruby library file or shared library missinglib\n%,
|
||||||
@ui.error
|
@ui.error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal '', @ui.output
|
assert_equal '', @ui.output
|
||||||
assert_match %r%Can.t find ruby library file or shared library missinglib\n%,
|
assert_match %r%Can.t find Ruby library file or shared library missinglib\n%,
|
||||||
@ui.error
|
@ui.error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -338,6 +338,34 @@ class TestGemDependency < Gem::TestCase
|
||||||
assert_match "Could not find 'a' (= 2.0) - did find: [a-1.0]", e.message
|
assert_match "Could not find 'a' (= 2.0) - did find: [a-1.0]", e.message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_to_specs_respects_bundler_version
|
||||||
|
b = util_spec 'bundler', '2.0.0.pre.1'
|
||||||
|
b_1 = util_spec 'bundler', '1'
|
||||||
|
install_specs b, b_1
|
||||||
|
|
||||||
|
b_file = File.join b.gem_dir, 'lib', 'bundler', 'setup.rb'
|
||||||
|
|
||||||
|
write_file b_file do |io|
|
||||||
|
io.puts '# setup.rb'
|
||||||
|
end
|
||||||
|
|
||||||
|
dep = Gem::Dependency.new "bundler", ">= 0.a"
|
||||||
|
|
||||||
|
assert_equal [b, b_1], dep.to_specs
|
||||||
|
|
||||||
|
Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["3.5", "reason"]) do
|
||||||
|
e = assert_raises Gem::MissingSpecVersionError do
|
||||||
|
dep.to_specs
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match "Could not find 'bundler' (3.5) required by reason.\nTo update to the lastest version installed on your system, run `bundle update --bundler`.\nTo install the missing version, run `gem install bundler:3.5`\n", e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["2.0.0.pre.1", "reason"]) do
|
||||||
|
assert_equal [b], dep.to_specs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_to_specs_indicates_total_gem_set_size
|
def test_to_specs_indicates_total_gem_set_size
|
||||||
a = util_spec 'a', '1.0'
|
a = util_spec 'a', '1.0'
|
||||||
install_specs a
|
install_specs a
|
||||||
|
|
|
@ -239,7 +239,7 @@ install:
|
||||||
|
|
||||||
assert_match(/\AERROR: Failed to build gem native extension.$/, e.message)
|
assert_match(/\AERROR: Failed to build gem native extension.$/, e.message)
|
||||||
|
|
||||||
assert_equal "Building native extensions. This could take a while...\n",
|
assert_equal "Building native extensions. This could take a while...\n",
|
||||||
@ui.output
|
@ui.output
|
||||||
assert_equal '', @ui.error
|
assert_equal '', @ui.error
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ install:
|
||||||
|
|
||||||
assert_match(/^\s*No builder for extension ''$/, e.message)
|
assert_match(/^\s*No builder for extension ''$/, e.message)
|
||||||
|
|
||||||
assert_equal "Building native extensions. This could take a while...\n",
|
assert_equal "Building native extensions. This could take a while...\n",
|
||||||
@ui.output
|
@ui.output
|
||||||
assert_equal '', @ui.error
|
assert_equal '', @ui.error
|
||||||
|
|
||||||
|
|
|
@ -121,9 +121,10 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
|
||||||
def test_security_policy_unknown
|
def test_security_policy_unknown
|
||||||
@cmd.add_install_update_options
|
@cmd.add_install_update_options
|
||||||
|
|
||||||
assert_raises OptionParser::InvalidArgument do
|
e = assert_raises OptionParser::InvalidArgument do
|
||||||
@cmd.handle_options %w[-P UnknownSecurity]
|
@cmd.handle_options %w[-P UnknownSecurity]
|
||||||
end
|
end
|
||||||
|
assert_includes e.message, "UnknownSecurity"
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_user_install_enabled
|
def test_user_install_enabled
|
||||||
|
|
|
@ -87,7 +87,7 @@ end
|
||||||
end
|
end
|
||||||
|
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir @spec
|
@installer.gem_dir = @spec.gem_dir
|
||||||
@installer.wrappers = true
|
@installer.wrappers = true
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ gem 'other', version
|
||||||
def test_extract_files
|
def test_extract_files
|
||||||
@installer.extract_files
|
@installer.extract_files
|
||||||
|
|
||||||
assert_path_exists File.join util_gem_dir, 'bin/executable'
|
assert_path_exists File.join @spec.gem_dir, 'bin/executable'
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_generate_bin_bindir
|
def test_generate_bin_bindir
|
||||||
|
@ -314,12 +314,12 @@ gem 'other', version
|
||||||
@spec.bindir = '.'
|
@spec.bindir = '.'
|
||||||
|
|
||||||
exec_file = @installer.formatted_program_filename 'executable'
|
exec_file = @installer.formatted_program_filename 'executable'
|
||||||
exec_path = File.join util_gem_dir(@spec), exec_file
|
exec_path = File.join @spec.gem_dir, exec_file
|
||||||
File.open exec_path, 'w' do |f|
|
File.open exec_path, 'w' do |f|
|
||||||
f.puts '#!/usr/bin/ruby'
|
f.puts '#!/usr/bin/ruby'
|
||||||
end
|
end
|
||||||
|
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ gem 'other', version
|
||||||
def test_generate_bin_script
|
def test_generate_bin_script
|
||||||
@installer.wrappers = true
|
@installer.wrappers = true
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
assert File.directory? util_inst_bindir
|
assert File.directory? util_inst_bindir
|
||||||
|
@ -371,7 +371,7 @@ gem 'other', version
|
||||||
@installer.format_executable = true
|
@installer.format_executable = true
|
||||||
@installer.wrappers = true
|
@installer.wrappers = true
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
Gem::Installer.exec_format = 'foo-%s-bar'
|
Gem::Installer.exec_format = 'foo-%s-bar'
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
@ -385,7 +385,7 @@ gem 'other', version
|
||||||
def test_generate_bin_script_format_disabled
|
def test_generate_bin_script_format_disabled
|
||||||
@installer.wrappers = true
|
@installer.wrappers = true
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
Gem::Installer.exec_format = 'foo-%s-bar'
|
Gem::Installer.exec_format = 'foo-%s-bar'
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
@ -474,10 +474,10 @@ gem 'other', version
|
||||||
def test_generate_bin_script_wrappers
|
def test_generate_bin_script_wrappers
|
||||||
@installer.wrappers = true
|
@installer.wrappers = true
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
installed_exec = File.join(util_inst_bindir, 'executable')
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
||||||
|
|
||||||
real_exec = File.join util_gem_dir, 'bin', 'executable'
|
real_exec = File.join @spec.gem_dir, 'bin', 'executable'
|
||||||
|
|
||||||
# fake --no-wrappers for previous install
|
# fake --no-wrappers for previous install
|
||||||
unless Gem.win_platform? then
|
unless Gem.win_platform? then
|
||||||
|
@ -501,13 +501,13 @@ gem 'other', version
|
||||||
|
|
||||||
@installer.wrappers = false
|
@installer.wrappers = false
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
assert_equal true, File.directory?(util_inst_bindir)
|
assert_equal true, File.directory?(util_inst_bindir)
|
||||||
installed_exec = File.join util_inst_bindir, 'executable'
|
installed_exec = File.join util_inst_bindir, 'executable'
|
||||||
assert_equal true, File.symlink?(installed_exec)
|
assert_equal true, File.symlink?(installed_exec)
|
||||||
assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
|
assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'),
|
||||||
File.readlink(installed_exec))
|
File.readlink(installed_exec))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -523,7 +523,7 @@ gem 'other', version
|
||||||
def test_generate_bin_symlink_no_perms
|
def test_generate_bin_symlink_no_perms
|
||||||
@installer.wrappers = false
|
@installer.wrappers = false
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
Dir.mkdir util_inst_bindir
|
Dir.mkdir util_inst_bindir
|
||||||
|
|
||||||
|
@ -545,11 +545,11 @@ gem 'other', version
|
||||||
|
|
||||||
@installer.wrappers = false
|
@installer.wrappers = false
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
installed_exec = File.join(util_inst_bindir, 'executable')
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
||||||
assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
|
assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'),
|
||||||
File.readlink(installed_exec))
|
File.readlink(installed_exec))
|
||||||
|
|
||||||
@spec = Gem::Specification.new do |s|
|
@spec = Gem::Specification.new do |s|
|
||||||
|
@ -562,7 +562,7 @@ gem 'other', version
|
||||||
end
|
end
|
||||||
|
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir @spec
|
@installer.gem_dir = @spec.gem_dir
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
installed_exec = File.join(util_inst_bindir, 'executable')
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
||||||
assert_equal(@spec.bin_file('executable'),
|
assert_equal(@spec.bin_file('executable'),
|
||||||
|
@ -575,11 +575,11 @@ gem 'other', version
|
||||||
|
|
||||||
@installer.wrappers = false
|
@installer.wrappers = false
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
installed_exec = File.join(util_inst_bindir, 'executable')
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
||||||
assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
|
assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'),
|
||||||
File.readlink(installed_exec))
|
File.readlink(installed_exec))
|
||||||
|
|
||||||
spec = Gem::Specification.new do |s|
|
spec = Gem::Specification.new do |s|
|
||||||
|
@ -595,12 +595,12 @@ gem 'other', version
|
||||||
one = @spec.dup
|
one = @spec.dup
|
||||||
one.version = 1
|
one.version = 1
|
||||||
@installer = Gem::Installer.for_spec spec
|
@installer = Gem::Installer.for_spec spec
|
||||||
@installer.gem_dir = util_gem_dir one
|
@installer.gem_dir = one.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
|
||||||
installed_exec = File.join util_inst_bindir, 'executable'
|
installed_exec = File.join util_inst_bindir, 'executable'
|
||||||
expected = File.join util_gem_dir, 'bin', 'executable'
|
expected = File.join @spec.gem_dir, 'bin', 'executable'
|
||||||
assert_equal(expected,
|
assert_equal(expected,
|
||||||
File.readlink(installed_exec),
|
File.readlink(installed_exec),
|
||||||
"Ensure symlink not moved")
|
"Ensure symlink not moved")
|
||||||
|
@ -611,7 +611,7 @@ gem 'other', version
|
||||||
|
|
||||||
@installer.wrappers = true
|
@installer.wrappers = true
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ gem 'other', version
|
||||||
|
|
||||||
util_installer @spec, @gemhome
|
util_installer @spec, @gemhome
|
||||||
@installer.wrappers = false
|
@installer.wrappers = false
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
|
||||||
|
@ -648,7 +648,7 @@ gem 'other', version
|
||||||
File.const_set(:ALT_SEPARATOR, '\\')
|
File.const_set(:ALT_SEPARATOR, '\\')
|
||||||
@installer.wrappers = false
|
@installer.wrappers = false
|
||||||
util_make_exec
|
util_make_exec
|
||||||
@installer.gem_dir = util_gem_dir
|
@installer.gem_dir = @spec.gem_dir
|
||||||
|
|
||||||
use_ui @ui do
|
use_ui @ui do
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
@ -1421,10 +1421,11 @@ gem 'other', version
|
||||||
def test_pre_install_checks_ruby_version
|
def test_pre_install_checks_ruby_version
|
||||||
use_ui @ui do
|
use_ui @ui do
|
||||||
installer = Gem::Installer.at old_ruby_required
|
installer = Gem::Installer.at old_ruby_required
|
||||||
e = assert_raises Gem::InstallError do
|
e = assert_raises Gem::RuntimeRequirementNotMetError do
|
||||||
installer.pre_install_checks
|
installer.pre_install_checks
|
||||||
end
|
end
|
||||||
assert_equal 'old_ruby_required requires Ruby version = 1.4.6.',
|
rv = Gem.ruby_api_version
|
||||||
|
assert_equal "old_ruby_required requires Ruby version = 1.4.6. The current ruby version is #{rv}.",
|
||||||
e.message
|
e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1440,10 +1441,11 @@ gem 'other', version
|
||||||
|
|
||||||
use_ui @ui do
|
use_ui @ui do
|
||||||
@installer = Gem::Installer.at gem
|
@installer = Gem::Installer.at gem
|
||||||
e = assert_raises Gem::InstallError do
|
e = assert_raises Gem::RuntimeRequirementNotMetError do
|
||||||
@installer.pre_install_checks
|
@installer.pre_install_checks
|
||||||
end
|
end
|
||||||
assert_equal 'old_rubygems_required requires RubyGems version < 0. ' +
|
rgv = Gem::VERSION
|
||||||
|
assert_equal "old_rubygems_required requires RubyGems version < 0. The current RubyGems version is #{rgv}. " +
|
||||||
"Try 'gem update --system' to update RubyGems itself.", e.message
|
"Try 'gem update --system' to update RubyGems itself.", e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1739,7 +1741,7 @@ gem 'other', version
|
||||||
|
|
||||||
@installer.wrappers = true
|
@installer.wrappers = true
|
||||||
@installer.options[:install_as_default] = true
|
@installer.options[:install_as_default] = true
|
||||||
@installer.gem_dir = util_gem_dir @spec
|
@installer.gem_dir = @spec.gem_dir
|
||||||
@installer.generate_bin
|
@installer.generate_bin
|
||||||
|
|
||||||
use_ui @ui do
|
use_ui @ui do
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# coding: UTF-8
|
# coding: utf-8
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rubygems/package/tar_test_case'
|
require 'rubygems/package/tar_test_case'
|
||||||
|
@ -84,7 +84,7 @@ class TestGemPackage < Gem::Package::TarTestCase
|
||||||
io.write spec.to_yaml
|
io.write spec.to_yaml
|
||||||
end
|
end
|
||||||
|
|
||||||
metadata_sha1 = Digest::SHA1.hexdigest s.string
|
metadata_sha256 = Digest::SHA256.hexdigest s.string
|
||||||
metadata_sha512 = Digest::SHA512.hexdigest s.string
|
metadata_sha512 = Digest::SHA512.hexdigest s.string
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
|
@ -95,9 +95,9 @@ class TestGemPackage < Gem::Package::TarTestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
if defined?(OpenSSL::Digest) then
|
if defined?(OpenSSL::Digest) then
|
||||||
expected['SHA1'] = {
|
expected['SHA256'] = {
|
||||||
'metadata.gz' => metadata_sha1,
|
'metadata.gz' => metadata_sha256,
|
||||||
'data.tar.gz' => Digest::SHA1.hexdigest(tar),
|
'data.tar.gz' => Digest::SHA256.hexdigest(tar),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -555,7 +555,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal nil, fetcher.fetch_path(@uri + 'foo.gz', Time.at(0))
|
assert_nil fetcher.fetch_path(@uri + 'foo.gz', Time.at(0))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_fetch_path_io_error
|
def test_fetch_path_io_error
|
||||||
|
@ -621,7 +621,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal nil, fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
|
assert_nil fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_implicit_no_proxy
|
def test_implicit_no_proxy
|
||||||
|
|
|
@ -753,7 +753,7 @@ end
|
||||||
@gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4'
|
@gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4'
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal 'Your ruby engine is ruby, but your gem.deps.rb requires jruby',
|
assert_equal 'Your Ruby engine is ruby, but your gem.deps.rb requires jruby',
|
||||||
e.message
|
e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -764,7 +764,7 @@ end
|
||||||
@gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4'
|
@gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4'
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal 'Your ruby engine version is jruby 1.7.6, but your gem.deps.rb requires jruby 1.7.4',
|
assert_equal 'Your Ruby engine version is jruby 1.7.6, but your gem.deps.rb requires jruby 1.7.4',
|
||||||
e.message
|
e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -774,7 +774,7 @@ end
|
||||||
@gda.ruby RUBY_VERSION, :engine => 'jruby'
|
@gda.ruby RUBY_VERSION, :engine => 'jruby'
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal 'you must specify engine_version along with the ruby engine',
|
assert_equal 'You must specify engine_version along with the Ruby engine',
|
||||||
e.message
|
e.message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,12 @@ class TestGemRequirement < Gem::TestCase
|
||||||
assert_requirement_equal "= 2", v(2)
|
assert_requirement_equal "= 2", v(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_create
|
||||||
|
assert_equal req("= 1"), Gem::Requirement.create("= 1")
|
||||||
|
assert_equal req(">= 1.2", "<= 1.3"), Gem::Requirement.create([">= 1.2", "<= 1.3"])
|
||||||
|
assert_equal req(">= 1.2", "<= 1.3"), Gem::Requirement.create(">= 1.2", "<= 1.3")
|
||||||
|
end
|
||||||
|
|
||||||
def test_empty_requirements_is_none
|
def test_empty_requirements_is_none
|
||||||
r = Gem::Requirement.new
|
r = Gem::Requirement.new
|
||||||
assert_equal true, r.none?
|
assert_equal true, r.none?
|
||||||
|
|
|
@ -683,6 +683,32 @@ class TestGemResolver < Gem::TestCase
|
||||||
assert_resolves_to [b1, c1, d2], r
|
assert_resolves_to [b1, c1, d2], r
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_sorts_by_source_then_version
|
||||||
|
sourceA = Gem::Source.new 'http://example.com/a'
|
||||||
|
sourceB = Gem::Source.new 'http://example.com/b'
|
||||||
|
sourceC = Gem::Source.new 'http://example.com/c'
|
||||||
|
|
||||||
|
spec_A_1 = new_spec 'some-dep', '0.0.1'
|
||||||
|
spec_A_2 = new_spec 'some-dep', '1.0.0'
|
||||||
|
spec_B_1 = new_spec 'some-dep', '0.0.1'
|
||||||
|
spec_B_2 = new_spec 'some-dep', '0.0.2'
|
||||||
|
spec_C_1 = new_spec 'some-dep', '0.1.0'
|
||||||
|
|
||||||
|
set = StaticSet.new [
|
||||||
|
Gem::Resolver::SpecSpecification.new(nil, spec_B_1, sourceB),
|
||||||
|
Gem::Resolver::SpecSpecification.new(nil, spec_B_2, sourceB),
|
||||||
|
Gem::Resolver::SpecSpecification.new(nil, spec_C_1, sourceC),
|
||||||
|
Gem::Resolver::SpecSpecification.new(nil, spec_A_2, sourceA),
|
||||||
|
Gem::Resolver::SpecSpecification.new(nil, spec_A_1, sourceA),
|
||||||
|
]
|
||||||
|
|
||||||
|
dependency = make_dep 'some-dep', '> 0'
|
||||||
|
|
||||||
|
resolver = Gem::Resolver.new [dependency], set
|
||||||
|
|
||||||
|
assert_resolves_to [spec_B_2], resolver
|
||||||
|
end
|
||||||
|
|
||||||
def test_select_local_platforms
|
def test_select_local_platforms
|
||||||
r = Gem::Resolver.new nil, nil
|
r = Gem::Resolver.new nil, nil
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class TestGemResolverConflict < Gem::TestCase
|
||||||
|
|
||||||
dep = Gem::Resolver::DependencyRequest.new dep('net-ssh', '>= 2.0.13'), nil
|
dep = Gem::Resolver::DependencyRequest.new dep('net-ssh', '>= 2.0.13'), nil
|
||||||
|
|
||||||
spec = quick_spec 'net-ssh', '2.2.2'
|
spec = util_spec 'net-ssh', '2.2.2'
|
||||||
active =
|
active =
|
||||||
Gem::Resolver::ActivationRequest.new spec, dep
|
Gem::Resolver::ActivationRequest.new spec, dep
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ class TestGemSecurity < Gem::TestCase
|
||||||
cert = @SEC.create_cert_self_signed subject, PRIVATE_KEY, 60
|
cert = @SEC.create_cert_self_signed subject, PRIVATE_KEY, 60
|
||||||
|
|
||||||
assert_equal '/CN=nobody/DC=example', cert.issuer.to_s
|
assert_equal '/CN=nobody/DC=example', cert.issuer.to_s
|
||||||
|
assert_equal "sha256WithRSAEncryption", cert.signature_algorithm
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_class_create_cert_email
|
def test_class_create_cert_email
|
||||||
|
@ -120,6 +121,7 @@ class TestGemSecurity < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_class_re_sign
|
def test_class_re_sign
|
||||||
|
assert_equal "sha1WithRSAEncryption", EXPIRED_CERT.signature_algorithm
|
||||||
re_signed = Gem::Security.re_sign EXPIRED_CERT, PRIVATE_KEY, 60
|
re_signed = Gem::Security.re_sign EXPIRED_CERT, PRIVATE_KEY, 60
|
||||||
|
|
||||||
assert_in_delta Time.now, re_signed.not_before, 10
|
assert_in_delta Time.now, re_signed.not_before, 10
|
||||||
|
@ -127,6 +129,7 @@ class TestGemSecurity < Gem::TestCase
|
||||||
assert_equal EXPIRED_CERT.serial + 1, re_signed.serial
|
assert_equal EXPIRED_CERT.serial + 1, re_signed.serial
|
||||||
|
|
||||||
assert re_signed.verify PUBLIC_KEY
|
assert re_signed.verify PUBLIC_KEY
|
||||||
|
assert_equal "sha256WithRSAEncryption", re_signed.signature_algorithm
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_class_re_sign_not_self_signed
|
def test_class_re_sign_not_self_signed
|
||||||
|
@ -218,6 +221,8 @@ class TestGemSecurity < Gem::TestCase
|
||||||
assert_in_delta Time.now, signed.not_before, 10
|
assert_in_delta Time.now, signed.not_before, 10
|
||||||
assert_in_delta Time.now + 60, signed.not_after, 10
|
assert_in_delta Time.now + 60, signed.not_after, 10
|
||||||
|
|
||||||
|
assert_equal "sha256WithRSAEncryption", signed.signature_algorithm
|
||||||
|
|
||||||
assert_equal 5, signed.extensions.length,
|
assert_equal 5, signed.extensions.length,
|
||||||
signed.extensions.map { |e| e.to_a.first }
|
signed.extensions.map { |e| e.to_a.first }
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# coding: UTF-8
|
# coding: utf-8
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rubygems/test_case'
|
require 'rubygems/test_case'
|
||||||
|
@ -34,7 +34,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
s.files = %w[lib/code.rb]
|
s.files = %w[lib/code.rb]
|
||||||
end
|
end
|
||||||
|
|
||||||
@sha1 = OpenSSL::Digest::SHA1
|
@digest = Gem::Security::DIGEST_ALGORITHM
|
||||||
@trust_dir = Gem::Security.trust_dir.dir # HACK use the object
|
@trust_dir = Gem::Security.trust_dir.dir # HACK use the object
|
||||||
|
|
||||||
@no = Gem::Security::NoSecurity
|
@no = Gem::Security::NoSecurity
|
||||||
|
@ -69,7 +69,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
|
|
||||||
signature = sign data
|
signature = sign data
|
||||||
|
|
||||||
assert @almost_no.check_data(PUBLIC_KEY, @sha1, signature, data)
|
assert @almost_no.check_data(PUBLIC_KEY, @digest, signature, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_check_data_invalid
|
def test_check_data_invalid
|
||||||
|
@ -80,7 +80,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
invalid = digest 'hello!'
|
invalid = digest 'hello!'
|
||||||
|
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@almost_no.check_data PUBLIC_KEY, @sha1, signature, invalid
|
@almost_no.check_data PUBLIC_KEY, @digest, signature, invalid
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal 'invalid signature', e.message
|
assert_equal 'invalid signature', e.message
|
||||||
|
@ -238,18 +238,18 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
def test_check_trust
|
def test_check_trust
|
||||||
Gem::Security.trust_dir.trust_cert PUBLIC_CERT
|
Gem::Security.trust_dir.trust_cert PUBLIC_CERT
|
||||||
|
|
||||||
assert @high.check_trust [PUBLIC_CERT], @sha1, @trust_dir
|
assert @high.check_trust [PUBLIC_CERT], @digest, @trust_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_check_trust_child
|
def test_check_trust_child
|
||||||
Gem::Security.trust_dir.trust_cert PUBLIC_CERT
|
Gem::Security.trust_dir.trust_cert PUBLIC_CERT
|
||||||
|
|
||||||
assert @high.check_trust [PUBLIC_CERT, CHILD_CERT], @sha1, @trust_dir
|
assert @high.check_trust [PUBLIC_CERT, CHILD_CERT], @digest, @trust_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_check_trust_empty_chain
|
def test_check_trust_empty_chain
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@chain.check_trust [], @sha1, @trust_dir
|
@chain.check_trust [], @digest, @trust_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal 'missing root certificate', e.message
|
assert_equal 'missing root certificate', e.message
|
||||||
|
@ -259,7 +259,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
Gem::Security.trust_dir.trust_cert PUBLIC_CERT
|
Gem::Security.trust_dir.trust_cert PUBLIC_CERT
|
||||||
|
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@high.check_trust [WRONG_KEY_CERT], @sha1, @trust_dir
|
@high.check_trust [WRONG_KEY_CERT], @digest, @trust_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal "trusted root certificate #{PUBLIC_CERT.subject} checksum " +
|
assert_equal "trusted root certificate #{PUBLIC_CERT.subject} checksum " +
|
||||||
|
@ -268,7 +268,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
|
|
||||||
def test_check_trust_no_chain
|
def test_check_trust_no_chain
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@chain.check_trust nil, @sha1, @trust_dir
|
@chain.check_trust nil, @digest, @trust_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal 'missing signing chain', e.message
|
assert_equal 'missing signing chain', e.message
|
||||||
|
@ -276,7 +276,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
|
|
||||||
def test_check_trust_no_trust
|
def test_check_trust_no_trust
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@high.check_trust [PUBLIC_CERT], @sha1, @trust_dir
|
@high.check_trust [PUBLIC_CERT], @digest, @trust_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted", e.message
|
assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted", e.message
|
||||||
|
@ -284,7 +284,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
|
|
||||||
def test_check_trust_no_trust_child
|
def test_check_trust_no_trust_child
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@high.check_trust [PUBLIC_CERT, CHILD_CERT], @sha1, @trust_dir
|
@high.check_trust [PUBLIC_CERT, CHILD_CERT], @digest, @trust_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted " +
|
assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted " +
|
||||||
|
@ -370,7 +370,7 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
|
|
||||||
data = digest 'goodbye'
|
data = digest 'goodbye'
|
||||||
|
|
||||||
signatures[1] = PRIVATE_KEY.sign @sha1.new, data.digest
|
signatures[1] = PRIVATE_KEY.sign @digest.new, data.digest
|
||||||
|
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@almost_no.verify [PUBLIC_CERT], nil, digests, signatures
|
@almost_no.verify [PUBLIC_CERT], nil, digests, signatures
|
||||||
|
@ -453,17 +453,17 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
metadata_gz = Gem.gzip @spec.to_yaml
|
metadata_gz = Gem.gzip @spec.to_yaml
|
||||||
|
|
||||||
package = Gem::Package.new 'nonexistent.gem'
|
package = Gem::Package.new 'nonexistent.gem'
|
||||||
package.checksums['SHA1'] = {}
|
package.checksums[Gem::Security::DIGEST_NAME] = {}
|
||||||
|
|
||||||
s = StringIO.new metadata_gz
|
s = StringIO.new metadata_gz
|
||||||
def s.full_name() 'metadata.gz' end
|
def s.full_name() 'metadata.gz' end
|
||||||
|
|
||||||
digests = package.digest s
|
digests = package.digest s
|
||||||
metadata_gz_digest = digests['SHA1']['metadata.gz']
|
metadata_gz_digest = digests[Gem::Security::DIGEST_NAME]['metadata.gz']
|
||||||
|
|
||||||
signatures = {}
|
signatures = {}
|
||||||
signatures['metadata.gz'] =
|
signatures['metadata.gz'] =
|
||||||
PRIVATE_KEY.sign @sha1.new, metadata_gz_digest.digest
|
PRIVATE_KEY.sign @digest.new, metadata_gz_digest.digest
|
||||||
|
|
||||||
assert @high.verify_signatures @spec, digests, signatures
|
assert @high.verify_signatures @spec, digests, signatures
|
||||||
end
|
end
|
||||||
|
@ -476,19 +476,19 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
metadata_gz = Gem.gzip @spec.to_yaml
|
metadata_gz = Gem.gzip @spec.to_yaml
|
||||||
|
|
||||||
package = Gem::Package.new 'nonexistent.gem'
|
package = Gem::Package.new 'nonexistent.gem'
|
||||||
package.checksums['SHA1'] = {}
|
package.checksums[Gem::Security::DIGEST_NAME] = {}
|
||||||
|
|
||||||
s = StringIO.new metadata_gz
|
s = StringIO.new metadata_gz
|
||||||
def s.full_name() 'metadata.gz' end
|
def s.full_name() 'metadata.gz' end
|
||||||
|
|
||||||
digests = package.digest s
|
digests = package.digest s
|
||||||
digests['SHA1']['data.tar.gz'] = OpenSSL::Digest.new 'SHA1', 'hello'
|
digests[Gem::Security::DIGEST_NAME]['data.tar.gz'] = @digest.new 'hello'
|
||||||
|
|
||||||
metadata_gz_digest = digests['SHA1']['metadata.gz']
|
metadata_gz_digest = digests[Gem::Security::DIGEST_NAME]['metadata.gz']
|
||||||
|
|
||||||
signatures = {}
|
signatures = {}
|
||||||
signatures['metadata.gz'] =
|
signatures['metadata.gz'] =
|
||||||
PRIVATE_KEY.sign @sha1.new, metadata_gz_digest.digest
|
PRIVATE_KEY.sign @digest.new, metadata_gz_digest.digest
|
||||||
|
|
||||||
e = assert_raises Gem::Security::Exception do
|
e = assert_raises Gem::Security::Exception do
|
||||||
@high.verify_signatures @spec, digests, signatures
|
@high.verify_signatures @spec, digests, signatures
|
||||||
|
@ -505,13 +505,13 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
metadata_gz = Gem.gzip @spec.to_yaml
|
metadata_gz = Gem.gzip @spec.to_yaml
|
||||||
|
|
||||||
package = Gem::Package.new 'nonexistent.gem'
|
package = Gem::Package.new 'nonexistent.gem'
|
||||||
package.checksums['SHA1'] = {}
|
package.checksums[Gem::Security::DIGEST_NAME] = {}
|
||||||
|
|
||||||
s = StringIO.new metadata_gz
|
s = StringIO.new metadata_gz
|
||||||
def s.full_name() 'metadata.gz' end
|
def s.full_name() 'metadata.gz' end
|
||||||
|
|
||||||
digests = package.digest s
|
digests = package.digest s
|
||||||
digests['SHA1']['data.tar.gz'] = OpenSSL::Digest.new 'SHA1', 'hello'
|
digests[Gem::Security::DIGEST_NAME]['data.tar.gz'] = @digest.new 'hello'
|
||||||
|
|
||||||
assert_raises Gem::Security::Exception do
|
assert_raises Gem::Security::Exception do
|
||||||
@high.verify_signatures @spec, digests, {}
|
@high.verify_signatures @spec, digests, {}
|
||||||
|
@ -519,19 +519,19 @@ class TestGemSecurityPolicy < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def digest data
|
def digest data
|
||||||
digester = @sha1.new
|
digester = @digest.new
|
||||||
digester << data
|
digester << data
|
||||||
digester
|
digester
|
||||||
end
|
end
|
||||||
|
|
||||||
def sign data, key = PRIVATE_KEY
|
def sign data, key = PRIVATE_KEY
|
||||||
key.sign @sha1.new, data.digest
|
key.sign @digest.new, data.digest
|
||||||
end
|
end
|
||||||
|
|
||||||
def dummy_signatures key = PRIVATE_KEY
|
def dummy_signatures key = PRIVATE_KEY
|
||||||
data = digest 'hello'
|
data = digest 'hello'
|
||||||
|
|
||||||
digests = { 'SHA1' => { 0 => data } }
|
digests = { Gem::Security::DIGEST_NAME => { 0 => data } }
|
||||||
signatures = { 0 => sign(data, key) }
|
signatures = { 0 => sign(data, key) }
|
||||||
|
|
||||||
return digests, signatures
|
return digests, signatures
|
||||||
|
|
|
@ -121,12 +121,12 @@ class TestGemSecuritySigner < Gem::TestCase
|
||||||
signature = signer.sign 'hello'
|
signature = signer.sign 'hello'
|
||||||
|
|
||||||
expected = <<-EXPECTED
|
expected = <<-EXPECTED
|
||||||
pxSf9ScaghbMNmNp8fqSJj7BiIGpbuoOVYCOM3TJNH9STLILA5z3xKp3gM6w
|
cHze2sEfRysoUMCfGVAx/7o8jxj5liJJ2ptNxe2jf3l+EZvyjdqpXo9Ndzxx
|
||||||
VJ7aGsh9KCP485ftS3J9Kb/lKJsyoSkkRSQ5QG+LnyZwMuWlThPDR5o7q6al
|
6xLp2rxLG4K2//ip4aCH5Sh7hnia+F5u6iuLBETPlklPrmw5dnuKZxolz+vM
|
||||||
0oxE7vvbbqxFqcT4ojWIkwxJxOluFWmt2D8I6QTX2vLAn09y+Kl66AOrT7R5
|
0O1aOZsQHcVzQoESTGjkms3KZk+gn3lg0sSBbAV5/LyDYoHCEjxlcA5D+Olb
|
||||||
UinbXkz04VwcNvkBqJyko3yWxFKiGNpntZQg4jIw4L+h97EOaZp8H96udzQH
|
rDmRyBMOnMS+q489OZ5Hr6B2YJJ3QbUwIZNhUeNmOxIBEYTrrKkZ92qkxbRN
|
||||||
Da3K0YZ6FsqLDFNnWAFhve3kmpE3CludpvDqH0piq0zKqnOiqAcvICIpPaJP
|
qhlqFP4jR6zXFeyBCOr0KpTiWBNuxBFXDsxmhGyt2BOIjD6qmKn7RSIfYg/U
|
||||||
c7NM7KZZjj7G++SXjYTEI1PHSA7aFQ/i/+qSUvx+Pg==
|
toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA==
|
||||||
EXPECTED
|
EXPECTED
|
||||||
|
|
||||||
assert_equal expected, [signature].pack('m')
|
assert_equal expected, [signature].pack('m')
|
||||||
|
|
|
@ -18,7 +18,7 @@ class TestGemSecurityTrustDir < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_cert_path
|
def test_cert_path
|
||||||
digest = OpenSSL::Digest::SHA1.hexdigest PUBLIC_CERT.subject.to_s
|
digest = Gem::Security::DIGEST_ALGORITHM.hexdigest PUBLIC_CERT.subject.to_s
|
||||||
|
|
||||||
expected = File.join @dest_dir, "cert-#{digest}.pem"
|
expected = File.join @dest_dir, "cert-#{digest}.pem"
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class TestGemSecurityTrustDir < Gem::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_name_path
|
def test_name_path
|
||||||
digest = OpenSSL::Digest::SHA1.hexdigest PUBLIC_CERT.subject.to_s
|
digest = Gem::Security::DIGEST_ALGORITHM.hexdigest PUBLIC_CERT.subject.to_s
|
||||||
|
|
||||||
expected = File.join @dest_dir, "cert-#{digest}.pem"
|
expected = File.join @dest_dir, "cert-#{digest}.pem"
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ class TestGemServer < Gem::TestCase
|
||||||
assert_equal 404, @res.status, @res.body
|
assert_equal 404, @res.status, @res.body
|
||||||
assert_match %r| \d\d:\d\d:\d\d |, @res['date']
|
assert_match %r| \d\d:\d\d:\d\d |, @res['date']
|
||||||
assert_equal 'text/plain', @res['content-type']
|
assert_equal 'text/plain', @res['content-type']
|
||||||
assert_equal 'No gems found matching "z" "9" nil', @res.body
|
assert_equal 'No gems found matching "z-9"', @res.body
|
||||||
assert_equal 404, @res.status
|
assert_equal 404, @res.status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -291,6 +291,23 @@ class TestGemServer < Gem::TestCase
|
||||||
assert_equal v('3.a'), spec.version
|
assert_equal v('3.a'), spec.version
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_quick_marshal_a_b_1_3_a_gemspec_rz
|
||||||
|
quick_gem 'a-b-1', '3.a'
|
||||||
|
|
||||||
|
data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-b-1-3.a.gemspec.rz HTTP/1.0\r\n\r\n"
|
||||||
|
@req.parse data
|
||||||
|
|
||||||
|
@server.quick @req, @res
|
||||||
|
|
||||||
|
assert_equal 200, @res.status, @res.body
|
||||||
|
assert @res['date']
|
||||||
|
assert_equal 'application/x-deflate', @res['content-type']
|
||||||
|
|
||||||
|
spec = Marshal.load Gem.inflate(@res.body)
|
||||||
|
assert_equal 'a-b-1', spec.name
|
||||||
|
assert_equal v('3.a'), spec.version
|
||||||
|
end
|
||||||
|
|
||||||
def test_rdoc
|
def test_rdoc
|
||||||
data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n"
|
data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n"
|
||||||
@req.parse data
|
@req.parse data
|
||||||
|
|
|
@ -228,6 +228,15 @@ class TestGemSource < Gem::TestCase
|
||||||
assert_equal(-1, remote. <=>(no_uri), 'remote <=> no_uri')
|
assert_equal(-1, remote. <=>(no_uri), 'remote <=> no_uri')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_spaceship_order_is_preserved_when_uri_differs
|
||||||
|
sourceA = Gem::Source.new "http://example.com/a"
|
||||||
|
sourceB = Gem::Source.new "http://example.com/b"
|
||||||
|
|
||||||
|
assert_equal( 0, sourceA. <=>(sourceA), 'sourceA <=> sourceA')
|
||||||
|
assert_equal( 1, sourceA. <=>(sourceB), 'sourceA <=> sourceB')
|
||||||
|
assert_equal( 1, sourceB. <=>(sourceA), 'sourceB <=> sourceA')
|
||||||
|
end
|
||||||
|
|
||||||
def test_update_cache_eh
|
def test_update_cache_eh
|
||||||
assert @source.update_cache?
|
assert @source.update_cache?
|
||||||
end
|
end
|
||||||
|
|
|
@ -169,6 +169,26 @@ class TestGemSpecFetcher < Gem::TestCase
|
||||||
assert_equal "bad news from the internet (#{@gem_repo})", sfp.error.message
|
assert_equal "bad news from the internet (#{@gem_repo})", sfp.error.message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_suggest_gems_from_name_latest
|
||||||
|
spec_fetcher do|fetcher|
|
||||||
|
fetcher.spec 'example', 1
|
||||||
|
fetcher.spec 'other-example', 1
|
||||||
|
end
|
||||||
|
|
||||||
|
suggestions = @sf.suggest_gems_from_name('examplw')
|
||||||
|
assert_equal ['example'], suggestions
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_suggest_gems_from_name_prerelease
|
||||||
|
spec_fetcher do|fetcher|
|
||||||
|
fetcher.spec 'example', '1.a'
|
||||||
|
fetcher.spec 'other-example', 1
|
||||||
|
end
|
||||||
|
|
||||||
|
suggestions = @sf.suggest_gems_from_name('examplw')
|
||||||
|
assert_equal ['example'], suggestions
|
||||||
|
end
|
||||||
|
|
||||||
def test_available_specs_latest
|
def test_available_specs_latest
|
||||||
spec_fetcher do |fetcher|
|
spec_fetcher do |fetcher|
|
||||||
fetcher.spec 'a', 1
|
fetcher.spec 'a', 1
|
||||||
|
|
|
@ -1586,7 +1586,7 @@ dependencies: []
|
||||||
refute @ext.contains_requirable_file? 'nonexistent'
|
refute @ext.contains_requirable_file? 'nonexistent'
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = "Ignoring ext-1 because its extensions are not built. " +
|
expected = "Ignoring ext-1 because its extensions are not built. " +
|
||||||
"Try: gem pristine ext --version 1\n"
|
"Try: gem pristine ext --version 1\n"
|
||||||
|
|
||||||
assert_equal expected, err
|
assert_equal expected, err
|
||||||
|
@ -2748,14 +2748,6 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
|
||||||
util_setup_validate
|
util_setup_validate
|
||||||
|
|
||||||
Dir.chdir @tempdir do
|
Dir.chdir @tempdir do
|
||||||
@a1.email = ""
|
|
||||||
|
|
||||||
use_ui @ui do
|
|
||||||
@a1.validate
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_match "#{w}: no email specified\n", @ui.error, "error"
|
|
||||||
|
|
||||||
@a1.email = "FIxxxXME (your e-mail)".sub(/xxx/, "")
|
@a1.email = "FIxxxXME (your e-mail)".sub(/xxx/, "")
|
||||||
|
|
||||||
e = assert_raises Gem::InvalidSpecificationException do
|
e = assert_raises Gem::InvalidSpecificationException do
|
||||||
|
@ -2977,6 +2969,43 @@ Did you mean 'Ruby'?
|
||||||
warning
|
warning
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_validate_empty_files
|
||||||
|
util_setup_validate
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
# we have to set all of these for #files to be empty
|
||||||
|
@a1.files = []
|
||||||
|
@a1.test_files = []
|
||||||
|
@a1.executables = []
|
||||||
|
|
||||||
|
@a1.validate
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match "no files specified", @ui.error
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_empty_homepage
|
||||||
|
util_setup_validate
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
@a1.homepage = nil
|
||||||
|
@a1.validate
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match "no homepage specified", @ui.error
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_empty_summary
|
||||||
|
util_setup_validate
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
@a1.summary = nil
|
||||||
|
@a1.validate
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match "no summary specified", @ui.error
|
||||||
|
end
|
||||||
|
|
||||||
def test_validate_name
|
def test_validate_name
|
||||||
util_setup_validate
|
util_setup_validate
|
||||||
|
|
||||||
|
@ -3252,7 +3281,11 @@ Did you mean 'Ruby'?
|
||||||
Dir.chdir @tempdir do
|
Dir.chdir @tempdir do
|
||||||
@m1 = quick_gem 'm', '1' do |s|
|
@m1 = quick_gem 'm', '1' do |s|
|
||||||
s.files = %w[lib/code.rb]
|
s.files = %w[lib/code.rb]
|
||||||
s.metadata = { 'one' => "two", 'two' => "three" }
|
s.metadata = {
|
||||||
|
"one" => "two",
|
||||||
|
"home" => "three",
|
||||||
|
"homepage_uri" => "https://example.com/user/repo"
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
use_ui @ui do
|
use_ui @ui do
|
||||||
|
@ -3329,6 +3362,23 @@ Did you mean 'Ruby'?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_metadata_link_validation_fails
|
||||||
|
util_setup_validate
|
||||||
|
|
||||||
|
Dir.chdir @tempdir do
|
||||||
|
@m2 = quick_gem 'm', '2' do |s|
|
||||||
|
s.files = %w[lib/code.rb]
|
||||||
|
s.metadata = { 'homepage_uri' => 'http:/example.com' }
|
||||||
|
end
|
||||||
|
|
||||||
|
e = assert_raises Gem::InvalidSpecificationException do
|
||||||
|
@m2.validate
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "metadata['homepage_uri'] has invalid link: \"http:/example.com\"", e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_metadata_specs
|
def test_metadata_specs
|
||||||
valid_ruby_spec = <<-EOF
|
valid_ruby_spec = <<-EOF
|
||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
@ -3406,6 +3456,31 @@ end
|
||||||
refute @a1.missing_extensions?
|
refute @a1.missing_extensions?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_find_all_by_full_name
|
||||||
|
pl = Gem::Platform.new 'i386-linux'
|
||||||
|
|
||||||
|
a1 = util_spec "a", "1"
|
||||||
|
a1_pre = util_spec "a", "1.0.0.pre.1"
|
||||||
|
a_1_platform = util_spec("a", "1") {|s| s.platform = pl }
|
||||||
|
a_b_1 = util_spec "a-b", "1"
|
||||||
|
a_b_1_platform = util_spec("a-b", "1") {|s| s.platform = pl }
|
||||||
|
|
||||||
|
a_b_1_1 = util_spec "a-b-1", "1"
|
||||||
|
a_b_1_1_platform = util_spec("a-b-1", "1") {|s| s.platform = pl }
|
||||||
|
|
||||||
|
install_specs(a1, a1_pre, a_1_platform, a_b_1, a_b_1_platform,
|
||||||
|
a_b_1_1, a_b_1_1_platform)
|
||||||
|
|
||||||
|
assert_equal [a1], Gem::Specification.find_all_by_full_name("a-1")
|
||||||
|
assert_equal [a1_pre], Gem::Specification.find_all_by_full_name("a-1.0.0.pre.1")
|
||||||
|
assert_equal [a_1_platform], Gem::Specification.find_all_by_full_name("a-1-x86-linux")
|
||||||
|
assert_equal [a_b_1_1], Gem::Specification.find_all_by_full_name("a-b-1-1")
|
||||||
|
assert_equal [a_b_1_1_platform], Gem::Specification.find_all_by_full_name("a-b-1-1-x86-linux")
|
||||||
|
|
||||||
|
assert_equal [], Gem::Specification.find_all_by_full_name("monkeys")
|
||||||
|
assert_equal [], Gem::Specification.find_all_by_full_name("a-1-foo")
|
||||||
|
end
|
||||||
|
|
||||||
def test_find_by_name
|
def test_find_by_name
|
||||||
install_specs util_spec "a"
|
install_specs util_spec "a"
|
||||||
install_specs util_spec "a", 1
|
install_specs util_spec "a", 1
|
||||||
|
|
|
@ -71,7 +71,7 @@ class TestStubSpecification < Gem::TestCase
|
||||||
refute stub.contains_requirable_file? 'nonexistent'
|
refute stub.contains_requirable_file? 'nonexistent'
|
||||||
end
|
end
|
||||||
|
|
||||||
expected = "Ignoring stub_e-2 because its extensions are not built. " +
|
expected = "Ignoring stub_e-2 because its extensions are not built. " +
|
||||||
"Try: gem pristine stub_e --version 2\n"
|
"Try: gem pristine stub_e --version 2\n"
|
||||||
|
|
||||||
assert_equal expected, err
|
assert_equal expected, err
|
||||||
|
@ -95,6 +95,12 @@ class TestStubSpecification < Gem::TestCase
|
||||||
assert_equal File.join(stub.full_gem_path, 'lib'), stub.lib_dirs_glob
|
assert_equal File.join(stub.full_gem_path, 'lib'), stub.lib_dirs_glob
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_lib_dirs_glob_with_extension
|
||||||
|
stub = stub_with_extension
|
||||||
|
|
||||||
|
assert_equal File.join(stub.full_gem_path, 'lib'), stub.lib_dirs_glob
|
||||||
|
end
|
||||||
|
|
||||||
def test_matches_for_glob
|
def test_matches_for_glob
|
||||||
stub = stub_without_extension
|
stub = stub_without_extension
|
||||||
code_rb = File.join stub.gem_dir, 'lib', 'code.rb'
|
code_rb = File.join stub.gem_dir, 'lib', 'code.rb'
|
||||||
|
|
|
@ -26,6 +26,7 @@ class TestGemUtil < Gem::TestCase
|
||||||
assert_equal File.join(@tempdir, 'a/b/c'), enum.next
|
assert_equal File.join(@tempdir, 'a/b/c'), enum.next
|
||||||
assert_equal File.join(@tempdir, 'a/b'), enum.next
|
assert_equal File.join(@tempdir, 'a/b'), enum.next
|
||||||
assert_equal File.join(@tempdir, 'a'), enum.next
|
assert_equal File.join(@tempdir, 'a'), enum.next
|
||||||
|
loop { break if enum.next.nil? } # exhaust the enumerator
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_linked_list_find
|
def test_linked_list_find
|
||||||
|
|
|
@ -41,6 +41,11 @@ class TestGemVersion < Gem::TestCase
|
||||||
assert_equal v('1.1'), Gem::Version.create(ver)
|
assert_equal v('1.1'), Gem::Version.create(ver)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_class_correct
|
||||||
|
assert_equal true, Gem::Version.correct?("5.1")
|
||||||
|
assert_equal false, Gem::Version.correct?("an incorrect version")
|
||||||
|
end
|
||||||
|
|
||||||
def test_class_new_subclass
|
def test_class_new_subclass
|
||||||
v1 = Gem::Version.new '1'
|
v1 = Gem::Version.new '1'
|
||||||
v2 = V.new '1'
|
v2 = V.new '1'
|
||||||
|
@ -65,7 +70,8 @@ class TestGemVersion < Gem::TestCase
|
||||||
def test_hash
|
def test_hash
|
||||||
assert_equal v("1.2").hash, v("1.2").hash
|
assert_equal v("1.2").hash, v("1.2").hash
|
||||||
refute_equal v("1.2").hash, v("1.3").hash
|
refute_equal v("1.2").hash, v("1.3").hash
|
||||||
refute_equal v("1.2").hash, v("1.2.0").hash
|
assert_equal v("1.2").hash, v("1.2.0").hash
|
||||||
|
assert_equal v("1.2.pre.1").hash, v("1.2.0.pre.1.0").hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_initialize
|
def test_initialize
|
||||||
|
@ -76,18 +82,23 @@ class TestGemVersion < Gem::TestCase
|
||||||
assert_version_equal "1", 1
|
assert_version_equal "1", 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_initialize_bad
|
def test_initialize_invalid
|
||||||
%W[
|
invalid_versions = %W[
|
||||||
junk
|
junk
|
||||||
1.0\n2.0
|
1.0\n2.0
|
||||||
1..2
|
1..2
|
||||||
1.2\ 3.4
|
1.2\ 3.4
|
||||||
].each do |bad|
|
]
|
||||||
e = assert_raises ArgumentError, bad do
|
|
||||||
Gem::Version.new bad
|
# DON'T TOUCH THIS WITHOUT CHECKING CVE-2013-4287
|
||||||
|
invalid_versions << "2.3422222.222.222222222.22222.ads0as.dasd0.ddd2222.2.qd3e."
|
||||||
|
|
||||||
|
invalid_versions.each do |invalid|
|
||||||
|
e = assert_raises ArgumentError, invalid do
|
||||||
|
Gem::Version.new invalid
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal "Malformed version number string #{bad}", e.message, bad
|
assert_equal "Malformed version number string #{invalid}", e.message, invalid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -105,6 +116,9 @@ class TestGemVersion < Gem::TestCase
|
||||||
|
|
||||||
assert_prerelease '1.A'
|
assert_prerelease '1.A'
|
||||||
|
|
||||||
|
assert_prerelease '1-1'
|
||||||
|
assert_prerelease '1-a'
|
||||||
|
|
||||||
refute_prerelease "1.2.0"
|
refute_prerelease "1.2.0"
|
||||||
refute_prerelease "2.9"
|
refute_prerelease "2.9"
|
||||||
refute_prerelease "22.1.50.0"
|
refute_prerelease "22.1.50.0"
|
||||||
|
@ -160,6 +174,12 @@ class TestGemVersion < Gem::TestCase
|
||||||
assert_equal [9,8,7], v("9.8.7").segments
|
assert_equal [9,8,7], v("9.8.7").segments
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_canonical_segments
|
||||||
|
assert_equal [1], v("1.0.0").canonical_segments
|
||||||
|
assert_equal [1, "a", 1], v("1.0.0.a.1.0").canonical_segments
|
||||||
|
assert_equal [1, 2, 3, "pre", 1], v("1.2.3-1").canonical_segments
|
||||||
|
end
|
||||||
|
|
||||||
# Asserts that +version+ is a prerelease.
|
# Asserts that +version+ is a prerelease.
|
||||||
|
|
||||||
def assert_prerelease version
|
def assert_prerelease version
|
||||||
|
@ -189,6 +209,7 @@ class TestGemVersion < Gem::TestCase
|
||||||
|
|
||||||
def assert_version_equal expected, actual
|
def assert_version_equal expected, actual
|
||||||
assert_equal v(expected), v(actual)
|
assert_equal v(expected), v(actual)
|
||||||
|
assert_equal v(expected).hash, v(actual).hash, "since #{actual} == #{expected}, they must have the same hash"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Assert that two versions are eql?. Checks both directions.
|
# Assert that two versions are eql?. Checks both directions.
|
||||||
|
|
|
@ -106,6 +106,21 @@ class TestGemVersionOption < Gem::TestCase
|
||||||
assert_equal expected, @cmd.options
|
assert_equal expected, @cmd.options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_multiple_version_operator_option_compound
|
||||||
|
@cmd.add_version_option
|
||||||
|
|
||||||
|
@cmd.handle_options ['--version', '< 1', '--version', '> 0.9']
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
:args => [],
|
||||||
|
:explicit_prerelease => false,
|
||||||
|
:prerelease => false,
|
||||||
|
:version => Gem::Requirement.new('< 1', '> 0.9'),
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal expected, @cmd.options
|
||||||
|
end
|
||||||
|
|
||||||
def test_version_option_explicit_prerelease
|
def test_version_option_explicit_prerelease
|
||||||
@cmd.add_prerelease_option
|
@cmd.add_prerelease_option
|
||||||
@cmd.add_version_option
|
@cmd.add_version_option
|
||||||
|
|
|
@ -90,4 +90,34 @@ class TestKernel < Gem::TestCase
|
||||||
assert gem('a', '= 1'), "Should load"
|
assert gem('a', '= 1'), "Should load"
|
||||||
refute $:.any? { |p| %r{a-1/bin} =~ p }
|
refute $:.any? { |p| %r{a-1/bin} =~ p }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_gem_bundler
|
||||||
|
quick_gem 'bundler', '1'
|
||||||
|
quick_gem 'bundler', '2.a'
|
||||||
|
|
||||||
|
assert gem('bundler')
|
||||||
|
assert $:.any? { |p| %r{bundler-1/lib} =~ p }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gem_bundler_missing_bundler_version
|
||||||
|
Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do
|
||||||
|
quick_gem 'bundler', '1'
|
||||||
|
quick_gem 'bundler', '2.a'
|
||||||
|
|
||||||
|
e = assert_raises Gem::MissingSpecVersionError do
|
||||||
|
gem('bundler')
|
||||||
|
end
|
||||||
|
assert_match "Could not find 'bundler' (55) required by reason.", e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gem_bundler_inferred_bundler_version
|
||||||
|
Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do
|
||||||
|
quick_gem 'bundler', '1'
|
||||||
|
quick_gem 'bundler', '2.a'
|
||||||
|
|
||||||
|
assert gem('bundler', '>= 0.a')
|
||||||
|
assert $:.any? { |p| %r{bundler-1/lib} =~ p }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -383,6 +383,44 @@ class TestGemRequire < Gem::TestCase
|
||||||
assert_equal %w(a-1), loaded_spec_names
|
assert_equal %w(a-1), loaded_spec_names
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def test_require_bundler
|
||||||
|
b1 = new_spec('bundler', '1', nil, "lib/bundler/setup.rb")
|
||||||
|
b2a = new_spec('bundler', '2.a', nil, "lib/bundler/setup.rb")
|
||||||
|
install_specs b1, b2a
|
||||||
|
|
||||||
|
require "rubygems/bundler_version_finder"
|
||||||
|
$:.clear
|
||||||
|
assert_require 'bundler/setup'
|
||||||
|
assert_equal %w[bundler-2.a], loaded_spec_names
|
||||||
|
assert_empty unresolved_names
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_require_bundler_missing_bundler_version
|
||||||
|
Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do
|
||||||
|
b1 = new_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb")
|
||||||
|
b2a = new_spec('bundler', '2.a', nil, "lib/bundler/setup.rb")
|
||||||
|
install_specs b1, b2a
|
||||||
|
|
||||||
|
e = assert_raises Gem::MissingSpecVersionError do
|
||||||
|
gem('bundler')
|
||||||
|
end
|
||||||
|
assert_match "Could not find 'bundler' (55) required by reason.", e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_require_bundler_with_bundler_version
|
||||||
|
Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do
|
||||||
|
b1 = new_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb")
|
||||||
|
b2 = new_spec('bundler', '2', nil, "lib/bundler/setup.rb")
|
||||||
|
install_specs b1, b2
|
||||||
|
|
||||||
|
$:.clear
|
||||||
|
assert_require 'bundler/setup'
|
||||||
|
assert_equal %w[bundler-1.999999999], loaded_spec_names
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def silence_warnings
|
def silence_warnings
|
||||||
old_verbose, $VERBOSE = $VERBOSE, false
|
old_verbose, $VERBOSE = $VERBOSE, false
|
||||||
yield
|
yield
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue