summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Rodríguez <deivid.rodriguez@riseup.net>2020-03-24 07:39:24 +0100
committerGitHub <noreply@github.com>2020-03-24 15:39:24 +0900
commit96064e6f1ce100a37680dc8f9509f06b3350e9c8 (patch)
tree798b59f015cb82ee3cd0427f80584032175829ba /lib
parent930b012ad96bfb0bd12446b89407120744ef92eb (diff)
Sync rubygems with current master (#2889)
Notes
Notes: Merged-By: hsbt <hsbt@ruby-lang.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/rubygems.rb62
-rw-r--r--lib/rubygems/bundler_version_finder.rb17
-rw-r--r--lib/rubygems/command.rb8
-rw-r--r--lib/rubygems/commands/contents_command.rb2
-rw-r--r--lib/rubygems/commands/update_command.rb4
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb31
-rw-r--r--lib/rubygems/dependency_installer.rb148
-rw-r--r--lib/rubygems/ext/builder.rb4
-rw-r--r--lib/rubygems/install_update_options.rb4
-rw-r--r--lib/rubygems/installer.rb37
-rw-r--r--lib/rubygems/installer_uninstaller_utils.rb8
-rw-r--r--lib/rubygems/source_specific_file.rb6
-rw-r--r--lib/rubygems/spec_fetcher.rb23
-rw-r--r--lib/rubygems/specification.rb14
-rw-r--r--lib/rubygems/test_case.rb19
-rw-r--r--lib/rubygems/uninstaller.rb5
16 files changed, 144 insertions, 248 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index f7380c7154..9bd4e9be20 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -190,6 +190,8 @@ module Gem
@pre_reset_hooks ||= []
@post_reset_hooks ||= []
+ @default_source_date_epoch = nil
+
##
# Try to activate a gem containing +path+. Returns true if
# activation succeeded or wasn't needed because it was already
@@ -317,6 +319,13 @@ module Gem
end
##
+ # The path were rubygems plugins are to be installed.
+
+ def self.plugindir(install_dir=Gem.dir)
+ File.join install_dir, 'plugins'
+ end
+
+ ##
# Reset the +dir+ and +path+ values. The next time +dir+ or +path+
# is requested, the values will be calculated from scratch. This is
# mainly used by the unit tests to provide test isolation.
@@ -423,10 +432,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
paths.spec_cache_dir
end
- def self.plugins_dir
- File.join(dir, "plugins")
- end
-
##
# Quietly ensure the Gem directory +dir+ contains all the proper
# subdirectories. If we can't create a directory due to a permission
@@ -466,7 +471,10 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
subdirs.each do |name|
subdir = File.join dir, name
next if File.exist? subdir
- FileUtils.mkdir_p subdir, **options rescue nil
+ begin
+ FileUtils.mkdir_p subdir, **options
+ rescue Errno::EACCES
+ end
end
ensure
File.umask old_umask
@@ -863,8 +871,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
def self.ruby
if @ruby.nil?
- @ruby = File.join(RbConfig::CONFIG['bindir'],
- "#{RbConfig::CONFIG['ruby_install_name']}#{RbConfig::CONFIG['EXEEXT']}")
+ @ruby = RbConfig.ruby
@ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
end
@@ -1099,7 +1106,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
# Find rubygems plugin files in the standard location and load them
def self.load_plugins
- load_plugin_files Gem::Util.glob_files_in_dir("*#{Gem.plugin_suffix_pattern}", plugins_dir)
+ load_plugin_files Gem::Util.glob_files_in_dir("*#{Gem.plugin_suffix_pattern}", plugindir)
end
##
@@ -1182,20 +1189,43 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
##
- # 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.
+ # If the SOURCE_DATE_EPOCH environment variable is set, returns it's value.
+ # Otherwise, returns the time that `Gem.source_date_epoch_string` was
+ # first called in the same format as SOURCE_DATE_EPOCH.
+ #
+ # NOTE(@duckinator): The implementation is a tad weird because we want to:
+ # 1. Make builds reproducible by default, by having this function always
+ # return the same result during a given run.
+ # 2. Allow changing ENV['SOURCE_DATE_EPOCH'] at runtime, since multiple
+ # tests that set this variable will be run in a single process.
#
- # If it is not set as an environment variable already, this also sets it.
+ # If you simplify this function and a lot of tests fail, that is likely
+ # due to #2 above.
#
# Details on SOURCE_DATE_EPOCH:
# https://reproducible-builds.org/specs/source-date-epoch/
- def self.source_date_epoch
- if ENV["SOURCE_DATE_EPOCH"].nil? || ENV["SOURCE_DATE_EPOCH"].empty?
- ENV["SOURCE_DATE_EPOCH"] = Time.now.to_i.to_s
- end
+ def self.source_date_epoch_string
+ # The value used if $SOURCE_DATE_EPOCH is not set.
+ @default_source_date_epoch ||= Time.now.to_i.to_s
+
+ specified_epoch = ENV["SOURCE_DATE_EPOCH"]
+
+ # If it's empty or just whitespace, treat it like it wasn't set at all.
+ specified_epoch = nil if !specified_epoch.nil? && specified_epoch.strip.empty?
+
+ epoch = specified_epoch || @default_source_date_epoch
+
+ epoch.strip
+ end
- Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc.freeze
+ ##
+ # Returns the value of Gem.source_date_epoch_string, as a Time object.
+ #
+ # This is used throughout RubyGems for enabling reproducible builds.
+
+ def self.source_date_epoch
+ Time.at(self.source_date_epoch_string.to_i).utc.freeze
end
# FIX: Almost everywhere else we use the `def self.` way of defining class
diff --git a/lib/rubygems/bundler_version_finder.rb b/lib/rubygems/bundler_version_finder.rb
index 38da7738a8..ea6698f26e 100644
--- a/lib/rubygems/bundler_version_finder.rb
+++ b/lib/rubygems/bundler_version_finder.rb
@@ -82,12 +82,19 @@ To install the missing version, run `gem install bundler:#{vr.first}`
def self.lockfile_contents
gemfile = ENV["BUNDLE_GEMFILE"]
gemfile = nil if gemfile && gemfile.empty?
- Gem::Util.traverse_parents Dir.pwd do |directory|
- next unless gemfile = Gem::GEM_DEP_FILES.find { |f| File.file?(f.tap(&Gem::UNTAINT)) }
- gemfile = File.join directory, gemfile
- break
- end unless gemfile
+ unless gemfile
+ begin
+ Gem::Util.traverse_parents(Dir.pwd) do |directory|
+ next unless gemfile = Gem::GEM_DEP_FILES.find { |f| File.file?(f.tap(&Gem::UNTAINT)) }
+
+ gemfile = File.join directory, gemfile
+ break
+ end
+ rescue Errno::ENOENT
+ return
+ end
+ end
return unless gemfile
diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb
index 11b6645e9d..9b7b41d3a7 100644
--- a/lib/rubygems/command.rb
+++ b/lib/rubygems/command.rb
@@ -77,7 +77,7 @@ class Gem::Command
when Array
@extra_args = value
when String
- @extra_args = value.split(' ')
+ @extra_args = value.split
end
end
@@ -174,8 +174,7 @@ class Gem::Command
alert_error msg
unless suppress_suggestions
- suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name gem_name
-
+ suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name(gem_name, :latest, 10)
unless suggestions.empty?
alert_error "Possible alternatives: #{suggestions.join(", ")}"
end
@@ -625,8 +624,7 @@ class Gem::Command
# :stopdoc:
HELP = <<-HELP.freeze
-RubyGems is a sophisticated package manager for Ruby. This is a
-basic help message containing pointers to more information.
+RubyGems is a package manager for Ruby.
Usage:
gem -h/--help
diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb
index 26d6828fe6..989ca5855c 100644
--- a/lib/rubygems/commands/contents_command.rb
+++ b/lib/rubygems/commands/contents_command.rb
@@ -167,7 +167,7 @@ prefix or only the files that are requireable.
end
def spec_for(name)
- spec = Gem::Specification.find_all_by_name(name, @version).last
+ spec = Gem::Specification.find_all_by_name(name, @version).first
return spec if spec
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index 7031ac0dd0..494b3eef67 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -184,14 +184,14 @@ command to remove old versions.
else
require "tmpdir"
tmpdir = Dir.mktmpdir
- FileUtils.mv Gem.plugins_dir, tmpdir
+ FileUtils.mv Gem.plugindir, tmpdir
status = yield
if status
FileUtils.rm_rf tmpdir
else
- FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugins_dir
+ FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugindir
end
status
diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb
index 60f4d18712..a8d170f13a 100644
--- a/lib/rubygems/core_ext/kernel_require.rb
+++ b/lib/rubygems/core_ext/kernel_require.rb
@@ -43,18 +43,21 @@ module Kernel
# https://github.com/rubygems/rubygems/pull/1868
resolved_path = begin
rp = nil
- $LOAD_PATH[0...Gem.load_path_insert_index || -1].each do |lp|
- safe_lp = lp.dup.tap(&Gem::UNTAINT)
- begin
- if File.symlink? safe_lp # for backward compatibility
- next
+ Gem.suffixes.each do |s|
+ load_path_insert_index = Gem.load_path_insert_index
+ break unless load_path_insert_index
+
+ $LOAD_PATH[0...load_path_insert_index].each do |lp|
+ safe_lp = lp.dup.tap(&Gem::UNTAINT)
+ begin
+ if File.symlink? safe_lp # for backward compatibility
+ next
+ end
+ rescue SecurityError
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ raise
end
- rescue SecurityError
- RUBYGEMS_ACTIVATION_MONITOR.exit
- raise
- end
- Gem.suffixes.each do |s|
full_path = File.expand_path(File.join(safe_lp, "#{path}#{s}"))
if File.file?(full_path)
rp = full_path
@@ -67,12 +70,8 @@ module Kernel
end
if resolved_path
- begin
- RUBYGEMS_ACTIVATION_MONITOR.exit
- return gem_original_require(resolved_path)
- rescue LoadError
- RUBYGEMS_ACTIVATION_MONITOR.enter
- end
+ RUBYGEMS_ACTIVATION_MONITOR.exit
+ return gem_original_require(resolved_path)
end
if spec = Gem.find_unresolved_default_spec(path)
diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb
index 6d45688888..14ff8beab2 100644
--- a/lib/rubygems/dependency_installer.rb
+++ b/lib/rubygems/dependency_installer.rb
@@ -7,7 +7,6 @@ require 'rubygems/spec_fetcher'
require 'rubygems/user_interaction'
require 'rubygems/source'
require 'rubygems/available_set'
-require 'rubygems/deprecate'
##
# Installs a gem along with all its dependencies from local and remote gems.
@@ -15,7 +14,6 @@ require 'rubygems/deprecate'
class Gem::DependencyInstaller
include Gem::UserInteraction
- extend Gem::Deprecate
DEFAULT_OPTIONS = { # :nodoc:
:env_shebang => false,
@@ -107,27 +105,6 @@ class Gem::DependencyInstaller
end
##
- # Creates an AvailableSet to install from based on +dep_or_name+ and
- # +version+
-
- def available_set_for(dep_or_name, version) # :nodoc:
- if String === dep_or_name
- Gem::Deprecate.skip_during do
- find_spec_by_name_and_version dep_or_name, version, @prerelease
- end
- else
- dep = dep_or_name.dup
- dep.prerelease = @prerelease
- @available = Gem::Deprecate.skip_during do
- find_gems_with_sources dep
- end
- end
-
- @available.pick_best!
- end
- deprecate :available_set_for, :none, 2019, 12
-
- ##
# Indicated, based on the requested domain, if local
# gems should be considered.
@@ -143,131 +120,6 @@ class Gem::DependencyInstaller
@domain == :both or @domain == :remote
end
- ##
- # Returns a list of pairs of gemspecs and source_uris that match
- # Gem::Dependency +dep+ from both local (Dir.pwd) and remote (Gem.sources)
- # sources. Gems are sorted with newer gems preferred over older gems, and
- # local gems preferred over remote gems.
-
- def find_gems_with_sources(dep, best_only=false) # :nodoc:
- set = Gem::AvailableSet.new
-
- if consider_local?
- sl = Gem::Source::Local.new
-
- if spec = sl.find_gem(dep.name)
- if dep.matches_spec? spec
- set.add spec, sl
- end
- end
- end
-
- if consider_remote?
- begin
- # This is pulled from #spec_for_dependency to allow
- # us to filter tuples before fetching specs.
- tuples, errors = Gem::SpecFetcher.fetcher.search_for_dependency dep
-
- if best_only && !tuples.empty?
- tuples.sort! do |a,b|
- if b[0].version == a[0].version
- if b[0].platform != Gem::Platform::RUBY
- 1
- else
- -1
- end
- else
- b[0].version <=> a[0].version
- end
- end
- tuples = [tuples.first]
- end
-
- specs = []
- tuples.each do |tup, source|
- begin
- spec = source.fetch_spec(tup)
- rescue Gem::RemoteFetcher::FetchError => e
- errors << Gem::SourceFetchProblem.new(source, e)
- else
- specs << [spec, source]
- end
- end
-
- if @errors
- @errors += errors
- else
- @errors = errors
- end
-
- set << specs
-
- rescue Gem::RemoteFetcher::FetchError => e
- # FIX if there is a problem talking to the network, we either need to always tell
- # the user (no really_verbose) or fail hard, not silently tell them that we just
- # couldn't find their requested gem.
- verbose do
- "Error fetching remote data:\t\t#{e.message}\n" \
- "Falling back to local-only install"
- end
- @domain = :local
- end
- end
-
- set
- end
- deprecate :find_gems_with_sources, :none, 2019, 12
-
- ##
- # Finds a spec and the source_uri it came from for gem +gem_name+ and
- # +version+. Returns an Array of specs and sources required for
- # installation of the gem.
-
- def find_spec_by_name_and_version(gem_name,
- version = Gem::Requirement.default,
- prerelease = false)
- set = Gem::AvailableSet.new
-
- if consider_local?
- if gem_name =~ /\.gem$/ and File.file? gem_name
- src = Gem::Source::SpecificFile.new(gem_name)
- set.add src.spec, src
- elsif gem_name =~ /\.gem$/
- Dir[gem_name].each do |name|
- begin
- src = Gem::Source::SpecificFile.new name
- set.add src.spec, src
- rescue Gem::Package::FormatError
- end
- end
- else
- local = Gem::Source::Local.new
-
- if s = local.find_gem(gem_name, version)
- set.add s, local
- end
- end
- end
-
- if set.empty?
- dep = Gem::Dependency.new gem_name, version
- dep.prerelease = true if prerelease
-
- set = Gem::Deprecate.skip_during do
- find_gems_with_sources(dep, true)
- end
-
- set.match_platform!
- end
-
- if set.empty?
- raise Gem::SpecificGemNotFoundException.new(gem_name, version, @errors)
- end
-
- @available = set
- end
- deprecate :find_spec_by_name_and_version, :none, 2019, 12
-
def in_background(what) # :nodoc:
fork_happened = false
if @build_docs_in_background and Process.respond_to?(:fork)
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb
index 2fc1074d92..a8bd4c8d1b 100644
--- a/lib/rubygems/ext/builder.rb
+++ b/lib/rubygems/ext/builder.rb
@@ -68,7 +68,9 @@ class Gem::Ext::Builder
results << (command.respond_to?(:shelljoin) ? command.shelljoin : command)
require "open3"
- output, status = Open3.capture2e(*command)
+ # Set $SOURCE_DATE_EPOCH for the subprocess.
+ env = {'SOURCE_DATE_EPOCH' => Gem.source_date_epoch_string}
+ output, status = Open3.capture2e(env, *command)
if verbose
puts output
else
diff --git a/lib/rubygems/install_update_options.rb b/lib/rubygems/install_update_options.rb
index 38a0682958..dbf787c7ba 100644
--- a/lib/rubygems/install_update_options.rb
+++ b/lib/rubygems/install_update_options.rb
@@ -25,8 +25,8 @@ module Gem::InstallUpdateOptions
end
add_option(:"Install/Update", '-n', '--bindir DIR',
- 'Directory where executables are',
- 'located') do |value, options|
+ 'Directory where executables will be',
+ 'placed when the gem is installed') do |value, options|
options[:bin_dir] = File.expand_path(value)
end
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 2ba92482cc..abb7048b00 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -47,11 +47,6 @@ class Gem::Installer
include Gem::InstallerUninstallerUtils
##
- # Filename of the gem being installed.
-
- attr_reader :gem
-
- ##
# The directory a gem's executables will be installed into
attr_reader :bin_dir
@@ -487,13 +482,7 @@ class Gem::Installer
def generate_bin # :nodoc:
return if spec.executables.nil? or spec.executables.empty?
- begin
- Dir.mkdir @bin_dir, *[options[:dir_mode] && 0755].compact
- rescue SystemCallError
- raise unless File.directory? @bin_dir
- end
-
- raise Gem::FilePermissionError.new(@bin_dir) unless File.writable? @bin_dir
+ ensure_writable_dir @bin_dir
spec.executables.each do |filename|
filename.tap(&Gem::UNTAINT)
@@ -523,10 +512,12 @@ class Gem::Installer
latest = Gem::Specification.latest_spec_for(spec.name)
return if latest && latest.version > spec.version
+ ensure_writable_dir @plugins_dir
+
if spec.plugins.empty?
- remove_plugins_for(spec)
+ remove_plugins_for(spec, @plugins_dir)
else
- regenerate_plugins_for(spec)
+ regenerate_plugins_for(spec, @plugins_dir)
end
end
@@ -690,6 +681,7 @@ class Gem::Installer
@force = options[:force]
@install_dir = options[:install_dir]
@gem_home = options[:install_dir] || Gem.dir
+ @plugins_dir = Gem.plugindir(@gem_home)
@ignore_dependencies = options[:ignore_dependencies]
@format_executable = options[:format_executable]
@wrappers = options[:wrappers]
@@ -890,6 +882,13 @@ TEXT
end
##
+ # Filename of the gem being installed.
+
+ def gem
+ @package.gem.path
+ end
+
+ ##
# Performs various checks before installing the gem such as the install
# repository is writable and its directories exist, required Ruby and
# rubygems versions are met and that dependencies are installed.
@@ -953,4 +952,14 @@ TEXT
@package.copy_to cache_file
end
+ def ensure_writable_dir(dir) # :nodoc:
+ begin
+ Dir.mkdir dir, *[options[:dir_mode] && 0755].compact
+ rescue SystemCallError
+ raise unless File.directory? dir
+ end
+
+ raise Gem::FilePermissionError.new(dir) unless File.writable? dir
+ end
+
end
diff --git a/lib/rubygems/installer_uninstaller_utils.rb b/lib/rubygems/installer_uninstaller_utils.rb
index b8436f4f0a..e81ed4cba3 100644
--- a/lib/rubygems/installer_uninstaller_utils.rb
+++ b/lib/rubygems/installer_uninstaller_utils.rb
@@ -5,9 +5,9 @@
module Gem::InstallerUninstallerUtils
- def regenerate_plugins_for(spec)
+ def regenerate_plugins_for(spec, plugins_dir)
spec.plugins.each do |plugin|
- plugin_script_path = File.join Gem.plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}"
+ plugin_script_path = File.join plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}"
File.open plugin_script_path, 'wb' do |file|
file.puts "require '#{plugin}'"
@@ -17,8 +17,8 @@ module Gem::InstallerUninstallerUtils
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)
+ def remove_plugins_for(spec, plugins_dir)
+ FileUtils.rm_f Gem::Util.glob_files_in_dir("#{spec.name}#{Gem.plugin_suffix_pattern}", plugins_dir)
end
end
diff --git a/lib/rubygems/source_specific_file.rb b/lib/rubygems/source_specific_file.rb
deleted file mode 100644
index b676b1d3a2..0000000000
--- a/lib/rubygems/source_specific_file.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# frozen_string_literal: true
-require 'rubygems/source/specific_file'
-
-unless Gem::Deprecate.skip
- Kernel.warn "#{Gem.location_of_caller(3).join(':')}: Warning: Requiring rubygems/source_specific_file is deprecated; please use rubygems/source/specific_file instead."
-end
diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb
index cf86b72188..56ccaea84d 100644
--- a/lib/rubygems/spec_fetcher.rb
+++ b/lib/rubygems/spec_fetcher.rb
@@ -171,30 +171,33 @@ class Gem::SpecFetcher
# Suggests gems based on the supplied +gem_name+. Returns an array of
# alternative gem names.
- def suggest_gems_from_name(gem_name, type = :latest)
+ def suggest_gems_from_name(gem_name, type = :latest, num_results = 5)
gem_name = gem_name.downcase.tr('_-', '')
max = gem_name.size / 2
names = available_specs(type).first.values.flatten(1)
matches = names.map do |n|
next unless n.match_platform?
-
- distance = levenshtein_distance gem_name, n.name.downcase.tr('_-', '')
-
- next if distance >= max
-
- return [n.name] if distance == 0
-
- [n.name, distance]
+ [n.name, 0] if n.name.downcase.tr('_-', '').include?(gem_name)
end.compact
+ if matches.length < num_results
+ matches += names.map do |n|
+ next unless n.match_platform?
+ distance = levenshtein_distance gem_name, n.name.downcase.tr('_-', '')
+ next if distance >= max
+ return [n.name] if distance == 0
+ [n.name, distance]
+ end.compact
+ end
+
matches = if matches.empty? && type != :prerelease
suggest_gems_from_name gem_name, :prerelease
else
matches.uniq.sort_by { |name, dist| dist }
end
- matches.first(5).map { |name, dist| name }
+ matches.map { |name, dist| name }.uniq.first(num_results)
end
##
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index ad43a63e80..3181303c30 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -790,16 +790,6 @@ class Gem::Specification < Gem::BasicSpecification
end
private_class_method :map_stubs
- def self.uniq_by(list, &block) # :nodoc:
- list.uniq(&block)
- end
- private_class_method :uniq_by
-
- def self.sort_by!(list, &block)
- list.sort_by!(&block)
- end
- private_class_method :sort_by!
-
def self.each_spec(dirs) # :nodoc:
each_gemspec(dirs) do |path|
spec = self.load path
@@ -814,7 +804,7 @@ class Gem::Specification < Gem::BasicSpecification
@@stubs ||= begin
pattern = "*.gemspec"
stubs = Gem.loaded_specs.values + installed_stubs(dirs, pattern) + default_stubs(pattern)
- stubs = uniq_by(stubs) { |stub| stub.full_name }
+ stubs = stubs.uniq { |stub| stub.full_name }
_resort!(stubs)
@@stubs_by_name = stubs.select { |s| Gem::Platform.match s.platform }.group_by(&:name)
@@ -847,7 +837,7 @@ class Gem::Specification < Gem::BasicSpecification
stubs = Gem.loaded_specs.values +
installed_stubs(dirs, pattern).select { |s| Gem::Platform.match s.platform } +
default_stubs(pattern)
- stubs = uniq_by(stubs) { |stub| stub.full_name }.group_by(&:name)
+ stubs = stubs.uniq { |stub| stub.full_name }.group_by(&:name)
stubs.each_value { |v| _resort!(v) }
@@stubs_by_name.merge! stubs
diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb
index 691985dcd2..ebfe979a1b 100644
--- a/lib/rubygems/test_case.rb
+++ b/lib/rubygems/test_case.rb
@@ -78,6 +78,20 @@ module Gem
end
end
+require "rubygems/command"
+
+class Gem::Command
+
+ ##
+ # Allows resetting the hash of specific args per command. This method is
+ # available when requiring 'rubygems/test_case'
+
+ def self.specific_extra_args_hash=(value)
+ @specific_extra_args_hash = value
+ end
+
+end
+
##
# RubyGemTestCase provides a variety of methods for testing rubygems and
# gem-related behavior in a sandbox. Through RubyGemTestCase you can install
@@ -1246,10 +1260,7 @@ Also, a list:
end
begin
- require "rbconfig"
- File.join(RbConfig::CONFIG["bindir"],
- RbConfig::CONFIG["ruby_install_name"] +
- RbConfig::CONFIG["EXEEXT"])
+ Gem.ruby
rescue LoadError
"ruby"
end
diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb
index 1766423429..69893dfb76 100644
--- a/lib/rubygems/uninstaller.rb
+++ b/lib/rubygems/uninstaller.rb
@@ -50,6 +50,7 @@ class Gem::Uninstaller
@gem = gem
@version = options[:version] || Gem::Requirement.default
@gem_home = File.realpath(options[:install_dir] || Gem.dir)
+ @plugins_dir = Gem.plugindir(@gem_home)
@force_executables = options[:executables]
@force_all = options[:all]
@force_ignore = options[:ignore]
@@ -281,7 +282,7 @@ class Gem::Uninstaller
def remove_plugins(spec) # :nodoc:
return if spec.plugins.empty?
- remove_plugins_for(spec)
+ remove_plugins_for(spec, @plugins_dir)
end
##
@@ -291,7 +292,7 @@ class Gem::Uninstaller
latest = Gem::Specification.latest_spec_for(@spec.name)
return if latest.nil?
- regenerate_plugins_for(latest)
+ regenerate_plugins_for(latest, @plugins_dir)
end
##