Merge the current master branch of rubygems/rubygems.

Just started to develop RubyGems 3.2.0.
This commit is contained in:
Hiroshi SHIBATA 2020-02-01 11:14:04 +09:00
parent adc3031311
commit 600a715c9b
No known key found for this signature in database
GPG Key ID: F9CF13417264FAC2
54 changed files with 1236 additions and 1207 deletions

View File

@ -9,7 +9,7 @@
require 'rbconfig' require 'rbconfig'
module Gem module Gem
VERSION = "3.1.2".freeze VERSION = "3.2.0.pre1".freeze
end end
# Must be first since it unloads the prelude from 1.9.2 # Must be first since it unloads the prelude from 1.9.2
@ -26,27 +26,27 @@ require 'rubygems/errors'
# For user documentation, see: # For user documentation, see:
# #
# * <tt>gem help</tt> and <tt>gem help [command]</tt> # * <tt>gem help</tt> and <tt>gem help [command]</tt>
# * {RubyGems User Guide}[http://guides.rubygems.org/] # * {RubyGems User Guide}[https://guides.rubygems.org/]
# * {Frequently Asked Questions}[http://guides.rubygems.org/faqs] # * {Frequently Asked Questions}[https://guides.rubygems.org/faqs]
# #
# For gem developer documentation see: # For gem developer documentation see:
# #
# * {Creating Gems}[http://guides.rubygems.org/make-your-own-gem] # * {Creating Gems}[https://guides.rubygems.org/make-your-own-gem]
# * Gem::Specification # * Gem::Specification
# * Gem::Version for version dependency notes # * Gem::Version for version dependency notes
# #
# Further RubyGems documentation can be found at: # Further RubyGems documentation can be found at:
# #
# * {RubyGems Guides}[http://guides.rubygems.org] # * {RubyGems Guides}[https://guides.rubygems.org]
# * {RubyGems API}[http://www.rubydoc.info/github/rubygems/rubygems] (also available from # * {RubyGems API}[https://www.rubydoc.info/github/rubygems/rubygems] (also available from
# <tt>gem server</tt>) # <tt>gem server</tt>)
# #
# == RubyGems Plugins # == RubyGems Plugins
# #
# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or # RubyGems will load plugins in the latest version of each installed gem 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 installed at a
# Gem::find_files and then loaded. # special location and loaded on boot.
# #
# For an example plugin, see the {Graph gem}[https://github.com/seattlerb/graph] # For an example plugin, see the {Graph gem}[https://github.com/seattlerb/graph]
# which adds a `gem graph` command. # which adds a `gem graph` command.
@ -148,6 +148,7 @@ module Gem
doc doc
extensions extensions
gems gems
plugins
specifications specifications
].freeze ].freeze
@ -409,8 +410,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
## ##
# The path where gems are to be installed. # The path where gems are to be installed.
#--
# FIXME deprecate these once everything else has been done -ebh
def self.dir def self.dir
paths.home paths.home
@ -424,6 +423,10 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
paths.spec_cache_dir paths.spec_cache_dir
end end
def self.plugins_dir
File.join(dir, "plugins")
end
## ##
# Quietly ensure the Gem directory +dir+ contains all the proper # Quietly ensure the Gem directory +dir+ contains all the proper
# subdirectories. If we can't create a directory due to a permission # subdirectories. If we can't create a directory due to a permission
@ -573,50 +576,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
private_class_method :find_home private_class_method :find_home
# TODO: remove in RubyGems 4.0
##
# Zlib::GzipReader wrapper that unzips +data+.
def self.gunzip(data)
Gem::Util.gunzip data
end
class << self
extend Gem::Deprecate
deprecate :gunzip, "Gem::Util.gunzip", 2018, 12
end
##
# Zlib::GzipWriter wrapper that zips +data+.
def self.gzip(data)
Gem::Util.gzip data
end
class << self
extend Gem::Deprecate
deprecate :gzip, "Gem::Util.gzip", 2018, 12
end
##
# A Zlib::Inflate#inflate wrapper
def self.inflate(data)
Gem::Util.inflate data
end
class << self
extend Gem::Deprecate
deprecate :inflate, "Gem::Util.inflate", 2018, 12
end
## ##
# Top level install helper method. Allows you to install gems interactively: # Top level install helper method. Allows you to install gems interactively:
# #
@ -1018,10 +977,27 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
@suffix_pattern ||= "{#{suffixes.join(',')}}" @suffix_pattern ||= "{#{suffixes.join(',')}}"
end end
##
# Regexp for require-able path suffixes.
def self.suffix_regexp def self.suffix_regexp
@suffix_regexp ||= /#{Regexp.union(suffixes)}\z/ @suffix_regexp ||= /#{Regexp.union(suffixes)}\z/
end end
##
# Glob pattern for require-able plugin suffixes.
def self.plugin_suffix_pattern
@plugin_suffix_pattern ||= "_plugin#{suffix_pattern}"
end
##
# Regexp for require-able plugin suffixes.
def self.plugin_suffix_regexp
@plugin_suffix_regexp ||= /_plugin#{suffix_regexp}\z/
end
## ##
# Suffixes for require-able paths. # Suffixes for require-able paths.
@ -1120,35 +1096,17 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end end
## ##
# Find the 'rubygems_plugin' files in the latest installed gems and load # Find rubygems plugin files in the standard location and load them
# them
def self.load_plugins def self.load_plugins
# Remove this env var by at least 3.0 load_plugin_files Gem::Util.glob_files_in_dir("*#{Gem.plugin_suffix_pattern}", plugins_dir)
if ENV['RUBYGEMS_LOAD_ALL_PLUGINS']
load_plugin_files find_files('rubygems_plugin', false)
else
load_plugin_files find_latest_files('rubygems_plugin', false)
end
end end
## ##
# Find all 'rubygems_plugin' files in $LOAD_PATH and load them # Find all 'rubygems_plugin' files in $LOAD_PATH and load them
def self.load_env_plugins def self.load_env_plugins
path = "rubygems_plugin" load_plugin_files find_files_from_load_path("rubygems_plugin")
files = []
glob = "#{path}#{Gem.suffix_pattern}"
$LOAD_PATH.each do |load_path|
globbed = Gem::Util.glob_files_in_dir(glob, load_path)
globbed.each do |load_path_file|
files << load_path_file if File.file?(load_path_file.tap(&Gem::UNTAINT))
end
end
load_plugin_files files
end end
## ##
@ -1223,18 +1181,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end end
end end
class << self
##
# TODO remove with RubyGems 4.0
alias detect_gemdeps use_gemdeps # :nodoc:
extend Gem::Deprecate
deprecate :detect_gemdeps, "Gem.use_gemdeps", 2018, 12
end
## ##
# The SOURCE_DATE_EPOCH environment variable (or, if that's not set, the current time), converted to Time object. # The SOURCE_DATE_EPOCH environment variable (or, if that's not set, the current time), converted to Time object.
# This is used throughout RubyGems for enabling reproducible builds. # This is used throughout RubyGems for enabling reproducible builds.
@ -1366,23 +1312,23 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/".freeze MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/".freeze
autoload :BundlerVersionFinder, 'rubygems/bundler_version_finder' autoload :BundlerVersionFinder, File.expand_path('rubygems/bundler_version_finder', __dir__)
autoload :ConfigFile, 'rubygems/config_file' autoload :ConfigFile, File.expand_path('rubygems/config_file', __dir__)
autoload :Dependency, 'rubygems/dependency' autoload :Dependency, File.expand_path('rubygems/dependency', __dir__)
autoload :DependencyList, 'rubygems/dependency_list' autoload :DependencyList, File.expand_path('rubygems/dependency_list', __dir__)
autoload :Installer, 'rubygems/installer' autoload :Installer, File.expand_path('rubygems/installer', __dir__)
autoload :Licenses, 'rubygems/util/licenses' autoload :Licenses, File.expand_path('rubygems/util/licenses', __dir__)
autoload :PathSupport, 'rubygems/path_support' autoload :PathSupport, File.expand_path('rubygems/path_support', __dir__)
autoload :Platform, 'rubygems/platform' autoload :Platform, File.expand_path('rubygems/platform', __dir__)
autoload :RequestSet, 'rubygems/request_set' autoload :RequestSet, File.expand_path('rubygems/request_set', __dir__)
autoload :Requirement, 'rubygems/requirement' autoload :Requirement, File.expand_path('rubygems/requirement', __dir__)
autoload :Resolver, 'rubygems/resolver' autoload :Resolver, File.expand_path('rubygems/resolver', __dir__)
autoload :Source, 'rubygems/source' autoload :Source, File.expand_path('rubygems/source', __dir__)
autoload :SourceList, 'rubygems/source_list' autoload :SourceList, File.expand_path('rubygems/source_list', __dir__)
autoload :SpecFetcher, 'rubygems/spec_fetcher' autoload :SpecFetcher, File.expand_path('rubygems/spec_fetcher', __dir__)
autoload :Specification, 'rubygems/specification' autoload :Specification, File.expand_path('rubygems/specification', __dir__)
autoload :Util, 'rubygems/util' autoload :Util, File.expand_path('rubygems/util', __dir__)
autoload :Version, 'rubygems/version' autoload :Version, File.expand_path('rubygems/version', __dir__)
require "rubygems/specification" require "rubygems/specification"
end end

View File

@ -274,12 +274,18 @@ class Gem::BasicSpecification
# Return all files in this gem that match for +glob+. # Return all files in this gem that match for +glob+.
def matches_for_glob(glob) # TODO: rename? def matches_for_glob(glob) # TODO: rename?
# TODO: do we need these?? Kill it
glob = File.join(self.lib_dirs_glob, glob) glob = File.join(self.lib_dirs_glob, glob)
Dir[glob].map { |f| f.tap(&Gem::UNTAINT) } # FIX our tests are broken, run w/ SAFE=1 Dir[glob].map { |f| f.tap(&Gem::UNTAINT) } # FIX our tests are broken, run w/ SAFE=1
end end
##
# Returns the list of plugins in this spec.
def plugins
matches_for_glob("rubygems#{Gem.plugin_suffix_pattern}")
end
## ##
# Returns a string usable in Dir.glob to match all requirable paths # Returns a string usable in Dir.glob to match all requirable paths
# for this spec. # for this spec.

View File

@ -466,6 +466,10 @@ class Gem::Command
result result
end end
def deprecated?
false
end
private private
def option_is_deprecated?(option) def option_is_deprecated?(option)
@ -646,7 +650,7 @@ basic help message containing pointers to more information.
http://localhost:8808/ http://localhost:8808/
with info about installed gems with info about installed gems
Further information: Further information:
http://guides.rubygems.org https://guides.rubygems.org
HELP HELP
# :startdoc: # :startdoc:

View File

@ -176,6 +176,7 @@ class Gem::CommandManager
cmd_name = args.shift.downcase cmd_name = args.shift.downcase
cmd = find_command cmd_name cmd = find_command cmd_name
cmd.invoke_with_build_args args, build_args cmd.invoke_with_build_args args, build_args
cmd.deprecation_warning if cmd.deprecated?
end end
end end

View File

@ -38,7 +38,7 @@ Some examples of 'gem' usage.
* Create a gem: * Create a gem:
See http://guides.rubygems.org/make-your-own-gem/ See https://guides.rubygems.org/make-your-own-gem/
* See information about RubyGems: * See information about RubyGems:

View File

@ -1,14 +1,19 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'rubygems/command' require 'rubygems/command'
require 'rubygems/commands/query_command' require 'rubygems/query_utils'
class Gem::Commands::InfoCommand < Gem::Commands::QueryCommand class Gem::Commands::InfoCommand < Gem::Command
include Gem::QueryUtils
def initialize def initialize
super "info", "Show information for the given gem" super "info", "Show information for the given gem",
:name => //, :domain => :local, :details => false, :versions => true,
:installed => nil, :version => Gem::Requirement.default
add_query_options
remove_option('--name-matches')
remove_option('-d') remove_option('-d')
defaults[:details] = true defaults[:details] = true

View File

@ -218,7 +218,7 @@ You can use `i` command instead of `install`.
gem_version ||= options[:version] gem_version ||= options[:version]
domain = options[:domain] domain = options[:domain]
domain = :local unless options[:suggest_alternate] domain = :local unless options[:suggest_alternate]
supress_suggestions = (domain == :local) suppress_suggestions = (domain == :local)
begin begin
install_gem gem_name, gem_version install_gem gem_name, gem_version
@ -226,11 +226,11 @@ You can use `i` command instead of `install`.
alert_error "Error installing #{gem_name}:\n\t#{e.message}" alert_error "Error installing #{gem_name}:\n\t#{e.message}"
exit_code |= 1 exit_code |= 1
rescue Gem::GemNotFoundException => e rescue Gem::GemNotFoundException => e
show_lookup_failure e.name, e.version, e.errors, supress_suggestions show_lookup_failure e.name, e.version, e.errors, suppress_suggestions
exit_code |= 2 exit_code |= 2
rescue Gem::UnsatisfiableDependencyError => e rescue Gem::UnsatisfiableDependencyError => e
show_lookup_failure e.name, e.version, e.errors, supress_suggestions, show_lookup_failure e.name, e.version, e.errors, suppress_suggestions,
"'#{gem_name}' (#{gem_version})" "'#{gem_name}' (#{gem_version})"
exit_code |= 2 exit_code |= 2

View File

@ -1,17 +1,20 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'rubygems/command' require 'rubygems/command'
require 'rubygems/commands/query_command' require 'rubygems/query_utils'
## ##
# An alternate to Gem::Commands::QueryCommand that searches for gems starting # Searches for gems starting with the supplied argument.
# with the supplied argument.
class Gem::Commands::ListCommand < Gem::Commands::QueryCommand class Gem::Commands::ListCommand < Gem::Command
include Gem::QueryUtils
def initialize def initialize
super 'list', 'Display local gems whose name matches REGEXP' super 'list', 'Display local gems whose name matches REGEXP',
:name => //, :domain => :local, :details => false, :versions => true,
:installed => nil, :version => Gem::Requirement.default
remove_option('--name-matches') add_query_options
end end
def arguments # :nodoc: def arguments # :nodoc:

View File

@ -40,6 +40,11 @@ class Gem::Commands::PristineCommand < Gem::Command
options[:only_executables] = value options[:only_executables] = value
end end
add_option('--only-plugins',
'Only restore plugins') do |value, options|
options[:only_plugins] = value
end
add_option('-E', '--[no-]env-shebang', add_option('-E', '--[no-]env-shebang',
'Rewrite executables with a shebang', 'Rewrite executables with a shebang',
'of /usr/bin/env') do |value, options| 'of /usr/bin/env') do |value, options|
@ -126,14 +131,14 @@ extensions will be restored.
end end
end end
unless spec.extensions.empty? or options[:extensions] or options[:only_executables] unless spec.extensions.empty? or options[:extensions] or options[:only_executables] or options[:only_plugins]
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 or options[:only_executables] unless File.exist? gem or options[:only_executables] or options[:only_plugins]
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..."
@ -172,6 +177,9 @@ extensions will be restored.
if options[:only_executables] if options[:only_executables]
installer = Gem::Installer.for_spec(spec, installer_options) installer = Gem::Installer.for_spec(spec, installer_options)
installer.generate_bin installer.generate_bin
elsif options[:only_plugins]
installer = Gem::Installer.for_spec(spec)
installer.generate_plugins
else else
installer = Gem::Installer.at(gem, installer_options) installer = Gem::Installer.at(gem, installer_options)
installer.install installer.install

View File

@ -1,15 +1,17 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'rubygems/command' require 'rubygems/command'
require 'rubygems/commands/query_command' require 'rubygems/query_utils'
class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand class Gem::Commands::SearchCommand < Gem::Command
include Gem::QueryUtils
def initialize def initialize
super 'search', 'Display remote gems whose name matches REGEXP' super 'search', 'Display remote gems whose name matches REGEXP',
:name => //, :domain => :remote, :details => false, :versions => true,
:installed => nil, :version => Gem::Requirement.default
remove_option '--name-matches' add_query_options
defaults[:domain] = :remote
end end
def arguments # :nodoc: def arguments # :nodoc:

View File

@ -20,7 +20,8 @@ class Gem::Commands::SetupCommand < Gem::Command
:force => true, :force => true,
:site_or_vendor => 'sitelibdir', :site_or_vendor => 'sitelibdir',
:destdir => '', :prefix => '', :previous_version => '', :destdir => '', :prefix => '', :previous_version => '',
:regenerate_binstubs => true :regenerate_binstubs => true,
:regenerate_plugins => true
add_option '--previous-version=VERSION', add_option '--previous-version=VERSION',
'Previous version of RubyGems', 'Previous version of RubyGems',
@ -89,6 +90,11 @@ class Gem::Commands::SetupCommand < Gem::Command
options[:regenerate_binstubs] = value options[:regenerate_binstubs] = value
end end
add_option '--[no-]regenerate-plugins',
'Regenerate gem plugins' do |value, options|
options[:regenerate_plugins] = value
end
add_option '-f', '--[no-]force', add_option '-f', '--[no-]force',
'Forcefully overwrite binstubs' do |value, options| 'Forcefully overwrite binstubs' do |value, options|
options[:force] = value options[:force] = value
@ -181,6 +187,7 @@ By default, this RubyGems will install gem as:
say "RubyGems #{Gem::VERSION} installed" say "RubyGems #{Gem::VERSION} installed"
regenerate_binstubs if options[:regenerate_binstubs] regenerate_binstubs if options[:regenerate_binstubs]
regenerate_plugins if options[:regenerate_plugins]
uninstall_old_gemcutter uninstall_old_gemcutter
@ -626,6 +633,16 @@ abort "#{deprecation_message}"
command.invoke(*args) command.invoke(*args)
end end
def regenerate_plugins
require "rubygems/commands/pristine_command"
say "Regenerating plugins"
args = %w[--all --only-plugins --silent]
command = Gem::Commands::PristineCommand.new
command.invoke(*args)
end
private private
def target_bin_path(bin_dir, bin_file) def target_bin_path(bin_dir, bin_file)

View File

@ -136,7 +136,7 @@ RubyGems has been configured to serve gems via the following URLs through
its history: its history:
* http://gems.rubyforge.org (RubyGems 1.3.6 and earlier) * http://gems.rubyforge.org (RubyGems 1.3.6 and earlier)
* http://rubygems.org (RubyGems 1.3.7 through 1.8.25) * https://rubygems.org/ (RubyGems 1.3.7 through 1.8.25)
* https://rubygems.org (RubyGems 2.0.1 and newer) * https://rubygems.org (RubyGems 2.0.1 and newer)
Since all of these sources point to the same set of gems you only need one Since all of these sources point to the same set of gems you only need one
@ -153,8 +153,8 @@ before it is added.
To remove a source use the --remove argument: To remove a source use the --remove argument:
$ gem sources --remove http://rubygems.org $ gem sources --remove https://rubygems.org/
http://rubygems.org removed from sources https://rubygems.org/ removed from sources
EOF EOF
end end

View File

@ -73,8 +73,6 @@ command to remove old versions.
say "Latest version already installed. Done." say "Latest version already installed. Done."
terminate_interaction terminate_interaction
end end
options[:user_install] = false
end end
def check_update_arguments # :nodoc: def check_update_arguments # :nodoc:
@ -90,9 +88,10 @@ command to remove old versions.
return return
end end
hig = highest_installed_gems gems_to_update = which_to_update(
highest_installed_gems,
gems_to_update = which_to_update hig, options[:args].uniq options[:args].uniq
)
if options[:explain] if options[:explain]
say "Gems to update:" say "Gems to update:"
@ -137,6 +136,9 @@ command to remove old versions.
def highest_installed_gems # :nodoc: def highest_installed_gems # :nodoc:
hig = {} # highest installed gems hig = {} # highest installed gems
# Get only gem specifications installed as --user-install
Gem::Specification.dirs = Gem.user_dir if options[:user_install]
Gem::Specification.each do |spec| Gem::Specification.each do |spec|
if hig[spec.name].nil? or hig[spec.name].version < spec.version if hig[spec.name].nil? or hig[spec.name].version < spec.version
hig[spec.name] = spec hig[spec.name] = spec
@ -168,11 +170,34 @@ command to remove old versions.
Dir.chdir update_dir do Dir.chdir update_dir do
say "Installing RubyGems #{version}" say "Installing RubyGems #{version}"
installed = system Gem.ruby, '--disable-gems', 'setup.rb', *args installed = preparing_gem_layout_for(version) do
system Gem.ruby, '--disable-gems', 'setup.rb', *args
end
say "RubyGems system software updated" if installed say "RubyGems system software updated" if installed
end end
end end
def preparing_gem_layout_for(version)
if Gem::Version.new(version) >= Gem::Version.new("3.2.a")
yield
else
require "tmpdir"
tmpdir = Dir.mktmpdir
FileUtils.mv Gem.plugins_dir, tmpdir
status = yield
if status
FileUtils.rm_rf tmpdir
else
FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugins_dir
end
status
end
end
def rubygems_target_version def rubygems_target_version
version = options[:system] version = options[:system]
update_latest = version == true update_latest = version == true

View File

@ -65,6 +65,22 @@ module Gem::Deprecate
end end
end end
module_function :deprecate, :skip_during # Deprecation method to deprecate Rubygems commands
def deprecate_command(year, month)
class_eval do
define_method "deprecated?" do
true
end
define_method "deprecation_warning" do
msg = [ "#{self.command} command is deprecated",
". It will be removed on or after %4d-%02d-01.\n" % [year, month],
]
alert_warning "#{msg.join}" unless Gem::Deprecate.skip
end
end
end
module_function :deprecate, :deprecate_command, :skip_during
end end

View File

@ -26,6 +26,7 @@ class Gem::Doctor
['doc', ''], ['doc', ''],
['extensions', ''], ['extensions', ''],
['gems', ''], ['gems', ''],
['plugins', ''],
].freeze ].freeze
missing = missing =
@ -112,6 +113,7 @@ class Gem::Doctor
next if installed_specs.include? basename next if installed_specs.include? basename
next if /^rubygems-\d/ =~ basename next if /^rubygems-\d/ =~ basename
next if 'specifications' == sub_directory and 'default' == basename next if 'specifications' == sub_directory and 'default' == basename
next if 'plugins' == sub_directory and Gem.plugin_suffix_regexp =~ basename
type = File.directory?(child) ? 'directory' : 'file' type = File.directory?(child) ? 'directory' : 'file'

View File

@ -5,18 +5,7 @@ require 'rubygems/deprecate'
## ##
# Base exception class for RubyGems. All exception raised by RubyGems are a # Base exception class for RubyGems. All exception raised by RubyGems are a
# subclass of this one. # subclass of this one.
class Gem::Exception < RuntimeError class Gem::Exception < RuntimeError; end
##
#--
# TODO: remove in RubyGems 4, nobody sets this
attr_accessor :source_exception # :nodoc:
extend Gem::Deprecate
deprecate :source_exception, :none, 2018, 12
end
class Gem::CommandLineError < Gem::Exception; end class Gem::CommandLineError < Gem::Exception; end

View File

@ -26,13 +26,9 @@ Gem.load_env_plugins rescue nil
class Gem::GemRunner class Gem::GemRunner
def initialize(options={}) def initialize
if !options.empty? && !Gem::Deprecate.skip @command_manager_class = Gem::CommandManager
Kernel.warn "NOTE: passing options to Gem::GemRunner.new is deprecated with no replacement. It will be removed on or after 2016-10-01." @config_file_class = Gem::ConfigFile
end
@command_manager_class = options[:command_manager] || Gem::CommandManager
@config_file_class = options[:config_file] || Gem::ConfigFile
end end
## ##

View File

@ -6,6 +6,7 @@
#++ #++
require 'rubygems/command' require 'rubygems/command'
require 'rubygems/installer_uninstaller_utils'
require 'rubygems/exceptions' require 'rubygems/exceptions'
require 'rubygems/deprecate' require 'rubygems/deprecate'
require 'rubygems/package' require 'rubygems/package'
@ -43,6 +44,8 @@ class Gem::Installer
include Gem::UserInteraction include Gem::UserInteraction
include Gem::InstallerUninstallerUtils
## ##
# Filename of the gem being installed. # Filename of the gem being installed.
@ -180,15 +183,7 @@ class Gem::Installer
require 'fileutils' require 'fileutils'
@options = options @options = options
if package.is_a? String @package = package
security_policy = options[:security_policy]
@package = Gem::Package.new package, security_policy
if $VERBOSE
warn "constructing an Installer object with a string is deprecated. Please use Gem::Installer.at (called from: #{caller.first})"
end
else
@package = package
end
process_options process_options
@ -330,6 +325,7 @@ class Gem::Installer
end end
generate_bin generate_bin
generate_plugins
unless @options[:install_as_default] unless @options[:install_as_default]
write_spec write_spec
@ -520,7 +516,17 @@ class Gem::Installer
else else
generate_bin_symlink filename, @bin_dir generate_bin_symlink filename, @bin_dir
end end
end
end
def generate_plugins # :nodoc:
latest = Gem::Specification.latest_spec_for(spec.name)
return if latest && latest.version > spec.version
if spec.plugins.empty?
remove_plugins_for(spec)
else
regenerate_plugins_for(spec)
end end
end end
@ -810,7 +816,7 @@ TEXT
ruby_exe = "ruby.exe" if ruby_exe.empty? ruby_exe = "ruby.exe" if ruby_exe.empty?
if File.exist?(File.join bindir, ruby_exe) if File.exist?(File.join bindir, ruby_exe)
# stub & ruby.exe withing same folder. Portable # stub & ruby.exe within same folder. Portable
<<-TEXT <<-TEXT
@ECHO OFF @ECHO OFF
@"%~dp0#{ruby_exe}" "%~dpn0" %* @"%~dp0#{ruby_exe}" "%~dpn0" %*
@ -844,18 +850,6 @@ TEXT
builder.build_extensions builder.build_extensions
end end
##
# Logs the build +output+ in +build_dir+, then raises Gem::Ext::BuildError.
#
# TODO: Delete this for RubyGems 4. It remains for API compatibility
def extension_build_error(build_dir, output, backtrace = nil) # :nodoc:
builder = Gem::Ext::Builder.new spec, @build_args
builder.build_error build_dir, output, backtrace
end
deprecate :extension_build_error, :none, 2018, 12
## ##
# Reads the file index and extracts each file into the gem directory. # Reads the file index and extracts each file into the gem directory.
# #

View File

@ -171,10 +171,10 @@ class Gem::InstallerTestCase < Gem::TestCase
## ##
# Sets up the base @gem, builds it and returns an installer for it. # Sets up the base @gem, builds it and returns an installer for it.
# #
def util_setup_installer def util_setup_installer(&block)
@gem = setup_base_gem @gem = setup_base_gem
util_setup_gem util_setup_gem(&block)
end end
## ##

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
##
# Helper methods for both Gem::Installer and Gem::Uninstaller
module Gem::InstallerUninstallerUtils
def regenerate_plugins_for(spec)
spec.plugins.each do |plugin|
plugin_script_path = File.join Gem.plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}"
File.open plugin_script_path, 'wb' do |file|
file.puts "require '#{plugin}'"
end
verbose plugin_script_path
end
end
def remove_plugins_for(spec)
FileUtils.rm_f Gem::Util.glob_files_in_dir("#{spec.name}#{Gem.plugin_suffix_pattern}", Gem.plugins_dir)
end
end

View File

@ -8,7 +8,8 @@
# Example using a Gem::Package # Example using a Gem::Package
# #
# Builds a .gem file given a Gem::Specification. A .gem file is a tarball # Builds a .gem file given a Gem::Specification. A .gem file is a tarball
# which contains a data.tar.gz and metadata.gz, and possibly signatures. # which contains a data.tar.gz, metadata.gz, checksums.yaml.gz and possibly
# signatures.
# #
# require 'rubygems' # require 'rubygems'
# require 'rubygems/package' # require 'rubygems/package'

362
lib/rubygems/query_utils.rb Normal file
View File

@ -0,0 +1,362 @@
# frozen_string_literal: true
require 'rubygems/local_remote_options'
require 'rubygems/spec_fetcher'
require 'rubygems/version_option'
require 'rubygems/text'
module Gem::QueryUtils
include Gem::Text
include Gem::LocalRemoteOptions
include Gem::VersionOption
def add_query_options
add_option('-i', '--[no-]installed',
'Check for installed gem') do |value, options|
options[:installed] = value
end
add_option('-I', 'Equivalent to --no-installed') do |value, options|
options[:installed] = false
end
add_version_option command, "for use with --installed"
add_option('-d', '--[no-]details',
'Display detailed information of gem(s)') do |value, options|
options[:details] = value
end
add_option('--[no-]versions',
'Display only gem names') do |value, options|
options[:versions] = value
options[:details] = false unless value
end
add_option('-a', '--all',
'Display all gem versions') do |value, options|
options[:all] = value
end
add_option('-e', '--exact',
'Name of gem(s) to query on matches the',
'provided STRING') do |value, options|
options[:exact] = value
end
add_option('--[no-]prerelease',
'Display prerelease versions') do |value, options|
options[:prerelease] = value
end
add_local_remote_options
end
def defaults_str # :nodoc:
"--local --name-matches // --no-details --versions --no-installed"
end
def description # :nodoc:
<<-EOF
The query command is the basis for the list and search commands.
You should really use the list and search commands instead. This command
is too hard to use.
EOF
end
def execute
gem_names = Array(options[:name])
if !args.empty?
gem_names = options[:exact] ? args.map{|arg| /\A#{Regexp.escape(arg)}\Z/ } : args.map{|arg| /#{arg}/i }
end
terminate_interaction(check_installed_gems(gem_names)) if check_installed_gems?
gem_names.each { |n| show_gems(n) }
end
private
def check_installed_gems(gem_names)
exit_code = 0
if args.empty? && !gem_name?
alert_error "You must specify a gem name"
exit_code = 4
elsif gem_names.count > 1
alert_error "You must specify only ONE gem!"
exit_code = 4
else
installed = installed?(gem_names.first, options[:version])
installed = !installed unless options[:installed]
say(installed)
exit_code = 1 if !installed
end
exit_code
end
def check_installed_gems?
!options[:installed].nil?
end
def gem_name?
!options[:name].source.empty?
end
def prerelease
options[:prerelease]
end
def show_prereleases?
prerelease.nil? || prerelease
end
def args
options[:args].to_a
end
def display_header(type)
if (ui.outs.tty? and Gem.configuration.verbose) or both?
say
say "*** #{type} GEMS ***"
say
end
end
#Guts of original execute
def show_gems(name)
show_local_gems(name) if local?
show_remote_gems(name) if remote?
end
def show_local_gems(name, req = Gem::Requirement.default)
display_header("LOCAL")
specs = Gem::Specification.find_all do |s|
s.name =~ name and req =~ s.version
end
dep = Gem::Deprecate.skip_during { Gem::Dependency.new name, req }
specs.select! do |s|
dep.match?(s.name, s.version, show_prereleases?)
end
spec_tuples = specs.map do |spec|
[spec.name_tuple, spec]
end
output_query_results(spec_tuples)
end
def show_remote_gems(name)
display_header("REMOTE")
fetcher = Gem::SpecFetcher.fetcher
spec_tuples = if name.respond_to?(:source) && name.source.empty?
fetcher.detect(specs_type) { true }
else
fetcher.detect(specs_type) do |name_tuple|
name === name_tuple.name
end
end
output_query_results(spec_tuples)
end
def specs_type
if options[:all]
if options[:prerelease]
:complete
else
:released
end
elsif options[:prerelease]
:prerelease
else
:latest
end
end
##
# Check if gem +name+ version +version+ is installed.
def installed?(name, req = Gem::Requirement.default)
Gem::Specification.any? { |s| s.name =~ name and req =~ s.version }
end
def output_query_results(spec_tuples)
output = []
versions = Hash.new { |h,name| h[name] = [] }
spec_tuples.each do |spec_tuple, source|
versions[spec_tuple.name] << [spec_tuple, source]
end
versions = versions.sort_by do |(n,_),_|
n.downcase
end
output_versions output, versions
say output.join(options[:details] ? "\n\n" : "\n")
end
def output_versions(output, versions)
versions.each do |gem_name, matching_tuples|
matching_tuples = matching_tuples.sort_by { |n,_| n.version }.reverse
platforms = Hash.new { |h,version| h[version] = [] }
matching_tuples.each do |n, _|
platforms[n.version] << n.platform if n.platform
end
seen = {}
matching_tuples.delete_if do |n,_|
if seen[n.version]
true
else
seen[n.version] = true
false
end
end
output << clean_text(make_entry(matching_tuples, platforms))
end
end
def entry_details(entry, detail_tuple, specs, platforms)
return unless options[:details]
name_tuple, spec = detail_tuple
spec = spec.fetch_spec(name_tuple)if spec.respond_to?(:fetch_spec)
entry << "\n"
spec_platforms entry, platforms
spec_authors entry, spec
spec_homepage entry, spec
spec_license entry, spec
spec_loaded_from entry, spec, specs
spec_summary entry, spec
end
def entry_versions(entry, name_tuples, platforms, specs)
return unless options[:versions]
list =
if platforms.empty? or options[:details]
name_tuples.map { |n| n.version }.uniq
else
platforms.sort.reverse.map do |version, pls|
out = version.to_s
if options[:domain] == :local
default = specs.any? do |s|
!s.is_a?(Gem::Source) && s.version == version && s.default_gem?
end
out = "default: #{out}" if default
end
if pls != [Gem::Platform::RUBY]
platform_list = [pls.delete(Gem::Platform::RUBY), *pls.sort].compact
out = platform_list.unshift(out).join(' ')
end
out
end
end
entry << " (#{list.join ', '})"
end
def make_entry(entry_tuples, platforms)
detail_tuple = entry_tuples.first
name_tuples, specs = entry_tuples.flatten.partition do |item|
Gem::NameTuple === item
end
entry = [name_tuples.first.name]
entry_versions(entry, name_tuples, platforms, specs)
entry_details(entry, detail_tuple, specs, platforms)
entry.join
end
def spec_authors(entry, spec)
authors = "Author#{spec.authors.length > 1 ? 's' : ''}: ".dup
authors << spec.authors.join(', ')
entry << format_text(authors, 68, 4)
end
def spec_homepage(entry, spec)
return if spec.homepage.nil? or spec.homepage.empty?
entry << "\n" << format_text("Homepage: #{spec.homepage}", 68, 4)
end
def spec_license(entry, spec)
return if spec.license.nil? or spec.license.empty?
licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: ".dup
licenses << spec.licenses.join(', ')
entry << "\n" << format_text(licenses, 68, 4)
end
def spec_loaded_from(entry, spec, specs)
return unless spec.loaded_from
if specs.length == 1
default = spec.default_gem? ? ' (default)' : nil
entry << "\n" << " Installed at#{default}: #{spec.base_dir}"
else
label = 'Installed at'
specs.each do |s|
version = s.version.to_s
version << ', default' if s.default_gem?
entry << "\n" << " #{label} (#{version}): #{s.base_dir}"
label = ' ' * label.length
end
end
end
def spec_platforms(entry, platforms)
non_ruby = platforms.any? do |_, pls|
pls.any? { |pl| pl != Gem::Platform::RUBY }
end
return unless non_ruby
if platforms.length == 1
title = platforms.values.length == 1 ? 'Platform' : 'Platforms'
entry << " #{title}: #{platforms.values.sort.join(', ')}\n"
else
entry << " Platforms:\n"
sorted_platforms = platforms.sort_by { |version,| version }
sorted_platforms.each do |version, pls|
label = " #{version}: "
data = format_text pls.sort.join(', '), 68, label.length
data[0, label.length] = label
entry << data << "\n"
end
end
end
def spec_summary(entry, spec)
summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
entry << "\n\n" << format_text(summary, 68, 4)
end
end

View File

@ -7,7 +7,6 @@ require 'rubygems/uri_formatter'
require 'rubygems/uri_parsing' require 'rubygems/uri_parsing'
require 'rubygems/user_interaction' require 'rubygems/user_interaction'
require 'resolv' require 'resolv'
require 'rubygems/deprecate'
## ##
# RemoteFetcher handles the details of fetching gems and gem information from # RemoteFetcher handles the details of fetching gems and gem information from
@ -16,8 +15,6 @@ require 'rubygems/deprecate'
class Gem::RemoteFetcher class Gem::RemoteFetcher
include Gem::UserInteraction include Gem::UserInteraction
extend Gem::Deprecate
include Gem::UriParsing include Gem::UriParsing
## ##
@ -309,17 +306,6 @@ class Gem::RemoteFetcher
data data
end end
##
# Returns the size of +uri+ in bytes.
def fetch_size(uri)
response = fetch_path(uri, nil, true)
response['content-length'].to_i
end
deprecate :fetch_size, :none, 2019, 12
## ##
# Performs a Net::HTTP request of type +request_class+ on +uri+ returning # Performs a Net::HTTP request of type +request_class+ on +uri+ returning
# a Net::HTTP response object. request maintains a table of persistent # a Net::HTTP response object. request maintains a table of persistent

View File

@ -235,7 +235,7 @@ class Gem::RequestSet::GemDependencyAPI
return unless (groups & @without_groups).empty? return unless (groups & @without_groups).empty?
dependencies.each do |dep| dependencies.each do |dep|
@set.gem dep.name, *dep.requirement @set.gem dep.name, *dep.requirement.as_list
end end
end end

View File

@ -23,7 +23,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
## ##
# Creates a new APISet that will retrieve gems from +uri+ using the RubyGems # Creates a new APISet that will retrieve gems from +uri+ using the RubyGems
# API URL +dep_uri+ which is described at # API URL +dep_uri+ which is described at
# http://guides.rubygems.org/rubygems-org-api # https://guides.rubygems.org/rubygems-org-api
def initialize(dep_uri = 'https://rubygems.org/api/v1/dependencies') def initialize(dep_uri = 'https://rubygems.org/api/v1/dependencies')
super() super()

View File

@ -11,7 +11,7 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
# Creates an APISpecification for the given +set+ from the rubygems.org # Creates an APISpecification for the given +set+ from the rubygems.org
# +api_data+. # +api_data+.
# #
# See http://guides.rubygems.org/rubygems-org-api/#misc_methods for the # See https://guides.rubygems.org/rubygems-org-api/#misc_methods for the
# format of the +api_data+. # format of the +api_data+.
def initialize(set, api_data) def initialize(set, api_data)

View File

@ -62,11 +62,11 @@ end
# #
# $ tar tf your-gem-1.0.gem # $ tar tf your-gem-1.0.gem
# metadata.gz # metadata.gz
# metadata.gz.sum
# metadata.gz.sig # metadata signature # metadata.gz.sig # metadata signature
# data.tar.gz # data.tar.gz
# data.tar.gz.sum
# data.tar.gz.sig # data signature # data.tar.gz.sig # data signature
# checksums.yaml.gz
# checksums.yaml.gz.sig # checksums signature
# #
# === Manually signing gems # === Manually signing gems
# #
@ -161,6 +161,8 @@ end
# -K, --private-key KEY Key for --sign or --build # -K, --private-key KEY Key for --sign or --build
# -s, --sign CERT Signs CERT with the key from -K # -s, --sign CERT Signs CERT with the key from -K
# and the certificate from -C # and the certificate from -C
# -d, --days NUMBER_OF_DAYS Days before the certificate expires
# -R, --re-sign Re-signs the certificate from -C with the key from -K
# #
# We've already covered the <code>--build</code> option, and the # We've already covered the <code>--build</code> option, and the
# <code>--add</code>, <code>--list</code>, and <code>--remove</code> commands # <code>--add</code>, <code>--list</code>, and <code>--remove</code> commands
@ -265,7 +267,7 @@ end
# 2. Grab the public key from the gemspec # 2. Grab the public key from the gemspec
# #
# gem spec some_signed_gem-1.0.gem cert_chain | \ # gem spec some_signed_gem-1.0.gem cert_chain | \
# ruby -ryaml -e 'puts YAML.load_documents($stdin)' > public_key.crt # ruby -ryaml -e 'puts YAML.load($stdin)' > public_key.crt
# #
# 3. Generate a SHA1 hash of the data.tar.gz # 3. Generate a SHA1 hash of the data.tar.gz
# #

View File

@ -39,7 +39,7 @@ class Gem::Security::Signer
}.freeze }.freeze
## ##
# Attemps to re-sign an expired cert with a given private key # Attempts to re-sign an expired cert with a given private key
def self.re_sign_cert(expired_cert, expired_cert_path, private_key) def self.re_sign_cert(expired_cert, expired_cert_path, private_key)
return unless expired_cert.not_after < Time.now return unless expired_cert.not_after < Time.now

View File

@ -661,7 +661,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
"only_one_executable" => true, "only_one_executable" => true,
"full_name" => "rubygems-#{Gem::VERSION}", "full_name" => "rubygems-#{Gem::VERSION}",
"has_deps" => false, "has_deps" => false,
"homepage" => "http://guides.rubygems.org/", "homepage" => "https://guides.rubygems.org/",
"name" => 'rubygems', "name" => 'rubygems',
"ri_installed" => true, "ri_installed" => true,
"summary" => "RubyGems itself", "summary" => "RubyGems itself",

View File

@ -384,6 +384,7 @@ class Gem::Specification < Gem::BasicSpecification
# "mailing_list_uri" => "https://groups.example.com/bestgemever", # "mailing_list_uri" => "https://groups.example.com/bestgemever",
# "source_code_uri" => "https://example.com/user/bestgemever", # "source_code_uri" => "https://example.com/user/bestgemever",
# "wiki_uri" => "https://example.com/user/bestgemever/wiki" # "wiki_uri" => "https://example.com/user/bestgemever/wiki"
# "funding_uri" => "https://example.com/donate"
# } # }
# #
# These links will be used on your gem's page on rubygems.org and must pass # These links will be used on your gem's page on rubygems.org and must pass
@ -1086,6 +1087,13 @@ class Gem::Specification < Gem::BasicSpecification
_latest_specs Gem::Specification._all, prerelease _latest_specs Gem::Specification._all, prerelease
end end
##
# Return the latest installed spec for gem +name+.
def self.latest_spec_for(name)
latest_specs(true).find { |installed_spec| installed_spec.name == name }
end
def self._latest_specs(specs, prerelease = false) # :nodoc: def self._latest_specs(specs, prerelease = false) # :nodoc:
result = Hash.new { |h,k| h[k] = {} } result = Hash.new { |h,k| h[k] = {} }
native = {} native = {}
@ -1752,10 +1760,11 @@ class Gem::Specification < Gem::BasicSpecification
# #
# [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]] # [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
def dependent_gems def dependent_gems(check_dev=true)
out = [] out = []
Gem::Specification.each do |spec| Gem::Specification.each do |spec|
spec.dependencies.each do |dep| deps = check_dev ? spec.dependencies : spec.runtime_dependencies
deps.each do |dep|
if self.satisfies_requirement?(dep) if self.satisfies_requirement?(dep)
sats = [] sats = []
find_all_satisfiers(dep) do |sat| find_all_satisfiers(dep) do |sat|
@ -1847,29 +1856,23 @@ class Gem::Specification < Gem::BasicSpecification
end end
## ##
# Sets executables to +value+, ensuring it is an array. Don't # Sets executables to +value+, ensuring it is an array.
# use this, push onto the array instead.
def executables=(value) def executables=(value)
# TODO: warn about setting instead of pushing
@executables = Array(value) @executables = Array(value)
end end
## ##
# Sets extensions to +extensions+, ensuring it is an array. Don't # Sets extensions to +extensions+, ensuring it is an array.
# use this, push onto the array instead.
def extensions=(extensions) def extensions=(extensions)
# TODO: warn about setting instead of pushing
@extensions = Array extensions @extensions = Array extensions
end end
## ##
# Sets extra_rdoc_files to +files+, ensuring it is an array. Don't # Sets extra_rdoc_files to +files+, ensuring it is an array.
# use this, push onto the array instead.
def extra_rdoc_files=(files) def extra_rdoc_files=(files)
# TODO: warn about setting instead of pushing
@extra_rdoc_files = Array files @extra_rdoc_files = Array files
end end
@ -2245,11 +2248,9 @@ class Gem::Specification < Gem::BasicSpecification
end end
## ##
# Sets rdoc_options to +value+, ensuring it is an array. Don't # Sets rdoc_options to +value+, ensuring it is an array.
# use this, push onto the array instead.
def rdoc_options=(options) def rdoc_options=(options)
# TODO: warn about setting instead of pushing
@rdoc_options = Array options @rdoc_options = Array options
end end
@ -2268,11 +2269,9 @@ class Gem::Specification < Gem::BasicSpecification
end end
## ##
# Set requirements to +req+, ensuring it is an array. Don't # Set requirements to +req+, ensuring it is an array.
# use this, push onto the array instead.
def requirements=(req) def requirements=(req)
# TODO: warn about setting instead of pushing
@requirements = Array req @requirements = Array req
end end

View File

@ -18,6 +18,7 @@ class Gem::SpecificationPolicy
mailing_list_uri mailing_list_uri
source_code_uri source_code_uri
wiki_uri wiki_uri
funding_uri
].freeze # :nodoc: ].freeze # :nodoc:
def initialize(specification) def initialize(specification)
@ -421,7 +422,7 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li
end end
def help_text # :nodoc: def help_text # :nodoc:
"See http://guides.rubygems.org/specification-reference/ for help" "See https://guides.rubygems.org/specification-reference/ for help"
end end
end end

View File

@ -169,20 +169,24 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
# original value when the block ends # original value when the block ends
# #
def bindir(value) def bindir(value)
bindir = RbConfig::CONFIG['bindir'] with_clean_path_to_ruby do
bindir = RbConfig::CONFIG['bindir']
if value if value
RbConfig::CONFIG['bindir'] = value RbConfig::CONFIG['bindir'] = value
else else
RbConfig::CONFIG.delete 'bindir' RbConfig::CONFIG.delete 'bindir'
end end
yield begin
ensure yield
if bindir ensure
RbConfig::CONFIG['bindir'] = bindir if bindir
else RbConfig::CONFIG['bindir'] = bindir
RbConfig::CONFIG.delete 'bindir' else
RbConfig::CONFIG.delete 'bindir'
end
end
end end
end end
@ -321,6 +325,11 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
@tempdir.tap(&Gem::UNTAINT) @tempdir.tap(&Gem::UNTAINT)
end end
@orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
File.join(@tempdir, 'system-gemrc')
@gemhome = File.join @tempdir, 'gemhome' @gemhome = File.join @tempdir, 'gemhome'
@userhome = File.join @tempdir, 'userhome' @userhome = File.join @tempdir, 'userhome'
ENV["GEM_SPEC_CACHE"] = File.join @tempdir, 'spec_cache' ENV["GEM_SPEC_CACHE"] = File.join @tempdir, 'spec_cache'
@ -331,7 +340,7 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
ruby ruby
end end
@git = ENV['GIT'] || 'git' @git = ENV['GIT'] || (win_platform? ? 'git.exe' : 'git')
Gem.ensure_gem_subdirectories @gemhome Gem.ensure_gem_subdirectories @gemhome
@ -442,6 +451,10 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
ENV.replace(@orig_env) ENV.replace(@orig_env)
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
@orig_SYSTEM_WIDE_CONFIG_FILE
Gem.ruby = @orig_ruby if @orig_ruby Gem.ruby = @orig_ruby if @orig_ruby
if Gem.java_platform? if Gem.java_platform?
@ -562,7 +575,7 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
def install_gem(spec, options = {}) def install_gem(spec, options = {})
require 'rubygems/installer' require 'rubygems/installer'
gem = File.join @tempdir, "gems", "#{spec.full_name}.gem" gem = spec.cache_file
unless File.exist? gem unless File.exist? gem
use_ui Gem::MockGemUi.new do use_ui Gem::MockGemUi.new do
@ -571,7 +584,7 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
end end
end end
gem = File.join(@tempdir, File.basename(spec.cache_file)).tap(&Gem::UNTAINT) gem = File.join(@tempdir, File.basename(gem)).tap(&Gem::UNTAINT)
end end
Gem::Installer.at(gem, options.merge({:wrappers => true})).install Gem::Installer.at(gem, options.merge({:wrappers => true})).install
@ -667,8 +680,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
yield(s) if block_given? yield(s) if block_given?
end end
Gem::Specification.map # HACK: force specs to (re-)load before we write
written_path = write_file spec.spec_file do |io| written_path = write_file spec.spec_file do |io|
io.write spec.to_ruby_for_cache io.write spec.to_ruby_for_cache
end end
@ -833,9 +844,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
util_build_gem spec util_build_gem spec
cache_file = File.join @tempdir, 'gems', "#{spec.full_name}.gem"
FileUtils.mkdir_p File.dirname cache_file
FileUtils.mv spec.cache_file, cache_file
FileUtils.rm spec.spec_file FileUtils.rm spec.spec_file
end end
@ -1247,6 +1255,16 @@ Also, a list:
end end
end end
def with_clean_path_to_ruby
orig_ruby = Gem.ruby
Gem.instance_variable_set :@ruby, nil
yield
ensure
Gem.instance_variable_set :@ruby, orig_ruby
end
class << self class << self
# :nodoc: # :nodoc:

View File

@ -7,6 +7,7 @@
require 'fileutils' require 'fileutils'
require 'rubygems' require 'rubygems'
require 'rubygems/installer_uninstaller_utils'
require 'rubygems/dependency_list' require 'rubygems/dependency_list'
require 'rubygems/rdoc' require 'rubygems/rdoc'
require 'rubygems/user_interaction' require 'rubygems/user_interaction'
@ -23,6 +24,8 @@ class Gem::Uninstaller
include Gem::UserInteraction include Gem::UserInteraction
include Gem::InstallerUninstallerUtils
## ##
# The directory a gem's executables will be installed into # The directory a gem's executables will be installed into
@ -158,8 +161,11 @@ class Gem::Uninstaller
end end
remove_executables @spec remove_executables @spec
remove_plugins @spec
remove @spec remove @spec
regenerate_plugins
Gem.post_uninstall_hooks.each do |hook| Gem.post_uninstall_hooks.each do |hook|
hook.call self hook.call self
end end
@ -168,11 +174,10 @@ class Gem::Uninstaller
end end
## ##
# Removes installed executables and batch files (windows only) for # Removes installed executables and batch files (windows only) for +spec+.
# +gemspec+.
def remove_executables(spec) def remove_executables(spec)
return if spec.nil? or spec.executables.empty? return if spec.executables.empty?
executables = spec.executables.clone executables = spec.executables.clone
@ -231,10 +236,6 @@ class Gem::Uninstaller
## ##
# spec:: the spec of the gem to be uninstalled # spec:: the spec of the gem to be uninstalled
# list:: the list of all such gems
#
# Warning: this method modifies the +list+ parameter. Once it has
# uninstalled a gem, it is removed from that list.
def remove(spec) def remove(spec)
unless path_ok?(@gem_home, spec) or unless path_ok?(@gem_home, spec) or
@ -274,6 +275,25 @@ class Gem::Uninstaller
Gem::Specification.reset Gem::Specification.reset
end end
##
# Remove any plugin wrappers for +spec+.
def remove_plugins(spec) # :nodoc:
return if spec.plugins.empty?
remove_plugins_for(spec)
end
##
# Regenerates plugin wrappers after removal.
def regenerate_plugins
latest = Gem::Specification.latest_spec_for(@spec.name)
return if latest.nil?
regenerate_plugins_for(latest)
end
## ##
# Is +spec+ in +gem_dir+? # Is +spec+ in +gem_dir+?
@ -317,7 +337,7 @@ class Gem::Uninstaller
s.name == spec.name && s.full_name != spec.full_name s.name == spec.name && s.full_name != spec.full_name
end end
spec.dependent_gems.each do |dep_spec, dep, satlist| spec.dependent_gems(@check_dev).each do |dep_spec, dep, satlist|
unless siblings.any? { |s| s.satisfies_requirement? dep } unless siblings.any? { |s| s.satisfies_requirement? dep }
msg << "#{dep_spec.name}-#{dep_spec.version} depends on #{dep}" msg << "#{dep_spec.name}-#{dep_spec.version} depends on #{dep}"
end end

View File

@ -358,14 +358,6 @@ class Gem::StreamUI
ask(question) if question ask(question) if question
end end
##
# Display a debug message on the same location as error messages.
def debug(statement)
@errs.puts statement
end
deprecate :debug, :none, 2018, 12
## ##
# Terminate the application with exit code +status+, running any exit # Terminate the application with exit code +status+, running any exit
# handlers that might have been defined. # handlers that might have been defined.

View File

@ -151,7 +151,7 @@
class Gem::Version class Gem::Version
autoload :Requirement, 'rubygems/requirement' autoload :Requirement, File.expand_path('requirement', __dir__)
include Comparable include Comparable

View File

@ -77,4 +77,22 @@ class TestDeprecate < Gem::TestCase
assert_match(/on or after 2099-03-01/, err) assert_match(/on or after 2099-03-01/, err)
end end
def test_deprecate_command
require 'rubygems/command'
foo_command = Class.new(Gem::Command) do
extend Gem::Deprecate
deprecate_command(2099, 4)
def execute
puts "pew pew!"
end
end
Gem::Commands.send(:const_set, :FooCommand, foo_command)
assert Gem::Commands::FooCommand.new("foo").deprecated?
ensure
Gem::Commands.send(:remove_const, :FooCommand)
end
end end

View File

@ -11,12 +11,6 @@ if File.exist?(File.join(Dir.tmpdir, "Gemfile"))
raise "rubygems/bundler tests do not work correctly if there is #{ File.join(Dir.tmpdir, "Gemfile") }" raise "rubygems/bundler tests do not work correctly if there is #{ File.join(Dir.tmpdir, "Gemfile") }"
end end
# TODO: push this up to test_case.rb once battle tested
$LOAD_PATH.map! do |path|
path.dup.tap(&Gem::UNTAINT)
end
class TestGem < Gem::TestCase class TestGem < Gem::TestCase
PLUGINS_LOADED = [] # rubocop:disable Style/MutableConstant PLUGINS_LOADED = [] # rubocop:disable Style/MutableConstant
@ -161,10 +155,8 @@ class TestGem < Gem::TestCase
def test_self_install_permissions_with_format_executable_and_non_standard_ruby_install_name def test_self_install_permissions_with_format_executable_and_non_standard_ruby_install_name
Gem::Installer.exec_format = nil Gem::Installer.exec_format = nil
with_clean_path_to_ruby do ruby_install_name 'ruby27' do
ruby_install_name 'ruby27' do assert_self_install_permissions(format_executable: true)
assert_self_install_permissions(format_executable: true)
end
end end
ensure ensure
Gem::Installer.exec_format = nil Gem::Installer.exec_format = nil
@ -1024,21 +1016,17 @@ class TestGem < Gem::TestCase
end end
def test_self_ruby_escaping_spaces_in_path def test_self_ruby_escaping_spaces_in_path
with_clean_path_to_ruby do with_bindir_and_exeext("C:/Ruby 1.8/bin", ".exe") do
with_bindir_and_exeext("C:/Ruby 1.8/bin", ".exe") do ruby_install_name "ruby" do
ruby_install_name "ruby" do assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby
assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby
end
end end
end end
end end
def test_self_ruby_path_without_spaces def test_self_ruby_path_without_spaces
with_clean_path_to_ruby do with_bindir_and_exeext("C:/Ruby18/bin", ".exe") do
with_bindir_and_exeext("C:/Ruby18/bin", ".exe") do ruby_install_name "ruby" do
ruby_install_name "ruby" do assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby
assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby
end
end end
end end
end end
@ -1090,7 +1078,7 @@ class TestGem < Gem::TestCase
util_restore_RUBY_VERSION util_restore_RUBY_VERSION
end end
def test_self_ruby_version_with_prerelease def test_self_ruby_version_with_svn_prerelease
util_set_RUBY_VERSION '2.6.0', -1, 63539, 'ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux]' util_set_RUBY_VERSION '2.6.0', -1, 63539, 'ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux]'
assert_equal Gem::Version.new('2.6.0.preview2'), Gem.ruby_version assert_equal Gem::Version.new('2.6.0.preview2'), Gem.ruby_version
@ -1098,6 +1086,14 @@ class TestGem < Gem::TestCase
util_restore_RUBY_VERSION util_restore_RUBY_VERSION
end end
def test_self_ruby_version_with_git_prerelease
util_set_RUBY_VERSION '2.7.0', -1, 'b563439274a402e33541f5695b1bfd4ac1085638', 'ruby 2.7.0preview3 (2019-11-23 master b563439274) [x86_64-linux]'
assert_equal Gem::Version.new('2.7.0.preview3'), Gem.ruby_version
ensure
util_restore_RUBY_VERSION
end
def test_self_ruby_version_with_non_mri_implementations_with_mri_prerelase_compatibility def test_self_ruby_version_with_non_mri_implementations_with_mri_prerelase_compatibility
util_set_RUBY_VERSION '2.6.0', -1, 63539, 'weirdjruby 9.2.0.0 (2.6.0preview2) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]', 'weirdjruby', '9.2.0.0' util_set_RUBY_VERSION '2.6.0', -1, 63539, 'weirdjruby 9.2.0.0 (2.6.0preview2) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]', 'weirdjruby', '9.2.0.0'
@ -1106,7 +1102,7 @@ class TestGem < Gem::TestCase
util_restore_RUBY_VERSION util_restore_RUBY_VERSION
end end
def test_self_ruby_version_with_trunk def test_self_ruby_version_with_svn_trunk
util_set_RUBY_VERSION '1.9.2', -1, 23493, 'ruby 1.9.2dev (2009-05-20 trunk 23493) [x86_64-linux]' util_set_RUBY_VERSION '1.9.2', -1, 23493, 'ruby 1.9.2dev (2009-05-20 trunk 23493) [x86_64-linux]'
assert_equal Gem::Version.new('1.9.2.dev'), Gem.ruby_version assert_equal Gem::Version.new('1.9.2.dev'), Gem.ruby_version
@ -1114,6 +1110,14 @@ class TestGem < Gem::TestCase
util_restore_RUBY_VERSION util_restore_RUBY_VERSION
end end
def test_self_ruby_version_with_git_master
util_set_RUBY_VERSION '2.7.0', -1, '5de284ec78220e75643f89b454ce999da0c1c195', 'ruby 2.7.0dev (2019-12-23T01:37:30Z master 5de284ec78) [x86_64-linux]'
assert_equal Gem::Version.new('2.7.0.dev'), Gem.ruby_version
ensure
util_restore_RUBY_VERSION
end
def test_self_rubygems_version def test_self_rubygems_version
assert_equal Gem::Version.new(Gem::VERSION), Gem.rubygems_version assert_equal Gem::Version.new(Gem::VERSION), Gem.rubygems_version
end end
@ -1470,7 +1474,6 @@ class TestGem < Gem::TestCase
install_gem foo2 install_gem foo2
end end
Gem.searcher = nil
Gem::Specification.reset Gem::Specification.reset
gem 'foo' gem 'foo'
@ -1904,15 +1907,19 @@ You may need to `gem install -g` to install missing gems
end end
def ruby_install_name(name) def ruby_install_name(name)
orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name'] with_clean_path_to_ruby do
RbConfig::CONFIG['ruby_install_name'] = name orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name']
RbConfig::CONFIG['ruby_install_name'] = name
yield begin
ensure yield
if orig_RUBY_INSTALL_NAME ensure
RbConfig::CONFIG['ruby_install_name'] = orig_RUBY_INSTALL_NAME if orig_RUBY_INSTALL_NAME
else RbConfig::CONFIG['ruby_install_name'] = orig_RUBY_INSTALL_NAME
RbConfig::CONFIG.delete 'ruby_install_name' else
RbConfig::CONFIG.delete 'ruby_install_name'
end
end
end end
end end
@ -1924,16 +1931,6 @@ You may need to `gem install -g` to install missing gems
end end
end end
def with_clean_path_to_ruby
orig_ruby = Gem.ruby
Gem.instance_variable_set :@ruby, nil
yield
ensure
Gem.instance_variable_set :@ruby, orig_ruby
end
def with_plugin(path) def with_plugin(path)
test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}", test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}",
PROJECT_DIR) PROJECT_DIR)

View File

@ -224,26 +224,34 @@ class TestGemCommandManager < Gem::TestCase
end end
#check defaults #check defaults
@command_manager.process_args %w[query] Gem::Deprecate.skip_during do
@command_manager.process_args %w[query]
end
assert_equal(//, check_options[:name]) assert_equal(//, check_options[:name])
assert_equal :local, check_options[:domain] assert_equal :local, check_options[:domain]
assert_equal false, check_options[:details] assert_equal false, check_options[:details]
#check settings #check settings
check_options = nil check_options = nil
@command_manager.process_args %w[query --name foobar --local --details] Gem::Deprecate.skip_during do
@command_manager.process_args %w[query --name foobar --local --details]
end
assert_equal(/foobar/i, check_options[:name]) assert_equal(/foobar/i, check_options[:name])
assert_equal :local, check_options[:domain] assert_equal :local, check_options[:domain]
assert_equal true, check_options[:details] assert_equal true, check_options[:details]
#remote domain #remote domain
check_options = nil check_options = nil
@command_manager.process_args %w[query --remote] Gem::Deprecate.skip_during do
@command_manager.process_args %w[query --remote]
end
assert_equal :remote, check_options[:domain] assert_equal :remote, check_options[:domain]
#both (local/remote) domains #both (local/remote) domains
check_options = nil check_options = nil
@command_manager.process_args %w[query --both] Gem::Deprecate.skip_during do
@command_manager.process_args %w[query --both]
end
assert_equal :both, check_options[:domain] assert_equal :both, check_options[:domain]
end end
@ -268,4 +276,29 @@ class TestGemCommandManager < Gem::TestCase
assert_equal Dir.pwd, check_options[:install_dir] assert_equal Dir.pwd, check_options[:install_dir]
end end
def test_deprecated_command
require 'rubygems/command'
foo_command = Class.new(Gem::Command) do
extend Gem::Deprecate
deprecate_command(2099, 4)
def execute
say "pew pew!"
end
end
Gem::Commands.send(:const_set, :FooCommand, foo_command)
@command_manager.register_command(:foo, foo_command.new("foo"))
use_ui @ui do
@command_manager.process_args(%w[foo])
end
assert_equal "pew pew!\n", @ui.output
assert_equal("WARNING: foo command is deprecated. It will be removed on or after 2099-04-01.\n", @ui.error)
ensure
Gem::Commands.send(:remove_const, :FooCommand)
end
end end

View File

@ -147,7 +147,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
error = @ui.error.split "\n" error = @ui.error.split "\n"
assert_equal "WARNING: licenses is empty, but is recommended. Use a license identifier from", error.shift assert_equal "WARNING: licenses is empty, but is recommended. Use a license identifier from", error.shift
assert_equal "http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.", error.shift assert_equal "http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.", error.shift
assert_equal "WARNING: See http://guides.rubygems.org/specification-reference/ for help", error.shift assert_equal "WARNING: See https://guides.rubygems.org/specification-reference/ for help", error.shift
assert_equal [], error assert_equal [], error
gem_file = File.join @tempdir, File.basename(@gem.cache_file) gem_file = File.join @tempdir, File.basename(@gem.cache_file)

View File

@ -215,7 +215,6 @@ class TestGemCommandsPristineCommand < Gem::TestCase
io.write "# extconf.rb\nrequire 'mkmf'; create_makefile 'a'" io.write "# extconf.rb\nrequire 'mkmf'; create_makefile 'a'"
end end
util_build_gem a
install_gem a install_gem a
@cmd.options[:args] = %w[a] @cmd.options[:args] = %w[a]
@ -491,6 +490,42 @@ class TestGemCommandsPristineCommand < Gem::TestCase
refute File.exist? gem_lib refute File.exist? gem_lib
end end
def test_execute_only_plugins
a = util_spec 'a' do |s|
s.executables = %w[foo]
s.files = %w[bin/foo lib/a.rb lib/rubygems_plugin.rb]
end
write_file File.join(@tempdir, 'lib', 'a.rb') do |fp|
fp.puts "puts __FILE__"
end
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |fp|
fp.puts "puts __FILE__"
end
write_file File.join(@tempdir, 'bin', 'foo') do |fp|
fp.puts "#!/usr/bin/ruby"
end
install_gem a
gem_lib = File.join @gemhome, 'gems', a.full_name, 'lib', 'a.rb'
gem_plugin = File.join @gemhome, 'plugins', 'a_plugin.rb'
gem_exec = File.join @gemhome, 'bin', 'foo'
FileUtils.rm gem_exec
FileUtils.rm gem_plugin
FileUtils.rm gem_lib
@cmd.handle_options %w[--all --only-plugins]
use_ui @ui do
@cmd.execute
end
refute File.exist? gem_exec
assert File.exist? gem_plugin
refute File.exist? gem_lib
end
def test_execute_bindir def test_execute_bindir
a = util_spec 'a' do |s| a = util_spec 'a' do |s|
s.name = "test_gem" s.name = "test_gem"

View File

@ -1,857 +0,0 @@
# frozen_string_literal: true
require 'rubygems/test_case'
require 'rubygems/commands/query_command'
module TestGemCommandsQueryCommandSetup
def setup
super
@cmd = Gem::Commands::QueryCommand.new
@specs = add_gems_to_fetcher
@stub_ui = Gem::MockGemUi.new
@stub_fetcher = Gem::FakeFetcher.new
@stub_fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
raise Gem::RemoteFetcher::FetchError
end
end
end
class TestGemCommandsQueryCommandWithInstalledGems < Gem::TestCase
include TestGemCommandsQueryCommandSetup
def test_execute
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[-r]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_all
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[-r --all]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_all_prerelease
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[-r --all --prerelease]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (3.a, 2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_details
spec_fetcher do |fetcher|
fetcher.spec 'a', 2 do |s|
s.summary = 'This is a lot of text. ' * 4
s.authors = ['Abraham Lincoln', 'Hirohito']
s.homepage = 'http://a.example.com/'
end
fetcher.legacy_platform
end
@cmd.handle_options %w[-r -d]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2)
Authors: Abraham Lincoln, Hirohito
Homepage: http://a.example.com/
This is a lot of text. This is a lot of text. This is a lot of text.
This is a lot of text.
pl (1)
Platform: i386-linux
Author: A User
Homepage: http://example.com
this is a summary
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_details_cleans_text
spec_fetcher do |fetcher|
fetcher.spec 'a', 2 do |s|
s.summary = 'This is a lot of text. ' * 4
s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
s.homepage = "http://a.example.com/\x03"
end
fetcher.legacy_platform
end
@cmd.handle_options %w[-r -d]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2)
Authors: Abraham Lincoln ., . Hirohito
Homepage: http://a.example.com/.
This is a lot of text. This is a lot of text. This is a lot of text.
This is a lot of text.
pl (1)
Platform: i386-linux
Author: A User
Homepage: http://example.com
this is a summary
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_details_truncates_summary
spec_fetcher do |fetcher|
fetcher.spec 'a', 2 do |s|
s.summary = 'This is a lot of text. ' * 10_000
s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
s.homepage = "http://a.example.com/\x03"
end
fetcher.legacy_platform
end
@cmd.handle_options %w[-r -d]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2)
Authors: Abraham Lincoln ., . Hirohito
Homepage: http://a.example.com/.
Truncating the summary for a-2 to 100,000 characters:
#{" This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449} This is a lot of te
pl (1)
Platform: i386-linux
Author: A User
Homepage: http://example.com
this is a summary
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_installed
@cmd.handle_options %w[-n a --installed]
assert_raises Gem::MockGemUi::SystemExitException do
use_ui @stub_ui do
@cmd.execute
end
end
assert_equal "true\n", @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_installed_inverse
@cmd.handle_options %w[-n a --no-installed]
e = assert_raises Gem::MockGemUi::TermError do
use_ui @stub_ui do
@cmd.execute
end
end
assert_equal "false\n", @stub_ui.output
assert_equal '', @stub_ui.error
assert_equal 1, e.exit_code
end
def test_execute_installed_inverse_not_installed
@cmd.handle_options %w[-n not_installed --no-installed]
assert_raises Gem::MockGemUi::SystemExitException do
use_ui @stub_ui do
@cmd.execute
end
end
assert_equal "true\n", @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_installed_no_name
@cmd.handle_options %w[--installed]
e = assert_raises Gem::MockGemUi::TermError do
use_ui @stub_ui do
@cmd.execute
end
end
assert_equal '', @stub_ui.output
assert_equal "ERROR: You must specify a gem name\n", @stub_ui.error
assert_equal 4, e.exit_code
end
def test_execute_installed_not_installed
@cmd.handle_options %w[-n not_installed --installed]
e = assert_raises Gem::MockGemUi::TermError do
use_ui @stub_ui do
@cmd.execute
end
end
assert_equal "false\n", @stub_ui.output
assert_equal '', @stub_ui.error
assert_equal 1, e.exit_code
end
def test_execute_installed_version
@cmd.handle_options %w[-n a --installed --version 2]
assert_raises Gem::MockGemUi::SystemExitException do
use_ui @stub_ui do
@cmd.execute
end
end
assert_equal "true\n", @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_installed_version_not_installed
@cmd.handle_options %w[-n c --installed --version 2]
e = assert_raises Gem::MockGemUi::TermError do
use_ui @stub_ui do
@cmd.execute
end
end
assert_equal "false\n", @stub_ui.output
assert_equal '', @stub_ui.error
assert_equal 1, e.exit_code
end
def test_execute_local
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.options[:domain] = :local
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
a (3.a, 2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_local_notty
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[]
@stub_ui.outs.tty = false
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
a (3.a, 2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_local_quiet
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.options[:domain] = :local
Gem.configuration.verbose = false
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
a (3.a, 2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_no_versions
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[-r --no-versions]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a
pl
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_notty
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[-r]
@stub_ui.outs.tty = false
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
a (2)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_prerelease
@cmd.handle_options %w[-r --prerelease]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (3.a)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_prerelease_local
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[-l --prerelease]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
a (3.a, 2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_no_prerelease_local
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[-l --no-prerelease]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
a (2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_remote
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.options[:domain] = :remote
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_remote_notty
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[]
@stub_ui.outs.tty = false
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
a (3.a, 2, 1)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_remote_quiet
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.options[:domain] = :remote
Gem.configuration.verbose = false
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
a (2)
pl (1 i386-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_make_entry
a_2_name = @specs['a-2'].original_name
@stub_fetcher.data.delete \
"#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{a_2_name}.gemspec.rz"
a2 = @specs['a-2']
entry_tuples = [
[Gem::NameTuple.new(a2.name, a2.version, a2.platform),
Gem.sources.first],
]
platforms = { a2.version => [a2.platform] }
entry = @cmd.send :make_entry, entry_tuples, platforms
assert_equal 'a (2)', entry
end
# Test for multiple args handling!
def test_execute_multiple_args
spec_fetcher do |fetcher|
fetcher.legacy_platform
end
@cmd.handle_options %w[a pl]
use_ui @stub_ui do
@cmd.execute
end
assert_match %r%^a %, @stub_ui.output
assert_match %r%^pl %, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_show_gems
@cmd.options[:name] = //
@cmd.options[:domain] = :remote
use_ui @stub_ui do
@cmd.send :show_gems, /a/i
end
assert_match %r%^a %, @stub_ui.output
refute_match %r%^pl %, @stub_ui.output
assert_empty @stub_ui.error
end
private
def add_gems_to_fetcher
spec_fetcher do |fetcher|
fetcher.spec 'a', 1
fetcher.spec 'a', 2
fetcher.spec 'a', '3.a'
end
end
end
class TestGemCommandsQueryCommandWithoutInstalledGems < Gem::TestCase
include TestGemCommandsQueryCommandSetup
def test_execute_platform
spec_fetcher do |fetcher|
fetcher.spec 'a', 1
fetcher.spec 'a', 1 do |s|
s.platform = 'x86-linux'
end
fetcher.spec 'a', 2 do |s|
s.platform = 'universal-darwin'
end
end
@cmd.handle_options %w[-r -a]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2 universal-darwin, 1 ruby x86-linux)
EOF
assert_equal expected, @stub_ui.output
assert_equal '', @stub_ui.error
end
def test_execute_show_default_gems
spec_fetcher { |fetcher| fetcher.spec 'a', 2 }
a1 = new_default_spec 'a', 1
install_default_specs a1
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
a (2, default: 1)
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_show_default_gems_with_platform
a1 = new_default_spec 'a', 1
a1.platform = 'java'
install_default_specs a1
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
a (default: 1 java)
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_default_details
spec_fetcher do |fetcher|
fetcher.spec 'a', 2
end
a1 = new_default_spec 'a', 1
install_default_specs a1
@cmd.handle_options %w[-l -d]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
a (2, 1)
Author: A User
Homepage: http://example.com
Installed at (2): #{@gemhome}
(1, default): #{a1.base_dir}
this is a summary
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_local_details
spec_fetcher do |fetcher|
fetcher.spec 'a', 1 do |s|
s.platform = 'x86-linux'
end
fetcher.spec 'a', 2 do |s|
s.summary = 'This is a lot of text. ' * 4
s.authors = ['Abraham Lincoln', 'Hirohito']
s.homepage = 'http://a.example.com/'
s.platform = 'universal-darwin'
end
fetcher.legacy_platform
end
@cmd.handle_options %w[-l -d]
use_ui @stub_ui do
@cmd.execute
end
str = @stub_ui.output
str.gsub!(/\(\d\): [^\n]*/, "-")
str.gsub!(/at: [^\n]*/, "at: -")
expected = <<-EOF
*** LOCAL GEMS ***
a (2, 1)
Platforms:
1: x86-linux
2: universal-darwin
Authors: Abraham Lincoln, Hirohito
Homepage: http://a.example.com/
Installed at -
-
This is a lot of text. This is a lot of text. This is a lot of text.
This is a lot of text.
pl (1)
Platform: i386-linux
Author: A User
Homepage: http://example.com
Installed at: -
this is a summary
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_exact_remote
spec_fetcher do |fetcher|
fetcher.spec 'coolgem-omg', 3
fetcher.spec 'coolgem', '4.2.1'
fetcher.spec 'wow_coolgem', 1
end
@cmd.handle_options %w[--remote --exact coolgem]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
coolgem (4.2.1)
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_exact_local
spec_fetcher do |fetcher|
fetcher.spec 'coolgem-omg', 3
fetcher.spec 'coolgem', '4.2.1'
fetcher.spec 'wow_coolgem', 1
end
@cmd.handle_options %w[--exact coolgem]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
coolgem (4.2.1)
EOF
assert_equal expected, @stub_ui.output
end
def test_execute_exact_multiple
spec_fetcher do |fetcher|
fetcher.spec 'coolgem-omg', 3
fetcher.spec 'coolgem', '4.2.1'
fetcher.spec 'wow_coolgem', 1
fetcher.spec 'othergem-omg', 3
fetcher.spec 'othergem', '1.2.3'
fetcher.spec 'wow_othergem', 1
end
@cmd.handle_options %w[--exact coolgem othergem]
use_ui @stub_ui do
@cmd.execute
end
expected = <<-EOF
*** LOCAL GEMS ***
coolgem (4.2.1)
*** LOCAL GEMS ***
othergem (1.2.3)
EOF
assert_equal expected, @stub_ui.output
end
private
def add_gems_to_fetcher
spec_fetcher do |fetcher|
fetcher.download 'a', 1
fetcher.download 'a', 2
fetcher.download 'a', '3.a'
end
end
end

View File

@ -98,6 +98,18 @@ class TestGemCommandsSetupCommand < Gem::TestCase
File.join @gemhome, 'bin', name File.join @gemhome, 'bin', name
end end
def gem_install_with_plugin(name)
gem = util_spec name do |s|
s.files = %W[lib/rubygems_plugin.rb]
end
write_file File.join @tempdir, 'lib', 'rubygems_plugin.rb' do |f|
f.puts "require '#{gem.plugins.first}'"
end
install_gem gem
File.join Gem.plugins_dir, "#{name}_plugin.rb"
end
def test_execute_regenerate_binstubs def test_execute_regenerate_binstubs
gem_bin_path = gem_install 'a' gem_bin_path = gem_install 'a'
write_file gem_bin_path do |io| write_file gem_bin_path do |io|
@ -123,6 +135,31 @@ class TestGemCommandsSetupCommand < Gem::TestCase
assert_equal "I changed it!\n", File.read(gem_bin_path) assert_equal "I changed it!\n", File.read(gem_bin_path)
end end
def test_execute_regenerate_plugins
gem_plugin_path = gem_install_with_plugin 'a'
write_file gem_plugin_path do |io|
io.puts 'I changed it!'
end
@cmd.options[:document] = []
@cmd.execute
assert_match %r{\Arequire}, File.read(gem_plugin_path)
end
def test_execute_no_regenerate_plugins
gem_plugin_path = gem_install_with_plugin 'a'
write_file gem_plugin_path do |io|
io.puts 'I changed it!'
end
@cmd.options[:document] = []
@cmd.options[:regenerate_plugins] = false
@cmd.execute
assert_equal "I changed it!\n", File.read(gem_plugin_path)
end
def test_execute_informs_about_installed_executables def test_execute_informs_about_installed_executables
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute

View File

@ -247,7 +247,7 @@ source http://gems.example.com/ already present in the cache
end end
def test_execute_add_http_rubygems_org def test_execute_add_http_rubygems_org
http_rubygems_org = 'http://rubygems.org' http_rubygems_org = 'http://rubygems.org/'
spec_fetcher do |fetcher| spec_fetcher do |fetcher|
fetcher.spec 'a', 1 fetcher.spec 'a', 1
@ -284,6 +284,44 @@ source http://gems.example.com/ already present in the cache
assert_empty @ui.error assert_empty @ui.error
end end
def test_execute_add_https_rubygems_org
https_rubygems_org = 'https://rubygems.org/'
spec_fetcher do |fetcher|
fetcher.spec 'a', 1
end
specs = Gem::Specification.map do |spec|
[spec.name, spec.version, spec.original_platform]
end
specs_dump_gz = StringIO.new
Zlib::GzipWriter.wrap specs_dump_gz do |io|
Marshal.dump specs, io
end
@fetcher.data["#{https_rubygems_org}/specs.#{@marshal_version}.gz"] =
specs_dump_gz.string
@cmd.handle_options %W[--add #{https_rubygems_org}]
ui = Gem::MockGemUi.new "n"
use_ui ui do
assert_raises Gem::MockGemUi::TermError do
@cmd.execute
end
end
assert_equal [@gem_repo], Gem.sources
expected = <<-EXPECTED
EXPECTED
assert_equal expected, @ui.output
assert_empty @ui.error
end
def test_execute_add_bad_uri def test_execute_add_bad_uri
@cmd.handle_options %w[--add beta-gems.example.com] @cmd.handle_options %w[--add beta-gems.example.com]

View File

@ -159,6 +159,44 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty out assert_empty out
end end
def test_execute_system_specific_older_than_3_2_removes_plugins_dir
spec_fetcher do |fetcher|
fetcher.download 'rubygems-update', 3.1 do |s|
s.files = %w[setup.rb]
end
end
@cmd.options[:args] = []
@cmd.options[:system] = "3.1"
FileUtils.mkdir_p Gem.plugins_dir
write_file File.join(Gem.plugins_dir, 'a_plugin.rb')
@cmd.execute
refute_path_exists Gem.plugins_dir, "Plugins folder not removed when updating rubygems to pre-3.2"
end
def test_execute_system_specific_newer_than_or_equal_to_3_2_leaves_plugins_dir_alone
spec_fetcher do |fetcher|
fetcher.download 'rubygems-update', 3.2 do |s|
s.files = %w[setup.rb]
end
end
@cmd.options[:args] = []
@cmd.options[:system] = "3.2"
FileUtils.mkdir_p Gem.plugins_dir
plugin_file = File.join(Gem.plugins_dir, 'a_plugin.rb')
write_file plugin_file
@cmd.execute
assert_path_exists Gem.plugins_dir, "Plugin folder removed when updating rubygems to post-3.2"
assert_path_exists plugin_file, "Plugin removed when updating rubygems to post-3.2"
end
def test_execute_system_specifically_to_latest_version def test_execute_system_specifically_to_latest_version
spec_fetcher do |fetcher| spec_fetcher do |fetcher|
fetcher.download 'rubygems-update', 8 do |s| fetcher.download 'rubygems-update', 8 do |s|
@ -359,10 +397,10 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end end
def test_execute_user_install def test_execute_user_install
spec_fetcher do |fetcher| a = util_spec "a", 1
fetcher.download 'a', 2 b = util_spec "b", 1
fetcher.spec 'a', 1 install_gem_user(a)
end install_gem(b)
@cmd.handle_options %w[--user-install] @cmd.handle_options %w[--user-install]
@ -373,7 +411,13 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
installer = @cmd.installer installer = @cmd.installer
user_install = installer.instance_variable_get :@user_install user_install = installer.instance_variable_get :@user_install
assert user_install, 'user_install must be set on the installer' assert user_install, "user_install must be set on the installer"
out = @ui.output.split "\n"
assert_equal "Updating installed gems", out.shift
assert_equal "Updating a", out.shift
assert_equal "Gems updated: a", out.shift
assert_empty out
end end
def test_fetch_remote_gems def test_fetch_remote_gems

View File

@ -11,10 +11,6 @@ class TestGemConfigFile < Gem::TestCase
@cfg_args = %W[--config-file #{@temp_conf}] @cfg_args = %W[--config-file #{@temp_conf}]
@orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
File.join(@tempdir, 'system-gemrc')
Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear
Gem::ConfigFile::PLATFORM_DEFAULTS.clear Gem::ConfigFile::PLATFORM_DEFAULTS.clear
@ -27,9 +23,6 @@ class TestGemConfigFile < Gem::TestCase
def teardown def teardown
Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear
Gem::ConfigFile::PLATFORM_DEFAULTS.clear Gem::ConfigFile::PLATFORM_DEFAULTS.clear
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
@orig_SYSTEM_WIDE_CONFIG_FILE
ENV['GEMRC'] = @env_gemrc ENV['GEMRC'] = @env_gemrc

View File

@ -440,7 +440,7 @@ class TestGemDependencyInstaller < Gem::TestCase
e1 = util_spec 'e', '1', nil, 'extconf.rb' do |s| e1 = util_spec 'e', '1', nil, 'extconf.rb' do |s|
s.extensions << 'extconf.rb' s.extensions << 'extconf.rb'
end end
e1_gem = File.join @tempdir, 'gems', "#{e1.full_name}.gem" e1_gem = e1.cache_file
_, f1_gem = util_gem 'f', '1', 'e' => nil _, f1_gem = util_gem 'f', '1', 'e' => nil

View File

@ -153,6 +153,34 @@ This directory does not appear to be a RubyGems repository, skipping
assert true # count assert true # count
end end
def test_doctor_badly_named_plugins
gem 'a'
Gem.use_paths @gemhome.to_s
FileUtils.mkdir_p Gem.plugins_dir
bad_plugin = File.join(Gem.plugins_dir, "a_badly_named_file.rb")
write_file bad_plugin
doctor = Gem::Doctor.new @gemhome
capture_io do
use_ui @ui do
doctor.doctor
end
end
# refute_path_exists bad_plugin
expected = <<-OUTPUT
Checking #{@gemhome}
Removed file plugins/a_badly_named_file.rb
OUTPUT
assert_equal expected, @ui.output
end
def test_gem_repository_eh def test_gem_repository_eh
doctor = Gem::Doctor.new @gemhome doctor = Gem::Doctor.new @gemhome

View File

@ -67,4 +67,34 @@ class TestGemGemRunner < Gem::TestCase
assert_equal %w[--foo], args assert_equal %w[--foo], args
end end
def test_info_succeeds
args = %w[info]
use_ui @ui do
assert_nil @runner.run(args)
end
assert_empty @ui.error
end
def test_list_succeeds
args = %w[list]
use_ui @ui do
assert_nil @runner.run(args)
end
assert_empty @ui.error
end
def test_search_succeeds
args = %w[search]
use_ui @ui do
assert_nil @runner.run(args)
end
assert_empty @ui.error
end
end end

View File

@ -744,6 +744,70 @@ gem 'other', version
assert_match(/#{default_shebang}/, shebang_line) assert_match(/#{default_shebang}/, shebang_line)
end end
def test_generate_plugins
installer = util_setup_installer do |spec|
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
io.write "puts __FILE__"
end
spec.files += %w[lib/rubygems_plugin.rb]
end
build_rake_in do
installer.install
end
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
FileUtils.rm plugin_path
installer.generate_plugins
assert File.exist?(plugin_path), 'plugin not written'
end
def test_keeps_plugins_up_to_date
# NOTE: version a-2 is already installed by setup hooks
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
io.write "puts __FILE__"
end
build_rake_in do
util_setup_installer do |spec|
spec.version = '1'
spec.files += %w[lib/rubygems_plugin.rb]
end.install
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
refute File.exist?(plugin_path), 'old version installed while newer version without plugin also installed, but plugin written'
util_setup_installer do |spec|
spec.version = '2'
spec.files += %w[lib/rubygems_plugin.rb]
end.install
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
assert File.exist?(plugin_path), 'latest version reinstalled, but plugin not written'
assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content'
util_setup_installer do |spec|
spec.version = '3'
spec.files += %w[lib/rubygems_plugin.rb]
end.install
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
assert File.exist?(plugin_path), 'latest version installed, but plugin removed'
assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content'
util_setup_installer do |spec|
spec.version = '4'
end.install
refute File.exist?(plugin_path), 'new version installed without a plugin while older version with a plugin installed, but plugin not removed'
end
end
def test_initialize def test_initialize
spec = util_spec 'a' do |s| spec = util_spec 'a' do |s|
s.platform = Gem::Platform.new 'mswin32' s.platform = Gem::Platform.new 'mswin32'
@ -940,7 +1004,13 @@ gem 'other', version
end end
def test_install_creates_binstub_that_prefers_user_installed_gem_to_default def test_install_creates_binstub_that_prefers_user_installed_gem_to_default
install_default_gems new_default_spec('default', '2') default_spec = new_default_spec('default', '2', nil, 'exe/executable')
default_spec.executables = 'executable'
install_default_gems default_spec
exe = File.join @gemhome, 'bin', 'executable'
assert_path_exists exe, "default gem's executable not installed"
installer = util_setup_installer do |spec| installer = util_setup_installer do |spec|
spec.name = 'default' spec.name = 'default'
@ -958,8 +1028,6 @@ gem 'other', version
end end
end end
exe = File.join @gemhome, 'bin', 'executable'
e = assert_raises RuntimeError do e = assert_raises RuntimeError do
instance_eval File.read(exe) instance_eval File.read(exe)
end end

View File

@ -153,20 +153,18 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
assert_equal proxy_uri, fetcher.instance_variable_get(:@proxy).to_s assert_equal proxy_uri, fetcher.instance_variable_get(:@proxy).to_s
end end
def test_fetch_size_bad_uri def test_fetch_path_bad_uri
fetcher = Gem::RemoteFetcher.new nil fetcher = Gem::RemoteFetcher.new nil
@fetcher = fetcher @fetcher = fetcher
e = assert_raises ArgumentError do e = assert_raises ArgumentError do
Gem::Deprecate.skip_during do @fetcher.fetch_path("gems.example.com/yaml", nil, true)
fetcher.fetch_size 'gems.example.com/yaml'
end
end end
assert_equal 'uri scheme is invalid: nil', e.message assert_equal 'uri scheme is invalid: nil', e.message
end end
def test_fetch_size_socket_error def test_fetch_path_socket_error
fetcher = Gem::RemoteFetcher.new nil fetcher = Gem::RemoteFetcher.new nil
@fetcher = fetcher @fetcher = fetcher
def fetcher.request(uri, request_class, last_modified = nil) def fetcher.request(uri, request_class, last_modified = nil)
@ -175,9 +173,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
uri = 'http://gems.example.com/yaml' uri = 'http://gems.example.com/yaml'
e = assert_raises Gem::RemoteFetcher::FetchError do e = assert_raises Gem::RemoteFetcher::FetchError do
Gem::Deprecate.skip_during do @fetcher.fetch_path(uri, nil, true)
fetcher.fetch_size uri
end
end end
assert_equal "SocketError: oops (#{uri})", e.message assert_equal "SocketError: oops (#{uri})", e.message
@ -186,9 +182,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_no_proxy def test_no_proxy
use_ui @stub_ui do use_ui @stub_ui do
assert_data_from_server @fetcher.fetch_path(@server_uri) assert_data_from_server @fetcher.fetch_path(@server_uri)
Gem::Deprecate.skip_during do response = @fetcher.fetch_path(@server_uri, nil, true)
assert_equal SERVER_DATA.size, @fetcher.fetch_size(@server_uri) assert_equal SERVER_DATA.size, response['content-length'].to_i
end
end end
end end
@ -917,7 +912,6 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end end
def test_ssl_client_cert_auth_connection def test_ssl_client_cert_auth_connection
skip 'openssl is missing' unless defined?(OpenSSL::SSL)
skip 'openssl in jruby fails' if java_platform? skip 'openssl in jruby fails' if java_platform?
ssl_server = self.class.start_ssl_server({ ssl_server = self.class.start_ssl_server({
@ -935,8 +929,6 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end end
def test_do_not_allow_invalid_client_cert_auth_connection def test_do_not_allow_invalid_client_cert_auth_connection
skip 'openssl is missing' unless defined?(OpenSSL::SSL)
ssl_server = self.class.start_ssl_server({ ssl_server = self.class.start_ssl_server({
:SSLVerifyClient => :SSLVerifyClient =>
OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT}) OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT})
@ -1083,9 +1075,6 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
DIR = File.expand_path(File.dirname(__FILE__)) DIR = File.expand_path(File.dirname(__FILE__))
def start_ssl_server(config = {}) def start_ssl_server(config = {})
raise MiniTest::Skip, 'openssl not installed' unless
defined?(OpenSSL::SSL)
null_logger = NilLog.new null_logger = NilLog.new
server = WEBrick::HTTPServer.new({ server = WEBrick::HTTPServer.new({
:Port => 0, :Port => 0,
@ -1109,8 +1098,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
begin begin
server.start server.start
rescue Exception => ex rescue Exception => ex
abort ex.message
puts "ERROR during server thread: #{ex.message}" puts "ERROR during server thread: #{ex.message}"
raise
ensure ensure
server.shutdown server.shutdown
end end

View File

@ -183,6 +183,58 @@ DEPENDENCIES
assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec' assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec'
end end
def test_install_from_gemdeps_complex_dependencies
quick_gem("z", 1)
quick_gem("z", "1.0.1")
quick_gem("z", "1.0.2")
quick_gem("z", "1.0.3")
quick_gem("z", 2)
spec_fetcher do |fetcher|
fetcher.download "z", 1
end
rs = Gem::RequestSet.new
installed = []
File.open 'Gemfile.lock', 'w' do |io|
io.puts <<-LOCKFILE
GEM
remote: #{@gem_repo}
specs:
z (1)
PLATFORMS
#{Gem::Platform::RUBY}
DEPENDENCIES
z (~> 1.0, >= 1.0.1)
LOCKFILE
end
File.open 'testo.gemspec', 'w' do |io|
io.puts <<-LOCKFILE
Gem::Specification.new do |spec|
spec.name = 'testo'
spec.version = '1.0.0'
spec.add_dependency('z', '~> 1.0', '>= 1.0.1')
end
LOCKFILE
end
File.open 'Gemfile', 'w' do |io|
io.puts("gemspec")
end
rs.install_from_gemdeps :gemdeps => 'Gemfile' do |req, installer|
installed << req.full_name
end
assert_includes installed, 'z-1.0.3'
assert_path_exists File.join @gemhome, 'specifications', 'z-1.0.3.gemspec'
end
def test_install_from_gemdeps_version_mismatch def test_install_from_gemdeps_version_mismatch
spec_fetcher do |fetcher| spec_fetcher do |fetcher|
fetcher.gem 'a', 2 fetcher.gem 'a', 2

View File

@ -2784,7 +2784,7 @@ end
add_runtime_dependency 'l', '~> 1.2', '> 1.2.3' add_runtime_dependency 'l', '~> 1.2', '> 1.2.3'
#{w}: open-ended dependency on o (>= 0) is not recommended #{w}: open-ended dependency on o (>= 0) is not recommended
use a bounded requirement, such as '~> x.y' use a bounded requirement, such as '~> x.y'
#{w}: See http://guides.rubygems.org/specification-reference/ for help #{w}: See https://guides.rubygems.org/specification-reference/ for help
EXPECTED EXPECTED
assert_equal expected, @ui.error, 'warning' assert_equal expected, @ui.error, 'warning'
@ -2816,7 +2816,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
end end
assert_equal <<-EXPECTED, @ui.error assert_equal <<-EXPECTED, @ui.error
#{w}: See http://guides.rubygems.org/specification-reference/ for help #{w}: See https://guides.rubygems.org/specification-reference/ for help
EXPECTED EXPECTED
end end
end end
@ -2927,7 +2927,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
end end
end end
assert_match 'See http://guides.rubygems.org/specification-reference/ for help', @ui.error assert_match 'See https://guides.rubygems.org/specification-reference/ for help', @ui.error
end end
def test_validate_executables def test_validate_executables
@ -3100,7 +3100,7 @@ Please report a bug if this causes problems.
assert_equal '"ftp://rubygems.org" is not a valid HTTP URI', e.message assert_equal '"ftp://rubygems.org" is not a valid HTTP URI', e.message
@a1.homepage = 'http://rubygems.org' @a1.homepage = 'https://rubygems.org/'
assert_equal true, @a1.validate assert_equal true, @a1.validate
@a1.homepage = 'https://rubygems.org' @a1.homepage = 'https://rubygems.org'
@ -3430,7 +3430,7 @@ Did you mean 'Ruby'?
@a1.validate @a1.validate
end end
assert_match 'See http://guides.rubygems.org/specification-reference/ for help', @ui.error assert_match 'See https://guides.rubygems.org/specification-reference/ for help', @ui.error
end end
def test_version def test_version
@ -3532,7 +3532,8 @@ Did you mean 'Ruby'?
s.metadata = { s.metadata = {
"one" => "two", "one" => "two",
"home" => "three", "home" => "three",
"homepage_uri" => "https://example.com/user/repo" "homepage_uri" => "https://example.com/user/repo",
"funding_uri" => "https://example.com/donate"
} }
end end

View File

@ -169,6 +169,41 @@ class TestGemUninstaller < Gem::InstallerTestCase
end end
end end
def test_remove_plugins
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
io.write "puts __FILE__"
end
@spec.files += %w[lib/rubygems_plugin.rb]
Gem::Installer.at(Gem::Package.build(@spec)).install
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
assert File.exist?(plugin_path), 'plugin not written'
Gem::Uninstaller.new(nil).remove_plugins @spec
refute File.exist?(plugin_path), 'plugin not removed'
end
def test_regenerate_plugins_for
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
io.write "puts __FILE__"
end
@spec.files += %w[lib/rubygems_plugin.rb]
Gem::Installer.at(Gem::Package.build(@spec)).install
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
assert File.exist?(plugin_path), 'plugin not written'
FileUtils.rm plugin_path
Gem::Uninstaller.new(nil).regenerate_plugins_for @spec
assert File.exist?(plugin_path), 'plugin not regenerated'
end
def test_path_ok_eh def test_path_ok_eh
uninstaller = Gem::Uninstaller.new nil uninstaller = Gem::Uninstaller.new nil
@ -524,6 +559,35 @@ create_makefile '#{@spec.name}'
assert_match %r!Successfully uninstalled q-1!, lines.last assert_match %r!Successfully uninstalled q-1!, lines.last
end end
def test_uninstall_prompt_only_lists_the_dependents_that_prevented_uninstallation
quick_gem 'r', '1' do |s|
s.add_development_dependency 'q', '= 1'
end
quick_gem 's', '1' do |s|
s.add_dependency 'q', '= 1'
end
quick_gem 'q', '1'
un = Gem::Uninstaller.new('q', :check_dev => false)
ui = Gem::MockGemUi.new("y\n")
use_ui ui do
un.uninstall
end
lines = ui.output.split("\n")
lines.shift
assert_match %r!You have requested to uninstall the gem:!, lines.shift
lines.shift
lines.shift
assert_match %r!s-1 depends on q \(= 1\)!, lines.shift
assert_match %r!Successfully uninstalled q-1!, lines.last
end
def test_uninstall_no_permission def test_uninstall_no_permission
uninstaller = Gem::Uninstaller.new @spec.name, :executables => true uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
@ -542,4 +606,44 @@ create_makefile '#{@spec.name}'
end end
end end
def test_uninstall_keeps_plugins_up_to_date
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
io.write "puts __FILE__"
end
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
@spec.version = '1'
Gem::Installer.at(Gem::Package.build(@spec)).install
refute File.exist?(plugin_path), 'version without plugin installed, but plugin written'
@spec.files += %w[lib/rubygems_plugin.rb]
@spec.version = '2'
Gem::Installer.at(Gem::Package.build(@spec)).install
assert File.exist?(plugin_path), 'version with plugin installed, but plugin not written'
assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content'
@spec.version = '3'
Gem::Installer.at(Gem::Package.build(@spec)).install
assert File.exist?(plugin_path), 'version with plugin installed, but plugin removed'
assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'old version installed, but plugin updated'
Gem::Uninstaller.new('a', :version => '1', :executables => true).uninstall
assert File.exist?(plugin_path), 'plugin removed when old version uninstalled'
assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'old version uninstalled, but plugin updated'
Gem::Uninstaller.new('a', version: '3', :executables => true).uninstall
assert File.exist?(plugin_path), 'plugin removed when old version uninstalled and another version with plugin still present'
assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'latest version uninstalled, but plugin not updated to previous version'
Gem::Uninstaller.new('a', version: '2', :executables => true).uninstall
refute File.exist?(plugin_path), 'last version uninstalled, but plugin still present'
end
end end

View File

@ -236,7 +236,7 @@ class TestGemVersion < Gem::TestCase
assert_equal expected, v(version).approximate_recommendation assert_equal expected, v(version).approximate_recommendation
end end
# Assert that the "approximate" recommendation for +version+ satifies +version+. # Assert that the "approximate" recommendation for +version+ satisfies +version+.
def assert_approximate_satisfies_itself(version) def assert_approximate_satisfies_itself(version)
gem_version = v(version) gem_version = v(version)