summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2019-06-01 12:45:11 +0300
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2019-06-01 13:50:41 +0300
commit56660de3c6df7a4ff8667ef4047d30d0de169935 (patch)
treedd1e526075687b4b24e089cee50eabc21a6143cc /lib
parent560cd5b1f04f30542a294b3d77527d3b12f7cc15 (diff)
Merge rubygems master from upstream.
I picked the commit from 3c469e0da538428a0ddd94f99aa73c32da22e8ba
Diffstat (limited to 'lib')
-rw-r--r--lib/rubygems.rb24
-rw-r--r--lib/rubygems/commands/pristine_command.rb2
-rw-r--r--lib/rubygems/commands/query_command.rb170
-rw-r--r--lib/rubygems/commands/setup_command.rb2
-rw-r--r--lib/rubygems/commands/update_command.rb4
-rw-r--r--lib/rubygems/core_ext/kernel_gem.rb3
-rw-r--r--lib/rubygems/defaults.rb7
-rw-r--r--lib/rubygems/ext/rake_builder.rb2
-rw-r--r--lib/rubygems/installer_test_case.rb116
-rw-r--r--lib/rubygems/package/tar_header.rb13
-rw-r--r--lib/rubygems/remote_fetcher.rb12
-rw-r--r--lib/rubygems/request/connection_pools.rb4
-rw-r--r--lib/rubygems/resolver.rb2
-rw-r--r--lib/rubygems/resolver/activation_request.rb49
-rw-r--r--lib/rubygems/specification.rb18
-rw-r--r--lib/rubygems/test_case.rb243
-rw-r--r--lib/rubygems/test_utilities.rb7
-rw-r--r--lib/rubygems/util.rb54
18 files changed, 290 insertions, 442 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 193e8d3..c013e4b 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -670,6 +670,21 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
index
end
+ ##
+ # Add a list of paths to the $LOAD_PATH at the proper place.
+
+ def self.add_to_load_path(*paths)
+ insert_index = load_path_insert_index
+
+ if insert_index
+ # gem directories must come after -I and ENV['RUBYLIB']
+ $LOAD_PATH.insert(insert_index, *paths)
+ else
+ # we are probably testing in core, -I and RUBYLIB don't apply
+ $LOAD_PATH.unshift(*paths)
+ end
+ end
+
@yaml_loaded = false
##
@@ -1084,6 +1099,13 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
end
##
+ # Is this a java platform?
+
+ def self.java_platform?
+ RUBY_PLATFORM == "java"
+ end
+
+ ##
# Load +plugins+ as Ruby files
def self.load_plugin_files(plugins) # :nodoc:
@@ -1243,7 +1265,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
#
def register_default_spec(spec)
- new_format = Gem.default_gems_use_full_paths? || spec.require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } }
+ new_format = spec.require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } }
if new_format
prefix_group = spec.require_paths.map {|f| f + "/"}.join("|")
diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb
index a25b690..e4628bd 100644
--- a/lib/rubygems/commands/pristine_command.rb
+++ b/lib/rubygems/commands/pristine_command.rb
@@ -104,7 +104,7 @@ extensions will be restored.
end.flatten
end
- specs = specs.select{|spec| RUBY_ENGINE == spec.platform || Gem::Platform.local === spec.platform }
+ specs = specs.select{|spec| RUBY_ENGINE == spec.platform || Gem::Platform.local === spec.platform || spec.platform == Gem::Platform::RUBY }
if specs.to_a.empty?
raise Gem::Exception,
diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb
index 5a42d45..4fb23bc 100644
--- a/lib/rubygems/commands/query_command.rb
+++ b/lib/rubygems/commands/query_command.rb
@@ -78,46 +78,58 @@ is too hard to use.
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 options[:args].to_a.empty? and options[:name].source.empty?
- name = options[:name]
- no_name = true
- elsif !options[:name].source.empty?
- name = Array(options[:name])
+
+ 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
- args = options[:args].to_a
- name = options[:exact] ? args.map{|arg| /\A#{Regexp.escape(arg)}\Z/ } : args.map{|arg| /#{arg}/i }
+ installed = installed?(gem_names.first, options[:version])
+ installed = !installed unless options[:installed]
+
+ say(installed)
+ exit_code = 1 if !installed
end
- prerelease = options[:prerelease]
+ exit_code
+ end
- unless options[:installed].nil?
- if no_name
- alert_error "You must specify a gem name"
- exit_code |= 4
- elsif name.count > 1
- alert_error "You must specify only ONE gem!"
- exit_code |= 4
- else
- installed = installed? name.first, options[:version]
- installed = !installed unless options[:installed]
+ def check_installed_gems?
+ !options[:installed].nil?
+ end
- if installed
- say "true"
- else
- say "false"
- exit_code |= 1
- end
- end
+ def gem_name?
+ !options[:name].source.empty?
+ end
- terminate_interaction exit_code
- end
+ def prerelease
+ options[:prerelease]
+ end
- names = Array(name)
- names.each { |n| show_gems n, prerelease }
+ def show_prereleases?
+ prerelease.nil? || prerelease
end
- private
+ def args
+ options[:args].to_a
+ end
def display_header(type)
if (ui.outs.tty? and Gem.configuration.verbose) or both?
@@ -128,56 +140,57 @@ is too hard to use.
end
#Guts of original execute
- def show_gems(name, prerelease)
- req = Gem::Requirement.default
- # TODO: deprecate for real
+ 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 }
- dep.prerelease = prerelease
+ specs.select! do |s|
+ dep.match?(s.name, s.version, show_prereleases?)
+ end
- if local?
- if prerelease and not both?
- alert_warning "prereleases are always shown locally"
- end
+ spec_tuples = specs.map do |spec|
+ [spec.name_tuple, spec]
+ end
+
+ output_query_results(spec_tuples)
+ end
- display_header 'LOCAL'
+ def show_remote_gems(name)
+ display_header("REMOTE")
- specs = Gem::Specification.find_all do |s|
- s.name =~ name and req =~ s.version
- end
+ fetcher = Gem::SpecFetcher.fetcher
- spec_tuples = specs.map do |spec|
- [spec.name_tuple, spec]
- end
+ 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
+ output_query_results(spec_tuples)
+ end
- if remote?
- display_header 'REMOTE'
-
- fetcher = Gem::SpecFetcher.fetcher
-
- type = if options[:all]
- if options[:prerelease]
- :complete
- else
- :released
- end
- elsif options[:prerelease]
- :prerelease
- else
- :latest
- end
-
- if name.respond_to?(:source) && name.source.empty?
- spec_tuples = fetcher.detect(type) { true }
+ def specs_type
+ if options[:all]
+ if options[:prerelease]
+ :complete
else
- spec_tuples = fetcher.detect(type) do |name_tuple|
- name === name_tuple.name
- end
+ :released
end
-
- output_query_results spec_tuples
+ elsif options[:prerelease]
+ :prerelease
+ else
+ :latest
end
end
@@ -235,7 +248,7 @@ is too hard to use.
name_tuple, spec = detail_tuple
- spec = spec.fetch_spec name_tuple if spec.respond_to? :fetch_spec
+ spec = spec.fetch_spec(name_tuple)if spec.respond_to?(:fetch_spec)
entry << "\n"
@@ -285,8 +298,8 @@ is too hard to use.
entry = [name_tuples.first.name]
- entry_versions entry, name_tuples, platforms, specs
- entry_details entry, detail_tuple, specs, platforms
+ entry_versions(entry, name_tuples, platforms, specs)
+ entry_details(entry, detail_tuple, specs, platforms)
entry.join
end
@@ -337,12 +350,13 @@ is too hard to use.
if platforms.length == 1
title = platforms.values.length == 1 ? 'Platform' : 'Platforms'
- entry << " #{title}: #{platforms.values.sort.join ', '}\n"
+ entry << " #{title}: #{platforms.values.sort.join(', ')}\n"
else
entry << " Platforms:\n"
- platforms.sort_by do |version,|
- version
- end.each do |version, pls|
+
+ 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
diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb
index f5e5236..1754630 100644
--- a/lib/rubygems/commands/setup_command.rb
+++ b/lib/rubygems/commands/setup_command.rb
@@ -429,7 +429,7 @@ By default, this RubyGems will install gem as:
Dir.chdir("bundler") do
built_gem = Gem::Package.build(bundler_spec)
begin
- installer = Gem::Installer.at(built_gem, env_shebang: options[:env_shebang], install_as_default: true, bin_dir: bin_dir, wrappers: true)
+ installer = Gem::Installer.at(built_gem, env_shebang: options[:env_shebang], format_executable: options[:format_executable], install_as_default: true, bin_dir: bin_dir, wrappers: true)
installer.install
ensure
FileUtils.rm_f built_gem
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index 4b18239..e8031a2 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -254,9 +254,7 @@ command to remove old versions.
def update_rubygems_arguments # :nodoc:
args = []
args << '--prefix' << Gem.prefix if Gem.prefix
- # TODO use --document for >= 1.9 , --no-rdoc --no-ri < 1.9
- args << '--no-rdoc' unless options[:document].include? 'rdoc'
- args << '--no-ri' unless options[:document].include? 'ri'
+ args << '--no-document' unless options[:document].include?('rdoc') || options[:document].include?('ri')
args << '--no-format-executable' if options[:no_format_executable]
args << '--previous-version' << Gem::VERSION if
options[:system] == true or
diff --git a/lib/rubygems/core_ext/kernel_gem.rb b/lib/rubygems/core_ext/kernel_gem.rb
index 39b0038..fb3053f 100644
--- a/lib/rubygems/core_ext/kernel_gem.rb
+++ b/lib/rubygems/core_ext/kernel_gem.rb
@@ -7,9 +7,6 @@
module Kernel
- # REFACTOR: This should be pulled out into some kind of hacks file.
- remove_method :gem if 'method' == defined? gem # from gem_prelude.rb on 1.9
-
##
# Use Kernel#gem to activate a specific version of +gem_name+.
#
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index 7aa0480..33b6ab3 100644
--- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb
@@ -148,13 +148,6 @@ module Gem
end
##
- # Whether to expect full paths in default gems - true for non-MRI
- # ruby implementations
- def self.default_gems_use_full_paths?
- ruby_engine != 'ruby'
- end
-
- ##
# Install extensions into lib as well as into the extension directory.
def self.install_extension_in_lib # :nodoc:
diff --git a/lib/rubygems/ext/rake_builder.rb b/lib/rubygems/ext/rake_builder.rb
index 52041a2..077f080 100644
--- a/lib/rubygems/ext/rake_builder.rb
+++ b/lib/rubygems/ext/rake_builder.rb
@@ -20,7 +20,7 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
rake = rake.shellsplit
else
begin
- rake = [Gem.ruby, "-rrubygems", Gem.bin_path('rake', 'rake')]
+ rake = [Gem.ruby, "-I#{File.expand_path("..", __dir__)}", "-rrubygems", Gem.bin_path('rake', 'rake')]
rescue Gem::Exception
rake = [Gem.default_exec_format % 'rake']
end
diff --git a/lib/rubygems/installer_test_case.rb b/lib/rubygems/installer_test_case.rb
index 1c16959..f48466d 100644
--- a/lib/rubygems/installer_test_case.rb
+++ b/lib/rubygems/installer_test_case.rb
@@ -66,44 +66,9 @@ end
class Gem::InstallerTestCase < Gem::TestCase
- ##
- # Creates the following instance variables:
- #
- # @spec::
- # a spec named 'a', intended for regular installs
- # @user_spec::
- # a spec named 'b', intended for user installs
- #
- # @gem::
- # the path to a built gem from @spec
- # @user_spec::
- # the path to a built gem from @user_spec
- #
- # @installer::
- # a Gem::Installer for the @spec that installs into @gemhome
- # @user_installer::
- # a Gem::Installer for the @user_spec that installs into Gem.user_dir
-
def setup
super
- @spec = quick_gem 'a' do |spec|
- util_make_exec spec
- end
-
- @user_spec = quick_gem 'b' do |spec|
- util_make_exec spec
- end
-
- util_build_gem @spec
- util_build_gem @user_spec
-
- @gem = @spec.cache_file
- @user_gem = @user_spec.cache_file
-
- @installer = util_installer @spec, @gemhome
- @user_installer = util_installer @user_spec, Gem.user_dir, :user
-
Gem::Installer.path_warning = false
end
@@ -136,6 +101,83 @@ class Gem::InstallerTestCase < Gem::TestCase
end
##
+ # Creates the following instance variables:
+ #
+ # @spec::
+ # a spec named 'a', intended for regular installs
+ #
+ # @gem::
+ # the path to a built gem from @spec
+ #
+ # And returns a Gem::Installer for the @spec that installs into @gemhome
+
+ def setup_base_installer
+ @gem = setup_base_gem
+ util_installer @spec, @gemhome
+ end
+
+ ##
+ # Creates the following instance variables:
+ #
+ # @spec::
+ # a spec named 'a', intended for regular installs
+ #
+ # And returns a gem built for the @spec
+
+ def setup_base_gem
+ @spec = setup_base_spec
+ util_build_gem @spec
+ @spec.cache_file
+ end
+
+ ##
+ # Sets up a generic specification for testing the rubygems installer
+ #
+ # And returns it
+
+ def setup_base_spec
+ quick_gem 'a' do |spec|
+ util_make_exec spec
+ end
+ end
+
+ ##
+ # Creates the following instance variables:
+ #
+ # @spec::
+ # a spec named 'a', intended for regular installs
+ # @user_spec::
+ # a spec named 'b', intended for user installs
+ #
+ # @gem::
+ # the path to a built gem from @spec
+ # @user_gem::
+ # the path to a built gem from @user_spec
+ #
+ # And returns a Gem::Installer for the @user_spec that installs into Gem.user_dir
+
+ def setup_base_user_installer
+ @user_spec = quick_gem 'b' do |spec|
+ util_make_exec spec
+ end
+
+ util_build_gem @user_spec
+
+ @user_gem = @user_spec.cache_file
+
+ util_installer @user_spec, Gem.user_dir, :user
+ end
+
+ ##
+ # Sets up the base @gem, builds it and returns an installer for it.
+ #
+ def util_setup_installer
+ @gem = setup_base_gem
+
+ util_setup_gem
+ end
+
+ ##
# Builds the @spec gem and returns an installer for it. The built gem
# includes:
#
@@ -143,7 +185,7 @@ class Gem::InstallerTestCase < Gem::TestCase
# lib/code.rb
# ext/a/mkrf_conf.rb
- def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic
+ def util_setup_gem(ui = @ui)
@spec.files << File.join('lib', 'code.rb')
@spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb')
@@ -175,7 +217,7 @@ class Gem::InstallerTestCase < Gem::TestCase
end
end
- @installer = Gem::Installer.at @gem
+ Gem::Installer.at @gem
end
##
diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb
index c7b5f88..c376127 100644
--- a/lib/rubygems/package/tar_header.rb
+++ b/lib/rubygems/package/tar_header.rb
@@ -107,8 +107,8 @@ class Gem::Package::TarHeader
new :name => fields.shift,
:mode => strict_oct(fields.shift),
- :uid => strict_oct(fields.shift),
- :gid => strict_oct(fields.shift),
+ :uid => oct_or_256based(fields.shift),
+ :gid => oct_or_256based(fields.shift),
:size => strict_oct(fields.shift),
:mtime => strict_oct(fields.shift),
:checksum => strict_oct(fields.shift),
@@ -130,6 +130,15 @@ class Gem::Package::TarHeader
raise ArgumentError, "#{str.inspect} is not an octal string"
end
+ def self.oct_or_256based(str)
+ # \x80 flags a positive 256-based number
+ # \ff flags a negative 256-based number
+ # In case we have a match, parse it as a signed binary value
+ # in big-endian order, except that the high-order bit is ignored.
+ return str.unpack('N2').last if str =~ /\A[\x80\xff]/n
+ strict_oct(str)
+ end
+
##
# Creates a new TarHeader using +vals+
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb
index 32c65ea..a40ee55 100644
--- a/lib/rubygems/remote_fetcher.rb
+++ b/lib/rubygems/remote_fetcher.rb
@@ -173,7 +173,7 @@ class Gem::RemoteFetcher
path = source_uri.path
path = File.dirname(path) if File.extname(path) == '.gem'
- remote_gem_path = correct_for_windows_path(File.join(path, 'gems', gem_file_name))
+ remote_gem_path = Gem::Util.correct_for_windows_path(File.join(path, 'gems', gem_file_name))
FileUtils.cp(remote_gem_path, local_gem_path)
rescue Errno::EACCES
@@ -210,7 +210,7 @@ class Gem::RemoteFetcher
# File Fetcher. Dispatched by +fetch_path+. Use it instead.
def fetch_file(uri, *_)
- Gem.read_binary correct_for_windows_path uri.path
+ Gem.read_binary Gem::Util.correct_for_windows_path uri.path
end
##
@@ -317,14 +317,6 @@ class Gem::RemoteFetcher
response['content-length'].to_i
end
- def correct_for_windows_path(path)
- if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
- path[1..-1]
- else
- path
- end
- end
-
##
# Performs a Net::HTTP request of type +request_class+ on +uri+ returning
# a Net::HTTP response object. request maintains a table of persistent
diff --git a/lib/rubygems/request/connection_pools.rb b/lib/rubygems/request/connection_pools.rb
index 7c273d5..9444239 100644
--- a/lib/rubygems/request/connection_pools.rb
+++ b/lib/rubygems/request/connection_pools.rb
@@ -76,9 +76,7 @@ class Gem::Request::ConnectionPools # :nodoc:
end
def net_http_args(uri, proxy_uri)
- # URI::Generic#hostname was added in ruby 1.9.3, use it if exists, otherwise
- # don't support IPv6 literals and use host.
- hostname = uri.respond_to?(:hostname) ? uri.hostname : uri.host
+ hostname = uri.hostname
net_http_args = [hostname, uri.port]
no_proxy = get_no_proxy_from_env
diff --git a/lib/rubygems/resolver.rb b/lib/rubygems/resolver.rb
index d308f68..f749957 100644
--- a/lib/rubygems/resolver.rb
+++ b/lib/rubygems/resolver.rb
@@ -246,7 +246,7 @@ class Gem::Resolver
sources.each do |source|
groups[source].
sort_by { |spec| [spec.version, Gem::Platform.local =~ spec.platform ? 1 : 0] }.
- map { |spec| ActivationRequest.new spec, dependency, [] }.
+ map { |spec| ActivationRequest.new spec, dependency }.
each { |activation_request| activation_requests << activation_request }
end
diff --git a/lib/rubygems/resolver/activation_request.rb b/lib/rubygems/resolver/activation_request.rb
index 7fbabbf..2a8d603 100644
--- a/lib/rubygems/resolver/activation_request.rb
+++ b/lib/rubygems/resolver/activation_request.rb
@@ -18,14 +18,10 @@ class Gem::Resolver::ActivationRequest
##
# Creates a new ActivationRequest that will activate +spec+. The parent
# +request+ is used to provide diagnostics in case of conflicts.
- #
- # +others_possible+ indicates that other specifications may also match this
- # activation request.
- def initialize(spec, request, others_possible = true)
+ def initialize(spec, request)
@spec = spec
@request = request
- @others_possible = others_possible
end
def ==(other) # :nodoc:
@@ -90,21 +86,8 @@ class Gem::Resolver::ActivationRequest
end
def inspect # :nodoc:
- others =
- case @others_possible
- when true then # TODO remove at RubyGems 3
- ' (others possible)'
- when false then # TODO remove at RubyGems 3
- nil
- else
- unless @others_possible.empty?
- others = @others_possible.map { |s| s.full_name }
- " (others possible: #{others.join ', '})"
- end
- end
-
- '#<%s for %p from %s%s>' % [
- self.class, @spec, @request, others
+ '#<%s for %p from %s>' % [
+ self.class, @spec, @request
]
end
@@ -132,19 +115,6 @@ class Gem::Resolver::ActivationRequest
end
##
- # Indicate if this activation is one of a set of possible
- # requests for the same Dependency request.
-
- def others_possible?
- case @others_possible
- when true, false then
- @others_possible
- else
- not @others_possible.empty?
- end
- end
-
- ##
# Return the ActivationRequest that contained the dependency
# that we were activated for.
@@ -160,19 +130,6 @@ class Gem::Resolver::ActivationRequest
q.breakable
q.text ' for '
q.pp @request
-
- case @others_possible
- when false then
- when true then
- q.breakable
- q.text 'others possible'
- else
- unless @others_possible.empty?
- q.breakable
- q.text 'others '
- q.pp @others_possible.map { |s| s.full_name }
- end
- end
end
end
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 942e49b..c128636 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -743,9 +743,6 @@ class Gem::Specification < Gem::BasicSpecification
def self._all # :nodoc:
unless defined?(@@all) && @@all
@@all = stubs.map(&:to_spec)
- if @@all.any?(&:nil?) # TODO: remove once we're happy
- raise "pid: #{$$} nil spec! included in #{stubs.inspect}"
- end
# After a reset, make sure already loaded specs
# are still marked as activated.
@@ -896,7 +893,6 @@ class Gem::Specification < Gem::BasicSpecification
# -- wilsonb
def self.all=(specs)
- raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy
@@stubs_by_name = specs.group_by(&:name)
@@all = @@stubs = specs
end
@@ -1498,16 +1494,7 @@ class Gem::Specification < Gem::BasicSpecification
paths = full_require_paths
- # gem directories must come after -I and ENV['RUBYLIB']
- insert_index = Gem.load_path_insert_index
-
- if insert_index
- # gem directories must come after -I and ENV['RUBYLIB']
- $LOAD_PATH.insert(insert_index, *paths)
- else
- # we are probably testing in core, -I and RUBYLIB don't apply
- $LOAD_PATH.unshift(*paths)
- end
+ Gem.add_to_load_path(*paths)
end
##
@@ -1927,8 +1914,7 @@ class Gem::Specification < Gem::BasicSpecification
end
def gems_dir
- # TODO: this logic seems terribly broken, but tests fail if just base_dir
- @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems")
+ @gems_dir ||= File.join(base_dir, "gems")
end
##
diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb
index 8e909e4..b466e7a 100644
--- a/lib/rubygems/test_case.rb
+++ b/lib/rubygems/test_case.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-# TODO: $SAFE = 1
require 'rubygems'
@@ -27,13 +26,6 @@ begin
rescue LoadError
end
-# We have to load these up front because otherwise we'll try to load
-# them while we're testing rubygems, and thus we can't actually load them.
-unless Gem::Dependency.new('rdoc', '>= 3.10').matching_specs.empty?
- gem 'rdoc'
- gem 'json'
-end
-
require 'bundler'
require 'minitest/autorun'
@@ -91,8 +83,6 @@ end
# gem-related behavior in a sandbox. Through RubyGemTestCase you can install
# and uninstall gems, fetch remote gems through a stub fetcher and be assured
# your normal set of gems is not affected.
-#
-# Tests are always run at a safe level of 1.
class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Unit::TestCase)
@@ -152,6 +142,28 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
end
end
+ ##
+ # Sets the vendordir entry in RbConfig::CONFIG to +value+ and restores the
+ # original value when the block ends
+ #
+ def vendordir(value)
+ vendordir = RbConfig::CONFIG['vendordir']
+
+ if value
+ RbConfig::CONFIG['vendordir'] = value
+ else
+ RbConfig::CONFIG.delete 'vendordir'
+ end
+
+ yield
+ ensure
+ if vendordir
+ RbConfig::CONFIG['vendordir'] = vendordir
+ else
+ RbConfig::CONFIG.delete 'vendordir'
+ end
+ end
+
# TODO: move to minitest
def refute_path_exists(path, msg = nil)
msg = message(msg) { "Expected path '#{path}' to not exist" }
@@ -222,8 +234,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
@@project_dir = Dir.pwd.untaint unless defined?(@@project_dir)
- @@initial_reset = false
-
##
# #setup prepares a sandboxed location to install gems. All installs are
# directed to a temporary directory. All install plugins are removed.
@@ -231,24 +241,11 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
# If the +RUBY+ environment variable is set the given path is used for
# Gem::ruby. The local platform is set to <tt>i386-mswin32</tt> for Windows
# or <tt>i686-darwin8.10.1</tt> otherwise.
- #
- # If the +KEEP_FILES+ environment variable is set the files will not be
- # removed from <tt>/tmp/test_rubygems_#{$$}.#{Time.now.to_i}</tt>.
def setup
super
- @orig_gem_home = ENV['GEM_HOME']
- @orig_gem_path = ENV['GEM_PATH']
- @orig_gem_vendor = ENV['GEM_VENDOR']
- @orig_gem_spec_cache = ENV['GEM_SPEC_CACHE']
- @orig_rubygems_gemdeps = ENV['RUBYGEMS_GEMDEPS']
- @orig_bundle_gemfile = ENV['BUNDLE_GEMFILE']
- @orig_rubygems_host = ENV['RUBYGEMS_HOST']
- ENV.keys.find_all { |k| k.start_with?('GEM_REQUIREMENT_') }.each do |k|
- ENV.delete k
- end
- @orig_gem_env_requirements = ENV.to_hash
+ @orig_env = ENV.to_hash
ENV['GEM_VENDOR'] = nil
ENV['SOURCE_DATE_EPOCH'] = nil
@@ -256,36 +253,20 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
@current_dir = Dir.pwd
@fetcher = nil
- Bundler.ui = Bundler::UI::Silent.new
-
@back_ui = Gem::DefaultUserInteraction.ui
@ui = Gem::MockGemUi.new
# This needs to be a new instance since we call use_ui(@ui) when we want to
# capture output
Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new
- tmpdir = File.expand_path Dir.tmpdir
+ tmpdir = File.realpath Dir.tmpdir
tmpdir.untaint
- if ENV['KEEP_FILES']
- @tempdir = File.join(tmpdir, "test_rubygems_#{$$}.#{Time.now.to_i}")
- else
- @tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
- end
+ @tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
@tempdir.untaint
FileUtils.mkdir_p @tempdir
- # This makes the tempdir consistent on OS X.
- # File.expand_path Dir.tmpdir #=> "/var/..."
- # Dir.chdir Dir.tmpdir do File.expand_path '.' end #=> "/private/var/..."
- # TODO use File#realpath above instead of #expand_path once 1.8 support is
- # dropped.
- Dir.chdir @tempdir do
- @tempdir = File.expand_path '.'
- @tempdir.untaint
- end
-
# This makes the tempdir consistent on Windows.
# Dir.tmpdir may return short path name, but Dir[Dir.tmpdir] returns long
# path name. https://bugs.ruby-lang.org/issues/10819
@@ -343,25 +324,21 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
@default_dir = File.join @tempdir, 'default'
@default_spec_dir = File.join @default_dir, "specifications", "default"
- Gem.instance_variable_set :@default_dir, @default_dir
- FileUtils.mkdir_p @default_spec_dir
-
- # We use Gem::Specification.reset the first time only so that if there
- # are unresolved deps that leak into the whole test suite, they're at least
- # reported once.
- if @@initial_reset
- Gem::Specification.unresolved_deps.clear # done to avoid cross-test warnings
+ if Gem.java_platform?
+ @orig_default_gem_home = RbConfig::CONFIG['default_gem_home']
+ RbConfig::CONFIG['default_gem_home'] = @default_dir
else
- @@initial_reset = true
- Gem::Specification.reset
+ Gem.instance_variable_set(:@default_dir, @default_dir)
end
+ FileUtils.mkdir_p @default_spec_dir
+
+ Gem::Specification.unresolved_deps.clear
Gem.use_paths(@gemhome)
Gem::Security.reset
Gem.loaded_specs.clear
Gem.clear_default_specs
- Gem::Specification.unresolved_deps.clear
Bundler.reset!
Gem.configuration.verbose = true
@@ -395,7 +372,7 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
##
# #teardown restores the process to its original state and removes the
- # tempdir unless the +KEEP_FILES+ environment variable was set.
+ # tempdir
def teardown
$LOAD_PATH.replace @orig_LOAD_PATH if @orig_LOAD_PATH
@@ -420,33 +397,18 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
Dir.chdir @current_dir
- FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES']
+ FileUtils.rm_rf @tempdir
- ENV.clear
- @orig_gem_env_requirements.each do |k,v|
- ENV[k] = v
- end
-
- ENV['GEM_HOME'] = @orig_gem_home
- ENV['GEM_PATH'] = @orig_gem_path
- ENV['GEM_VENDOR'] = @orig_gem_vendor
- ENV['GEM_SPEC_CACHE'] = @orig_gem_spec_cache
- ENV['RUBYGEMS_GEMDEPS'] = @orig_rubygems_gemdeps
- ENV['BUNDLE_GEMFILE'] = @orig_bundle_gemfile
- ENV['RUBYGEMS_HOST'] = @orig_rubygems_host
+ ENV.replace(@orig_env)
Gem.ruby = @orig_ruby if @orig_ruby
- if @orig_ENV_HOME
- ENV['HOME'] = @orig_ENV_HOME
+ if Gem.java_platform?
+ RbConfig::CONFIG['default_gem_home'] = @orig_default_gem_home
else
- ENV.delete 'HOME'
+ Gem.instance_variable_set :@default_dir, nil
end
- Gem.instance_variable_set :@default_dir, nil
-
- ENV['GEM_PRIVATE_KEY_PASSPHRASE'] = @orig_gem_private_key_passphrase
-
Gem::Specification._clear_load_cache
Gem::Specification.unresolved_deps.clear
Gem::refresh
@@ -594,22 +556,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
end
##
- # creates a temporary directory with hax
- # TODO: deprecate and remove
-
- def create_tmpdir
- tmpdir = nil
-
- Dir.chdir Dir.tmpdir do
- tmpdir = Dir.pwd
- end # HACK OSX /private/tmp
-
- tmpdir = File.join tmpdir, "test_rubygems_#{$$}"
- FileUtils.mkdir_p tmpdir
- return tmpdir
- end
-
- ##
# Enables pretty-print for all tests
def mu_pp(obj)
@@ -686,7 +632,7 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
io.write spec.to_ruby_for_cache
end
- spec.loaded_from = spec.loaded_from = written_path
+ spec.loaded_from = written_path
Gem::Specification.reset
@@ -694,14 +640,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
end
##
- # TODO: remove in RubyGems 4.0
-
- def quick_spec(name, version = '2') # :nodoc:
- util_spec name, version
- end
- deprecate :quick_spec, :util_spec, 2018, 12
-
- ##
# Builds a gem from +spec+ and places it in <tt>File.join @gemhome,
# 'cache'</tt>. Automatically creates files based on +spec.files+
@@ -744,11 +682,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
Gem::Specification.reset
end
- def util_clear_default_gems
- FileUtils.rm_rf @default_spec_dir
- FileUtils.mkdir @default_spec_dir
- end
-
##
# Install the provided specs
@@ -802,52 +735,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
$LOADED_FEATURES.replace old_loaded_features
end
- ##
- # new_spec is deprecated as it is never used.
- #
- # TODO: remove in RubyGems 4.0
-
- def new_spec(name, version, deps = nil, *files) # :nodoc:
- require 'rubygems/specification'
-
- spec = Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = name
- s.version = version
- s.author = 'A User'
- s.email = 'example@example.com'
- s.homepage = 'http://example.com'
- s.summary = "this is a summary"
- s.description = "This is a test description"
-
- Array(deps).each do |n, req|
- s.add_dependency n, (req || '>= 0')
- end
-
- s.files.push(*files) unless files.empty?
-
- yield s if block_given?
- end
-
- spec.loaded_from = spec.spec_file
-
- unless files.empty?
- write_file spec.spec_file do |io|
- io.write spec.to_ruby_for_cache
- end
-
- 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
- end
-
- spec
- end
- deprecate :new_spec, :none, 2018, 12
-
def new_default_spec(name, version, deps = nil, *files)
spec = util_spec name, version, deps
@@ -910,8 +797,6 @@ class Gem::TestCase < (defined?(Minitest::Test) ? Minitest::Test : MiniTest::Uni
FileUtils.rm spec.spec_file
end
- Gem::Specification.reset
-
return spec
end
@@ -1061,31 +946,6 @@ Also, a list:
end
##
- # Sets up a fake fetcher using the gems from #util_make_gems. Optionally
- # additional +prerelease+ gems may be included.
- #
- # Gems created by this method may be fetched using Gem::RemoteFetcher.
-
- def util_setup_fake_fetcher(prerelease = false)
- require 'zlib'
- require 'socket'
- require 'rubygems/remote_fetcher'
-
- @fetcher = Gem::FakeFetcher.new
-
- util_make_gems(prerelease)
- Gem::Specification.reset
-
- @all_gems = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2].sort
- @all_gem_names = @all_gems.map { |gem| gem.full_name }
-
- gem_names = [@a1.full_name, @a2.full_name, @a3a.full_name, @b2.full_name]
- @gem_names = gem_names.sort.join("\n")
-
- Gem::RemoteFetcher.fetcher = @fetcher
- end
-
- ##
# Add +spec+ to +@fetcher+ serving the data in the file +path+.
# +repo+ indicates which repo to make +spec+ appear to be in.
@@ -1096,7 +956,6 @@ Also, a list:
##
# Sets up Gem::SpecFetcher to return information from the gems in +specs+.
- # Best used with +@all_gems+ from #util_setup_fake_fetcher.
def util_setup_spec_fetcher(*specs)
all_specs = Gem::Specification.to_a + specs
@@ -1163,8 +1022,7 @@ Also, a list:
end
def util_set_RUBY_VERSION(version, patchlevel = nil, revision = nil, description = nil, engine = "ruby", engine_version = nil)
- if Gem.instance_variables.include? :@ruby_version or
- Gem.instance_variables.include? '@ruby_version'
+ if Gem.instance_variables.include? :@ruby_version
Gem.send :remove_instance_variable, :@ruby_version
end
@@ -1224,6 +1082,20 @@ Also, a list:
end
##
+ # Is this test being run on a Java platform?
+
+ def self.java_platform?
+ Gem.java_platform?
+ end
+
+ ##
+ # Is this test being run on a Java platform?
+
+ def java_platform?
+ Gem.java_platform?
+ end
+
+ ##
# Returns whether or not we're on a version of Ruby built with VC++ (or
# Borland) versus Cygwin, Mingw, etc.
@@ -1623,10 +1495,3 @@ rescue LoadError, Gem::LoadError
end
require 'rubygems/test_utilities'
-tmpdirs = []
-tmpdirs << (ENV['GEM_HOME'] = Dir.mktmpdir("home"))
-tmpdirs << (ENV['GEM_PATH'] = Dir.mktmpdir("path"))
-pid = $$
-END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid}
-Gem.clear_paths
-Gem.loaded_specs.clear
diff --git a/lib/rubygems/test_utilities.rb b/lib/rubygems/test_utilities.rb
index 5d02b04..69ff053 100644
--- a/lib/rubygems/test_utilities.rb
+++ b/lib/rubygems/test_utilities.rb
@@ -241,21 +241,22 @@ class Gem::TestCase::SpecFetcherSetup
def execute_operations # :nodoc:
@operations.each do |operation, *arguments|
+ block = arguments.pop
case operation
when :gem then
- spec, gem = @test.util_gem(*arguments, &arguments.pop)
+ spec, gem = @test.util_gem(*arguments, &block)
write_spec spec
@gems[spec] = gem
@installed << spec
when :download then
- spec, gem = @test.util_gem(*arguments, &arguments.pop)
+ spec, gem = @test.util_gem(*arguments, &block)
@gems[spec] = gem
@downloaded << spec
when :spec then
- spec = @test.util_spec(*arguments, &arguments.pop)
+ spec = @test.util_spec(*arguments, &block)
write_spec spec
diff --git a/lib/rubygems/util.rb b/lib/rubygems/util.rb
index 401e560..b5f1408 100644
--- a/lib/rubygems/util.rb
+++ b/lib/rubygems/util.rb
@@ -44,29 +44,10 @@ module Gem::Util
end
##
- # This calls IO.popen where it accepts an array for a +command+ (Ruby 1.9+)
- # and implements an IO.popen-like behavior where it does not accept an array
- # for a command.
+ # This calls IO.popen and reads the result
def self.popen(*command)
IO.popen command, &:read
- rescue TypeError # ruby 1.8 only supports string command
- r, w = IO.pipe
-
- pid = fork do
- STDIN.close
- STDOUT.reopen w
-
- exec(*command)
- end
-
- w.close
-
- begin
- return r.read
- ensure
- Process.wait pid
- end
end
##
@@ -80,26 +61,7 @@ module Gem::Util
else
cmds = command.dup
end
- return system(*(cmds << opt))
- rescue TypeError
- @silent_mutex ||= Mutex.new
-
- @silent_mutex.synchronize do
- begin
- stdout = STDOUT.dup
- stderr = STDERR.dup
-
- STDOUT.reopen IO::NULL, 'w'
- STDERR.reopen IO::NULL, 'w'
-
- return system(*command)
- ensure
- STDOUT.reopen stdout
- STDERR.reopen stderr
- stdout.close
- stderr.close
- end
- end
+ system(*(cmds << opt))
end
##
@@ -130,4 +92,16 @@ module Gem::Util
end
end
+ ##
+ # Corrects +path+ (usually returned by `URI.parse().path` on Windows), that
+ # comes with a leading slash.
+
+ def self.correct_for_windows_path(path)
+ if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
+ path[1..-1]
+ else
+ path
+ end
+ end
+
end