mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Sync rubygems with current master (#2889)
This commit is contained in:
parent
930b012ad9
commit
96064e6f1c
Notes:
git
2020-03-24 15:39:48 +09:00
Merged-By: hsbt <hsbt@ruby-lang.org>
33 changed files with 434 additions and 559 deletions
|
@ -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
|
||||
|
@ -316,6 +318,13 @@ module Gem
|
|||
Gem.default_bindir
|
||||
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
|
||||
|
@ -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.
|
||||
#
|
||||
# If it is not set as an environment variable already, this also sets it.
|
||||
# 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 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
|
||||
|
||||
Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc.freeze
|
||||
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
|
||||
|
||||
##
|
||||
# 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
end
|
||||
rescue SecurityError
|
||||
RUBYGEMS_ACTIVATION_MONITOR.exit
|
||||
raise
|
||||
end
|
||||
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
|
||||
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
@ -106,27 +104,6 @@ class Gem::DependencyInstaller
|
|||
@errors = []
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -46,11 +46,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
|
||||
|
||||
|
@ -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]
|
||||
|
@ -889,6 +881,13 @@ TEXT
|
|||
gem_dir.to_s
|
||||
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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
##
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
##
|
||||
|
|
|
@ -1016,16 +1016,16 @@ class TestGem < Gem::TestCase
|
|||
end
|
||||
|
||||
def test_self_ruby_escaping_spaces_in_path
|
||||
with_bindir_and_exeext("C:/Ruby 1.8/bin", ".exe") do
|
||||
ruby_install_name "ruby" do
|
||||
with_clean_path_to_ruby do
|
||||
with_rb_config_ruby("C:/Ruby 1.8/bin/ruby.exe") do
|
||||
assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_self_ruby_path_without_spaces
|
||||
with_bindir_and_exeext("C:/Ruby18/bin", ".exe") do
|
||||
ruby_install_name "ruby" do
|
||||
with_clean_path_to_ruby do
|
||||
with_rb_config_ruby("C:/Ruby18/bin/ruby.exe") do
|
||||
assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby
|
||||
end
|
||||
end
|
||||
|
@ -1906,6 +1906,24 @@ You may need to `gem install -g` to install missing gems
|
|||
assert platform_defaults.is_a? Hash
|
||||
end
|
||||
|
||||
# Ensure that `Gem.source_date_epoch` is consistent even if
|
||||
# $SOURCE_DATE_EPOCH has not been set.
|
||||
def test_default_source_date_epoch_doesnt_change
|
||||
old_epoch = ENV['SOURCE_DATE_EPOCH']
|
||||
ENV['SOURCE_DATE_EPOCH'] = nil
|
||||
|
||||
# Unfortunately, there is no real way to test this aside from waiting
|
||||
# enough for `Time.now.to_i` to change -- which is a whole second.
|
||||
#
|
||||
# Fortunately, we only need to do this once.
|
||||
a = Gem.source_date_epoch
|
||||
sleep 1
|
||||
b = Gem.source_date_epoch
|
||||
assert_equal a, b
|
||||
ensure
|
||||
ENV['SOURCE_DATE_EPOCH'] = old_epoch
|
||||
end
|
||||
|
||||
def ruby_install_name(name)
|
||||
with_clean_path_to_ruby do
|
||||
orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name']
|
||||
|
@ -1923,11 +1941,24 @@ You may need to `gem install -g` to install missing gems
|
|||
end
|
||||
end
|
||||
|
||||
def with_bindir_and_exeext(bindir, exeext)
|
||||
bindir(bindir) do
|
||||
exeext(exeext) do
|
||||
yield
|
||||
end
|
||||
def with_rb_config_ruby(path)
|
||||
rb_config_singleton_class = class << RbConfig; self; end
|
||||
orig_path = RbConfig.ruby
|
||||
|
||||
redefine_method(rb_config_singleton_class, :ruby, path)
|
||||
|
||||
yield
|
||||
ensure
|
||||
redefine_method(rb_config_singleton_class, :ruby, orig_path)
|
||||
end
|
||||
|
||||
def redefine_method(base, method, new_result)
|
||||
if RUBY_VERSION >= "2.5"
|
||||
base.alias_method(method, method)
|
||||
base.define_method(method) { new_result }
|
||||
else
|
||||
base.send(:alias_method, method, method)
|
||||
base.send(:define_method, method) { new_result }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -78,6 +78,23 @@ class TestGemBundlerVersionFinder < Gem::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_deleted_directory
|
||||
skip "Cannot perform this test on windows" if win_platform?
|
||||
require "tmpdir"
|
||||
|
||||
orig_dir = Dir.pwd
|
||||
|
||||
begin
|
||||
Dir.mktmpdir("some_dir") do |dir|
|
||||
Dir.chdir(dir)
|
||||
end
|
||||
ensure
|
||||
Dir.chdir(orig_dir)
|
||||
end
|
||||
|
||||
assert_nil bvf.bundler_version_with_reason
|
||||
end
|
||||
|
||||
def test_compatible
|
||||
assert bvf.compatible?(util_spec("foo"))
|
||||
assert bvf.compatible?(util_spec("bundler", 1.1))
|
||||
|
|
|
@ -105,6 +105,22 @@ class TestGemCommandsContentsCommand < Gem::TestCase
|
|||
assert_empty @ui.error
|
||||
end
|
||||
|
||||
def test_execute_missing_version
|
||||
@cmd.options[:args] = %w[foo]
|
||||
@cmd.options[:version] = Gem::Requirement.new '= 2'
|
||||
|
||||
gem 'foo', 1
|
||||
|
||||
assert_raises Gem::MockGemUi::TermError do
|
||||
use_ui @ui do
|
||||
@cmd.execute
|
||||
end
|
||||
end
|
||||
|
||||
assert_match "Unable to find gem 'foo'", @ui.output
|
||||
assert_empty @ui.error
|
||||
end
|
||||
|
||||
def test_execute_missing_multiple
|
||||
@cmd.options[:args] = %w[foo bar]
|
||||
|
||||
|
@ -152,6 +168,23 @@ class TestGemCommandsContentsCommand < Gem::TestCase
|
|||
assert_equal "", @ui.error
|
||||
end
|
||||
|
||||
def test_execute_show_install_dir_latest_version
|
||||
@cmd.options[:args] = %w[foo]
|
||||
@cmd.options[:show_install_dir] = true
|
||||
|
||||
gem 'foo', 1
|
||||
gem 'foo', 2
|
||||
|
||||
use_ui @ui do
|
||||
@cmd.execute
|
||||
end
|
||||
|
||||
expected = File.join @gemhome, 'gems', 'foo-2'
|
||||
|
||||
assert_equal "#{expected}\n", @ui.output
|
||||
assert_equal "", @ui.error
|
||||
end
|
||||
|
||||
def test_execute_show_install_dir_version
|
||||
@cmd.options[:args] = %w[foo]
|
||||
@cmd.options[:show_install_dir] = true
|
||||
|
|
|
@ -160,9 +160,11 @@ class TestGemCommandsPristineCommand < Gem::TestCase
|
|||
|
||||
ruby_exec = sprintf Gem.default_exec_format, 'ruby'
|
||||
|
||||
bin_env = win_platform? ? "" : %w(/usr/bin/env /bin/env).find {|f| File.executable?(f) }
|
||||
|
||||
assert_match %r%\A#!\s*#{bin_env} #{ruby_exec}%, File.read(gem_exec)
|
||||
if win_platform?
|
||||
assert_match %r%\A#!\s*#{ruby_exec}%, File.read(gem_exec)
|
||||
else
|
||||
assert_match %r%\A#!\s*/usr/bin/env #{ruby_exec}%, File.read(gem_exec)
|
||||
end
|
||||
end
|
||||
|
||||
def test_execute_extensions_explicit
|
||||
|
|
|
@ -107,7 +107,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
|||
end
|
||||
install_gem gem
|
||||
|
||||
File.join Gem.plugins_dir, "#{name}_plugin.rb"
|
||||
File.join Gem.plugindir, "#{name}_plugin.rb"
|
||||
end
|
||||
|
||||
def test_execute_regenerate_binstubs
|
||||
|
@ -160,6 +160,18 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
|||
assert_equal "I changed it!\n", File.read(gem_plugin_path)
|
||||
end
|
||||
|
||||
def test_execute_regenerate_plugins_creates_plugins_dir_if_not_there
|
||||
gem_plugin_path = gem_install_with_plugin 'a'
|
||||
|
||||
# Simulate gem installed with an older rubygems without a plugins layout
|
||||
FileUtils.rm_rf Gem.plugindir
|
||||
|
||||
@cmd.options[:document] = []
|
||||
@cmd.execute
|
||||
|
||||
assert_match %r{\Arequire}, File.read(gem_plugin_path)
|
||||
end
|
||||
|
||||
def test_execute_informs_about_installed_executables
|
||||
use_ui @ui do
|
||||
@cmd.execute
|
||||
|
@ -184,11 +196,15 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
|||
|
||||
ruby_exec = sprintf Gem.default_exec_format, 'ruby'
|
||||
|
||||
bin_env = win_platform? ? "" : %w(/usr/bin/env /bin/env).find {|f| File.executable?(f) }
|
||||
|
||||
assert_match %r%\A#!#{bin_env}\s*#{ruby_exec}%, File.read(default_gem_bin_path)
|
||||
assert_match %r%\A#!#{bin_env}\s*#{ruby_exec}%, File.read(default_bundle_bin_path)
|
||||
assert_match %r%\A#!#{bin_env}\s*#{ruby_exec}%, File.read(gem_bin_path)
|
||||
if Gem.win_platform?
|
||||
assert_match %r%\A#!\s*#{ruby_exec}%, File.read(default_gem_bin_path)
|
||||
assert_match %r%\A#!\s*#{ruby_exec}%, File.read(default_bundle_bin_path)
|
||||
assert_match %r%\A#!\s*#{ruby_exec}%, File.read(gem_bin_path)
|
||||
else
|
||||
assert_match %r%\A#!/usr/bin/env #{ruby_exec}%, File.read(default_gem_bin_path)
|
||||
assert_match %r%\A#!/usr/bin/env #{ruby_exec}%, File.read(default_bundle_bin_path)
|
||||
assert_match %r%\A#!/usr/bin/env #{ruby_exec}%, File.read(gem_bin_path)
|
||||
end
|
||||
end
|
||||
|
||||
def test_pem_files_in
|
||||
|
|
|
@ -169,12 +169,12 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
|
|||
@cmd.options[:args] = []
|
||||
@cmd.options[:system] = "3.1"
|
||||
|
||||
FileUtils.mkdir_p Gem.plugins_dir
|
||||
write_file File.join(Gem.plugins_dir, 'a_plugin.rb')
|
||||
FileUtils.mkdir_p Gem.plugindir
|
||||
write_file File.join(Gem.plugindir, 'a_plugin.rb')
|
||||
|
||||
@cmd.execute
|
||||
|
||||
refute_path_exists Gem.plugins_dir, "Plugins folder not removed when updating rubygems to pre-3.2"
|
||||
refute_path_exists Gem.plugindir, "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
|
||||
|
@ -187,13 +187,13 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
|
|||
@cmd.options[:args] = []
|
||||
@cmd.options[:system] = "3.2"
|
||||
|
||||
FileUtils.mkdir_p Gem.plugins_dir
|
||||
plugin_file = File.join(Gem.plugins_dir, 'a_plugin.rb')
|
||||
FileUtils.mkdir_p Gem.plugindir
|
||||
plugin_file = File.join(Gem.plugindir, '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 Gem.plugindir, "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
|
||||
|
||||
|
|
|
@ -48,69 +48,6 @@ class TestGemDependencyInstaller < Gem::TestCase
|
|||
util_reset_gems
|
||||
end
|
||||
|
||||
def test_available_set_for_name
|
||||
util_setup_gems
|
||||
p1a, = util_gem 'a', '10.a'
|
||||
util_setup_spec_fetcher p1a, @a1, @a1_pre
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
|
||||
available = Gem::Deprecate.skip_during do
|
||||
inst.available_set_for 'a', Gem::Requirement.default
|
||||
end
|
||||
|
||||
assert_equal %w[a-1], available.set.map { |s| s.spec.full_name }
|
||||
end
|
||||
|
||||
def test_available_set_for_name_prerelease
|
||||
util_setup_gems
|
||||
p1a, = util_gem 'a', '10.a'
|
||||
util_setup_spec_fetcher p1a, @a1, @a1_pre
|
||||
|
||||
inst = Gem::DependencyInstaller.new :prerelease => true
|
||||
|
||||
available = Gem::Deprecate.skip_during do
|
||||
inst.available_set_for 'a', Gem::Requirement.default
|
||||
end
|
||||
|
||||
assert_equal %w[a-10.a],
|
||||
available.sorted.map { |s| s.spec.full_name }
|
||||
end
|
||||
|
||||
def test_available_set_for_dep
|
||||
util_setup_gems
|
||||
p1a, = util_gem 'a', '10.a'
|
||||
util_setup_spec_fetcher p1a, @a1, @a1_pre
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
|
||||
dep = Gem::Dependency.new 'a', Gem::Requirement.default
|
||||
|
||||
available = Gem::Deprecate.skip_during do
|
||||
inst.available_set_for dep, Gem::Requirement.default
|
||||
end
|
||||
|
||||
assert_equal %w[a-1], available.set.map { |s| s.spec.full_name }
|
||||
end
|
||||
|
||||
def test_available_set_for_dep_prerelease
|
||||
util_setup_gems
|
||||
p1a, = util_gem 'a', '10.a'
|
||||
util_setup_spec_fetcher p1a, @a1, @a1_pre
|
||||
|
||||
inst = Gem::DependencyInstaller.new :prerelease => true
|
||||
|
||||
dep = Gem::Dependency.new 'a', Gem::Requirement.default
|
||||
dep.prerelease = true
|
||||
|
||||
available = Gem::Deprecate.skip_during do
|
||||
inst.available_set_for dep, Gem::Requirement.default
|
||||
end
|
||||
|
||||
assert_equal %w[a-10.a],
|
||||
available.sorted.map { |s| s.spec.full_name }
|
||||
end
|
||||
|
||||
def test_install
|
||||
util_setup_gems
|
||||
|
||||
|
@ -974,191 +911,6 @@ class TestGemDependencyInstaller < Gem::TestCase
|
|||
assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name }
|
||||
end
|
||||
|
||||
def test_find_gems_gems_with_sources
|
||||
util_setup_gems
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
dep = Gem::Dependency.new 'b', '>= 0'
|
||||
|
||||
Gem::Specification.reset
|
||||
|
||||
set = Gem::Deprecate.skip_during do
|
||||
inst.find_gems_with_sources(dep)
|
||||
end
|
||||
|
||||
assert_kind_of Gem::AvailableSet, set
|
||||
|
||||
s = set.set.first
|
||||
|
||||
assert_equal @b1, s.spec
|
||||
assert_equal Gem::Source.new(@gem_repo), s.source
|
||||
end
|
||||
|
||||
def test_find_spec_by_name_and_version_wildcard
|
||||
util_gem 'a', 1
|
||||
FileUtils.mv 'gems/a-1.gem', @tempdir
|
||||
|
||||
FileUtils.touch 'rdoc.gem'
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
|
||||
available = Gem::Deprecate.skip_during do
|
||||
inst.find_spec_by_name_and_version('*.gem')
|
||||
end
|
||||
|
||||
assert_equal %w[a-1], available.each_spec.map { |spec| spec.full_name }
|
||||
end
|
||||
|
||||
def test_find_spec_by_name_and_version_wildcard_bad_gem
|
||||
FileUtils.touch 'rdoc.gem'
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
|
||||
assert_raises Gem::Package::FormatError do
|
||||
Gem::Deprecate.skip_during do
|
||||
inst.find_spec_by_name_and_version '*.gem'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_find_spec_by_name_and_version_bad_gem
|
||||
FileUtils.touch 'rdoc.gem'
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
|
||||
e = assert_raises Gem::Package::FormatError do
|
||||
Gem::Deprecate.skip_during do
|
||||
inst.find_spec_by_name_and_version 'rdoc.gem'
|
||||
end
|
||||
end
|
||||
|
||||
full_path = File.join @tempdir, 'rdoc.gem'
|
||||
assert_equal "package metadata is missing in #{full_path}", e.message
|
||||
end
|
||||
|
||||
def test_find_spec_by_name_and_version_directory
|
||||
Dir.mkdir 'rdoc'
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
|
||||
e = assert_raises Gem::SpecificGemNotFoundException do
|
||||
Gem::Deprecate.skip_during do
|
||||
inst.find_spec_by_name_and_version 'rdoc'
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal "Could not find a valid gem 'rdoc' (>= 0) " +
|
||||
"locally or in a repository",
|
||||
e.message
|
||||
end
|
||||
|
||||
def test_find_spec_by_name_and_version_file
|
||||
FileUtils.touch 'rdoc'
|
||||
|
||||
inst = Gem::DependencyInstaller.new
|
||||
|
||||
e = assert_raises Gem::SpecificGemNotFoundException do
|
||||
Gem::Deprecate.skip_during do
|
||||
inst.find_spec_by_name_and_version 'rdoc'
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal "Could not find a valid gem 'rdoc' (>= 0) " +
|
||||
"locally or in a repository",
|
||||
e.message
|
||||
end
|
||||
|
||||
def test_find_gems_with_sources_local
|
||||
util_setup_gems
|
||||
|
||||
FileUtils.mv @a1_gem, @tempdir
|
||||
inst = Gem::DependencyInstaller.new
|
||||
dep = Gem::Dependency.new 'a', '>= 0'
|
||||
set = nil
|
||||
|
||||
Dir.chdir @tempdir do
|
||||
set = Gem::Deprecate.skip_during do
|
||||
inst.find_gems_with_sources dep
|
||||
end
|
||||
end
|
||||
|
||||
gems = set.sorted
|
||||
|
||||
assert_equal 2, gems.length
|
||||
|
||||
remote, local = gems
|
||||
|
||||
assert_equal 'a-1', local.spec.full_name, 'local spec'
|
||||
assert_equal File.join(@tempdir, @a1.file_name),
|
||||
local.source.download(local.spec), 'local path'
|
||||
|
||||
assert_equal 'a-1', remote.spec.full_name, 'remote spec'
|
||||
assert_equal Gem::Source.new(@gem_repo), remote.source, 'remote path'
|
||||
end
|
||||
|
||||
def test_find_gems_with_sources_prerelease
|
||||
util_setup_gems
|
||||
|
||||
installer = Gem::DependencyInstaller.new
|
||||
|
||||
dependency = Gem::Dependency.new('a', Gem::Requirement.default)
|
||||
|
||||
set = Gem::Deprecate.skip_during do
|
||||
installer.find_gems_with_sources(dependency)
|
||||
end
|
||||
|
||||
releases = set.all_specs
|
||||
|
||||
assert releases.any? { |s| s.name == 'a' and s.version.to_s == '1' }
|
||||
refute releases.any? { |s| s.name == 'a' and s.version.to_s == '1.a' }
|
||||
|
||||
dependency.prerelease = true
|
||||
|
||||
set = Gem::Deprecate.skip_during do
|
||||
installer.find_gems_with_sources(dependency)
|
||||
end
|
||||
|
||||
prereleases = set.all_specs
|
||||
|
||||
assert_equal [@a1_pre, @a1], prereleases
|
||||
end
|
||||
|
||||
def test_find_gems_with_sources_with_best_only_and_platform
|
||||
util_setup_gems
|
||||
a1_x86_mingw32, = util_gem 'a', '1' do |s|
|
||||
s.platform = 'x86-mingw32'
|
||||
end
|
||||
util_setup_spec_fetcher @a1, a1_x86_mingw32
|
||||
Gem.platforms << Gem::Platform.new('x86-mingw32')
|
||||
|
||||
installer = Gem::DependencyInstaller.new
|
||||
|
||||
dependency = Gem::Dependency.new('a', Gem::Requirement.default)
|
||||
|
||||
set = Gem::Deprecate.skip_during do
|
||||
installer.find_gems_with_sources(dependency, true)
|
||||
end
|
||||
|
||||
releases = set.all_specs
|
||||
|
||||
assert_equal [a1_x86_mingw32], releases
|
||||
end
|
||||
|
||||
def test_find_gems_with_sources_with_bad_source
|
||||
Gem.sources.replace ["http://not-there.nothing"]
|
||||
|
||||
installer = Gem::DependencyInstaller.new
|
||||
|
||||
dep = Gem::Dependency.new('a')
|
||||
|
||||
out = Gem::Deprecate.skip_during do
|
||||
installer.find_gems_with_sources(dep)
|
||||
end
|
||||
|
||||
assert out.empty?
|
||||
assert_kind_of Gem::SourceFetchProblem, installer.errors.first
|
||||
end
|
||||
|
||||
def test_resolve_dependencies
|
||||
util_setup_gems
|
||||
|
||||
|
|
|
@ -158,8 +158,8 @@ This directory does not appear to be a RubyGems repository, skipping
|
|||
|
||||
Gem.use_paths @gemhome.to_s
|
||||
|
||||
FileUtils.mkdir_p Gem.plugins_dir
|
||||
bad_plugin = File.join(Gem.plugins_dir, "a_badly_named_file.rb")
|
||||
FileUtils.mkdir_p Gem.plugindir
|
||||
bad_plugin = File.join(Gem.plugindir, "a_badly_named_file.rb")
|
||||
write_file bad_plugin
|
||||
|
||||
doctor = Gem::Doctor.new @gemhome
|
||||
|
|
|
@ -8,6 +8,7 @@ class TestGemGemRunner < Gem::TestCase
|
|||
|
||||
require 'rubygems/command'
|
||||
@orig_args = Gem::Command.build_args
|
||||
@orig_specific_extra_args = Gem::Command.specific_extra_args_hash.dup
|
||||
|
||||
require 'rubygems/gem_runner'
|
||||
@runner = Gem::GemRunner.new
|
||||
|
@ -17,6 +18,7 @@ class TestGemGemRunner < Gem::TestCase
|
|||
super
|
||||
|
||||
Gem::Command.build_args = @orig_args
|
||||
Gem::Command.specific_extra_args_hash = @orig_specific_extra_args
|
||||
end
|
||||
|
||||
def test_do_configuration
|
||||
|
|
|
@ -757,7 +757,7 @@ gem 'other', version
|
|||
installer.install
|
||||
end
|
||||
|
||||
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
|
||||
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
||||
|
||||
FileUtils.rm plugin_path
|
||||
|
||||
|
@ -766,6 +766,25 @@ gem 'other', version
|
|||
assert File.exist?(plugin_path), 'plugin not written'
|
||||
end
|
||||
|
||||
def test_generate_plugins_with_install_dir
|
||||
spec = quick_gem 'a' 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
|
||||
|
||||
util_build_gem spec
|
||||
|
||||
plugin_path = File.join "#{@gemhome}2", 'plugins', 'a_plugin.rb'
|
||||
installer = util_installer spec, "#{@gemhome}2"
|
||||
|
||||
assert_equal spec, installer.install
|
||||
|
||||
assert File.exist?(plugin_path), 'plugin not written to install_dir'
|
||||
end
|
||||
|
||||
def test_keeps_plugins_up_to_date
|
||||
# NOTE: version a-2 is already installed by setup hooks
|
||||
|
||||
|
@ -779,7 +798,7 @@ gem 'other', version
|
|||
spec.files += %w[lib/rubygems_plugin.rb]
|
||||
end.install
|
||||
|
||||
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
|
||||
plugin_path = File.join Gem.plugindir, '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|
|
||||
|
@ -787,7 +806,7 @@ gem 'other', version
|
|||
spec.files += %w[lib/rubygems_plugin.rb]
|
||||
end.install
|
||||
|
||||
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
|
||||
plugin_path = File.join Gem.plugindir, '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'
|
||||
|
||||
|
@ -796,7 +815,7 @@ gem 'other', version
|
|||
spec.files += %w[lib/rubygems_plugin.rb]
|
||||
end.install
|
||||
|
||||
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
|
||||
plugin_path = File.join Gem.plugindir, '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'
|
||||
|
||||
|
@ -808,6 +827,17 @@ gem 'other', version
|
|||
end
|
||||
end
|
||||
|
||||
def test_generates_plugins_dir_under_install_dir_if_not_there
|
||||
Gem.use_paths "#{@gemhome}2" # Set GEM_HOME to an uninitialized repo
|
||||
|
||||
@spec = util_spec 'a'
|
||||
|
||||
path = Gem::Package.build @spec
|
||||
|
||||
installer = Gem::Installer.at path, :install_dir => "#{@gemhome}3"
|
||||
assert_equal @spec, installer.install
|
||||
end
|
||||
|
||||
def test_initialize
|
||||
spec = util_spec 'a' do |s|
|
||||
s.platform = Gem::Platform.new 'mswin32'
|
||||
|
@ -1794,9 +1824,9 @@ gem 'other', version
|
|||
|
||||
shebang = installer.shebang 'executable'
|
||||
|
||||
bin_env = get_bin_env
|
||||
env_shebang = "/usr/bin/env" unless Gem.win_platform?
|
||||
|
||||
assert_equal("#!#{bin_env} #{RbConfig::CONFIG['ruby_install_name']}",
|
||||
assert_equal("#!#{env_shebang} #{RbConfig::CONFIG['ruby_install_name']}",
|
||||
shebang)
|
||||
end
|
||||
|
||||
|
@ -1875,18 +1905,10 @@ gem 'other', version
|
|||
assert_equal "#!test", shebang
|
||||
end
|
||||
|
||||
def get_bin_env
|
||||
if win_platform?
|
||||
""
|
||||
else
|
||||
%w(/usr/bin/env /bin/env).find {|f| File.executable?(f) }
|
||||
end
|
||||
end
|
||||
|
||||
def test_shebang_custom_with_expands
|
||||
installer = setup_base_installer
|
||||
|
||||
bin_env = get_bin_env
|
||||
bin_env = win_platform? ? '' : '/usr/bin/env'
|
||||
conf = Gem::ConfigFile.new []
|
||||
conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec 4 $name'
|
||||
|
||||
|
@ -1902,7 +1924,7 @@ gem 'other', version
|
|||
def test_shebang_custom_with_expands_and_arguments
|
||||
installer = setup_base_installer
|
||||
|
||||
bin_env = get_bin_env
|
||||
bin_env = win_platform? ? '' : '/usr/bin/env'
|
||||
conf = Gem::ConfigFile.new []
|
||||
conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec'
|
||||
|
||||
|
@ -2130,6 +2152,16 @@ gem 'other', version
|
|||
assert_kind_of(Gem::Package, installer.package)
|
||||
end
|
||||
|
||||
def test_gem_attribute
|
||||
gem = quick_gem 'c' do |spec|
|
||||
util_make_exec spec, '#!/usr/bin/ruby', 'exe'
|
||||
end
|
||||
|
||||
installer = util_installer(gem, @gemhome)
|
||||
assert_respond_to(installer, :gem)
|
||||
assert_kind_of(String, installer.gem)
|
||||
end
|
||||
|
||||
def old_ruby_required(requirement)
|
||||
spec = util_spec 'old_ruby_required', '1' do |s|
|
||||
s.required_ruby_version = requirement
|
||||
|
|
|
@ -106,7 +106,7 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|||
assert_equal expected, YAML.load(checksums)
|
||||
end
|
||||
|
||||
def test_build_time_source_date_epoch
|
||||
def test_build_time_uses_source_date_epoch
|
||||
epoch = ENV["SOURCE_DATE_EPOCH"]
|
||||
ENV["SOURCE_DATE_EPOCH"] = "123456789"
|
||||
|
||||
|
@ -124,12 +124,10 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|||
ENV["SOURCE_DATE_EPOCH"] = epoch
|
||||
end
|
||||
|
||||
def test_build_time_source_date_epoch_automatically_set
|
||||
def test_build_time_without_source_date_epoch
|
||||
epoch = ENV["SOURCE_DATE_EPOCH"]
|
||||
ENV["SOURCE_DATE_EPOCH"] = nil
|
||||
|
||||
start_time = Time.now.utc.to_i
|
||||
|
||||
spec = Gem::Specification.new 'build', '1'
|
||||
spec.summary = 'build'
|
||||
spec.authors = 'build'
|
||||
|
@ -138,14 +136,11 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|||
|
||||
package = Gem::Package.new spec.file_name
|
||||
|
||||
end_time = Time.now.utc.to_i
|
||||
|
||||
assert_kind_of Time, package.build_time
|
||||
|
||||
build_time = package.build_time.to_i
|
||||
|
||||
assert_operator(start_time, :<=, build_time)
|
||||
assert_operator(build_time, :<=, end_time)
|
||||
assert_equal Gem.source_date_epoch.to_i, build_time
|
||||
ensure
|
||||
ENV["SOURCE_DATE_EPOCH"] = epoch
|
||||
end
|
||||
|
|
|
@ -8,6 +8,11 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
|
|||
def setup
|
||||
super
|
||||
|
||||
# Setting `@default_source_date_epoch` to `nil` effectively resets the
|
||||
# value used for `Gem.source_date_epoch` whenever `$SOURCE_DATE_EPOCH`
|
||||
# is not set.
|
||||
Gem.instance_variable_set(:'@default_source_date_epoch', nil)
|
||||
|
||||
@data = 'abcde12345'
|
||||
@io = TempIO.new
|
||||
@tar_writer = Gem::Package::TarWriter.new @io
|
||||
|
|
|
@ -897,8 +897,6 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
|
|||
end
|
||||
|
||||
def test_ssl_client_cert_auth_connection
|
||||
skip 'openssl in jruby fails' if java_platform?
|
||||
|
||||
ssl_server = self.class.start_ssl_server({
|
||||
:SSLVerifyClient =>
|
||||
OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT})
|
||||
|
|
|
@ -173,10 +173,19 @@ class TestGemSpecFetcher < Gem::TestCase
|
|||
spec_fetcher do|fetcher|
|
||||
fetcher.spec 'example', 1
|
||||
fetcher.spec 'other-example', 1
|
||||
fetcher.spec 'examp', 1
|
||||
end
|
||||
|
||||
suggestions = @sf.suggest_gems_from_name('examplw')
|
||||
suggestions = @sf.suggest_gems_from_name('examplw', type = :latest, num_results = 1)
|
||||
assert_equal ['example'], suggestions
|
||||
|
||||
suggestions = @sf.suggest_gems_from_name('other')
|
||||
assert_equal ['other-example'], suggestions
|
||||
|
||||
suggestions = @sf.suggest_gems_from_name('exam')
|
||||
assert suggestions.any? { ['examp'] }
|
||||
assert suggestions.any? { ['example'] }
|
||||
assert suggestions.any? { ['other-example'] }
|
||||
end
|
||||
|
||||
def test_suggest_gems_from_name_prerelease
|
||||
|
|
|
@ -83,6 +83,11 @@ end
|
|||
def setup
|
||||
super
|
||||
|
||||
# Setting `@default_source_date_epoch` to `nil` effectively resets the
|
||||
# value used for `Gem.source_date_epoch` whenever `$SOURCE_DATE_EPOCH`
|
||||
# is not set.
|
||||
Gem.instance_variable_set(:'@default_source_date_epoch', nil)
|
||||
|
||||
@a1 = util_spec 'a', '1' do |s|
|
||||
s.executable = 'exec'
|
||||
s.test_file = 'test/suite.rb'
|
||||
|
|
|
@ -178,7 +178,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
|
|||
|
||||
Gem::Installer.at(Gem::Package.build(@spec)).install
|
||||
|
||||
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
|
||||
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
||||
assert File.exist?(plugin_path), 'plugin not written'
|
||||
|
||||
Gem::Uninstaller.new(nil).remove_plugins @spec
|
||||
|
@ -186,6 +186,24 @@ class TestGemUninstaller < Gem::InstallerTestCase
|
|||
refute File.exist?(plugin_path), 'plugin not removed'
|
||||
end
|
||||
|
||||
def test_remove_plugins_with_install_dir
|
||||
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.plugindir, 'a_plugin.rb'
|
||||
assert File.exist?(plugin_path), 'plugin not written'
|
||||
|
||||
Dir.mkdir "#{@gemhome}2"
|
||||
Gem::Uninstaller.new(nil, :install_dir => "#{@gemhome}2").remove_plugins @spec
|
||||
|
||||
assert File.exist?(plugin_path), 'plugin unintentionally removed'
|
||||
end
|
||||
|
||||
def test_regenerate_plugins_for
|
||||
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
|
||||
io.write "puts __FILE__"
|
||||
|
@ -195,11 +213,11 @@ class TestGemUninstaller < Gem::InstallerTestCase
|
|||
|
||||
Gem::Installer.at(Gem::Package.build(@spec)).install
|
||||
|
||||
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
|
||||
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
||||
assert File.exist?(plugin_path), 'plugin not written'
|
||||
|
||||
FileUtils.rm plugin_path
|
||||
Gem::Uninstaller.new(nil).regenerate_plugins_for @spec
|
||||
Gem::Uninstaller.new(nil).regenerate_plugins_for @spec, Gem.plugindir
|
||||
|
||||
assert File.exist?(plugin_path), 'plugin not regenerated'
|
||||
end
|
||||
|
@ -611,7 +629,7 @@ create_makefile '#{@spec.name}'
|
|||
io.write "puts __FILE__"
|
||||
end
|
||||
|
||||
plugin_path = File.join Gem.plugins_dir, 'a_plugin.rb'
|
||||
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
||||
|
||||
@spec.version = '1'
|
||||
Gem::Installer.at(Gem::Package.build(@spec)).install
|
||||
|
|
|
@ -120,6 +120,24 @@ class TestGemRequire < Gem::TestCase
|
|||
Object.send :remove_const, :HELLO if Object.const_defined? :HELLO
|
||||
end
|
||||
|
||||
def test_dash_i_respects_default_library_extension_priority
|
||||
skip "extensions don't quite work on jruby" if Gem.java_platform?
|
||||
|
||||
dash_i_ext_arg = util_install_extension_file('a')
|
||||
dash_i_lib_arg = util_install_ruby_file('a')
|
||||
|
||||
lp = $LOAD_PATH.dup
|
||||
|
||||
begin
|
||||
$LOAD_PATH.unshift dash_i_lib_arg
|
||||
$LOAD_PATH.unshift dash_i_ext_arg
|
||||
assert_require 'a'
|
||||
assert_match(/a\.rb$/, $LOADED_FEATURES.last)
|
||||
ensure
|
||||
$LOAD_PATH.replace lp
|
||||
end
|
||||
end
|
||||
|
||||
def test_concurrent_require
|
||||
Object.const_set :FILE_ENTERED_LATCH, Latch.new(2)
|
||||
Object.const_set :FILE_EXIT_LATCH, Latch.new(1)
|
||||
|
@ -518,15 +536,15 @@ class TestGemRequire < Gem::TestCase
|
|||
define_method "test_no_other_behavioral_changes_with_#{prefix.tr(".", "_")}warn" do
|
||||
lib = File.realpath("../../../lib", __FILE__)
|
||||
Dir.mktmpdir("warn_test") do |dir|
|
||||
File.write(dir + "/main.rb", "warn({x:1}, {y:2}, [])\n")
|
||||
File.write(dir + "/main.rb", "#{prefix}warn({x:1}, {y:2}, [])\n")
|
||||
_, err = capture_subprocess_io do
|
||||
system(@@ruby, "-w", "-rpp", "--disable=gems", "-I", lib, "-C", dir, "-I.", "main.rb")
|
||||
system(@@ruby, "-w", "--disable=gems", "-I", lib, "-C", dir, "main.rb")
|
||||
end
|
||||
assert_equal("{:x=>1}\n{:y=>2}\n", err)
|
||||
assert_match(/{:x=>1}\n{:y=>2}\n$/, err)
|
||||
_, err = capture_subprocess_io do
|
||||
system(@@ruby, "-w", "-rpp", "--enable=gems", "-I", lib, "-C", dir, "-I.", "main.rb")
|
||||
system(@@ruby, "-w", "--enable=gems", "-I", lib, "-C", dir, "main.rb")
|
||||
end
|
||||
assert_equal("{:x=>1}\n{:y=>2}\n", err)
|
||||
assert_match(/{:x=>1}\n{:y=>2}\n$/, err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -541,4 +559,50 @@ class TestGemRequire < Gem::TestCase
|
|||
$VERBOSE = old_verbose
|
||||
end
|
||||
|
||||
def util_install_extension_file(name)
|
||||
spec = quick_gem name
|
||||
util_build_gem spec
|
||||
|
||||
spec.extensions << "extconf.rb"
|
||||
write_file File.join(@tempdir, "extconf.rb") do |io|
|
||||
io.write <<-RUBY
|
||||
require "mkmf"
|
||||
CONFIG['LDSHARED'] = '$(TOUCH) $@ ||'
|
||||
create_makefile("#{name}")
|
||||
RUBY
|
||||
end
|
||||
|
||||
write_file File.join(@tempdir, "#{name}.c") do |io|
|
||||
io.write <<-C
|
||||
void Init_#{name}() { }
|
||||
C
|
||||
end
|
||||
|
||||
write_file File.join(@tempdir, "depend")
|
||||
|
||||
spec.files += ["extconf.rb", "depend", "#{name}.c"]
|
||||
|
||||
so = File.join(spec.gem_dir, "#{name}.#{RbConfig::CONFIG["DLEXT"]}")
|
||||
refute_path_exists so
|
||||
|
||||
path = Gem::Package.build spec
|
||||
installer = Gem::Installer.at path
|
||||
installer.install
|
||||
assert_path_exists so
|
||||
|
||||
spec.gem_dir
|
||||
end
|
||||
|
||||
def util_install_ruby_file(name)
|
||||
dir_lib = Dir.mktmpdir("test_require_lib", @tempdir)
|
||||
dash_i_lib_arg = File.join dir_lib
|
||||
|
||||
a_rb = File.join dash_i_lib_arg, "#{name}.rb"
|
||||
|
||||
FileUtils.mkdir_p File.dirname a_rb
|
||||
File.open(a_rb, 'w') { |f| f.write "# #{name}.rb" }
|
||||
|
||||
dash_i_lib_arg
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue