summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--lib/rubygems.rb444
-rw-r--r--lib/rubygems/builder.rb13
-rw-r--r--lib/rubygems/command.rb10
-rw-r--r--lib/rubygems/command_manager.rb18
-rw-r--r--lib/rubygems/commands/build_command.rb24
-rw-r--r--lib/rubygems/commands/cert_command.rb2
-rw-r--r--lib/rubygems/commands/cleanup_command.rb29
-rw-r--r--lib/rubygems/commands/contents_command.rb31
-rw-r--r--lib/rubygems/commands/dependency_command.rb68
-rw-r--r--lib/rubygems/commands/fetch_command.rb11
-rw-r--r--lib/rubygems/commands/install_command.rb3
-rw-r--r--lib/rubygems/commands/lock_command.rb8
-rw-r--r--lib/rubygems/commands/outdated_command.rb8
-rw-r--r--lib/rubygems/commands/pristine_command.rb50
-rw-r--r--lib/rubygems/commands/query_command.rb15
-rw-r--r--lib/rubygems/commands/server_command.rb2
-rw-r--r--lib/rubygems/commands/setup_command.rb2
-rw-r--r--lib/rubygems/commands/specification_command.rb31
-rw-r--r--lib/rubygems/commands/stale_command.rb3
-rw-r--r--lib/rubygems/commands/unpack_command.rb60
-rw-r--r--lib/rubygems/commands/update_command.rb40
-rw-r--r--lib/rubygems/commands/which_command.rb14
-rw-r--r--lib/rubygems/config_file.rb16
-rw-r--r--lib/rubygems/custom_require.rb11
-rw-r--r--lib/rubygems/defaults.rb44
-rw-r--r--lib/rubygems/dependency.rb52
-rw-r--r--lib/rubygems/dependency_installer.rb78
-rw-r--r--lib/rubygems/dependency_list.rb29
-rw-r--r--lib/rubygems/deprecate.rb74
-rw-r--r--lib/rubygems/doc_manager.rb21
-rw-r--r--lib/rubygems/ext/builder.rb2
-rw-r--r--lib/rubygems/ext/rake_builder.rb4
-rw-r--r--lib/rubygems/gem_path_searcher.rb26
-rw-r--r--lib/rubygems/gem_runner.rb4
-rw-r--r--lib/rubygems/indexer.rb238
-rw-r--r--lib/rubygems/installer.rb209
-rw-r--r--lib/rubygems/installer_test_case.rb58
-rw-r--r--lib/rubygems/local_remote_options.rb4
-rw-r--r--lib/rubygems/mock_gem_ui.rb14
-rw-r--r--lib/rubygems/package.rb28
-rw-r--r--lib/rubygems/package/tar_input.rb12
-rw-r--r--lib/rubygems/package/tar_writer.rb2
-rw-r--r--lib/rubygems/package_task.rb2
-rw-r--r--lib/rubygems/path_support.rb78
-rw-r--r--lib/rubygems/platform.rb14
-rw-r--r--lib/rubygems/remote_fetcher.rb114
-rw-r--r--lib/rubygems/requirement.rb12
-rw-r--r--lib/rubygems/security.rb2
-rw-r--r--lib/rubygems/server.rb134
-rw-r--r--lib/rubygems/source_index.rb172
-rw-r--r--lib/rubygems/spec_fetcher.rb17
-rw-r--r--lib/rubygems/specification.rb2467
-rw-r--r--lib/rubygems/test_case.rb188
-rw-r--r--lib/rubygems/test_utilities.rb7
-rw-r--r--lib/rubygems/text.rb2
-rw-r--r--lib/rubygems/uninstaller.rb89
-rw-r--r--lib/rubygems/user_interaction.rb58
-rw-r--r--test/rubygems/functional.rb98
-rw-r--r--test/rubygems/test_gem.rb277
-rw-r--r--test/rubygems/test_gem_builder.rb19
-rw-r--r--test/rubygems/test_gem_command_manager.rb2
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb34
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb57
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb49
-rw-r--r--test/rubygems/test_gem_commands_dependency_command.rb29
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb9
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb64
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb49
-rw-r--r--test/rubygems/test_gem_commands_list_command.rb5
-rw-r--r--test/rubygems/test_gem_commands_outdated_command.rb19
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb115
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb2
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb97
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb17
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb16
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb8
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb57
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb69
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb11
-rw-r--r--test/rubygems/test_gem_dependency.rb29
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb120
-rw-r--r--test/rubygems/test_gem_dependency_list.rb12
-rw-r--r--test/rubygems/test_gem_doc_manager.rb6
-rw-r--r--test/rubygems/test_gem_format.rb2
-rw-r--r--test/rubygems/test_gem_gem_path_searcher.rb74
-rw-r--r--test/rubygems/test_gem_gem_runner.rb5
-rw-r--r--test/rubygems/test_gem_indexer.rb95
-rw-r--r--test/rubygems/test_gem_install_update_options.rb11
-rw-r--r--test/rubygems/test_gem_installer.rb102
-rw-r--r--test/rubygems/test_gem_package_tar_output.rb1
-rw-r--r--test/rubygems/test_gem_path_support.rb64
-rw-r--r--test/rubygems/test_gem_platform.rb2
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb194
-rw-r--r--test/rubygems/test_gem_requirement.rb13
-rw-r--r--test/rubygems/test_gem_server.rb38
-rw-r--r--test/rubygems/test_gem_silent_ui.rb4
-rw-r--r--test/rubygems/test_gem_source_index.rb463
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb91
-rw-r--r--test/rubygems/test_gem_specification.rb437
-rw-r--r--test/rubygems/test_gem_text.rb15
-rw-r--r--test/rubygems/test_gem_uninstaller.rb66
-rw-r--r--test/rubygems/test_kernel.rb3
103 files changed, 4707 insertions, 3416 deletions
diff --git a/ChangeLog b/ChangeLog
index 003d346..74535f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Jun 1 12:35:50 2011 Ryan Davis <ryand-ruby@zenspider.com>
+
+ * lib/rubygems*: Import rubygems 1.8.5 (released @ 137c80f)
+ * test/rubygems: Ditto
+
Wed Jun 1 12:34:00 2011 Kenta Murata <mrkn@mrkn.jp>
* NEWS: add new features of bigdecimal.
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 429dfda..0f3a073 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -33,7 +33,9 @@ end
require 'rubygems/defaults'
require "rubygems/dependency_list"
+require 'rubygems/path_support'
require 'rbconfig'
+require "rubygems/deprecate"
##
# RubyGems is the Ruby standard for publishing and managing third party
@@ -124,7 +126,7 @@ require 'rbconfig'
# -The RubyGems Team
module Gem
- VERSION = '1.6.2'
+ VERSION = '1.8.5'
##
# Raised when RubyGems is unable to load or activate a gem. Contains the
@@ -160,11 +162,6 @@ module Gem
end
end
- ##
- # Default directories in a gem repository
-
- DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
-
RubyGemsPackageVersion = VERSION
RUBYGEMS_DIR = File.dirname File.expand_path(__FILE__)
@@ -188,16 +185,17 @@ module Gem
@configuration = nil
@loaded_specs = {}
- @loaded_stacks = {}
@platforms = []
@ruby = nil
- @sources = []
+ @sources = nil
@post_build_hooks ||= []
@post_install_hooks ||= []
@post_uninstall_hooks ||= []
@pre_uninstall_hooks ||= []
@pre_install_hooks ||= []
+ @pre_reset_hooks ||= []
+ @post_reset_hooks ||= []
##
# Try to activate a gem containing +path+. Returns true if
@@ -205,17 +203,18 @@ module Gem
# activated. Returns false if it can't find the path in a gem.
def self.try_activate path
+ # TODO: deprecate when 1.9.3 comes out.
# finds the _latest_ version... regardless of loaded specs and their deps
# TODO: use find_all and bork if ambiguous
- spec = Gem.searcher.find path
+ spec = Gem::Specification.find_by_path path
return false unless spec
begin
- Gem.activate spec.name, "= #{spec.version}"
+ spec.activate
rescue Gem::LoadError # this could fail due to gem dep collisions, go lax
- Gem.activate spec.name
+ Gem::Specification.find_by_name(spec.name).activate
end
return true
@@ -238,94 +237,18 @@ module Gem
# Gem::Requirement and Gem::Version documentation.
def self.activate(dep, *requirements)
- # TODO: remove options entirely
- if requirements.last.is_a?(Hash)
- options = requirements.pop
- else
- options = {}
- end
-
- requirements = Gem::Requirement.default if requirements.empty?
- dep = Gem::Dependency.new(dep, requirements) unless Gem::Dependency === dep
-
- # TODO: remove sources entirely
- sources = options[:sources] || []
- matches = Gem.source_index.search dep, true
- report_activate_error(dep) if matches.empty?
-
- if @loaded_specs[dep.name] then
- # This gem is already loaded. If the currently loaded gem is not in the
- # list of candidate gems, then we have a version conflict.
- existing_spec = @loaded_specs[dep.name]
-
- # TODO: unless dep.matches_spec? existing_spec then
- unless matches.any? { |spec| spec.version == existing_spec.version } then
- sources_message = sources.map { |spec| spec.full_name }
- stack_message = @loaded_stacks[dep.name].map { |spec| spec.full_name }
-
- msg = "can't activate #{dep} for #{sources_message.inspect}, "
- msg << "already activated #{existing_spec.full_name} for "
- msg << "#{stack_message.inspect}"
-
- e = Gem::LoadError.new msg
- e.name = dep.name
- e.requirement = dep.requirement
-
- raise e
- end
-
- return false
- end
-
- spec = matches.last
-
- conf = spec.conflicts
- unless conf.empty? then
- why = conf.map { |act,con|
- "#{act.full_name} conflicts with #{con.join(", ")}"
- }.join ", "
-
- # TODO: improve message by saying who activated `con`
-
- raise LoadError, "Unable to activate #{spec.full_name}, because #{why}"
- end
-
- return false if spec.loaded?
-
- spec.loaded = true
- @loaded_specs[spec.name] = spec
- @loaded_stacks[spec.name] = sources.dup
-
- spec.runtime_dependencies.each do |spec_dep|
- next if Gem.loaded_specs.include? spec_dep.name
- specs = Gem.source_index.search spec_dep, true
-
- if specs.size == 1 then
- self.activate spec_dep
- else
- name = spec_dep.name
- unresolved_deps[name] = unresolved_deps[name].merge spec_dep
- end
- end
-
- unresolved_deps.delete spec.name
+ raise ArgumentError, "Deprecated use of Gem.activate(dep)" if
+ Gem::Dependency === dep
- require_paths = spec.require_paths.map do |path|
- File.join spec.full_gem_path, path
- end
-
- # gem directories must come after -I and ENV['RUBYLIB']
- insert_index = load_path_insert_index
+ Gem::Specification.find_by_name(dep, *requirements).activate
+ end
- if insert_index then
- # gem directories must come after -I and ENV['RUBYLIB']
- $LOAD_PATH.insert(insert_index, *require_paths)
- else
- # we are probably testing in core, -I and RUBYLIB don't apply
- $LOAD_PATH.unshift(*require_paths)
- end
+ def self.activate_dep dep, *requirements # :nodoc:
+ dep.to_spec.activate
+ end
- return true
+ def self.activate_spec spec # :nodoc:
+ spec.activate
end
def self.unresolved_deps
@@ -341,7 +264,7 @@ module Gem
Gem.path.each do |gemdir|
each_load_path all_partials(gemdir) do |load_path|
- result << load_path
+ result << gemdir.add(load_path).expand_path
end
end
@@ -352,7 +275,7 @@ module Gem
# Return all the partial paths in +gemdir+.
def self.all_partials(gemdir)
- Dir[File.join(gemdir, 'gems/*')]
+ Dir[File.join(gemdir, "gems/*")]
end
private_class_method :all_partials
@@ -360,15 +283,14 @@ module Gem
##
# See if a given gem is available.
- def self.available?(gem, *requirements)
+ def self.available?(dep, *requirements)
requirements = Gem::Requirement.default if requirements.empty?
- unless gem.respond_to?(:name) and
- gem.respond_to?(:requirement) then
- gem = Gem::Dependency.new gem, requirements
+ unless dep.respond_to?(:name) and dep.respond_to?(:requirement) then
+ dep = Gem::Dependency.new dep, requirements
end
- !Gem.source_index.search(gem).empty?
+ not dep.matching_specs(true).empty?
end
##
@@ -378,30 +300,29 @@ module Gem
# you to specify specific gem versions.
def self.bin_path(name, exec_name = nil, *requirements)
+ # TODO: fails test_self_bin_path_bin_file_gone_in_latest
+ # Gem::Specification.find_by_name(name, *requirements).bin_file exec_name
+
+ raise ArgumentError, "you must supply exec_name" unless exec_name
+
requirements = Gem::Requirement.default if
requirements.empty?
- specs = Gem.source_index.find_name(name, requirements)
+
+ specs = Gem::Dependency.new(name, requirements).matching_specs(true)
raise Gem::GemNotFoundException,
"can't find gem #{name} (#{requirements})" if specs.empty?
- specs = specs.find_all do |spec|
- spec.executables.include?(exec_name)
- end if exec_name
+ specs = specs.find_all { |spec|
+ spec.executables.include? exec_name
+ } if exec_name
unless spec = specs.last
msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
raise Gem::GemNotFoundException, msg
end
- exec_name ||= spec.default_executable
-
- unless exec_name
- msg = "no default executable for #{spec.full_name} and none given"
- raise Gem::Exception, msg
- end
-
- File.join(spec.full_gem_path, spec.bindir, exec_name)
+ spec.bin_file exec_name
end
##
@@ -415,8 +336,9 @@ module Gem
# The path where gem executables are to be installed.
def self.bindir(install_dir=Gem.dir)
- return File.join(install_dir, 'bin') unless
- install_dir.to_s == Gem.default_dir
+ # TODO: move to Gem::Dirs
+ return File.join install_dir, 'bin' unless
+ install_dir.to_s == Gem.default_dir.to_s
Gem.default_bindir
end
@@ -426,20 +348,18 @@ module Gem
# mainly used by the unit tests to provide test isolation.
def self.clear_paths
- @gem_home = nil
- @gem_path = nil
- @user_home = nil
-
@@source_index = nil
-
- @searcher = nil
+ @paths = nil
+ @user_home = nil
+ @searcher = nil
+ Gem::Specification.reset
end
##
# The path to standard location of the user's .gemrc file.
def self.config_file
- File.join Gem.user_home, '.gemrc'
+ @config_file ||= File.join Gem.user_home, '.gemrc'
end
##
@@ -462,9 +382,10 @@ module Gem
# package is not available as a gem, return nil.
def self.datadir(gem_name)
+# TODO: deprecate
spec = @loaded_specs[gem_name]
return nil if spec.nil?
- File.join(spec.full_gem_path, 'data', gem_name)
+ File.join spec.full_gem_path, "data", gem_name
end
##
@@ -475,13 +396,29 @@ module Gem
Zlib::Deflate.deflate data
end
+ def self.paths
+ @paths ||= Gem::PathSupport.new
+ end
+
+ def self.paths=(env)
+ clear_paths
+ @paths = Gem::PathSupport.new env
+ Gem::Specification.dirs = @paths.path # FIX: home is at end
+ end
+
##
# The path where gems are to be installed.
+ #--
+ # FIXME deprecate these once everything else has been done -ebh
def self.dir
- @gem_home ||= nil
- set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
- @gem_home
+ # TODO: raise "no"
+ paths.home
+ end
+
+ def self.path
+ # TODO: raise "no"
+ paths.path
end
##
@@ -490,33 +427,35 @@ module Gem
def self.each_load_path(partials)
partials.each do |gp|
- base = File.basename(gp)
- specfn = File.join(dir, "specifications", base + ".gemspec")
- if File.exist?(specfn)
- spec = eval(File.read(specfn))
+ base = File.basename gp
+ specfn = dir.specifications.add(base + ".gemspec")
+ if specfn.exist?
+ spec = eval(specfn.read)
spec.require_paths.each do |rp|
- yield(File.join(gp, rp))
+ yield(gp.add(rp))
end
else
- filename = File.join(gp, 'lib')
- yield(filename) if File.exist?(filename)
+ filename = dir.add(gp, 'lib')
+ yield(filename) if filename.exist?
end
end
end
private_class_method :each_load_path
+
##
# Quietly ensure the named Gem directory contains all the proper
# subdirectories. If we can't create a directory due to a permission
# problem, then we will silently continue.
- def self.ensure_gem_subdirectories(gemdir)
+ def self.ensure_gem_subdirectories dir = Gem.dir
require 'fileutils'
- Gem::DIRECTORIES.each do |filename|
- fn = File.join gemdir, filename
- FileUtils.mkdir_p fn rescue nil unless File.exist? fn
+ %w[cache doc gems specifications].each do |name|
+ subdir = File.join dir, name
+ next if File.exist? subdir
+ FileUtils.mkdir_p subdir rescue nil # in case of perms issues -- lame
end
end
@@ -541,11 +480,9 @@ module Gem
}.flatten.select { |file| File.file? file.untaint }
end
- specs = searcher.find_all glob
-
- specs.each do |spec|
- files.concat searcher.matching_files(spec, glob)
- end
+ files.concat Gem::Specification.map { |spec|
+ spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
+ }.flatten
# $LOAD_PATH might contain duplicate entries or reference
# the spec dirs directly, so we prune.
@@ -565,25 +502,30 @@ module Gem
# it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
# least on Win32).
#++
+ #--
+ #
+ # FIXME move to pathsupport
+ #
+ #++
def self.find_home
- unless RUBY_VERSION > '1.9' then
- ['HOME', 'USERPROFILE'].each do |homekey|
- return File.expand_path(ENV[homekey]) if ENV[homekey]
+ windows = File::ALT_SEPARATOR
+ if not windows or RUBY_VERSION >= '1.9' then
+ File.expand_path "~"
+ else
+ ['HOME', 'USERPROFILE'].each do |key|
+ return File.expand_path ENV[key] if ENV[key]
end
if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
- return File.expand_path("#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}")
+ File.expand_path "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
end
end
-
- File.expand_path "~"
rescue
- if File::ALT_SEPARATOR then
- drive = ENV['HOMEDRIVE'] || ENV['SystemDrive']
- File.join(drive.to_s, '/')
+ if windows then
+ File.expand_path File.join(ENV['HOMEDRIVE'] || ENV['SystemDrive'], '/')
else
- "/"
+ File.expand_path "/"
end
end
@@ -593,6 +535,7 @@ module Gem
# Zlib::GzipReader wrapper that unzips +data+.
def self.gunzip(data)
+ # TODO: move to utils
require 'stringio'
require 'zlib'
data = StringIO.new data
@@ -604,6 +547,7 @@ module Gem
# Zlib::GzipWriter wrapper that zips +data+.
def self.gzip(data)
+ # TODO: move to utils
require 'stringio'
require 'zlib'
zipped = StringIO.new
@@ -617,6 +561,7 @@ module Gem
# A Zlib::Inflate#inflate wrapper
def self.inflate(data)
+ # TODO: move to utils
require 'zlib'
Zlib::Inflate.inflate data
end
@@ -626,12 +571,14 @@ module Gem
# <tt>https://rubygems.org</tt>.
def self.host
+ # TODO: move to utils
@host ||= "https://rubygems.org"
end
## Set the default RubyGems API host.
def self.host= host
+ # TODO: move to utils
@host = host
end
@@ -644,7 +591,7 @@ module Gem
Gem.path.each do |gemdir|
each_load_path(latest_partials(gemdir)) do |load_path|
- result << load_path
+ result << gemdir.add(load_path).expand_path
end
end
@@ -657,8 +604,9 @@ module Gem
def self.latest_partials(gemdir)
latest = {}
all_partials(gemdir).each do |gp|
- base = File.basename(gp)
- if base =~ /(.*)-((\d+\.)*\d+)/ then
+ base = File.basename gp
+
+ if base.to_s =~ /(.*)-((\d+\.)*\d+)/ then
name, version = $1, $2
ver = Gem::Version.new(version)
if latest[name].nil? || ver > latest[name][0]
@@ -712,6 +660,7 @@ module Gem
file = $1
lineno = $2.to_i
+ # TODO: it is ALWAYS joined! STUPID!
[file, lineno]
end
@@ -723,25 +672,6 @@ module Gem
end
##
- # Array of paths to search for Gems.
-
- def self.path
- @gem_path ||= nil
-
- unless @gem_path then
- paths = [ENV['GEM_PATH'] || default_path]
-
- if defined?(APPLE_GEM_HOME) and not ENV['GEM_PATH'] then
- paths << APPLE_GEM_HOME
- end
-
- set_paths paths.compact.join(File::PATH_SEPARATOR)
- end
-
- @gem_path
- end
-
- ##
# Get the appropriate cache path.
#
# Pass a string to use a different base path, or nil/false (default) for
@@ -749,7 +679,7 @@ module Gem
#
def self.cache_dir(custom_dir=false)
- File.join(custom_dir ? custom_dir : Gem.dir, 'cache')
+ File.join(custom_dir || Gem.dir, "cache")
end
##
@@ -759,7 +689,7 @@ module Gem
# nil/false (default) for Gem.dir.
def self.cache_gem(filename, user_dir=false)
- File.join(cache_dir(user_dir), filename)
+ cache_dir(user_dir).add(filename)
end
##
@@ -800,6 +730,14 @@ module Gem
end
##
+ # Adds a hook that will get run after Gem::Specification.reset is
+ # run.
+
+ def self.post_reset(&hook)
+ @post_reset_hooks << hook
+ end
+
+ ##
# Adds a post-uninstall hook that will be passed a Gem::Uninstaller instance
# and the spec that was uninstalled when Gem::Uninstaller#uninstall is
# called
@@ -818,6 +756,14 @@ module Gem
end
##
+ # Adds a hook that will get run before Gem::Specification.reset is
+ # run.
+
+ def self.pre_reset(&hook)
+ @pre_reset_hooks << hook
+ end
+
+ ##
# Adds a pre-uninstall hook that will be passed an Gem::Uninstaller instance
# and the spec that will be uninstalled when Gem::Uninstaller#uninstall is
# called
@@ -853,10 +799,10 @@ module Gem
raise ArgumentError, "gem #{gem_name} is not activated" if gem.nil?
raise ArgumentError, "gem #{over_name} is not activated" if over.nil?
- last_gem_path = File.join gem.full_gem_path, gem.require_paths.last
+ last_gem_path = Gem::Path.path(gem.full_gem_path).add(gem.require_paths.last)
over_paths = over.require_paths.map do |path|
- File.join over.full_gem_path, path
+ Gem::Path.path(over.full_gem_path).add(path).to_s
end
over_paths.each do |path|
@@ -872,8 +818,8 @@ module Gem
# Refresh source_index from disk and clear searcher.
def self.refresh
- source_index.refresh!
-
+ Gem::Specification.reset
+ @source_index = nil
@searcher = nil
end
@@ -890,7 +836,7 @@ module Gem
# any version by the requested name.
def self.report_activate_error(gem)
- matches = Gem.source_index.find_name(gem.name)
+ matches = Gem::Specification.find_by_name(gem.name)
if matches.empty? then
error = Gem::LoadError.new(
@@ -915,14 +861,14 @@ module Gem
def self.required_location(gemname, libfile, *requirements)
requirements = Gem::Requirement.default if requirements.empty?
- matches = Gem.source_index.find_name gemname, requirements
+ matches = Gem::Specification.find_all_by_name gemname, *requirements
return nil if matches.empty?
spec = matches.last
spec.require_paths.each do |path|
- result = File.join spec.full_gem_path, path, libfile
- return result if File.exist? result
+ result = Gem::Path.path(spec.full_gem_path).add(path, libfile)
+ return result if result.exist?
end
nil
@@ -934,11 +880,9 @@ module Gem
def self.ruby
if @ruby.nil? then
@ruby = File.join(ConfigMap[:bindir],
- ConfigMap[:ruby_install_name])
- @ruby << ConfigMap[:EXEEXT]
+ "#{ConfigMap[:ruby_install_name]}#{ConfigMap[:EXEEXT]}")
- # escape string in case path to ruby executable contain spaces.
- @ruby.sub!(/.*\s.*/m, '"\&"')
+ @ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
end
@ruby
@@ -991,44 +935,12 @@ module Gem
end
##
- # Set the Gem home directory (as reported by Gem.dir).
-
- def self.set_home(home)
- home = home.gsub File::ALT_SEPARATOR, File::SEPARATOR if File::ALT_SEPARATOR
- @gem_home = home
- end
-
- private_class_method :set_home
-
- ##
- # Set the Gem search path (as reported by Gem.path).
-
- def self.set_paths(gpaths)
- if gpaths
- @gem_path = gpaths.split(File::PATH_SEPARATOR)
-
- if File::ALT_SEPARATOR then
- @gem_path.map! do |path|
- path.gsub File::ALT_SEPARATOR, File::SEPARATOR
- end
- end
-
- @gem_path << Gem.dir
- else
- # TODO: should this be Gem.default_path instead?
- @gem_path = [Gem.dir]
- end
-
- @gem_path.uniq!
- end
-
- private_class_method :set_paths
-
- ##
# Returns the Gem::SourceIndex of specifications that are in the Gem.path
def self.source_index
- @@source_index ||= SourceIndex.from_installed_gems
+ @@source_index ||= Deprecate.skip_during do
+ SourceIndex.new Gem::Specification.dirs
+ end
end
##
@@ -1037,23 +949,14 @@ module Gem
# default_sources if it is not installed.
def self.sources
- if @sources.empty? then
- begin
- gem 'sources', '> 0.0.1'
- require 'sources'
- rescue LoadError
- @sources = default_sources
- end
- end
-
- @sources
+ @sources ||= default_sources
end
##
# Need to be able to set the sources without calling
# Gem.sources.replace since that would cause an infinite loop.
- def self.sources=(new_sources)
+ def self.sources= new_sources
@sources = new_sources
end
@@ -1115,9 +1018,8 @@ module Gem
# by the unit tests to provide environment isolation.
def self.use_paths(home, paths=[])
- clear_paths
- set_home(home) if home
- set_paths(paths.join(File::PATH_SEPARATOR)) if paths
+ self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths }
+ # TODO: self.paths = home, paths
end
##
@@ -1202,6 +1104,11 @@ module Gem
attr_reader :post_install_hooks
##
+ # The list of hooks to be run after Gem::Specification.reset is run.
+
+ attr_reader :post_reset_hooks
+
+ ##
# The list of hooks to be run before Gem::Uninstall#uninstall does any
# work
@@ -1213,18 +1120,17 @@ module Gem
attr_reader :pre_install_hooks
##
+ # The list of hooks to be run before Gem::Specification.reset is run.
+
+ attr_reader :pre_reset_hooks
+
+ ##
# The list of hooks to be run after Gem::Uninstall#uninstall is finished
attr_reader :pre_uninstall_hooks
-
end
def self.cache # :nodoc:
- warn "#{Gem.location_of_caller.join ':'}:Warning: " \
- "Gem::cache is deprecated and will be removed on or after " \
- "August 2011. " \
- "Use Gem::source_index."
-
source_index
end
@@ -1233,17 +1139,17 @@ module Gem
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
- autoload :Version, 'rubygems/version'
- autoload :Requirement, 'rubygems/requirement'
- autoload :Dependency, 'rubygems/dependency'
+ autoload :Version, 'rubygems/version'
+ autoload :Requirement, 'rubygems/requirement'
+ autoload :Dependency, 'rubygems/dependency'
autoload :GemPathSearcher, 'rubygems/gem_path_searcher'
- autoload :SpecFetcher, 'rubygems/spec_fetcher'
- autoload :Specification, 'rubygems/specification'
- autoload :Cache, 'rubygems/source_index'
- autoload :SourceIndex, 'rubygems/source_index'
- autoload :Platform, 'rubygems/platform'
- autoload :Builder, 'rubygems/builder'
- autoload :ConfigFile, 'rubygems/config_file'
+ autoload :SpecFetcher, 'rubygems/spec_fetcher'
+ autoload :Specification, 'rubygems/specification'
+ autoload :Cache, 'rubygems/source_index'
+ autoload :SourceIndex, 'rubygems/source_index'
+ autoload :Platform, 'rubygems/platform'
+ autoload :Builder, 'rubygems/builder'
+ autoload :ConfigFile, 'rubygems/config_file'
end
module Kernel
@@ -1279,7 +1185,8 @@ module Kernel
def gem(gem_name, *requirements) # :doc:
skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
- Gem.activate(gem_name, *requirements)
+ spec = Gem::Dependency.new(gem_name, *requirements).to_spec
+ spec.activate if spec
end
private :gem
@@ -1300,8 +1207,7 @@ def RbConfig.datadir(package_name)
require 'rbconfig/datadir'
- Gem.datadir(package_name) ||
- File.join(Gem::ConfigMap[:datadir], package_name)
+ Gem.datadir(package_name) || File.join(Gem::ConfigMap[:datadir], package_name)
end
require 'rubygems/exceptions'
@@ -1334,3 +1240,25 @@ require 'rubygems/custom_require'
Gem.clear_paths
+module Gem
+ class << self
+ extend Deprecate
+ deprecate :activate_dep, "Specification#activate", 2011, 6
+ deprecate :activate_spec, "Specification#activate", 2011, 6
+ deprecate :cache, "Gem::source_index", 2011, 8
+ deprecate :activate, "Specification#activate", 2011, 10
+ deprecate :all_load_paths, :none, 2011, 10
+ deprecate :all_partials, :none, 2011, 10
+ deprecate :latest_load_paths, :none, 2011, 10
+ deprecate :promote_load_path, :none, 2011, 10
+ deprecate :available?, "Specification::find_by_name", 2011, 11
+ deprecate :cache_dir, "Specification#cache_dir", 2011, 11
+ deprecate :cache_gem, "Specification#cache_file", 2011, 11
+ deprecate :default_system_source_cache_dir, :none, 2011, 11
+ deprecate :default_user_source_cache_dir, :none, 2011, 11
+ deprecate :report_activate_error, :none, 2011, 11
+ deprecate :required_location, :none, 2011, 11
+ deprecate :searcher, "Specification", 2011, 11
+ deprecate :source_index, "Specification", 2011, 11
+ end
+end
diff --git a/lib/rubygems/builder.rb b/lib/rubygems/builder.rb
index c07369f..ea4e13e 100644
--- a/lib/rubygems/builder.rb
+++ b/lib/rubygems/builder.rb
@@ -44,7 +44,7 @@ class Gem::Builder
@signer = sign
write_package
say success if Gem.configuration.verbose
- @spec.file_name
+ File.basename @spec.cache_file
end
def success
@@ -52,7 +52,7 @@ class Gem::Builder
Successfully built RubyGem
Name: #{@spec.name}
Version: #{@spec.version}
- File: #{@spec.file_name}
+ File: #{File.basename @spec.cache_file}
EOM
end
@@ -79,16 +79,17 @@ EOM
end
def write_package
- open @spec.file_name, 'wb' do |gem_io|
+ file_name = File.basename @spec.cache_file
+ open file_name, 'wb' do |gem_io|
Gem::Package.open gem_io, 'w', @signer do |pkg|
yaml = @spec.to_yaml
pkg.metadata = yaml
@spec.files.each do |file|
- next if File.directory? file
- next if file == @spec.file_name # Don't add gem onto itself
+ next if File.directory?(file)
+ next if file == file_name # Don't add gem onto itself
- stat = File.stat file
+ stat = File.stat(file)
mode = stat.mode & 0777
size = stat.size
diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb
index 98503cb..fd6cb01 100644
--- a/lib/rubygems/command.rb
+++ b/lib/rubygems/command.rb
@@ -410,10 +410,12 @@ class Gem::Command
end
end
- @parser.separator nil
- @parser.separator " Summary:"
- wrap(@summary, 80 - 4).split("\n").each do |line|
- @parser.separator " #{line.strip}"
+ if @summary then
+ @parser.separator nil
+ @parser.separator " Summary:"
+ wrap(@summary, 80 - 4).split("\n").each do |line|
+ @parser.separator " #{line.strip}"
+ end
end
if description then
diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb
index 60d82c8..3665f31 100644
--- a/lib/rubygems/command_manager.rb
+++ b/lib/rubygems/command_manager.rb
@@ -44,6 +44,13 @@ class Gem::CommandManager
end
##
+ # Reset the authoritative instance of the command manager.
+
+ def self.reset
+ @command_manager = nil
+ end
+
+ ##
# Register all the subcommands supported by the gem command.
def initialize
@@ -87,6 +94,13 @@ class Gem::CommandManager
end
##
+ # Unregister the Symbol +command+ as a gem command.
+
+ def unregister_command(command)
+ @commands.delete command
+ end
+
+ ##
# Return the registered command from the command name.
def [](command_name)
@@ -166,7 +180,7 @@ class Gem::CommandManager
retried = false
begin
- commands.const_get const_name
+ commands.const_get(const_name).new
rescue NameError
raise if retried
@@ -179,7 +193,7 @@ class Gem::CommandManager
Gem.configuration.backtrace
end
retry
- end.new
+ end
end
end
diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb
index 5aac489..cdae367 100644
--- a/lib/rubygems/commands/build_command.rb
+++ b/lib/rubygems/commands/build_command.rb
@@ -23,32 +23,34 @@ class Gem::Commands::BuildCommand < Gem::Command
def execute
gemspec = get_one_gem_name
- if File.exist?(gemspec)
- specs = load_gemspecs(gemspec)
- specs.each do |spec|
+
+ if File.exist? gemspec
+ spec = load_gemspec gemspec
+
+ if spec then
Gem::Builder.new(spec).build
+ else
+ alert_error "Error loading gemspec. Aborting."
+ terminate_interaction 1
end
else
alert_error "Gemspec file not found: #{gemspec}"
+ terminate_interaction 1
end
end
- def load_gemspecs(filename)
+ def load_gemspec filename
if yaml?(filename)
- result = []
open(filename) do |f|
begin
- while not f.eof? and spec = Gem::Specification.from_yaml(f)
- result << spec
- end
+ Gem::Specification.from_yaml(f)
rescue Gem::EndOfYAMLException
- # OK
+ nil
end
end
else
- result = [Gem::Specification.load(filename)]
+ Gem::Specification.load(filename) # can return nil
end
- result
end
def yaml?(filename)
diff --git a/lib/rubygems/commands/cert_command.rb b/lib/rubygems/commands/cert_command.rb
index 17eaaa1..d667f5c 100644
--- a/lib/rubygems/commands/cert_command.rb
+++ b/lib/rubygems/commands/cert_command.rb
@@ -56,7 +56,7 @@ class Gem::Commands::CertCommand < Gem::Command
'Build private key and self-signed',
'certificate for EMAIL_ADDR.') do |value, options|
vals = Gem::Security.build_self_signed_cert(value)
- File.chmod 0600, vals[:key_path]
+ FileUtils.chmod 0600, vals[:key_path]
say "Public Cert: #{vals[:cert_path]}"
say "Private Key: #{vals[:key_path]}"
say "Don't forget to move the key file to somewhere private..."
diff --git a/lib/rubygems/commands/cleanup_command.rb b/lib/rubygems/commands/cleanup_command.rb
index 0cdf504..2d8d8ff 100644
--- a/lib/rubygems/commands/cleanup_command.rb
+++ b/lib/rubygems/commands/cleanup_command.rb
@@ -5,7 +5,6 @@
######################################################################
require 'rubygems/command'
-require 'rubygems/source_index'
require 'rubygems/dependency_list'
require 'rubygems/uninstaller'
@@ -44,28 +43,20 @@ installed elsewhere in GEM_PATH the cleanup command won't touch it.
say "Cleaning up installed gems..."
primary_gems = {}
- Gem.source_index.each do |name, spec|
+ Gem::Specification.each do |spec|
if primary_gems[spec.name].nil? or
primary_gems[spec.name].version < spec.version then
primary_gems[spec.name] = spec
end
end
- gems_to_cleanup = []
-
- unless options[:args].empty? then
- options[:args].each do |gem_name|
- dep = Gem::Dependency.new gem_name, Gem::Requirement.default
- specs = Gem.source_index.search dep
- specs.each do |spec|
- gems_to_cleanup << spec
- end
- end
- else
- Gem.source_index.each do |name, spec|
- gems_to_cleanup << spec
- end
- end
+ gems_to_cleanup = unless options[:args].empty? then
+ options[:args].map do |gem_name|
+ Gem::Specification.find_all_by_name gem_name
+ end.flatten
+ else
+ Gem::Specification.to_a
+ end
gems_to_cleanup = gems_to_cleanup.select { |spec|
primary_gems[spec.name].version != spec.version
@@ -89,8 +80,8 @@ installed elsewhere in GEM_PATH the cleanup command won't touch it.
:version => "= #{spec.version}",
}
- if Gem.user_dir == spec.installation_path then
- uninstall_options[:install_dir] = spec.installation_path
+ if Gem.user_dir == spec.base_dir then
+ uninstall_options[:install_dir] = spec.base_dir
end
uninstaller = Gem::Uninstaller.new spec.name, uninstall_options
diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb
index 42ae913..8e015ae 100644
--- a/lib/rubygems/commands/contents_command.rb
+++ b/lib/rubygems/commands/contents_command.rb
@@ -58,24 +58,24 @@ class Gem::Commands::ContentsCommand < Gem::Command
end.flatten
path_kind = if spec_dirs.empty? then
- spec_dirs = Gem::SourceIndex.installed_spec_directories
+ spec_dirs = Gem::Specification.dirs
"default gem paths"
else
"specified path"
end
- si = Gem::SourceIndex.from_gems_in(*spec_dirs)
-
gem_names = if options[:all] then
- si.map { |_, spec| spec.name }
+ Gem::Specification.map(&:name)
else
get_all_gem_names
end
gem_names.each do |name|
- gem_spec = si.find_name(name, version).last
+ # HACK: find_by_name fails for some reason... ARGH
+ # How many places must we embed our resolve logic?
+ spec = Gem::Specification.find_all_by_name(name, version).last
- unless gem_spec then
+ unless spec then
say "Unable to find gem '#{name}' in #{path_kind}"
if Gem.configuration.verbose then
@@ -86,16 +86,19 @@ class Gem::Commands::ContentsCommand < Gem::Command
terminate_interaction 1 if gem_names.length == 1
end
- files = options[:lib_only] ? gem_spec.lib_files : gem_spec.files
+ gem_path = spec.full_gem_path
+ extra = "/{#{spec.require_paths.join ','}}" if options[:lib_only]
+ glob = "#{gem_path}#{extra}/**/*"
+ files = Dir[glob]
+
+ gem_path = File.join gem_path, '' # add trailing / if missing
+
+ files.sort.each do |file|
+ next if File.directory? file
- files.each do |f|
- path = if options[:prefix] then
- File.join gem_spec.full_gem_path, f
- else
- f
- end
+ file = file.sub gem_path, '' unless options[:prefix]
- say path
+ say file
end
end
end
diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb
index b6840c3..209fdeb 100644
--- a/lib/rubygems/commands/dependency_command.rb
+++ b/lib/rubygems/commands/dependency_command.rb
@@ -49,13 +49,13 @@ class Gem::Commands::DependencyCommand < Gem::Command
end
def execute
- options[:args] << '' if options[:args].empty?
- specs = {}
-
- source_indexes = Hash.new do |h, source_uri|
- h[source_uri] = Gem::SourceIndex.new
+ if options[:reverse_dependencies] and remote? and not local? then
+ alert_error 'Only reverse dependencies for local gems are supported.'
+ terminate_interaction 1
end
+ options[:args] << '' if options[:args].empty?
+
pattern = if options[:args].length == 1 and
options[:args].first =~ /\A\/(.*)\/(i)?\z/m then
flags = $2 ? Regexp::IGNORECASE : nil
@@ -64,34 +64,30 @@ class Gem::Commands::DependencyCommand < Gem::Command
/\A#{Regexp.union(*options[:args])}/
end
- dependency = Gem::Dependency.new pattern, options[:version]
+ # TODO: deprecate for real damnit
+ dependency = Deprecate.skip_during {
+ Gem::Dependency.new pattern, options[:version]
+ }
dependency.prerelease = options[:prerelease]
- if options[:reverse_dependencies] and remote? and not local? then
- alert_error 'Only reverse dependencies for local gems are supported.'
- terminate_interaction 1
- end
+ specs = []
- if local? then
- Gem.source_index.search(dependency).each do |spec|
- source_indexes[:local].add_spec spec
- end
- end
+ specs.concat dependency.matching_specs if local?
if remote? and not options[:reverse_dependencies] then
fetcher = Gem::SpecFetcher.fetcher
- specs_and_sources = fetcher.find_matching(dependency, false, true,
+ # REFACTOR: fetcher.find_specs_matching => specs
+ specs_and_sources = fetcher.find_matching(dependency,
+ dependency.specific?, true,
dependency.prerelease?)
- specs_and_sources.each do |spec_tuple, source_uri|
- spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
-
- source_indexes[source_uri].add_spec spec
- end
+ specs.concat specs_and_sources.map { |spec_tuple, source_uri|
+ fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
+ }
end
- if source_indexes.empty? then
+ if specs.empty? then
patterns = options[:args].join ','
say "No gems found matching #{patterns} (#{options[:version]})" if
Gem.configuration.verbose
@@ -99,24 +95,18 @@ class Gem::Commands::DependencyCommand < Gem::Command
terminate_interaction 1
end
- specs = {}
-
- source_indexes.values.each do |source_index|
- source_index.gems.each do |name, spec|
- specs[spec.full_name] = [source_index, spec]
- end
- end
+ specs = specs.uniq.sort
reverse = Hash.new { |h, k| h[k] = [] }
if options[:reverse_dependencies] then
- specs.values.each do |_, spec|
+ specs.each do |spec|
reverse[spec.full_name] = find_reverse_dependencies spec
end
end
if options[:pipe_format] then
- specs.values.sort_by { |_, spec| spec }.each do |_, spec|
+ specs.each do |spec|
unless spec.dependencies.empty?
spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
say "#{dep.name} --version '#{dep.requirement}'"
@@ -126,7 +116,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
else
response = ''
- specs.values.sort_by { |_, spec| spec }.each do |_, spec|
+ specs.each do |spec|
response << print_dependencies(spec)
unless reverse[spec.full_name].empty? then
response << " Used by\n"
@@ -158,7 +148,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
def find_reverse_dependencies(spec)
result = []
- Gem.source_index.each do |name, sp|
+ Gem::Specification.each do |sp|
sp.dependencies.each do |dep|
dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep
@@ -172,17 +162,5 @@ class Gem::Commands::DependencyCommand < Gem::Command
result
end
- def find_gems(name, source_index)
- specs = {}
-
- spec_list = source_index.search name, options[:version]
-
- spec_list.each do |spec|
- specs[spec.full_name] = [source_index, spec]
- end
-
- specs
- end
-
end
diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb
index c0fdc83..7d99276 100644
--- a/lib/rubygems/commands/fetch_command.rb
+++ b/lib/rubygems/commands/fetch_command.rb
@@ -41,19 +41,22 @@ class Gem::Commands::FetchCommand < Gem::Command
version = options[:version] || Gem::Requirement.default
all = Gem::Requirement.default != version
+ platform = Gem.platforms.last
gem_names = get_all_gem_names
gem_names.each do |gem_name|
dep = Gem::Dependency.new gem_name, version
dep.prerelease = options[:prerelease]
- specs_and_sources = Gem::SpecFetcher.fetcher.fetch(dep, all, true,
- dep.prerelease?)
-
specs_and_sources, errors =
Gem::SpecFetcher.fetcher.fetch_with_errors(dep, all, true,
dep.prerelease?)
+ if platform then
+ filtered = specs_and_sources.select { |s,| s.platform == platform }
+ specs_and_sources = filtered unless filtered.empty?
+ end
+
spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last
if spec.nil? then
@@ -62,7 +65,7 @@ class Gem::Commands::FetchCommand < Gem::Command
end
path = Gem::RemoteFetcher.fetcher.download spec, source_uri
- FileUtils.mv path, spec.file_name
+ FileUtils.mv path, File.basename(spec.cache_file)
say "Downloaded #{spec.full_name}"
end
diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb
index 530f746..fff41cf 100644
--- a/lib/rubygems/commands/install_command.rb
+++ b/lib/rubygems/commands/install_command.rb
@@ -120,7 +120,8 @@ to write the specification by hand. For example:
get_all_gem_names.each do |gem_name|
begin
- next if options[:conservative] && Gem.available?(gem_name, options[:version])
+ next if options[:conservative] and
+ not Gem::Dependency.new(gem_name, options[:version]).matching_specs.empty?
inst = Gem::DependencyInstaller.new options
inst.install gem_name, options[:version]
diff --git a/lib/rubygems/commands/lock_command.rb b/lib/rubygems/commands/lock_command.rb
index a17dd36..9ce9da6 100644
--- a/lib/rubygems/commands/lock_command.rb
+++ b/lib/rubygems/commands/lock_command.rb
@@ -93,7 +93,7 @@ lock it down to the exact version.
spec.runtime_dependencies.each do |dep|
next if locked[dep.name]
- candidates = Gem.source_index.search dep
+ candidates = dep.matching_specs
if candidates.empty? then
complain "Unable to satisfy '#{dep}' from currently installed gems"
@@ -105,11 +105,11 @@ lock it down to the exact version.
end
def spec_path(gem_full_name)
- gemspecs = Gem.path.map do |path|
+ gemspecs = Gem.path.map { |path|
File.join path, "specifications", "#{gem_full_name}.gemspec"
- end
+ }
- gemspecs.find { |gemspec| File.exist? gemspec }
+ gemspecs.find { |path| File.exist? path }
end
end
diff --git a/lib/rubygems/commands/outdated_command.rb b/lib/rubygems/commands/outdated_command.rb
index 7b6e1cf..8b7dda6 100644
--- a/lib/rubygems/commands/outdated_command.rb
+++ b/lib/rubygems/commands/outdated_command.rb
@@ -22,10 +22,8 @@ class Gem::Commands::OutdatedCommand < Gem::Command
end
def execute
- locals = Gem::SourceIndex.from_installed_gems
-
- locals.outdated.sort.each do |name|
- local = locals.find_name(name).last
+ Gem::Specification.outdated.sort.each do |name|
+ local = Gem::Specification.find_all_by_name(name).max
dep = Gem::Dependency.new local.name, ">= #{local.version}"
remotes = Gem::SpecFetcher.fetcher.fetch dep
@@ -35,6 +33,4 @@ class Gem::Commands::OutdatedCommand < Gem::Command
say "#{local.name} (#{local.version} < #{remote.version})"
end
end
-
end
-
diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb
index 9a0b2e9..9972275 100644
--- a/lib/rubygems/commands/pristine_command.rb
+++ b/lib/rubygems/commands/pristine_command.rb
@@ -16,7 +16,8 @@ class Gem::Commands::PristineCommand < Gem::Command
def initialize
super 'pristine',
'Restores installed gems to pristine condition from files located in the gem cache',
- :version => Gem::Requirement.default
+ :version => Gem::Requirement.default, :extensions => true,
+ :all => false
add_option('--all',
'Restore all installed gems to pristine',
@@ -24,6 +25,11 @@ class Gem::Commands::PristineCommand < Gem::Command
options[:all] = value
end
+ add_option('--[no-]extensions',
+ 'Restore gems with extensions') do |value, options|
+ options[:extensions] = value
+ end
+
add_version_option('restore to', 'pristine condition')
end
@@ -32,7 +38,7 @@ class Gem::Commands::PristineCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--all"
+ "--all --extensions"
end
def description # :nodoc:
@@ -46,6 +52,9 @@ for the gem are regenerated.
If the cached gem cannot be found, you will need to use `gem install` to
revert the gem.
+
+If --no-extensions is provided pristine will not attempt to restore gems with
+extensions.
EOF
end
@@ -54,21 +63,17 @@ revert the gem.
end
def execute
- gem_name = nil
-
specs = if options[:all] then
- Gem::SourceIndex.from_installed_gems.map do |name, spec|
- spec
- end
+ Gem::Specification.map
else
- gem_name = get_one_gem_name
- Gem::SourceIndex.from_installed_gems.find_name(gem_name,
- options[:version])
+ get_all_gem_names.map do |gem_name|
+ Gem::Specification.find_all_by_name gem_name, options[:version]
+ end.flatten
end
- if specs.empty? then
+ if specs.to_a.empty? then
raise Gem::Exception,
- "Failed to find gem #{gem_name} #{options[:version]}"
+ "Failed to find gems #{options[:args]} #{options[:version]}"
end
install_dir = Gem.dir # TODO use installer option
@@ -76,25 +81,32 @@ revert the gem.
raise Gem::FilePermissionError.new(install_dir) unless
File.writable?(install_dir)
- say "Restoring gem(s) to pristine condition..."
+ say "Restoring gems to pristine condition..."
specs.each do |spec|
- gem = spec.cache_gem
+ unless spec.extensions.empty? or options[:extensions] then
+ say "Skipped #{spec.full_name}, it needs to compile an extension"
+ next
+ end
+
+ gem = spec.cache_file
+
+ unless File.exist? gem then
+ require 'rubygems/remote_fetcher'
- if gem.nil? then
say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
dep = Gem::Dependency.new spec.name, spec.version
Gem::RemoteFetcher.fetcher.download_to_cache dep
- gem = spec.cache_gem
end
# TODO use installer options
- installer = Gem::Installer.new gem, :wrappers => true, :force => true
+ installer = Gem::Installer.new(gem,
+ :wrappers => true,
+ :force => true,
+ :install_dir => spec.base_dir)
installer.install
say "Restored #{spec.full_name}"
end
end
-
end
-
diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb
index 29e5306..d82f8ae 100644
--- a/lib/rubygems/commands/query_command.rb
+++ b/lib/rubygems/commands/query_command.rb
@@ -80,10 +80,12 @@ class Gem::Commands::QueryCommand < Gem::Command
exit_code |= 1
end
- raise Gem::SystemExitException, exit_code
+ terminate_interaction exit_code
end
- dep = Gem::Dependency.new name, Gem::Requirement.default
+ req = Gem::Requirement.default
+ # TODO: deprecate for real
+ dep = Deprecate.skip_during { Gem::Dependency.new name, req }
if local? then
if prerelease and not both? then
@@ -96,7 +98,9 @@ class Gem::Commands::QueryCommand < Gem::Command
say
end
- specs = Gem.source_index.search dep
+ specs = Gem::Specification.find_all { |s|
+ s.name =~ name and req =~ s.version
+ }
spec_tuples = specs.map do |spec|
[[spec.name, spec.version, spec.original_platform, spec], :local]
@@ -129,9 +133,8 @@ class Gem::Commands::QueryCommand < Gem::Command
##
# Check if gem +name+ version +version+ is installed.
- def installed?(name, version = Gem::Requirement.default)
- dep = Gem::Dependency.new name, version
- !Gem.source_index.search(dep).empty?
+ def installed?(name, req = Gem::Requirement.default)
+ Gem::Specification.any? { |s| s.name =~ name and req =~ s.version }
end
def output_query_results(spec_tuples)
diff --git a/lib/rubygems/commands/server_command.rb b/lib/rubygems/commands/server_command.rb
index c59f216..0d18a82 100644
--- a/lib/rubygems/commands/server_command.rb
+++ b/lib/rubygems/commands/server_command.rb
@@ -50,7 +50,7 @@ class Gem::Commands::ServerCommand < Gem::Command
options[:addresses].push(*address)
end
- add_option '-l', '--launch[=COMMAND]',
+ add_option '-l', '--launch[=COMMAND]',
'launches a browser window',
"COMMAND defaults to 'start' on Windows",
"and 'open' on all other platforms" do |launch, options|
diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb
index cf844c6..6aa8005 100644
--- a/lib/rubygems/commands/setup_command.rb
+++ b/lib/rubygems/commands/setup_command.rb
@@ -338,7 +338,7 @@ abort "#{deprecation_message}"
args << '--main' << 'README.rdoc' << '--quiet'
args << '.'
args << 'README.rdoc' << 'UPGRADING.rdoc'
- args << 'LICENSE.txt' << 'GPL.txt' << 'History.txt'
+ args << 'LICENSE.txt' << 'MIT.txt' << 'History.txt'
r = RDoc::RDoc.new
r.document args
diff --git a/lib/rubygems/commands/specification_command.rb b/lib/rubygems/commands/specification_command.rb
index 987e401..e4036ae 100644
--- a/lib/rubygems/commands/specification_command.rb
+++ b/lib/rubygems/commands/specification_command.rb
@@ -72,18 +72,8 @@ FIELD name of gemspec field to show
field = get_one_optional_argument
- if field then
- field = field.intern
-
- if options[:format] == :ruby then
- raise Gem::CommandLineError, "--ruby and FIELD are mutually exclusive"
- end
-
- unless Gem::Specification.attribute_names.include? field then
- raise Gem::CommandLineError,
- "no field %p on Gem::Specification" % field.to_s
- end
- end
+ raise Gem::CommandLineError, "--ruby and FIELD are mutually exclusive" if
+ field and options[:format] == :ruby
if local? then
if File.exist? gem then
@@ -91,7 +81,7 @@ FIELD name of gemspec field to show
end
if specs.empty? then
- specs.push(*Gem.source_index.search(dep))
+ specs.push(*dep.matching_specs)
end
end
@@ -106,7 +96,11 @@ FIELD name of gemspec field to show
terminate_interaction 1
end
- output = lambda do |s|
+ unless options[:all] then
+ specs = [specs.sort_by { |s| s.version }.last]
+ end
+
+ specs.each do |s|
s = s.send field if field
say case options[:format]
@@ -117,14 +111,5 @@ FIELD name of gemspec field to show
say "\n"
end
-
- if options[:all] then
- specs.each(&output)
- else
- spec = specs.sort_by { |s| s.version }.last
- output[spec]
- end
end
-
end
-
diff --git a/lib/rubygems/commands/stale_command.rb b/lib/rubygems/commands/stale_command.rb
index 9a024fa..712e62a 100644
--- a/lib/rubygems/commands/stale_command.rb
+++ b/lib/rubygems/commands/stale_command.rb
@@ -17,7 +17,8 @@ class Gem::Commands::StaleCommand < Gem::Command
def execute
gem_to_atime = {}
- Gem.source_index.each do |name, spec|
+ Gem::Specification.each do |spec|
+ name = spec.full_name
Dir["#{spec.full_gem_path}/**/*.*"].each do |file|
next if File.directory?(file)
stat = File.stat(file)
diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb
index ef0d65e..b0fa2bf 100644
--- a/lib/rubygems/commands/unpack_command.rb
+++ b/lib/rubygems/commands/unpack_command.rb
@@ -25,6 +25,10 @@ class Gem::Commands::UnpackCommand < Gem::Command
options[:target] = value
end
+ add_option('--spec', 'unpack the gem specification') do |value, options|
+ options[:spec] = true
+ end
+
add_version_option
end
@@ -50,14 +54,30 @@ class Gem::Commands::UnpackCommand < Gem::Command
dependency = Gem::Dependency.new name, options[:version]
path = get_path dependency
- if path then
+ unless path then
+ alert_error "Gem '#{name}' not installed nor fetchable."
+ next
+ end
+
+ if @options[:spec] then
+ spec, metadata = get_metadata path
+
+ if metadata.nil? then
+ alert_error "--spec is unsupported on '#{name}' (old format gem)"
+ next
+ end
+
+ spec_file = File.basename spec.spec_file
+
+ open spec_file, 'w' do |io|
+ io.write metadata
+ end
+ else
basename = File.basename path, '.gem'
target_dir = File.expand_path basename, options[:target]
FileUtils.mkdir_p target_dir
Gem::Installer.new(path, :unpack => true).unpack target_dir
say "Unpacked gem: '#{target_dir}'"
- else
- alert_error "Gem '#{name}' not installed."
end
end
end
@@ -70,9 +90,8 @@ class Gem::Commands::UnpackCommand < Gem::Command
# TODO: see comments in get_path() about general service.
def find_in_cache(filename)
-
Gem.path.each do |path|
- this_path = Gem.cache_gem(filename, path)
+ this_path = File.join(path, "cache", filename)
return this_path if File.exist? this_path
end
@@ -99,9 +118,9 @@ class Gem::Commands::UnpackCommand < Gem::Command
def get_path dependency
return dependency.name if dependency.name =~ /\.gem$/i
- specs = Gem.source_index.search dependency
+ specs = dependency.matching_specs
- selected = specs.sort_by { |s| s.version }.last
+ selected = specs.sort_by { |s| s.version }.last # HACK: hunt last down
return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
selected
@@ -111,12 +130,37 @@ class Gem::Commands::UnpackCommand < Gem::Command
# We expect to find (basename).gem in the 'cache' directory. Furthermore,
# the name match must be exact (ignoring case).
- path = find_in_cache selected.file_name
+ path = find_in_cache File.basename selected.cache_file
return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path
path
end
+ ##
+ # Extracts the Gem::Specification and raw metadata from the .gem file at
+ # +path+.
+
+ def get_metadata path
+ format = Gem::Format.from_file_by_path path
+ spec = format.spec
+
+ metadata = nil
+
+ open path, Gem.binary_mode do |io|
+ tar = Gem::Package::TarReader.new io
+ tar.each_entry do |entry|
+ case entry.full_name
+ when 'metadata' then
+ metadata = entry.read
+ when 'metadata.gz' then
+ metadata = Gem.gunzip entry.read
+ end
+ end
+ end
+
+ return spec, metadata
+ end
+
end
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index b7c65eb..2d7da44 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -71,14 +71,14 @@ class Gem::Commands::UpdateCommand < Gem::Command
hig = {} # highest installed gems
- Gem.source_index.each do |name, spec|
+ Gem::Specification.each do |spec|
if hig[spec.name].nil? or hig[spec.name].version < spec.version then
hig[spec.name] = spec
end
end
end
- gems_to_update = which_to_update hig, options[:args]
+ gems_to_update = which_to_update hig, options[:args].uniq
updated = update_gems gems_to_update
@@ -123,8 +123,8 @@ class Gem::Commands::UpdateCommand < Gem::Command
end
def update_gems gems_to_update
- gems_to_update.uniq.sort.each do |name|
- update_gem name
+ gems_to_update.uniq.sort.each do |(name, version)|
+ update_gem name, version
end
@updated
@@ -141,6 +141,9 @@ class Gem::Commands::UpdateCommand < Gem::Command
options[:user_install] = false
+ # TODO: rename version and other variable name conflicts
+ # TODO: get rid of all this indirection on name and other BS
+
version = options[:system]
if version == true then
version = Gem::Version.new Gem::VERSION
@@ -158,18 +161,25 @@ class Gem::Commands::UpdateCommand < Gem::Command
'rubygems-update' => rubygems_update
}
- gems_to_update = which_to_update hig, options[:args]
+ gems_to_update = which_to_update hig, options[:args], :system
+ name, up_ver = gems_to_update.first
+ current_ver = Gem::Version.new Gem::VERSION
+
+ target = if options[:system] == true then
+ up_ver
+ else
+ version
+ end
- if gems_to_update.empty? then
+ if current_ver == target then
+ # if options[:system] != true and version == current_ver then
say "Latest version currently installed. Aborting."
terminate_interaction
end
- update_gem gems_to_update.first, requirement
+ update_gem name, target
- Gem.source_index.refresh!
-
- installed_gems = Gem.source_index.find_name 'rubygems-update', requirement
+ installed_gems = Gem::Specification.find_all_by_name 'rubygems-update', requirement
version = installed_gems.last.version
args = []
@@ -193,7 +203,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
end
end
- def which_to_update(highest_installed_gems, gem_names)
+ def which_to_update highest_installed_gems, gem_names, system = false
result = []
highest_installed_gems.each do |l_name, l_spec|
@@ -213,9 +223,11 @@ class Gem::Commands::UpdateCommand < Gem::Command
version
end.last
- if highest_remote_gem and
- l_spec.version < highest_remote_gem.first[1] then
- result << l_name
+ highest_remote_gem ||= [[nil, Gem::Version.new(0), nil]] # "null" object
+ highest_remote_ver = highest_remote_gem.first[1]
+
+ if system or (l_spec.version < highest_remote_ver) then
+ result << [l_spec.name, [l_spec.version, highest_remote_ver].max]
end
end
diff --git a/lib/rubygems/commands/which_command.rb b/lib/rubygems/commands/which_command.rb
index aeb91f2..2962491 100644
--- a/lib/rubygems/commands/which_command.rb
+++ b/lib/rubygems/commands/which_command.rb
@@ -5,12 +5,8 @@
######################################################################
require 'rubygems/command'
-require 'rubygems/gem_path_searcher'
class Gem::Commands::WhichCommand < Gem::Command
-
- EXT = %w[.rb .rbw .so .dll .bundle] # HACK
-
def initialize
super 'which', 'Find the location of a library file you can require',
:search_gems_first => false, :show_all => false
@@ -34,14 +30,13 @@ class Gem::Commands::WhichCommand < Gem::Command
end
def execute
- searcher = Gem::GemPathSearcher.new
-
found = false
options[:args].each do |arg|
- arg = arg.sub(/#{Regexp.union(*EXT)}$/, '')
+ arg = arg.sub(/#{Regexp.union(*Gem.suffixes)}$/, '')
dirs = $LOAD_PATH
- spec = searcher.find arg
+
+ spec = Gem::Specification.find_by_path arg
if spec then
if options[:search_gems_first] then
@@ -51,6 +46,7 @@ class Gem::Commands::WhichCommand < Gem::Command
end
end
+ # TODO: this is totally redundant and stupid
paths = find_paths arg, dirs
if paths.empty? then
@@ -68,7 +64,7 @@ class Gem::Commands::WhichCommand < Gem::Command
result = []
dirs.each do |dir|
- EXT.each do |ext|
+ Gem.suffixes.each do |ext|
full_path = File.join dir, "#{package_name}#{ext}"
if File.exist? full_path then
result << full_path
diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb
index 1d16cd9..d005755 100644
--- a/lib/rubygems/config_file.rb
+++ b/lib/rubygems/config_file.rb
@@ -207,11 +207,15 @@ class Gem::ConfigFile
# Location of RubyGems.org credentials
def credentials_path
- File.join(Gem.user_home, '.gem', 'credentials')
+ File.join Gem.user_home, '.gem', 'credentials'
end
def load_api_keys
- @api_keys = File.exists?(credentials_path) ? load_file(credentials_path) : @hash
+ @api_keys = if File.exist? credentials_path then
+ load_file(credentials_path)
+ else
+ @hash
+ end
if @api_keys.key? :rubygems_api_key then
@rubygems_api_key = @api_keys[:rubygems_api_key]
@api_keys[:rubygems] = @api_keys.delete :rubygems_api_key unless @api_keys.key? :rubygems
@@ -221,8 +225,8 @@ class Gem::ConfigFile
def rubygems_api_key=(api_key)
config = load_file(credentials_path).merge(:rubygems_api_key => api_key)
- dirname = File.dirname(credentials_path)
- Dir.mkdir(dirname) unless File.exists?(dirname)
+ dirname = File.dirname credentials_path
+ Dir.mkdir(dirname) unless File.exist? dirname
Gem.load_yaml
@@ -236,7 +240,7 @@ class Gem::ConfigFile
def load_file(filename)
Gem.load_yaml
- return {} unless filename and File.exists?(filename)
+ return {} unless filename and File.exist? filename
begin
YAML.load(File.read(filename))
rescue ArgumentError
@@ -360,6 +364,4 @@ class Gem::ConfigFile
protected
attr_reader :hash
-
end
-
diff --git a/lib/rubygems/custom_require.rb b/lib/rubygems/custom_require.rb
index eaa04b3..f32d100 100644
--- a/lib/rubygems/custom_require.rb
+++ b/lib/rubygems/custom_require.rb
@@ -41,19 +41,20 @@ module Kernel
if Gem.unresolved_deps.empty? or Gem.loaded_path? path then
gem_original_require path
else
- spec = Gem.searcher.find_active path
+ spec = Gem::Specification.find { |s|
+ s.activated? and s.contains_requirable_file? path
+ }
unless spec then
- found_specs = Gem.searcher.find_in_unresolved path
+ found_specs = Gem::Specification.find_in_unresolved path
unless found_specs.empty? then
found_specs = [found_specs.last]
else
- found_specs = Gem.searcher.find_in_unresolved_tree path
+ found_specs = Gem::Specification.find_in_unresolved_tree path
end
found_specs.each do |found_spec|
- # FIX: this is dumb, activate a spec instead of name/version
- Gem.activate found_spec.name, found_spec.version
+ found_spec.activate
end
end
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index 63ccd85..714dc4f 100644
--- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb
@@ -6,6 +6,8 @@
module Gem
+ # TODO: move this whole file back into rubygems.rb
+
@post_install_hooks ||= []
@post_uninstall_hooks ||= []
@pre_uninstall_hooks ||= []
@@ -23,16 +25,28 @@ module Gem
# specified in the environment
def self.default_dir
- if defined? RUBY_FRAMEWORK_VERSION then
- File.join File.dirname(ConfigMap[:sitedir]), 'Gems',
- ConfigMap[:ruby_version]
- elsif ConfigMap[:rubylibprefix] then
- File.join(ConfigMap[:rubylibprefix], 'gems',
- ConfigMap[:ruby_version])
- else
- File.join(ConfigMap[:libdir], ruby_engine, 'gems',
- ConfigMap[:ruby_version])
- end
+ path = if defined? RUBY_FRAMEWORK_VERSION then
+ [
+ File.dirname(ConfigMap[:sitedir]),
+ 'Gems',
+ ConfigMap[:ruby_version]
+ ]
+ elsif ConfigMap[:rubylibprefix] then
+ [
+ ConfigMap[:rubylibprefix],
+ 'gems',
+ ConfigMap[:ruby_version]
+ ]
+ else
+ [
+ ConfigMap[:libdir],
+ ruby_engine,
+ 'gems',
+ ConfigMap[:ruby_version]
+ ]
+ end
+
+ @default_dir ||= File.join(*path)
end
##
@@ -82,14 +96,18 @@ module Gem
# The default system-wide source info cache directory
def self.default_system_source_cache_dir
- File.join Gem.dir, 'source_cache'
+ File.join(Gem.dir, 'source_cache')
end
##
# The default user-specific source info cache directory
def self.default_user_source_cache_dir
- File.join Gem.user_home, '.gem', 'source_cache'
+ #
+ # NOTE Probably an argument for moving this to per-ruby supported dirs like
+ # user_dir
+ #
+ File.join(Gem.user_home, '.gem', 'source_cache')
end
##
@@ -102,6 +120,4 @@ module Gem
'ruby'
end
end
-
end
-
diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb
index e4d1bff..1261154 100644
--- a/lib/rubygems/dependency.rb
+++ b/lib/rubygems/dependency.rb
@@ -38,6 +38,12 @@ class Gem::Dependency
# <tt>:runtime</tt>.
def initialize name, *requirements
+ if Regexp === name then
+ msg = ["NOTE: Dependency.new w/ a regexp is deprecated.",
+ "Dependency.new called from #{Gem.location_of_caller.join(":")}"]
+ warn msg.join("\n") unless Deprecate.skip
+ end
+
type = Symbol === requirements.last ? requirements.pop : :runtime
requirements = requirements.first if 1 == requirements.length # unpack
@@ -212,5 +218,49 @@ class Gem::Dependency
self.class.new name, self_req.as_list.concat(other_req.as_list)
end
-end
+ def matching_specs platform_only = false
+ matches = Gem::Specification.find_all { |spec|
+ self.name === spec.name and # TODO: == instead of ===
+ requirement.satisfied_by? spec.version
+ }
+
+ if platform_only
+ matches.reject! { |spec|
+ not Gem::Platform.match spec.platform
+ }
+ end
+
+ matches = matches.sort_by { |s| s.sort_obj } # HACK: shouldn't be needed
+ end
+
+ ##
+ # True if the dependency will not always match the latest version.
+
+ def specific?
+ @requirement.specific?
+ end
+ def to_specs
+ matches = matching_specs true
+
+ # TODO: check Gem.activated_spec[self.name] in case matches falls outside
+
+ if matches.empty? then
+ specs = Gem::Specification.all_names.join ", "
+ error = Gem::LoadError.new "Could not find #{name} (#{requirement}) amongst [#{specs}]"
+ error.name = self.name
+ error.requirement = self.requirement
+ raise error
+ end
+
+ # TODO: any other resolver validations should go here
+
+ matches
+ end
+
+ def to_spec
+ matches = self.to_specs
+
+ matches.find { |spec| spec.activated? } or matches.last
+ end
+end
diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb
index 5afb1bf..29e8b21 100644
--- a/lib/rubygems/dependency_installer.rb
+++ b/lib/rubygems/dependency_installer.rb
@@ -21,14 +21,14 @@ class Gem::DependencyInstaller
attr_reader :installed_gems
DEFAULT_OPTIONS = {
- :env_shebang => false,
- :domain => :both, # HACK dup
- :force => false,
- :format_executable => false, # HACK dup
+ :env_shebang => false,
+ :domain => :both, # HACK dup
+ :force => false,
+ :format_executable => false, # HACK dup
:ignore_dependencies => false,
- :prerelease => false,
- :security_policy => nil, # HACK NoSecurity requires OpenSSL. AlmostNo? Low?
- :wrappers => true,
+ :prerelease => false,
+ :security_policy => nil, # HACK NoSecurity requires OpenSSL. AlmostNo? Low?
+ :wrappers => true,
}
##
@@ -51,25 +51,26 @@ class Gem::DependencyInstaller
def initialize(options = {})
if options[:install_dir] then
- spec_dir = options[:install_dir], 'specifications'
- @source_index = Gem::SourceIndex.from_gems_in spec_dir
- else
- @source_index = Gem.source_index
+ @gem_home = options[:install_dir]
+
+ Gem::Specification.dirs = @gem_home
+ Gem.ensure_gem_subdirectories @gem_home
+ options[:install_dir] = @gem_home # FIX: because we suck and reuse below
end
options = DEFAULT_OPTIONS.merge options
- @bin_dir = options[:bin_dir]
- @development = options[:development]
- @domain = options[:domain]
- @env_shebang = options[:env_shebang]
- @force = options[:force]
- @format_executable = options[:format_executable]
+ @bin_dir = options[:bin_dir]
+ @development = options[:development]
+ @domain = options[:domain]
+ @env_shebang = options[:env_shebang]
+ @force = options[:force]
+ @format_executable = options[:format_executable]
@ignore_dependencies = options[:ignore_dependencies]
- @prerelease = options[:prerelease]
- @security_policy = options[:security_policy]
- @user_install = options[:user_install]
- @wrappers = options[:wrappers]
+ @prerelease = options[:prerelease]
+ @security_policy = options[:security_policy]
+ @user_install = options[:user_install]
+ @wrappers = options[:wrappers]
@installed_gems = []
@@ -101,6 +102,7 @@ class Gem::DependencyInstaller
if @domain == :both or @domain == :remote then
begin
+ # REFACTOR: all = dep.requirement.needs_all?
requirements = dep.requirement.requirements.map do |req, ver|
req
end
@@ -146,8 +148,8 @@ class Gem::DependencyInstaller
add_found_dependencies to_do, dependency_list unless @ignore_dependencies
dependency_list.specs.reject! { |spec|
- ! keep_names.include? spec.full_name and
- @source_index.any? { |n,_| n == spec.full_name }
+ not keep_names.include?(spec.full_name) and
+ Gem::Specification.include?(spec)
}
unless dependency_list.ok? or @ignore_dependencies or @force then
@@ -181,7 +183,7 @@ class Gem::DependencyInstaller
to_do.push dep_spec
# already locally installed
- @source_index.any? do |_, installed_spec|
+ Gem::Specification.any? do |installed_spec|
dep.name == installed_spec.name and
dep.requirement.satisfied_by? installed_spec.version
end
@@ -216,23 +218,20 @@ class Gem::DependencyInstaller
local_gems = Dir["#{glob}*"].sort.reverse
- unless local_gems.empty? then
- local_gems.each do |gem_file|
- next unless gem_file =~ /gem$/
- begin
- spec = Gem::Format.from_file_by_path(gem_file).spec
- spec_and_source = [spec, gem_file]
- break
- rescue SystemCallError, Gem::Package::FormatError
- end
+ local_gems.each do |gem_file|
+ next unless gem_file =~ /gem$/
+ begin
+ spec = Gem::Format.from_file_by_path(gem_file).spec
+ spec_and_source = [spec, gem_file]
+ break
+ rescue SystemCallError, Gem::Package::FormatError
end
end
- if spec_and_source.nil? then
+ unless spec_and_source then
dep = Gem::Dependency.new gem_name, version
dep.prerelease = true if prerelease
spec_and_sources = find_gems_with_sources(dep).reverse
-
spec_and_source = spec_and_sources.find { |spec, source|
Gem::Platform.match spec.platform
}
@@ -273,9 +272,9 @@ class Gem::DependencyInstaller
gather_dependencies
- @gems_to_install.each do |spec|
- last = spec == @gems_to_install.last
- next if @source_index.any? { |n,_| n == spec.full_name } and not last
+ last = @gems_to_install.size - 1
+ @gems_to_install.each_with_index do |spec, index|
+ next if Gem::Specification.include?(spec) and index != last
# TODO: make this sorta_verbose so other users can benefit from it
say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose
@@ -298,7 +297,6 @@ class Gem::DependencyInstaller
:ignore_dependencies => @ignore_dependencies,
:install_dir => @install_dir,
:security_policy => @security_policy,
- :source_index => @source_index,
:user_install => @user_install,
:wrappers => @wrappers
@@ -309,6 +307,4 @@ class Gem::DependencyInstaller
@installed_gems
end
-
end
-
diff --git a/lib/rubygems/dependency_list.rb b/lib/rubygems/dependency_list.rb
index a3db1d6..232f83c 100644
--- a/lib/rubygems/dependency_list.rb
+++ b/lib/rubygems/dependency_list.rb
@@ -11,6 +11,7 @@
#++
require 'tsort'
+require 'rubygems/deprecate'
##
# Gem::DependencyList is used for installing and uninstalling gems in the
@@ -28,16 +29,21 @@ class Gem::DependencyList
attr_accessor :development
##
- # Creates a DependencyList from a Gem::SourceIndex +source_index+
+ # Creates a DependencyList from the current specs.
- def self.from_source_index(source_index)
+ def self.from_specs
list = new
+ list.add(*Gem::Specification.map)
+ list
+ end
- source_index.each do |full_name, spec|
- list.add spec
- end
+ ##
+ # Creates a DependencyList from a Gem::SourceIndex +source_index+
- list
+ def self.from_source_index(ignored=nil)
+ warn "NOTE: DependencyList.from_source_index ignores it's arg" if ignored
+
+ from_specs
end
##
@@ -120,10 +126,9 @@ class Gem::DependencyList
def why_not_ok? quick = false
unsatisfied = Hash.new { |h,k| h[k] = [] }
- source_index = Gem.source_index
each do |spec|
spec.runtime_dependencies.each do |dep|
- inst = source_index.any? { |_, installed_spec|
+ inst = Gem::Specification.any? { |installed_spec|
dep.name == installed_spec.name and
dep.requirement.satisfied_by? installed_spec.version
}
@@ -134,6 +139,7 @@ class Gem::DependencyList
end
end
end
+
unsatisfied
end
@@ -242,6 +248,11 @@ class Gem::DependencyList
def active_count(specs, ignored)
specs.count { |spec| ignored[spec.full_name].nil? }
end
-
end
+class Gem::DependencyList
+ class << self
+ extend Deprecate
+ deprecate :from_source_index, "from_specs", 2011, 11
+ end
+end
diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb
new file mode 100644
index 0000000..948538d
--- /dev/null
+++ b/lib/rubygems/deprecate.rb
@@ -0,0 +1,74 @@
+######################################################################
+# This file is imported from the rubygems project.
+# DO NOT make modifications in this repo. They _will_ be reverted!
+# File a patch instead and assign it to Ryan Davis or Eric Hodel.
+######################################################################
+
+##
+# Provides a single method +deprecate+ to be used to declare when
+# something is going away.
+#
+# class Legacy
+# def self.klass_method
+# # ...
+# end
+#
+# def instance_method
+# # ...
+# end
+#
+# extend Deprecate
+# deprecate :instance_method, "X.z", 2011, 4
+#
+# class << self
+# extend Deprecate
+# deprecate :klass_method, :none, 2011, 4
+# end
+# end
+
+module Deprecate
+
+ def self.skip # :nodoc:
+ @skip ||= false
+ end
+
+ def self.skip= v # :nodoc:
+ @skip = v
+ end
+
+ ##
+ # Temporarily turn off warnings. Intended for tests only.
+
+ def skip_during
+ Deprecate.skip, original = true, Deprecate.skip
+ yield
+ ensure
+ Deprecate.skip = original
+ end
+
+ ##
+ # Simple deprecation method that deprecates +name+ by wrapping it up
+ # in a dummy method. It warns on each call to the dummy method
+ # telling the user of +repl+ (unless +repl+ is :none) and the
+ # year/month that it is planned to go away.
+
+ def deprecate name, repl, year, month
+ class_eval {
+ old = "_deprecated_#{name}"
+ alias_method old, name
+ define_method name do |*args, &block| # TODO: really works on 1.8.7?
+ klass = self.kind_of? Module
+ target = klass ? "#{self}." : "#{self.class}#"
+ msg = [ "NOTE: #{target}#{name} is deprecated",
+ repl == :none ? " with no replacement" : ", use #{repl}",
+ ". It will be removed on or after %4d-%02d-01." % [year, month],
+ "\n#{target}#{name} called from #{Gem.location_of_caller.join(":")}",
+ ]
+ warn "#{msg.join}." unless Deprecate.skip
+ send old, *args, &block
+ end
+ }
+ end
+
+ module_function :deprecate, :skip_during
+end
diff --git a/lib/rubygems/doc_manager.rb b/lib/rubygems/doc_manager.rb
index 9cfa31a..20c5281 100644
--- a/lib/rubygems/doc_manager.rb
+++ b/lib/rubygems/doc_manager.rb
@@ -92,7 +92,7 @@ class Gem::DocManager
def initialize(spec, rdoc_args="")
require 'fileutils'
@spec = spec
- @doc_dir = File.join(spec.installation_path, "doc", spec.full_name)
+ @doc_dir = spec.doc_dir
@rdoc_args = rdoc_args.nil? ? [] : rdoc_args.split
end
@@ -224,25 +224,24 @@ class Gem::DocManager
# Remove RDoc and RI documentation
def uninstall_doc
- raise Gem::FilePermissionError.new(@spec.installation_path) unless
- File.writable? @spec.installation_path
+ base_dir = @spec.base_dir
+ raise Gem::FilePermissionError.new base_dir unless File.writable? base_dir
- original_name = [
+ # TODO: ok... that's twice... ugh
+ old_name = [
@spec.name, @spec.version, @spec.original_platform].join '-'
- doc_dir = File.join @spec.installation_path, 'doc', @spec.full_name
+ doc_dir = @spec.doc_dir
unless File.directory? doc_dir then
- doc_dir = File.join @spec.installation_path, 'doc', original_name
+ doc_dir = File.join File.dirname(doc_dir), old_name
end
- FileUtils.rm_rf doc_dir
-
- ri_dir = File.join @spec.installation_path, 'ri', @spec.full_name
-
+ ri_dir = @spec.ri_dir
unless File.directory? ri_dir then
- ri_dir = File.join @spec.installation_path, 'ri', original_name
+ ri_dir = File.join File.dirname(ri_dir), old_name
end
+ FileUtils.rm_rf doc_dir
FileUtils.rm_rf ri_dir
end
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb
index 2a147d5..29d5af5 100644
--- a/lib/rubygems/ext/builder.rb
+++ b/lib/rubygems/ext/builder.rb
@@ -19,7 +19,7 @@ class Gem::Ext::Builder
def self.make(dest_path, results)
unless File.exist? 'Makefile' then
- raise Gem::InstallError, "Makefile not found:\n\n#{results.join "\n"}"
+ raise Gem::InstallError, "Makefile not found:\n\n#{results.join "\n"}"
end
mf = File.read('Makefile')
diff --git a/lib/rubygems/ext/rake_builder.rb b/lib/rubygems/ext/rake_builder.rb
index ba9fa8a..6b7086c 100644
--- a/lib/rubygems/ext/rake_builder.rb
+++ b/lib/rubygems/ext/rake_builder.rb
@@ -23,12 +23,12 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
end
# Deal with possible spaces in the path, e.g. C:/Program Files
- dest_path = '"' + dest_path + '"' if dest_path.include?(' ')
+ dest_path = '"' + dest_path.to_s + '"' if dest_path.to_s.include?(' ')
rake = ENV['rake']
rake ||= begin
- "\"#{Gem.ruby}\" -rubygems #{Gem.bin_path('rake')}"
+ "\"#{Gem.ruby}\" -rubygems #{Gem.bin_path('rake', 'rake')}"
rescue Gem::Exception
end
diff --git a/lib/rubygems/gem_path_searcher.rb b/lib/rubygems/gem_path_searcher.rb
index 79c3b0f..36a86de 100644
--- a/lib/rubygems/gem_path_searcher.rb
+++ b/lib/rubygems/gem_path_searcher.rb
@@ -4,6 +4,9 @@
# File a patch instead and assign it to Ryan Davis or Eric Hodel.
######################################################################
+require "rubygems"
+require "rubygems/deprecate"
+
##
# GemPathSearcher has the capability to find loadable files inside
# gems. It generates data up front to speed up searches later.
@@ -56,6 +59,15 @@ class Gem::GemPathSearcher
end
end
+ # Looks through the available gemspecs and finds the first
+ # one that contains +file+ as a requirable file.
+
+ def find_spec_for_file(file)
+ @gemspecs.find do |spec|
+ return spec if spec.contains_requirable_file?(file)
+ end
+ end
+
def find_active(glob)
# HACK violation of encapsulation
@gemspecs.find do |spec|
@@ -138,9 +150,7 @@ class Gem::GemPathSearcher
# in reverse version order. (bar-2, bar-1, foo-2)
def init_gemspecs
- specs = Gem.source_index.map { |_, spec| spec }
-
- specs.sort { |a, b|
+ Gem::Specification.sort { |a, b|
names = a.name <=> b.name
next names if names.nonzero?
b.version <=> a.version
@@ -156,5 +166,13 @@ class Gem::GemPathSearcher
spec.require_paths
end
-end
+ extend Deprecate
+ deprecate :initialize, :none, 2011, 10
+ deprecate :find, :none, 2011, 10
+ deprecate :find_active, :none, 2011, 10
+ deprecate :find_all, :none, 2011, 10
+ deprecate :find_in_unresolved, :none, 2011, 10
+ deprecate :find_in_unresolved_tree, :none, 2011, 10
+ deprecate :find_spec_for_file, :none, 2011, 10
+end
diff --git a/lib/rubygems/gem_runner.rb b/lib/rubygems/gem_runner.rb
index 1c432ba..6b5aef3 100644
--- a/lib/rubygems/gem_runner.rb
+++ b/lib/rubygems/gem_runner.rb
@@ -10,6 +10,7 @@
# See LICENSE.txt for permissions.
#++
+require "rubygems"
require 'rubygems/command_manager'
require 'rubygems/config_file'
require 'rubygems/doc_manager'
@@ -31,6 +32,7 @@ Gem.load_env_plugins rescue nil
class Gem::GemRunner
def initialize(options={})
+ # TODO: nuke these options
@command_manager_class = options[:command_manager] || Gem::CommandManager
@config_file_class = options[:config_file] || Gem::ConfigFile
@doc_manager_class = options[:doc_manager] || Gem::DocManager
@@ -80,7 +82,7 @@ class Gem::GemRunner
def do_configuration(args)
Gem.configuration = @config_file_class.new(args)
- Gem.use_paths(Gem.configuration[:gemhome], Gem.configuration[:gempath])
+ Gem.use_paths Gem.configuration[:gemhome], Gem.configuration[:gempath]
Gem::Command.extra_args = Gem.configuration[:gem]
@doc_manager_class.configured_args = Gem.configuration[:rdoc]
end
diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb
index 6e481c6..c367532 100644
--- a/lib/rubygems/indexer.rb
+++ b/lib/rubygems/indexer.rb
@@ -79,7 +79,7 @@ class Gem::Indexer
@rss_gems_host = options[:rss_gems_host]
@dest_directory = directory
- @directory = File.join Dir.tmpdir, "gem_generate_index_#{$$}"
+ @directory = File.join(Dir.tmpdir, "gem_generate_index_#{$$}")
marshal_name = "Marshal.#{Gem.marshal_version}"
@@ -87,24 +87,23 @@ class Gem::Indexer
@marshal_index = File.join @directory, marshal_name
@quick_dir = File.join @directory, 'quick'
-
@quick_marshal_dir = File.join @quick_dir, marshal_name
+ @quick_marshal_dir_base = File.join "quick", marshal_name # FIX: UGH
@quick_index = File.join @quick_dir, 'index'
@latest_index = File.join @quick_dir, 'latest_index'
@specs_index = File.join @directory, "specs.#{Gem.marshal_version}"
- @latest_specs_index = File.join @directory,
- "latest_specs.#{Gem.marshal_version}"
- @prerelease_specs_index = File.join(@directory,
- "prerelease_specs.#{Gem.marshal_version}")
-
- @dest_specs_index = File.join @dest_directory,
- "specs.#{Gem.marshal_version}"
- @dest_latest_specs_index = File.join @dest_directory,
- "latest_specs.#{Gem.marshal_version}"
- @dest_prerelease_specs_index = File.join @dest_directory,
- "prerelease_specs.#{Gem.marshal_version}"
+ @latest_specs_index =
+ File.join(@directory, "latest_specs.#{Gem.marshal_version}")
+ @prerelease_specs_index =
+ File.join(@directory, "prerelease_specs.#{Gem.marshal_version}")
+ @dest_specs_index =
+ File.join(@dest_directory, "specs.#{Gem.marshal_version}")
+ @dest_latest_specs_index =
+ File.join(@dest_directory, "latest_specs.#{Gem.marshal_version}")
+ @dest_prerelease_specs_index =
+ File.join(@dest_directory, "prerelease_specs.#{Gem.marshal_version}")
@rss_index = File.join @directory, 'index.rss'
@@ -129,12 +128,16 @@ class Gem::Indexer
##
# Build various indicies
- def build_indicies(index)
+ def build_indicies
# Marshal gemspecs are used by both modern and legacy RubyGems
- build_marshal_gemspecs index
- build_legacy_indicies index if @build_legacy
- build_modern_indicies index if @build_modern
- build_rss index
+
+ Gem::Specification.dirs = []
+ Gem::Specification.add_specs(*map_gems_to_specs(gem_file_list))
+
+ build_marshal_gemspecs
+ build_legacy_indicies if @build_legacy
+ build_modern_indicies if @build_modern
+ build_rss
compress_indicies
end
@@ -142,7 +145,9 @@ class Gem::Indexer
##
# Builds indicies for RubyGems older than 1.2.x
- def build_legacy_indicies(index)
+ def build_legacy_indicies
+ index = collect_specs
+
say "Generating Marshal master index"
Gem.time 'Generated Marshal master index' do
@@ -158,16 +163,17 @@ class Gem::Indexer
##
# Builds Marshal quick index gemspecs.
- def build_marshal_gemspecs(index)
- progress = ui.progress_reporter index.size,
- "Generating Marshal quick index gemspecs for #{index.size} gems",
+ def build_marshal_gemspecs
+ count = Gem::Specification.count
+ progress = ui.progress_reporter count,
+ "Generating Marshal quick index gemspecs for #{count} gems",
"Complete"
files = []
Gem.time 'Generated Marshal quick index gemspecs' do
- index.gems.each do |original_name, spec|
- spec_file_name = "#{original_name}.gemspec.rz"
+ Gem::Specification.each do |spec|
+ spec_file_name = "#{spec.original_name}.gemspec.rz"
marshal_name = File.join @quick_marshal_dir, spec_file_name
marshal_zipped = Gem.deflate Marshal.dump(spec)
@@ -175,7 +181,7 @@ class Gem::Indexer
files << marshal_name
- progress.updated original_name
+ progress.updated spec.original_name
end
progress.done
@@ -195,8 +201,8 @@ class Gem::Indexer
Gem.time "Generated #{name} index" do
open(file, 'wb') do |io|
specs = index.map do |*spec|
- # We have to splat here because latest_specs is an array,
- # while the others are hashes. See the TODO in source_index.rb
+ # We have to splat here because latest_specs is an array, while the
+ # others are hashes.
spec = spec.flatten.last
platform = spec.original_platform
@@ -219,13 +225,15 @@ class Gem::Indexer
##
# Builds indicies for RubyGems 1.2 and newer. Handles full, latest, prerelease
- def build_modern_indicies(index)
- build_modern_index(index.released_specs.sort, @specs_index, 'specs')
- build_modern_index(index.latest_specs.sort,
- @latest_specs_index,
- 'latest specs')
- build_modern_index(index.prerelease_specs.sort,
- @prerelease_specs_index,
+ def build_modern_indicies
+ prerelease, released = Gem::Specification.partition { |s|
+ s.version.prerelease?
+ }
+ latest_specs = Gem::Specification.latest_specs
+
+ build_modern_index(released.sort, @specs_index, 'specs')
+ build_modern_index(latest_specs.sort, @latest_specs_index, 'latest specs')
+ build_modern_index(prerelease.sort, @prerelease_specs_index,
'prerelease specs')
@files += [@specs_index,
@@ -240,7 +248,7 @@ class Gem::Indexer
# Builds an RSS feed for past two days gem releases according to the gem's
# date.
- def build_rss(index)
+ def build_rss
if @rss_host.nil? or @rss_gems_host.nil? then
if Gem.configuration.really_verbose then
alert_warning "no --rss-host or --rss-gems-host, RSS generation disabled"
@@ -272,31 +280,18 @@ class Gem::Indexer
today = Gem::Specification::TODAY
yesterday = today - 86400
- index = index.select do |_, spec|
- spec_date = spec.date
-
- case spec_date
- when Date
- Time.parse(spec_date.to_s) >= yesterday
- when Time
- spec_date >= yesterday
- end
- end
-
- index = index.select do |_, spec|
+ index = Gem::Specification.select do |spec|
spec_date = spec.date
+ # TODO: remove this and make YAML based specs properly normalized
+ spec_date = Time.parse(spec_date.to_s) if Date === spec_date
- case spec_date
- when Date
- Time.parse(spec_date.to_s) <= today
- when Time
- spec_date <= today
- end
+ spec_date >= yesterday && spec_date <= today
end
- index.sort_by { |_, spec| [-spec.date.to_i, spec] }.each do |_, spec|
- gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{spec.file_name}"
- size = File.stat(spec.loaded_from).size rescue next
+ index.sort_by { |spec| [-spec.date.to_i, spec] }.each do |spec|
+ file_name = File.basename spec.cache_file
+ gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{file_name}"
+ size = File.stat(spec.loaded_from).size # rescue next
description = spec.description || spec.summary || ''
authors = Array spec.authors
@@ -347,54 +342,56 @@ class Gem::Indexer
@files << @rss_index
end
+ def map_gems_to_specs gems
+ gems.map { |gemfile|
+ if File.size(gemfile) == 0 then
+ alert_warning "Skipping zero-length gem: #{gemfile}"
+ next
+ end
+
+ begin
+ spec = Gem::Format.from_file_by_path(gemfile).spec
+ spec.loaded_from = gemfile
+
+ # HACK: fuck this shit - borks all tests that use pl1
+ # if File.basename(gemfile, ".gem") != spec.original_name then
+ # exp = spec.full_name
+ # exp << " (#{spec.original_name})" if
+ # spec.original_name != spec.full_name
+ # msg = "Skipping misnamed gem: #{gemfile} should be named #{exp}"
+ # alert_warning msg
+ # next
+ # end
+
+ abbreviate spec
+ sanitize spec
+
+ spec
+ rescue SignalException => e
+ alert_error "Received signal, exiting"
+ raise
+ rescue Exception => e
+ msg = ["Unable to process #{gemfile}",
+ "#{e.message} (#{e.class})",
+ "\t#{e.backtrace.join "\n\t"}"].join("\n")
+ alert_error msg
+ end
+ }.compact
+ end
+
##
# Collect specifications from .gem files from the gem directory.
def collect_specs(gems = gem_file_list)
- index = Gem::SourceIndex.new
-
- progress = ui.progress_reporter gems.size,
- "Loading #{gems.size} gems from #{@dest_directory}",
- "Loaded all gems"
+ Deprecate.skip_during do
+ index = Gem::SourceIndex.new
- Gem.time 'loaded' do
- gems.each do |gemfile|
- if File.size(gemfile.to_s) == 0 then
- alert_warning "Skipping zero-length gem: #{gemfile}"
- next
- end
-
- begin
- spec = Gem::Format.from_file_by_path(gemfile).spec
- spec.loaded_from = gemfile
-
- unless gemfile =~ /\/#{Regexp.escape spec.original_name}.*\.gem\z/i then
- expected_name = spec.full_name
- expected_name << " (#{spec.original_name})" if
- spec.original_name != spec.full_name
- alert_warning "Skipping misnamed gem: #{gemfile} should be named #{expected_name}"
- next
- end
-
- abbreviate spec
- sanitize spec
-
- index.add_spec spec, spec.original_name
-
- progress.updated spec.original_name
-
- rescue SignalException => e
- alert_error "Received signal, exiting"
- raise
- rescue Exception => e
- alert_error "Unable to process #{gemfile}\n#{e.message} (#{e.class})\n\t#{e.backtrace.join "\n\t"}"
- end
+ map_gems_to_specs(gems).each do |spec|
+ index.add_spec spec, spec.original_name
end
- progress.done
+ index
end
-
- index
end
##
@@ -454,7 +451,7 @@ class Gem::Indexer
# List of gem file names to index.
def gem_file_list
- Dir.glob(File.join(@dest_directory, "gems", "*.gem"))
+ Dir[File.join(@dest_directory, "gems", '*.gem')]
end
##
@@ -462,8 +459,7 @@ class Gem::Indexer
def generate_index
make_temp_directories
- index = collect_specs
- build_indicies index
+ build_indicies
install_indicies
rescue SignalException
ensure
@@ -487,24 +483,22 @@ class Gem::Indexer
say "Moving index into production dir #{@dest_directory}" if verbose
- files = @files.dup
+ files = @files
files.delete @quick_marshal_dir if files.include? @quick_dir
- if files.include? @quick_marshal_dir and
- not files.include? @quick_dir then
+ if files.include? @quick_marshal_dir and not files.include? @quick_dir then
files.delete @quick_marshal_dir
- quick_marshal_dir = @quick_marshal_dir.sub @directory, ''
- dst_name = File.join @dest_directory, quick_marshal_dir
+ dst_name = File.join(@dest_directory, @quick_marshal_dir_base)
FileUtils.mkdir_p File.dirname(dst_name), :verbose => verbose
FileUtils.rm_rf dst_name, :verbose => verbose
- FileUtils.mv @quick_marshal_dir, dst_name, :verbose => verbose,
- :force => true
+ FileUtils.mv(@quick_marshal_dir, dst_name,
+ :verbose => verbose, :force => true)
end
files = files.map do |path|
- path.sub @directory, ''
+ path.sub(/^#{Regexp.escape @directory}\/?/, '') # HACK?
end
files.each do |file|
@@ -512,8 +506,8 @@ class Gem::Indexer
dst_name = File.join @dest_directory, file
FileUtils.rm_rf dst_name, :verbose => verbose
- FileUtils.mv src_name, @dest_directory, :verbose => verbose,
- :force => true
+ FileUtils.mv(src_name, @dest_directory,
+ :verbose => verbose, :force => true)
end
end
@@ -544,10 +538,10 @@ class Gem::Indexer
# be replaced by their XML entity equivalent.
def sanitize(spec)
- spec.summary = sanitize_string(spec.summary)
- spec.description = sanitize_string(spec.description)
+ spec.summary = sanitize_string(spec.summary)
+ spec.description = sanitize_string(spec.description)
spec.post_install_message = sanitize_string(spec.post_install_message)
- spec.authors = spec.authors.collect { |a| sanitize_string(a) }
+ spec.authors = spec.authors.collect { |a| sanitize_string(a) }
spec
end
@@ -593,14 +587,16 @@ class Gem::Indexer
terminate_interaction 0
end
- index = collect_specs updated_gems
+ specs = map_gems_to_specs updated_gems
+ prerelease, released = specs.partition { |s| s.version.prerelease? }
- files = build_marshal_gemspecs index
+ files = build_marshal_gemspecs
Gem.time 'Updated indexes' do
- update_specs_index index.released_gems, @dest_specs_index, @specs_index
- update_specs_index index.released_gems, @dest_latest_specs_index, @latest_specs_index
- update_specs_index(index.prerelease_gems, @dest_prerelease_specs_index,
+ update_specs_index released, @dest_specs_index, @specs_index
+ update_specs_index released, @dest_latest_specs_index, @latest_specs_index
+ update_specs_index(prerelease,
+ @dest_prerelease_specs_index,
@prerelease_specs_index)
end
@@ -618,12 +614,12 @@ class Gem::Indexer
files << "#{@prerelease_specs_index}.gz"
files = files.map do |path|
- path.sub @directory, ''
+ path.sub(/^#{Regexp.escape @directory}\/?/, '') # HACK?
end
files.each do |file|
src_name = File.join @directory, file
- dst_name = File.join @dest_directory, File.dirname(file)
+ dst_name = File.join @dest_directory, file # REFACTOR: duped above
FileUtils.mv src_name, dst_name, :verbose => verbose,
:force => true
@@ -639,7 +635,7 @@ class Gem::Indexer
def update_specs_index(index, source, dest)
specs_index = Marshal.load Gem.read_binary(source)
- index.each do |_, spec|
+ index.each do |spec|
platform = spec.original_platform
platform = Gem::Platform::RUBY if platform.nil? or platform.empty?
specs_index << [spec.name, spec.version, platform]
@@ -651,6 +647,4 @@ class Gem::Indexer
Marshal.dump specs_index, io
end
end
-
end
-
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 8c6aeb4..7ef96dd 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -47,6 +47,8 @@ class Gem::Installer
include Gem::RequirePathsBuilder if Gem::QUICKLOADER_SUCKAGE
+ attr_reader :gem
+
##
# The directory a gem's executables will be installed into
@@ -58,11 +60,6 @@ class Gem::Installer
attr_reader :gem_home
##
- # The Gem::Specification for the gem being installed
-
- attr_reader :spec
-
- ##
# The options passed when the Gem::Installer was instantiated.
attr_reader :options
@@ -106,18 +103,36 @@ class Gem::Installer
@gem = gem
@options = options
process_options
- load_gem_file
if options[:user_install] and not options[:unpack] then
@gem_home = Gem.user_dir
check_that_user_bin_dir_is_in_path
end
+ end
- verify_gem_home(options[:unpack])
+ ##
+ # Lazy accessor for the spec's gem directory.
+
+ def gem_dir
+ @gem_dir ||= spec.gem_dir.dup.untaint
+ end
+
+ ##
+ # Lazy accessor for the installer's Gem::Format instance.
+
+ def format
+ begin
+ @format ||= Gem::Format.from_file_by_path gem, @security_policy
+ rescue Gem::Package::FormatError
+ raise Gem::InstallError, "invalid gem format for #{gem}"
+ end
+ end
- @spec = @format.spec
+ ##
+ # Lazy accessor for the installer's spec.
- @gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint
+ def spec
+ @spec ||= format.spec
end
##
@@ -132,6 +147,12 @@ class Gem::Installer
# specifications/<gem-version>.gemspec #=> the Gem::Specification
def install
+ current_home = Gem.dir
+ current_path = Gem.paths.path
+
+ verify_gem_home(options[:unpack])
+ Gem.use_paths gem_home, current_path # HACK: shouldn't need Gem.paths.path
+
# If we're forcing the install then disable security unless the security
# policy says that we only install signed gems.
@security_policy = nil if @force and @security_policy and
@@ -149,17 +170,17 @@ class Gem::Installer
if result == false then
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
- message = "pre-install hook#{location} failed for #{@spec.full_name}"
+ message = "pre-install hook#{location} failed for #{spec.full_name}"
raise Gem::InstallError, message
end
end
- Gem.ensure_gem_subdirectories @gem_home
+ Gem.ensure_gem_subdirectories gem_home
# Completely remove any previous gem files
- FileUtils.rm_rf(@gem_dir) if File.exist?(@gem_dir)
+ FileUtils.rm_rf(gem_dir) if File.exist? gem_dir
- FileUtils.mkdir_p @gem_dir
+ FileUtils.mkdir_p gem_dir
extract_files
build_extensions
@@ -168,11 +189,11 @@ class Gem::Installer
result = hook.call self
if result == false then
- FileUtils.rm_rf @gem_dir
+ FileUtils.rm_rf gem_dir
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
- message = "post-build hook#{location} failed for #{@spec.full_name}"
+ message = "post-build hook#{location} failed for #{spec.full_name}"
raise Gem::InstallError, message
end
end
@@ -182,24 +203,27 @@ class Gem::Installer
write_require_paths_file_if_needed if Gem::QUICKLOADER_SUCKAGE
- cached_gem = Gem.cache_gem(File.basename(@gem), @gem_home)
- unless File.exist? cached_gem then
- FileUtils.cp @gem, Gem.cache_dir(@gem_home)
- end
+ cache_file = spec.cache_file
+ FileUtils.cp gem, cache_file unless File.exist? cache_file
- say @spec.post_install_message unless @spec.post_install_message.nil?
+ say spec.post_install_message unless spec.post_install_message.nil?
- @spec.loaded_from = File.join(@gem_home, 'specifications', @spec.spec_name)
+ spec.loaded_from = spec.spec_file
- @source_index.add_spec @spec
+ Gem::Specification.add_spec spec unless Gem::Specification.include? spec
Gem.post_install_hooks.each do |hook|
hook.call self
end
- return @spec
+ return spec
rescue Zlib::GzipFile::Error
- raise Gem::InstallError, "gzip error installing #{@gem}"
+ raise Gem::InstallError, "gzip error installing #{gem}"
+ ensure
+ # conditional since we might be here because we're erroring out early.
+ if current_path
+ Gem.use_paths current_home, current_path
+ end
end
##
@@ -220,7 +244,7 @@ class Gem::Installer
# True if the gems in the source_index satisfy +dependency+.
def installation_satisfies_dependency?(dependency)
- @source_index.find_name(dependency.name, dependency.requirement).size > 0
+ not dependency.matching_specs.empty?
end
##
@@ -228,7 +252,7 @@ class Gem::Installer
def unpack(directory)
@gem_dir = directory
- @format = Gem::Format.from_file_by_path @gem, @security_policy
+ @format = Gem::Format.from_file_by_path gem, @security_policy
extract_files
end
@@ -237,14 +261,10 @@ class Gem::Installer
# specifications directory.
def write_spec
- rubycode = @spec.to_ruby_for_cache
-
- file_name = File.join @gem_home, 'specifications', @spec.spec_name
-
- file_name.untaint
+ file_name = spec.spec_file.untaint
File.open(file_name, "w") do |file|
- file.puts rubycode
+ file.puts spec.to_ruby_for_cache
end
end
@@ -264,24 +284,28 @@ class Gem::Installer
end
def generate_bin
- return if @spec.executables.nil? or @spec.executables.empty?
+ return if spec.executables.nil? or spec.executables.empty?
# If the user has asked for the gem to be installed in a directory that is
# the system gem directory, then use the system bin directory, else create
# (or use) a new bin dir under the gem_home.
- bindir = @bin_dir ? @bin_dir : Gem.bindir(@gem_home)
+ bindir = @bin_dir || Gem.bindir(gem_home)
Dir.mkdir bindir unless File.exist? bindir
raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir
- @spec.executables.each do |filename|
+ spec.executables.each do |filename|
filename.untaint
- bin_path = File.expand_path "#{@spec.bindir}/#{filename}", @gem_dir
- if File.exist?(bin_path)
- mode = File.stat(bin_path).mode | 0111
- File.chmod mode, bin_path
+ bin_path = File.expand_path File.join(gem_dir, spec.bindir, filename)
+
+ unless File.exist? bin_path
+ warn "Hey?!?! Where did #{bin_path} go??"
+ next
end
+ mode = File.stat(bin_path).mode | 0111
+ FileUtils.chmod mode, bin_path
+
if @wrappers then
generate_bin_script filename, bindir
else
@@ -322,14 +346,14 @@ class Gem::Installer
return
end
- src = File.join @gem_dir, 'bin', filename
+ src = File.join gem_dir, spec.bindir, filename
dst = File.join bindir, formatted_program_filename(filename)
if File.exist? dst then
if File.symlink? dst then
link = File.readlink(dst).split File::SEPARATOR
cur_version = Gem::Version.create(link[-3].sub(/^.*-/, ''))
- return if @spec.version < cur_version
+ return if spec.version < cur_version
end
File.unlink dst
end
@@ -343,7 +367,7 @@ class Gem::Installer
def shebang(bin_file_name)
ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang
- path = File.join @gem_dir, @spec.bindir, bin_file_name
+ path = spec.bin_file bin_file_name
first_line = File.open(path, "rb") {|file| file.gets}
if /\A#!/ =~ first_line then
@@ -365,29 +389,29 @@ class Gem::Installer
end
def ensure_required_ruby_version_met
- if rrv = @spec.required_ruby_version then
+ if rrv = spec.required_ruby_version then
unless rrv.satisfied_by? Gem.ruby_version then
- raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}."
+ raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}."
end
end
end
def ensure_required_rubygems_version_met
- if rrgv = @spec.required_rubygems_version then
+ if rrgv = spec.required_rubygems_version then
unless rrgv.satisfied_by? Gem::Version.new(Gem::VERSION) then
raise Gem::InstallError,
- "#{@spec.name} requires RubyGems version #{rrgv}. " +
+ "#{spec.name} requires RubyGems version #{rrgv}. " +
"Try 'gem update --system' to update RubyGems itself."
end
end
end
def ensure_dependencies_met
- deps = @spec.runtime_dependencies
- deps |= @spec.development_dependencies if @development
+ deps = spec.runtime_dependencies
+ deps |= spec.development_dependencies if @development
deps.each do |dep_gem|
- ensure_dependency @spec, dep_gem
+ ensure_dependency spec, dep_gem
end
end
@@ -398,32 +422,24 @@ class Gem::Installer
:exec_format => false,
:force => false,
:install_dir => Gem.dir,
- :source_index => Gem.source_index,
}.merge options
@env_shebang = options[:env_shebang]
@force = options[:force]
- gem_home = options[:install_dir]
- @gem_home = File.expand_path(gem_home)
+ @gem_home = options[:install_dir]
@ignore_dependencies = options[:ignore_dependencies]
@format_executable = options[:format_executable]
@security_policy = options[:security_policy]
@wrappers = options[:wrappers]
@bin_dir = options[:bin_dir]
@development = options[:development]
- @source_index = options[:source_index]
- end
- def load_gem_file
- begin
- @format = Gem::Format.from_file_by_path @gem, @security_policy
- rescue Gem::Package::FormatError
- raise Gem::InstallError, "invalid gem format for #{@gem}"
- end
+ raise "NOTE: Installer option :source_index is dead" if
+ options[:source_index]
end
def check_that_user_bin_dir_is_in_path
- user_bin_dir = File.join(@gem_home, 'bin')
+ user_bin_dir = File.join gem_home, "bin"
unless ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
unless self.class.path_warning then
alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
@@ -433,21 +449,21 @@ class Gem::Installer
end
def verify_gem_home(unpack = false)
- FileUtils.mkdir_p @gem_home
- raise Gem::FilePermissionError, @gem_home unless
- unpack or File.writable? @gem_home
+ FileUtils.mkdir_p gem_home
+ raise Gem::FilePermissionError, gem_home unless
+ unpack or File.writable?(gem_home)
end
##
# Return the text for an application file.
def app_script_text(bin_file_name)
- <<-TEXT
+ return <<-TEXT
#{shebang bin_file_name}
#
# This file was generated by RubyGems.
#
-# The application '#{@spec.name}' is installed as part of a gem, and
+# The application '#{spec.name}' is installed as part of a gem, and
# this file is here to facilitate running it.
#
@@ -460,8 +476,8 @@ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
ARGV.shift
end
-gem '#{@spec.name}', version
-load Gem.bin_path('#{@spec.name}', '#{bin_file_name}', version)
+gem '#{spec.name}', version
+load Gem.bin_path('#{spec.name}', '#{bin_file_name}', version)
TEXT
end
@@ -469,14 +485,16 @@ TEXT
# return the stub script text used to launch the true ruby script
def windows_stub_script(bindir, bin_file_name)
- <<-TEXT
+ ruby = File.basename(Gem.ruby).chomp('"')
+ return <<-TEXT
@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
-@"#{File.basename(Gem.ruby).chomp('"')}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
+@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
+@"#{ruby}" "%~dpn0" %*
TEXT
+
end
##
@@ -484,12 +502,12 @@ TEXT
# configure scripts and rakefiles or mkrf_conf files.
def build_extensions
- return if @spec.extensions.empty?
+ return if spec.extensions.empty?
say "Building native extensions. This could take a while..."
- dest_path = File.join @gem_dir, @spec.require_paths.first
+ dest_path = File.join gem_dir, spec.require_paths.first
ran_rake = false # only run rake once
- @spec.extensions.each do |extension|
+ spec.extensions.each do |extension|
break if ran_rake
results = []
@@ -508,15 +526,15 @@ TEXT
extension_dir = begin
- File.join @gem_dir, File.dirname(extension)
+ File.join gem_dir, File.dirname(extension)
rescue TypeError # extension == nil
- @gem_dir
+ gem_dir
end
begin
Dir.chdir extension_dir do
- results = builder.build(extension, @gem_dir, dest_path, results)
+ results = builder.build(extension, gem_dir, dest_path, results)
say results.join("\n") if Gem.configuration.really_verbose
end
@@ -532,7 +550,7 @@ ERROR: Failed to build gem native extension.
#{results}
-Gem files will remain installed in #{@gem_dir} for inspection.
+Gem files will remain installed in #{gem_dir} for inspection.
Results logged to #{gem_make_out}
EOF
@@ -547,35 +565,27 @@ EOF
# Ensures that files can't be installed outside the gem directory.
def extract_files
- @gem_dir = File.expand_path @gem_dir
-
raise ArgumentError, "format required to extract from" if @format.nil?
- dirs = []
-
@format.file_entries.each do |entry, file_data|
path = entry['path'].untaint
- if path =~ /\A\// then # for extra sanity
- raise Gem::InstallError,
- "attempt to install file into #{entry['path'].inspect}"
+ if path.start_with? "/" then # for extra sanity
+ raise Gem::InstallError, "attempt to install file into #{entry['path']}"
end
- path = File.expand_path File.join(@gem_dir, path)
+ path = File.expand_path File.join(gem_dir, path)
- if path !~ /\A#{Regexp.escape @gem_dir}/ then
- msg = "attempt to install file into %p under %p" %
- [entry['path'], @gem_dir]
+ unless path.start_with? gem_dir then
+ msg = "attempt to install file into %p under %s" %
+ [entry['path'], gem_dir]
raise Gem::InstallError, msg
end
- FileUtils.rm_rf(path) if File.exists?(path)
+ FileUtils.rm_rf(path) if File.exist? path
- dir = File.dirname(path)
- if !dirs.include?(dir)
- dirs << dir
- FileUtils.mkdir_p dir
- end
+ dir = File.dirname path
+ FileUtils.mkdir_p dir unless File.exist? dir
File.open(path, "wb") do |out|
out.write file_data
@@ -598,5 +608,14 @@ EOF
end
end
+ ##
+ #
+ # Return the target directory where the gem is to be installed. This
+ # directory is not guaranteed to be populated.
+ #
+
+ def dir
+ gem_dir.to_s
+ end
end
diff --git a/lib/rubygems/installer_test_case.rb b/lib/rubygems/installer_test_case.rb
index 26b5907..a548bd5 100644
--- a/lib/rubygems/installer_test_case.rb
+++ b/lib/rubygems/installer_test_case.rb
@@ -12,7 +12,7 @@ class Gem::Installer
##
# Available through requiring rubygems/installer_test_case
- attr_accessor :gem_dir
+ attr_writer :gem_dir
##
# Available through requiring rubygems/installer_test_case
@@ -63,29 +63,38 @@ class Gem::InstallerTestCase < Gem::TestCase
def setup
super
- @spec = quick_gem 'a'
- util_make_exec @spec
+ @installer_tmp = File.join @tempdir, 'installer'
+ FileUtils.mkdir_p @installer_tmp
- @gem = File.join @tempdir, @spec.file_name
+ Gem.use_paths @installer_tmp
+ Gem.ensure_gem_subdirectories @installer_tmp
- @installer = util_installer @spec, @gem, @gemhome
+ @spec = quick_gem 'a'
+ util_make_exec @spec
+ util_build_gem @spec
+ @gem = @spec.cache_file
@user_spec = quick_gem 'b'
util_make_exec @user_spec
+ util_build_gem @user_spec
+ @user_gem = @user_spec.cache_file
+
+ Gem.use_paths @gemhome
- @user_gem = File.join @tempdir, @user_spec.file_name
+ @installer = util_installer @spec, @gemhome
+ @user_installer = util_installer @user_spec, Gem.user_dir, :user
- @user_installer = util_installer @user_spec, @user_gem, Gem.user_dir
- @user_installer.gem_dir = File.join(Gem.user_dir, 'gems',
- @user_spec.full_name)
+ Gem.use_paths @gemhome
end
def util_gem_bindir spec = @spec
- File.join util_gem_dir(spec), "bin"
+ # TODO: deprecate
+ spec.bin_dir
end
def util_gem_dir spec = @spec
- File.join @gemhome, "gems", spec.full_name
+ # TODO: deprecate
+ spec.gem_dir
end
def util_inst_bindir
@@ -96,16 +105,13 @@ class Gem::InstallerTestCase < Gem::TestCase
spec.executables = %w[executable]
spec.files << 'bin/executable'
- bindir = util_gem_bindir spec
- FileUtils.mkdir_p bindir
- exec_path = File.join bindir, 'executable'
- open exec_path, 'w' do |io|
+ exec_path = spec.bin_file "executable"
+ write_file exec_path do |io|
io.puts shebang
end
- temp_bin = File.join(@tempdir, 'bin')
- FileUtils.mkdir_p temp_bin
- open File.join(temp_bin, 'executable'), 'w' do |io|
+ bin_path = File.join @tempdir, "bin", "executable"
+ write_file bin_path do |io|
io.puts shebang
end
end
@@ -128,23 +134,15 @@ class Gem::InstallerTestCase < Gem::TestCase
use_ui ui do
FileUtils.rm @gem
- Gem::Builder.new(@spec).build
+
+ @gem = Gem::Builder.new(@spec).build
end
end
@installer = Gem::Installer.new @gem
end
- def util_installer(spec, gem_path, gem_home)
- util_build_gem spec
- FileUtils.mv Gem.cache_gem(spec.file_name), @tempdir
- installer = Gem::Installer.new gem_path
- installer.gem_dir = util_gem_dir
- installer.gem_home = gem_home
- installer.spec = spec
-
- installer
+ def util_installer(spec, gem_home, user=false)
+ Gem::Installer.new spec.cache_file, :user_install => user
end
-
end
-
diff --git a/lib/rubygems/local_remote_options.rb b/lib/rubygems/local_remote_options.rb
index b752423..77a8006 100644
--- a/lib/rubygems/local_remote_options.rb
+++ b/lib/rubygems/local_remote_options.rb
@@ -82,7 +82,7 @@ module Gem::LocalRemoteOptions
add_option(:"Local/Remote", '--clear-sources',
'Clear the gem sources') do |value, options|
- Gem.sources.clear
+ Gem.sources = nil
options[:sources_cleared] = true
end
end
@@ -123,7 +123,7 @@ module Gem::LocalRemoteOptions
# Add the --update-sources option
def add_update_sources_option
- add_option(:"Local/Remote", '-u', '--[no-]update-sources',
+ add_option(:Deprecated, '-u', '--[no-]update-sources',
'Update local source cache') do |value, options|
Gem.configuration.update_sources = value
end
diff --git a/lib/rubygems/mock_gem_ui.rb b/lib/rubygems/mock_gem_ui.rb
index 4450cc9..88c3662 100644
--- a/lib/rubygems/mock_gem_ui.rb
+++ b/lib/rubygems/mock_gem_ui.rb
@@ -12,7 +12,15 @@ require 'rubygems/user_interaction'
# retrieval during tests.
class Gem::MockGemUi < Gem::StreamUI
- class TermError < RuntimeError; end
+ class TermError < RuntimeError
+ attr_reader :exit_code
+
+ def initialize exit_code
+ super
+ @exit_code = exit_code
+ end
+ end
+ class SystemExitException < RuntimeError; end
module TTY
@@ -61,8 +69,8 @@ class Gem::MockGemUi < Gem::StreamUI
def terminate_interaction(status=0)
@terminated = true
- raise TermError unless status == 0
- raise Gem::SystemExitException, status
+ raise TermError, status if status != 0
+ raise SystemExitException
end
end
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb
index 3a50ca1..2e108bf 100644
--- a/lib/rubygems/package.rb
+++ b/lib/rubygems/package.rb
@@ -12,32 +12,6 @@
require 'rubygems/specification'
-##
-# Wrapper for FileUtils meant to provide logging and additional operations if
-# needed.
-
-class Gem::FileOperations
-
- def initialize(logger = nil)
- require 'fileutils'
- @logger = logger
- end
-
- def method_missing(meth, *args, &block)
- case
- when FileUtils.respond_to?(meth)
- @logger.log "#{meth}: #{args}" if @logger
- FileUtils.send meth, *args, &block
- when Gem::FileOperations.respond_to?(meth)
- @logger.log "#{meth}: #{args}" if @logger
- Gem::FileOperations.send meth, *args, &block
- else
- super
- end
- end
-
-end
-
module Gem::Package
class Error < StandardError; end
@@ -63,6 +37,8 @@ module Gem::Package
class TarInvalidError < Error; end
+ # FIX: zenspider said: does it really take an IO?
+ # passed to a method called open?!? that seems stupid.
def self.open(io, mode = "r", signer = nil, &block)
tar_type = case mode
when 'r' then TarInput
diff --git a/lib/rubygems/package/tar_input.rb b/lib/rubygems/package/tar_input.rb
index 401df80..92c190c 100644
--- a/lib/rubygems/package/tar_input.rb
+++ b/lib/rubygems/package/tar_input.rb
@@ -55,6 +55,7 @@ class Gem::Package::TarInput
sio.rewind
end
+ # TODO use Gem.gunzip
gzis = Zlib::GzipReader.new(sio || entry)
# YAML wants an instance of IO
@metadata = load_gemspec(gzis)
@@ -115,7 +116,6 @@ class Gem::Package::TarInput
end
@tarreader.rewind
- @fileops = Gem::FileOperations.new
unless has_meta then
path = io.path if io.respond_to? :path
@@ -151,9 +151,9 @@ class Gem::Package::TarInput
dest = File.join destdir, entry.full_name
if File.directory? dest then
- @fileops.chmod entry.header.mode, dest, :verbose => false
+ FileUtils.chmod entry.header.mode, dest, :verbose => false
else
- @fileops.mkdir_p dest, :mode => entry.header.mode, :verbose => false
+ FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
end
fsync_dir dest
@@ -165,9 +165,9 @@ class Gem::Package::TarInput
# it's a file
md5 = Digest::MD5.new if expected_md5sum
destdir = File.join destdir, File.dirname(entry.full_name)
- @fileops.mkdir_p destdir, :mode => 0755, :verbose => false
+ FileUtils.mkdir_p destdir, :mode => 0755, :verbose => false
destfile = File.join destdir, File.basename(entry.full_name)
- @fileops.chmod 0600, destfile, :verbose => false rescue nil # Errno::ENOENT
+ FileUtils.chmod 0600, destfile, :verbose => false rescue nil # Errno::ENOENT
open destfile, "wb", entry.header.mode do |os|
loop do
@@ -181,7 +181,7 @@ class Gem::Package::TarInput
os.fsync
end
- @fileops.chmod entry.header.mode, destfile, :verbose => false
+ FileUtils.chmod entry.header.mode, destfile, :verbose => false
fsync_dir File.dirname(destfile)
fsync_dir File.join(File.dirname(destfile), "..")
diff --git a/lib/rubygems/package/tar_writer.rb b/lib/rubygems/package/tar_writer.rb
index 823f20c..aeb11ad 100644
--- a/lib/rubygems/package/tar_writer.rb
+++ b/lib/rubygems/package/tar_writer.rb
@@ -236,7 +236,7 @@ class Gem::Package::TarWriter
name = newname
if name.size > 100 or prefix.size > 155 then
- raise Gem::Package::TooLongFileName
+ raise Gem::Package::TooLongFileName
end
end
diff --git a/lib/rubygems/package_task.rb b/lib/rubygems/package_task.rb
index ae4f201..5b6b381 100644
--- a/lib/rubygems/package_task.rb
+++ b/lib/rubygems/package_task.rb
@@ -106,7 +106,7 @@ class Gem::PackageTask < Rake::PackageTask
task :package => [:gem]
- gem_file = gem_spec.file_name
+ gem_file = File.basename gem_spec.cache_file
gem_path = File.join package_dir, gem_file
gem_dir = File.join package_dir, gem_spec.full_name
diff --git a/lib/rubygems/path_support.rb b/lib/rubygems/path_support.rb
new file mode 100644
index 0000000..0809f8a
--- /dev/null
+++ b/lib/rubygems/path_support.rb
@@ -0,0 +1,78 @@
+######################################################################
+# This file is imported from the rubygems project.
+# DO NOT make modifications in this repo. They _will_ be reverted!
+# File a patch instead and assign it to Ryan Davis or Eric Hodel.
+######################################################################
+
+##
+#
+# Gem::PathSupport facilitates the GEM_HOME and GEM_PATH environment settings
+# to the rest of RubyGems.
+#
+class Gem::PathSupport
+ ##
+ # The default system path for managing Gems.
+ attr_reader :home
+
+ ##
+ # Array of paths to search for Gems.
+ attr_reader :path
+
+ ##
+ #
+ # Constructor. Takes a single argument which is to be treated like a
+ # hashtable, or defaults to ENV, the system environment.
+ #
+ def initialize(env=ENV)
+ @env = env
+
+ # note 'env' vs 'ENV'...
+ @home = env["GEM_HOME"] || ENV["GEM_HOME"] || Gem.default_dir
+ self.path = env["GEM_PATH"] || ENV["GEM_PATH"]
+ end
+
+ private
+
+ ##
+ # Set the Gem home directory (as reported by Gem.dir).
+
+ def home=(home)
+ @home = home.to_s
+ end
+
+ ##
+ # Set the Gem search path (as reported by Gem.path).
+
+ def path=(gpaths)
+ # FIX: it should be [home, *path], not [*path, home]
+
+ gem_path = []
+
+ # FIX: I can't tell wtf this is doing.
+ gpaths ||= (ENV['GEM_PATH'] || "").empty? ? nil : ENV["GEM_PATH"]
+
+ if gpaths
+ if gpaths.kind_of?(Array)
+ gem_path = gpaths.dup
+ else
+ gem_path = gpaths.split(File::PATH_SEPARATOR)
+ end
+
+ if File::ALT_SEPARATOR then
+ gem_path.map! do |this_path|
+ this_path.gsub File::ALT_SEPARATOR, File::SEPARATOR
+ end
+ end
+
+ gem_path << @home
+ else
+ gem_path = Gem.default_path + [@home]
+
+ if defined?(Gem::APPLE_GEM_HOME)
+ gem_path << Gem::APPLE_GEM_HOME
+ end
+ end
+
+ @path = gem_path.uniq
+ end
+end
diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index b6608c7..cf6db7c 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -4,6 +4,8 @@
# File a patch instead and assign it to Ryan Davis or Eric Hodel.
######################################################################
+require "rubygems/deprecate"
+
##
# Available list of platforms for targeting Gem installations.
@@ -121,8 +123,13 @@ class Gem::Platform
# the same CPU, OS and version.
def ==(other)
- self.class === other and
- @cpu == other.cpu and @os == other.os and @version == other.version
+ self.class === other and to_a == other.to_a
+ end
+
+ alias :eql? :==
+
+ def hash # :nodoc:
+ to_a.hash
end
##
@@ -185,5 +192,8 @@ class Gem::Platform
CURRENT = 'current'
+ extend Deprecate
+
+ deprecate :empty?, :none, 2011, 11
end
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb
index 520adb5..4613bff 100644
--- a/lib/rubygems/remote_fetcher.rb
+++ b/lib/rubygems/remote_fetcher.rb
@@ -75,6 +75,7 @@ class Gem::RemoteFetcher
when URI::HTTP then proxy
else URI.parse(proxy)
end
+ @user_agent = user_agent
end
##
@@ -85,7 +86,8 @@ class Gem::RemoteFetcher
# larger, more emcompassing effort. -erikh
def download_to_cache dependency
- found = Gem::SpecFetcher.fetcher.fetch dependency
+ found = Gem::SpecFetcher.fetcher.fetch dependency, true, true,
+ dependency.prerelease?
return if found.empty?
@@ -103,12 +105,12 @@ class Gem::RemoteFetcher
Gem.ensure_gem_subdirectories(install_dir) rescue nil
if File.writable?(install_dir)
- cache_dir = Gem.cache_dir(install_dir)
+ cache_dir = File.join install_dir, "cache"
else
- cache_dir = Gem.cache_dir(Gem.user_dir)
+ cache_dir = File.join Gem.user_dir, "cache"
end
- gem_file_name = spec.file_name
+ gem_file_name = File.basename spec.cache_file
local_gem_path = File.join cache_dir, gem_file_name
FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
@@ -116,8 +118,8 @@ class Gem::RemoteFetcher
# Always escape URI's to deal with potential spaces and such
unless URI::Generic === source_uri
source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ?
- URI::DEFAULT_PARSER.escape(source_uri) :
- URI.escape(source_uri))
+ URI::DEFAULT_PARSER.escape(source_uri.to_s) :
+ URI.escape(source_uri.to_s))
end
scheme = source_uri.scheme
@@ -193,18 +195,54 @@ class Gem::RemoteFetcher
end
##
+ # File Fetcher. Dispatched by +fetch_path+. Use it instead.
+
+ def fetch_file uri, *_
+ Gem.read_binary correct_for_windows_path uri.path
+ end
+
+ ##
+ # HTTP Fetcher. Dispatched by +fetch_path+. Use it instead.
+
+ def fetch_http uri, last_modified = nil, head = false, depth = 0
+ fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
+ response = request uri, fetch_type, last_modified
+
+ case response
+ when Net::HTTPOK, Net::HTTPNotModified then
+ head ? response : response.body
+ when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
+ Net::HTTPTemporaryRedirect then
+ raise FetchError.new('too many redirects', uri) if depth > 10
+
+ location = URI.parse response['Location']
+ fetch_http(location, last_modified, head, depth + 1)
+ else
+ raise FetchError.new("bad response #{response.message} #{response.code}", uri)
+ end
+ end
+
+ alias :fetch_https :fetch_http
+
+ ##
# Downloads +uri+ and returns it as a String.
def fetch_path(uri, mtime = nil, head = false)
- data = open_uri_or_path uri, mtime, head
+ uri = URI.parse uri unless URI::Generic === uri
+
+ raise ArgumentError, "bad uri: #{uri}" unless uri
+ raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}" unless
+ uri.scheme
+
+ data = send "fetch_#{uri.scheme}", uri, mtime, head
data = Gem.gunzip data if data and not head and uri.to_s =~ /gz$/
data
rescue FetchError
raise
rescue Timeout::Error
- raise FetchError.new('timed out', uri)
+ raise FetchError.new('timed out', uri.to_s)
rescue IOError, SocketError, SystemCallError => e
- raise FetchError.new("#{e.class}: #{e}", uri)
+ raise FetchError.new("#{e.class}: #{e}", uri.to_s)
end
##
@@ -306,36 +344,8 @@ class Gem::RemoteFetcher
# read from the filesystem instead.
def open_uri_or_path(uri, last_modified = nil, head = false, depth = 0)
- raise "block is dead" if block_given?
-
- uri = URI.parse uri unless URI::Generic === uri
-
- # This check is redundant unless Gem::RemoteFetcher is likely
- # to be used directly, since the scheme is checked elsewhere.
- # - Daniel Berger
- unless ['http', 'https', 'file'].include?(uri.scheme)
- raise ArgumentError, 'uri scheme is invalid'
- end
-
- if uri.scheme == 'file'
- path = correct_for_windows_path(uri.path)
- return Gem.read_binary(path)
- end
-
- fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
- response = request uri, fetch_type, last_modified
-
- case response
- when Net::HTTPOK, Net::HTTPNotModified then
- head ? response : response.body
- when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
- Net::HTTPTemporaryRedirect then
- raise FetchError.new('too many redirects', uri) if depth > 10
-
- open_uri_or_path(response['Location'], last_modified, head, depth + 1)
- else
- raise FetchError.new("bad response #{response.message} #{response.code}", uri)
- end
+ raise "NO: Use fetch_path instead"
+ # TODO: deprecate for fetch_path
end
##
@@ -350,12 +360,7 @@ class Gem::RemoteFetcher
request.basic_auth uri.user, uri.password
end
- ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}"
- ua << " Ruby/#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
- ua << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
- ua << ")"
-
- request.add_field 'User-Agent', ua
+ request.add_field 'User-Agent', @user_agent
request.add_field 'Connection', 'keep-alive'
request.add_field 'Keep-Alive', '30'
@@ -447,5 +452,24 @@ class Gem::RemoteFetcher
connection.start
end
+ def user_agent
+ ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}"
+
+ ruby_version = RUBY_VERSION
+ ruby_version += 'dev' if RUBY_PATCHLEVEL == -1
+
+ ua << " Ruby/#{ruby_version} (#{RUBY_RELEASE_DATE}"
+ if RUBY_PATCHLEVEL >= 0 then
+ ua << " patchlevel #{RUBY_PATCHLEVEL}"
+ elsif defined?(RUBY_REVISION) then
+ ua << " revision #{RUBY_REVISION}"
+ end
+ ua << ")"
+
+ ua << " #{RUBY_ENGINE}" if defined?(RUBY_ENGINE) and RUBY_ENGINE != 'ruby'
+
+ ua
+ end
+
end
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
index 35f7d08..f7bda10 100644
--- a/lib/rubygems/requirement.rb
+++ b/lib/rubygems/requirement.rb
@@ -141,6 +141,18 @@ class Gem::Requirement
requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv }
end
+ alias :=== :satisfied_by?
+ alias :=~ :satisfied_by?
+
+ ##
+ # True if the requirement will not always match the latest version.
+
+ def specific?
+ return true if @requirements.length > 1 # GIGO, > 1, > 2 is silly
+
+ not %w[> >=].include? @requirements.first.first # grab the operator
+ end
+
def to_s # :nodoc:
as_list.join ", "
end
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
index 1ff375d..2709279 100644
--- a/lib/rubygems/security.rb
+++ b/lib/rubygems/security.rb
@@ -393,7 +393,7 @@ module Gem::Security
:munge_re => Regexp.new(/[^a-z0-9_.-]+/),
# output directory for trusted certificate checksums
- :trust_dir => File::join(Gem.user_home, '.gem', 'trust'),
+ :trust_dir => File.join(Gem.user_home, '.gem', 'trust'),
# default permissions for trust directory and certs
:perms => {
diff --git a/lib/rubygems/server.rb b/lib/rubygems/server.rb
index 76cb22f..95ca292 100644
--- a/lib/rubygems/server.rb
+++ b/lib/rubygems/server.rb
@@ -81,47 +81,47 @@ class Gem::Server
<dl>
<% values["specs"].each do |spec| %>
- <dt>
- <% if spec["first_name_entry"] then %>
- <a name="<%=spec["name"]%>"></a>
- <% end %>
-
- <b><%=spec["name"]%> <%=spec["version"]%></b>
-
- <% if spec["rdoc_installed"] then %>
- <a href="<%=spec["doc_path"]%>">[rdoc]</a>
- <% else %>
- <span title="rdoc not installed">[rdoc]</span>
- <% end %>
-
- <% if spec["homepage"] then %>
- <a href="<%=spec["homepage"]%>" title="<%=spec["homepage"]%>">[www]</a>
- <% else %>
- <span title="no homepage available">[www]</span>
- <% end %>
-
- <% if spec["has_deps"] then %>
- - depends on
- <%= spec["dependencies"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
- <% end %>
- </dt>
- <dd>
- <%=spec["summary"]%>
- <% if spec["executables"] then %>
- <br/>
-
- <% if spec["only_one_executable"] then %>
- Executable is
- <% else %>
- Executables are
- <%end%>
-
- <%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>.
-
- <%end%>
- <br/>
- <br/>
- </dd>
+ <dt>
+ <% if spec["first_name_entry"] then %>
+ <a name="<%=spec["name"]%>"></a>
+ <% end %>
+
+ <b><%=spec["name"]%> <%=spec["version"]%></b>
+
+ <% if spec["rdoc_installed"] then %>
+ <a href="<%=spec["doc_path"]%>">[rdoc]</a>
+ <% else %>
+ <span title="rdoc not installed">[rdoc]</span>
+ <% end %>
+
+ <% if spec["homepage"] then %>
+ <a href="<%=spec["homepage"]%>" title="<%=spec["homepage"]%>">[www]</a>
+ <% else %>
+ <span title="no homepage available">[www]</span>
+ <% end %>
+
+ <% if spec["has_deps"] then %>
+ - depends on
+ <%= spec["dependencies"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
+ <% end %>
+ </dt>
+ <dd>
+ <%=spec["summary"]%>
+ <% if spec["executables"] then %>
+ <br/>
+
+ <% if spec["only_one_executable"] then %>
+ Executable is
+ <% else %>
+ Executables are
+ <%end%>
+
+ <%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>.
+
+ <%end%>
+ <br/>
+ <br/>
+ </dd>
<% end %>
</dl>
@@ -460,15 +460,15 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
spec_dir
end
- @source_index = Gem::SourceIndex.from_gems_in(*@spec_dirs)
+ Gem::Specification.dirs = @gem_dirs
end
def Marshal(req, res)
- @source_index.refresh!
+ Gem::Specification.reset
add_date res
- index = Marshal.dump @source_index
+ index = Deprecate.skip_during { Marshal.dump Gem.source_index }
if req.request_method == 'HEAD' then
res['content-length'] = index.length
@@ -492,15 +492,16 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end
def latest_specs(req, res)
- @source_index.refresh!
+ Gem::Specification.reset
res['content-type'] = 'application/x-gzip'
add_date res
- specs = @source_index.latest_specs.sort.map do |spec|
- platform = spec.original_platform
- platform = Gem::Platform::RUBY if platform.nil?
+ latest_specs = Gem::Specification.latest_specs
+
+ specs = latest_specs.sort.map do |spec|
+ platform = spec.original_platform || Gem::Platform::RUBY
[spec.name, spec.version, platform]
end
@@ -552,21 +553,20 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end
def quick(req, res)
- @source_index.refresh!
+ Gem::Specification.reset
res['content-type'] = 'text/plain'
add_date res
case req.request_uri.path
when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+)(-.*?)?\.gemspec\.rz$| then
- dep = Gem::Dependency.new $2, $3
- specs = @source_index.search dep
- marshal_format = $1
+ marshal_format, name, version, platform = $1, $2, $3, $4
+ specs = Gem::Specification.find_all_by_name name, version
- selector = [$2, $3, $4].map { |s| s.inspect }.join ' '
+ selector = [name, version, platform].map(&:inspect).join ' '
- platform = if $4 then
- Gem::Platform.new $4.sub(/^-/, '')
+ platform = if platform then
+ Gem::Platform.new platform.sub(/^-/, '')
else
Gem::Platform::RUBY
end
@@ -589,7 +589,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end
def root(req, res)
- @source_index.refresh!
+ Gem::Specification.reset
add_date res
raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." unless
@@ -598,13 +598,15 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
specs = []
total_file_count = 0
- @source_index.each do |path, spec|
+ Gem::Specification.each do |spec|
total_file_count += spec.files.size
- deps = spec.dependencies.map do |dep|
- { "name" => dep.name,
+ deps = spec.dependencies.map { |dep|
+ {
+ "name" => dep.name,
"type" => dep.type,
- "version" => dep.requirement.to_s, }
- end
+ "version" => dep.requirement.to_s,
+ }
+ }
deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] }
deps.last["is_last"] = true unless deps.empty?
@@ -798,13 +800,12 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end
def specs(req, res)
- @source_index.refresh!
+ Gem::Specification.reset
add_date res
- specs = @source_index.sort.map do |_, spec|
- platform = spec.original_platform
- platform = Gem::Platform::RUBY if platform.nil?
+ specs = Gem::Specification.sort_by(&:sort_obj).map do |spec|
+ platform = spec.original_platform || Gem::Platform::RUBY
[spec.name, spec.version, platform]
end
@@ -827,12 +828,11 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
def launch
listeners = @server.listeners.map{|l| l.addr[2] }
+ # TODO: 0.0.0.0 == any, not localhost.
host = listeners.any?{|l| l == '0.0.0.0'} ? 'localhost' : listeners.first
say "Launching browser to http://#{host}:#{@port}"
system("#{@launch} http://#{host}:#{@port}")
end
-
end
-
diff --git a/lib/rubygems/source_index.rb b/lib/rubygems/source_index.rb
index a6733fa..74ad547 100644
--- a/lib/rubygems/source_index.rb
+++ b/lib/rubygems/source_index.rb
@@ -11,6 +11,7 @@
#++
require 'rubygems/specification'
+require 'rubygems/deprecate'
##
# The SourceIndex object indexes all the gems available from a
@@ -34,79 +35,86 @@ class Gem::SourceIndex
attr_accessor :spec_dirs
- class << self
- ##
- # Factory method to construct a source index instance for a given
- # path.
- #
- # deprecated::
- # If supplied, from_installed_gems will act just like
- # +from_gems_in+. This argument is deprecated and is provided
- # just for backwards compatibility, and should not generally
- # be used.
- #
- # return::
- # SourceIndex instance
-
- def from_installed_gems(*deprecated)
- if deprecated.empty?
- from_gems_in(*installed_spec_directories)
- else
- from_gems_in(*deprecated) # HACK warn
- end
+ ##
+ # Factory method to construct a source index instance for a given
+ # path.
+ #
+ # deprecated::
+ # If supplied, from_installed_gems will act just like
+ # +from_gems_in+. This argument is deprecated and is provided
+ # just for backwards compatibility, and should not generally
+ # be used.
+ #
+ # return::
+ # SourceIndex instance
+
+ def self.from_installed_gems(*deprecated)
+ if deprecated.empty?
+ from_gems_in(*installed_spec_directories)
+ else
+ warn "NOTE: from_installed_gems(arg) is deprecated. From #{caller.first}"
+ from_gems_in(*deprecated) # HACK warn
end
+ end
- ##
- # Returns a list of directories from Gem.path that contain specifications.
+ ##
+ # Returns a list of directories from Gem.path that contain specifications.
- def installed_spec_directories
- Gem.path.collect { |dir| File.join(dir, "specifications") }
- end
+ def self.installed_spec_directories
+ # TODO: move to Gem::Utils
+ Gem.path.collect { |dir| File.join(dir, "specifications") }
+ end
- ##
- # Creates a new SourceIndex from the ruby format gem specifications in
- # +spec_dirs+.
+ ##
+ # Creates a new SourceIndex from the ruby format gem specifications in
+ # +spec_dirs+.
- def from_gems_in(*spec_dirs)
- source_index = new
- source_index.spec_dirs = spec_dirs
- source_index.refresh!
- end
+ def self.from_gems_in(*spec_dirs)
+ new spec_dirs
+ end
- ##
- # Loads a ruby-format specification from +file_name+ and returns the
- # loaded spec.
+ ##
+ # Loads a ruby-format specification from +file_name+ and returns the
+ # loaded spec.
- def load_specification(file_name)
- Gem::Specification.load file_name
+ def self.load_specification(file_name)
+ Deprecate.skip_during do
+ Gem::Specification.load Gem::Path.new(file_name)
end
-
end
##
# Constructs a source index instance from the provided specifications, which
# is a Hash of gem full names and Gem::Specifications.
- #--
- # TODO merge @gems and @prerelease_gems and provide a separate method
- # #prerelease_gems
- def initialize(specifications={})
+ def initialize specs_or_dirs = []
@gems = {}
- specifications.each{ |full_name, spec| add_spec spec }
@spec_dirs = nil
+
+ case specs_or_dirs
+ when Hash then
+ specs_or_dirs.each do |full_name, spec|
+ add_spec spec
+ end
+ when Array, String then
+ self.spec_dirs = Array(specs_or_dirs)
+ refresh!
+ else
+ arg = specs_or_dirs.inspect
+ warn "NOTE: SourceIndex.new(#{arg}) is deprecated; From #{caller.first}."
+ end
end
- # TODO: remove method
def all_gems
- @gems
+ gems
end
def prerelease_gems
- @gems.reject{ |name, gem| !gem.version.prerelease? }
+ @gems.reject { |name, gem| !gem.version.prerelease? }
end
def released_gems
- @gems.reject{ |name, gem| gem.version.prerelease? }
+ @gems.reject { |name, gem| gem.version.prerelease? }
end
##
@@ -116,10 +124,12 @@ class Gem::SourceIndex
@gems.clear
spec_dirs.reverse_each do |spec_dir|
- spec_files = Dir.glob File.join(spec_dir, '*.gemspec')
+ spec_files = Dir[File.join(spec_dir, "*.gemspec")]
spec_files.each do |spec_file|
- gemspec = Gem::Specification.load spec_file
+ gemspec = Deprecate.skip_during do
+ Gem::Specification.load spec_file
+ end
add_spec gemspec if gemspec
end
end
@@ -159,8 +169,6 @@ class Gem::SourceIndex
result[name] << spec
end
- # TODO: why is this a hash while @gems is an array? Seems like
- # structural similarity would be good.
result.values.flatten
end
@@ -246,7 +254,10 @@ class Gem::SourceIndex
def find_name(gem_name, requirement = Gem::Requirement.default)
dep = Gem::Dependency.new gem_name, requirement
- search dep
+
+ Deprecate.skip_during do
+ search dep
+ end
end
##
@@ -258,9 +269,9 @@ class Gem::SourceIndex
# +gem_pattern+, and a Gem::Requirement for +platform_only+. This
# behavior is deprecated and will be removed.
- def search(gem_pattern, platform_only = false)
+ def search(gem_pattern, platform_or_requirement = false)
requirement = nil
- only_platform = false
+ only_platform = false # FIX: WTF is this?!?
# TODO - Remove support and warning for legacy arguments after 2008/11
unless Gem::Dependency === gem_pattern
@@ -269,9 +280,9 @@ class Gem::SourceIndex
case gem_pattern
when Regexp then
- requirement = platform_only || Gem::Requirement.default
+ requirement = platform_or_requirement || Gem::Requirement.default
when Gem::Dependency then
- only_platform = platform_only
+ only_platform = platform_or_requirement
requirement = gem_pattern.requirement
gem_pattern = if Regexp === gem_pattern.name then
@@ -282,7 +293,7 @@ class Gem::SourceIndex
/^#{Regexp.escape gem_pattern.name}$/
end
else
- requirement = platform_only || Gem::Requirement.default
+ requirement = platform_or_requirement || Gem::Requirement.default
gem_pattern = /#{gem_pattern}/i
end
@@ -290,7 +301,7 @@ class Gem::SourceIndex
requirement = Gem::Requirement.create requirement
end
- specs = all_gems.values.select do |spec|
+ specs = @gems.values.select do |spec|
spec.name =~ gem_pattern and
requirement.satisfied_by? spec.version
end
@@ -343,7 +354,6 @@ class Gem::SourceIndex
def dump
Marshal.dump(self)
end
-
end
# :stopdoc:
@@ -356,5 +366,45 @@ module Gem
Cache = SourceIndex
end
-# :startdoc:
+class Gem::SourceIndex
+ extend Deprecate
+
+ deprecate :all_gems, :none, 2011, 10
+
+ deprecate :==, :none, 2011, 11 # noisy
+ deprecate :add_specs, :none, 2011, 11 # noisy
+ deprecate :each, :none, 2011, 11
+ deprecate :gems, :none, 2011, 11
+ deprecate :load_gems_in, :none, 2011, 11
+ deprecate :refresh!, :none, 2011, 11
+ deprecate :spec_dirs=, "Specification.dirs=", 2011, 11 # noisy
+ deprecate :add_spec, "Specification.add_spec", 2011, 11
+ deprecate :find_name, "Specification.find_by_name", 2011, 11
+ deprecate :gem_signature, :none, 2011, 11
+ deprecate :index_signature, :none, 2011, 11
+ deprecate :initialize, :none, 2011, 11
+ deprecate :latest_specs, "Specification.latest_specs", 2011, 11
+ deprecate :length, "Specification.all.length", 2011, 11
+ deprecate :outdated, :none, 2011, 11
+ deprecate :prerelease_gems, :none, 2011, 11
+ deprecate :prerelease_specs, :none, 2011, 11
+ deprecate :released_gems, :none, 2011, 11
+ deprecate :released_specs, :none, 2011, 11
+ deprecate :remove_spec, "Specification.remove_spec", 2011, 11
+ deprecate :search, :none, 2011, 11
+ deprecate :size, "Specification.all.size", 2011, 11
+ deprecate :spec_dirs, "Specification.dirs", 2011, 11
+ deprecate :specification, "Specification.find", 2011, 11
+
+ class << self
+ extend Deprecate
+
+ deprecate :from_gems_in, :none, 2011, 10
+ deprecate :from_installed_gems, :none, 2011, 10
+ deprecate :installed_spec_directories, "Specification.dirs", 2011, 11
+ deprecate :load_specification, :none, 2011, 10
+ end
+end
+
+# :startdoc:
diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb
index 6c71ee6..3823dbd 100644
--- a/lib/rubygems/spec_fetcher.rb
+++ b/lib/rubygems/spec_fetcher.rb
@@ -91,6 +91,7 @@ class Gem::SpecFetcher
all = false,
matching_platform = true,
prerelease = false)
+
specs_and_sources, errors = find_matching_with_errors(dependency,
all,
matching_platform,
@@ -144,7 +145,10 @@ class Gem::SpecFetcher
# matching released versions are returned. If +matching_platform+
# is false, gems for all platforms are returned.
- def find_matching_with_errors(dependency, all = false, matching_platform = true, prerelease = false)
+ def find_matching_with_errors(dependency,
+ all = false,
+ matching_platform = true,
+ prerelease = false)
found = {}
rejected_specs = {}
@@ -257,13 +261,12 @@ class Gem::SpecFetcher
loaded = false
if File.exist? local_file then
- spec_dump = @fetcher.fetch_path spec_path, File.mtime(local_file)
+ spec_dump =
+ @fetcher.fetch_path(spec_path, File.mtime(local_file)) rescue nil
- if spec_dump.nil? then
- spec_dump = Gem.read_binary local_file
- else
- loaded = true
- end
+ loaded = true if spec_dump
+
+ spec_dump ||= Gem.read_binary local_file
else
spec_dump = @fetcher.fetch_path spec_path
loaded = true
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index a5e250a..0d3cb4e 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -13,6 +13,7 @@
require 'rubygems/version'
require 'rubygems/requirement'
require 'rubygems/platform'
+require "rubygems/deprecate"
# :stopdoc:
class Date; end # for ruby_code if date.rb wasn't required
@@ -34,11 +35,6 @@ class Date; end # for ruby_code if date.rb wasn't required
class Gem::Specification
##
- # Allows deinstallation of gems with legacy platforms.
-
- attr_accessor :original_platform # :nodoc:
-
- ##
# The the version number of a specification that does not specify one
# (i.e. RubyGems 0.7 or earlier).
@@ -48,6 +44,17 @@ class Gem::Specification
# The specification version applied to any new Specification instances
# created. This should be bumped whenever something in the spec format
# changes.
+ #
+ # Specification Version History:
+ #
+ # spec ruby
+ # ver ver yyyy-mm-dd description
+ # -1 <0.8.0 pre-spec-version-history
+ # 1 0.8.0 2004-08-01 Deprecated "test_suite_file" for "test_files"
+ # "test_file=x" is a shortcut for "test_files=[x]"
+ # 2 0.9.5 2007-10-01 Added "required_rubygems_version"
+ # Now forward-compatible with future versions
+ # 3 1.3.2 2009-01-03 Added Fixnum validation to specification_version
#--
# When updating this number, be sure to also update #to_ruby.
#
@@ -55,423 +62,423 @@ class Gem::Specification
CURRENT_SPECIFICATION_VERSION = 3
- ##
- # An informal list of changes to the specification. The highest-valued
- # key should be equal to the CURRENT_SPECIFICATION_VERSION.
-
- SPECIFICATION_VERSION_HISTORY = {
- -1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'],
- 1 => [
- 'Deprecated "test_suite_file" in favor of the new, but equivalent, "test_files"',
- '"test_file=x" is a shortcut for "test_files=[x]"'
- ],
- 2 => [
- 'Added "required_rubygems_version"',
- 'Now forward-compatible with future versions',
- ],
- 3 => [
- 'Added Fixnum validation to the specification_version'
- ]
- }
-
# :stopdoc:
+
+ # version => # of fields
MARSHAL_FIELDS = { -1 => 16, 1 => 16, 2 => 16, 3 => 17 }
- now = Time.at(Time.now.to_i)
- TODAY = now - ((now.to_i + now.gmt_offset) % 86400)
+ today = Time.now.utc
+ TODAY = Time.utc(today.year, today.month, today.day)
+
# :startdoc:
##
- # Optional block used to gather newly defined instances.
+ # List of attribute names: [:name, :version, ...]
- @@gather = nil
+ @@required_attributes = [:rubygems_version,
+ :specification_version,
+ :name,
+ :version,
+ :date,
+ :summary,
+ :require_paths]
##
- # List of attribute names: [:name, :version, ...]
+ # Map of attribute names to default values.
+
+ @@default_value = {
+ :authors => [],
+ :autorequire => nil,
+ :bindir => 'bin',
+ :cert_chain => [],
+ :date => TODAY,
+ :dependencies => [],
+ :description => nil,
+ :email => nil,
+ :executables => [],
+ :extensions => [],
+ :extra_rdoc_files => [],
+ :files => [],
+ :homepage => nil,
+ :licenses => [],
+ :name => nil,
+ :platform => Gem::Platform::RUBY,
+ :post_install_message => nil,
+ :rdoc_options => [],
+ :require_paths => ['lib'],
+ :required_ruby_version => Gem::Requirement.default,
+ :required_rubygems_version => Gem::Requirement.default,
+ :requirements => [],
+ :rubyforge_project => nil,
+ :rubygems_version => Gem::VERSION,
+ :signing_key => nil,
+ :specification_version => CURRENT_SPECIFICATION_VERSION,
+ :summary => nil,
+ :test_files => [],
+ :version => nil,
+ }
+
+ @@attributes = @@default_value.keys.sort_by { |s| s.to_s }
+ @@array_attributes = @@default_value.reject { |k,v| v != [] }.keys
+ @@nil_attributes, @@non_nil_attributes = @@default_value.keys.partition { |k|
+ @@default_value[k].nil?
+ }
- @@required_attributes = []
+ ######################################################################
+ # :section: Required gemspec attributes
##
- # List of _all_ attributes and default values:
- #
- # [[:name, nil],
- # [:bindir, 'bin'],
- # ...]
+ # This gem's name
- @@attributes = []
+ attr_accessor :name
- @@nil_attributes = []
- @@non_nil_attributes = [:@original_platform]
+ ##
+ # This gem's version
+
+ attr_reader :version
##
- # List of array attributes
+ # Paths in the gem to add to $LOAD_PATH when this gem is activated.
+ #
+ # The default ['lib'] is typically sufficient.
- @@array_attributes = []
+ attr_accessor :require_paths
##
- # Map of attribute names to default values.
+ # The version of RubyGems used to create this gem.
+ #
+ # Do not set this, it is set automatically when the gem is packaged.
- @@default_value = {}
+ attr_accessor :rubygems_version
##
- # Names of all specification attributes
+ # The Gem::Specification version of this gemspec.
+ #
+ # Do not set this, it is set automatically when the gem is packaged.
- def self.attribute_names
- @@attributes.map { |name, default| name }
- end
+ attr_accessor :specification_version
##
- # Default values for specification attributes
+ # A short summary of this gem's description. Displayed in `gem list -d`.
+ #
+ # The description should be more detailed than the summary. For example,
+ # you might wish to copy the entire README into the description.
- def self.attribute_defaults
- @@attributes.dup
- end
+ attr_reader :summary
+
+ ######################################################################
+ # :section: Optional gemspec attributes
##
- # The default value for specification attribute +name+
+ # Autorequire was used by old RubyGems to automatically require a file.
+ #
+ # Deprecated: It is neither supported nor functional.
- def self.default_value(name)
- @@default_value[name]
- end
+ attr_accessor :autorequire
##
- # Required specification attributes
+ # The path in the gem for executable scripts. Usually 'bin'
- def self.required_attributes
- @@required_attributes.dup
- end
+ attr_accessor :bindir
##
- # Is +name+ a required attribute?
+ # The certificate chain used to sign this gem. See Gem::Security for
+ # details.
- def self.required_attribute?(name)
- @@required_attributes.include? name.to_sym
- end
+ attr_accessor :cert_chain
##
- # Specification attributes that are arrays (appendable and so-forth)
+ # A long description of this gem
- def self.array_attributes
- @@array_attributes.dup
- end
+ attr_reader :description
##
- # Specifies the +name+ and +default+ for a specification attribute, and
- # creates a reader and writer method like Module#attr_accessor.
+ # Sets the default executable for this gem.
#
- # The reader method returns the default if the value hasn't been set.
+ # Deprecated: You must now specify the executable name to Gem.bin_path.
- def self.attribute(name, default=nil)
- ivar_name = "@#{name}".intern
- if default.nil? then
- @@nil_attributes << ivar_name
- else
- @@non_nil_attributes << [ivar_name, default]
- end
+ attr_writer :default_executable
- @@attributes << [name, default]
- @@default_value[name] = default
- attr_accessor(name)
- end
+ ##
+ # A contact email for this gem
+ #
+ # If you are providing multiple authors and multiple emails they should be
+ # in the same order such that:
+ #
+ # Hash[*spec.authors.zip(spec.emails).flatten]
+ #
+ # Gives a hash of author name to email address.
+
+ attr_accessor :email
##
- # Same as :attribute, but ensures that values assigned to the attribute
- # are array values by applying :to_a to the value.
+ # The URL of this gem's home page
- def self.array_attribute(name)
- @@non_nil_attributes << ["@#{name}".intern, []]
+ attr_accessor :homepage
- @@array_attributes << name
- @@attributes << [name, []]
- @@default_value[name] = []
- code = %{
- def #{name}
- @#{name} ||= []
- end
- def #{name}=(value)
- @#{name} = Array(value)
- end
- }
+ ##
+ # True when this gemspec has been activated. This attribute is not persisted.
- module_eval code, __FILE__, __LINE__ - 9
- end
+ attr_accessor :loaded
+
+ alias :loaded? :loaded
##
- # Same as attribute above, but also records this attribute as mandatory.
+ # True when this gemspec has been activated. This attribute is not persisted.
- def self.required_attribute(*args)
- @@required_attributes << args.first
- attribute(*args)
- end
+ attr_accessor :activated
+
+ alias :activated? :activated
##
- # Sometimes we don't want the world to use a setter method for a
- # particular attribute.
- #
- # +read_only+ makes it private so we can still use it internally.
+ # Path this gemspec was loaded from. This attribute is not persisted.
- def self.read_only(*names)
- names.each do |name|
- private "#{name}="
- end
- end
+ attr_reader :loaded_from
- # Shortcut for creating several attributes at once (each with a default
- # value of +nil+).
+ ##
+ # Allows deinstallation of gems with legacy platforms.
- def self.attributes(*args)
- args.each do |arg|
- attribute(arg, nil)
- end
- end
+ attr_writer :original_platform # :nodoc:
##
- # Some attributes require special behaviour when they are accessed. This
- # allows for that.
+ # A message that gets displayed after the gem is installed
- def self.overwrite_accessor(name, &block)
- remove_method name
- define_method(name, &block)
- end
+ attr_accessor :post_install_message
##
- # Defines a _singular_ version of an existing _plural_ attribute (i.e. one
- # whose value is expected to be an array). This means just creating a
- # helper method that takes a single value and appends it to the array.
- # These are created for convenience, so that in a spec, one can write
- #
- # s.require_path = 'mylib'
- #
- # instead of:
- #
- # s.require_paths = ['mylib']
- #
- # That above convenience is available courtesy of:
- #
- # attribute_alias_singular :require_path, :require_paths
+ # The version of ruby required by this gem
- def self.attribute_alias_singular(singular, plural)
- define_method("#{singular}=") { |val|
- send("#{plural}=", [val])
- }
- define_method("#{singular}") {
- val = send("#{plural}")
- val.nil? ? nil : val.first
- }
- end
+ attr_reader :required_ruby_version
##
- # Dump only crucial instance variables.
- #--
- # MAINTAIN ORDER!
+ # The RubyGems version required by this gem
- def _dump(limit)
- Marshal.dump [
- @rubygems_version,
- @specification_version,
- @name,
- @version,
- (Time === @date ? @date : (require 'time'; Time.parse(@date.to_s))),
- @summary,
- @required_ruby_version,
- @required_rubygems_version,
- @original_platform,
- @dependencies,
- @rubyforge_project,
- @email,
- @authors,
- @description,
- @homepage,
- @has_rdoc,
- @new_platform,
- @licenses
- ]
- end
+ attr_reader :required_rubygems_version
##
- # Load custom marshal format, re-initializing defaults as needed
+ # The rubyforge project this gem lives under. i.e. RubyGems'
+ # rubyforge_project is "rubygems".
- def self._load(str)
- array = Marshal.load str
+ attr_accessor :rubyforge_project
- spec = Gem::Specification.new
- spec.instance_variable_set :@specification_version, array[1]
+ ##
+ # The key used to sign this gem. See Gem::Security for details.
- current_version = CURRENT_SPECIFICATION_VERSION
+ attr_accessor :signing_key
- field_count = if spec.specification_version > current_version then
- spec.instance_variable_set :@specification_version,
- current_version
- MARSHAL_FIELDS[current_version]
- else
- MARSHAL_FIELDS[spec.specification_version]
- end
+ def self._all # :nodoc:
+ unless defined?(@@all) && @@all then
+ specs = []
- if array.size < field_count then
- raise TypeError, "invalid Gem::Specification format #{array.inspect}"
+ self.dirs.reverse_each { |dir|
+ Dir[File.join(dir, "*.gemspec")].each { |path|
+ spec = Gem::Specification.load path.untaint
+ # #load returns nil if the spec is bad, so we just ignore
+ # it at this stage
+ specs << spec if spec
+ }
+ }
+
+ @@all = specs
+ _resort!
end
+ @@all
+ end
- spec.instance_variable_set :@rubygems_version, array[0]
- # spec version
- spec.instance_variable_set :@name, array[2]
- spec.instance_variable_set :@version, array[3]
- spec.instance_variable_set :@date, array[4]
- spec.instance_variable_set :@summary, array[5]
- spec.instance_variable_set :@required_ruby_version, array[6]
- spec.instance_variable_set :@required_rubygems_version, array[7]
- spec.instance_variable_set :@original_platform, array[8]
- spec.instance_variable_set :@dependencies, array[9]
- spec.instance_variable_set :@rubyforge_project, array[10]
- spec.instance_variable_set :@email, array[11]
- spec.instance_variable_set :@authors, array[12]
- spec.instance_variable_set :@description, array[13]
- spec.instance_variable_set :@homepage, array[14]
- spec.instance_variable_set :@has_rdoc, array[15]
- spec.instance_variable_set :@new_platform, array[16]
- spec.instance_variable_set :@platform, array[16].to_s
- spec.instance_variable_set :@license, array[17]
- spec.instance_variable_set :@loaded, false
+ def self._resort! # :nodoc:
+ @@all.sort! { |a, b|
+ names = a.name <=> b.name
+ next names if names.nonzero?
+ b.version <=> a.version
+ }
+ end
- spec
+ ##
+ # Adds +spec+ to the known specifications, keeping the collection
+ # properly sorted.
+
+ def self.add_spec spec
+ # TODO: find all extraneous adds
+ # puts
+ # p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }]
+
+ # TODO: flush the rest of the crap from the tests
+ # raise "no dupes #{spec.full_name} in #{all_names.inspect}" if
+ # _all.include? spec
+
+ raise "nil spec!" unless spec # TODO: remove once we're happy with tests
+
+ return if _all.include? spec
+
+ _all << spec
+ _resort!
end
##
- # List of dependencies that will automatically be activated at runtime.
+ # Adds multiple specs to the known specifications.
- def runtime_dependencies
- # TODO: fix #type to return :runtime if nil
- dependencies.select { |d| d.type == :runtime }
+ def self.add_specs *specs
+ raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy
+
+ # TODO: this is much more efficient, but we need the extra checks for now
+ # _all.concat specs
+ # _resort!
+
+ specs.each do |spec| # TODO: slow
+ add_spec spec
+ end
end
##
- # List of dependencies that are used for development
+ # Returns all specifications. This method is discouraged from use.
+ # You probably want to use one of the Enumerable methods instead.
- def development_dependencies
- dependencies.select { |d| d.type == :development }
+ def self.all
+ warn "NOTE: Specification.all called from #{caller.first}" unless
+ Deprecate.skip
+ _all
end
- def test_suite_file # :nodoc:
- warn 'test_suite_file deprecated, use test_files'
- test_files.first
+ ##
+ # Sets the known specs to +specs+. Not guaranteed to work for you in
+ # the future. Use at your own risk. Caveat emptor. Doomy doom doom.
+ # Etc etc.
+ #
+ #--
+ # Makes +specs+ the known specs
+ # Listen, time is a river
+ # Winter comes, code breaks
+ #
+ # -- wilsonb
+
+ def self.all= specs
+ @@all = specs
end
- def test_suite_file=(val) # :nodoc:
- warn 'test_suite_file= deprecated, use test_files='
- @test_files = [] unless defined? @test_files
- @test_files << val
+ ##
+ # Return full names of all specs in sorted order.
+
+ def self.all_names
+ self._all.map(&:full_name)
end
##
- # true when this gemspec has been loaded from a specifications directory.
- # This attribute is not persisted.
+ # Return the list of all array-oriented instance variables.
+ #--
+ # Not sure why we need to use so much stupid reflection in here...
- attr_accessor :loaded
+ def self.array_attributes
+ @@array_attributes.dup
+ end
##
- # Path this gemspec was loaded from. This attribute is not persisted.
+ # Return the list of all instance variables.
+ #--
+ # Not sure why we need to use so much stupid reflection in here...
- attr_accessor :loaded_from
+ def self.attribute_names
+ @@attributes.dup
+ end
##
- # Returns an array with bindir attached to each executable in the
- # executables list
+ # Return the directories that Specification uses to find specs.
- def add_bindir(executables)
- return nil if executables.nil?
+ def self.dirs
+ @@dirs ||= Gem.path.collect { |dir|
+ File.join dir, "specifications"
+ }
+ end
- if @bindir then
- Array(executables).map { |e| File.join(@bindir, e) }
- else
- executables
- end
- rescue
- return nil
+ ##
+ # Set the directories that Specification uses to find specs. Setting
+ # this resets the list of known specs.
+
+ def self.dirs= dirs
+ # TODO: find extra calls to dir=
+ # warn "NOTE: dirs= called from #{caller.first} for #{dirs.inspect}"
+
+ self.reset
+
+ # ugh
+ @@dirs = Array(dirs).map { |dir| File.join dir, "specifications" }
end
+ extend Enumerable
+
##
- # Files in the Gem under one of the require_paths
+ # Enumerate every known spec. See ::dirs= and ::add_spec to set the list of
+ # specs.
- def lib_files
- @files.select do |file|
- require_paths.any? do |path|
- file.index(path) == 0
- end
+ def self.each
+ return enum_for(:each) unless block_given?
+
+ self._all.each do |x|
+ yield x
end
end
##
- # True if this gem was loaded from disk
+ # Returns every spec that matches +name+ and optional +requirements+.
- alias :loaded? :loaded
+ def self.find_all_by_name name, *requirements
+ requirements = Gem::Requirement.default if requirements.empty?
- ##
- # True if this gem has files in test_files
+ # TODO: maybe try: find_all { |s| spec === dep }
- def has_unit_tests?
- not test_files.empty?
+ Gem::Dependency.new(name, *requirements).matching_specs
end
- # :stopdoc:
- alias has_test_suite? has_unit_tests?
- # :startdoc:
-
##
- # Specification constructor. Assigns the default values to the
- # attributes and yields itself for further
- # initialization. Optionally takes +name+ and +version+.
+ # Find the best specification matching a +name+ and +requirements+. Raises
+ # if the dependency doesn't resolve to a valid specification.
- def initialize name = nil, version = nil
- @new_platform = nil
- assign_defaults
- @loaded = false
- @loaded_from = nil
+ def self.find_by_name name, *requirements
+ requirements = Gem::Requirement.default if requirements.empty?
- self.name = name if name
- self.version = version if version
+ # TODO: maybe try: find { |s| spec === dep }
- yield self if block_given?
+ Gem::Dependency.new(name, *requirements).to_spec
+ end
- @@gather.call(self) if @@gather
+ ##
+ # Return the best specification that contains the file matching +path+.
+
+ def self.find_by_path path
+ self.find { |spec|
+ spec.contains_requirable_file? path
+ }
end
##
- # Duplicates array_attributes from +other_spec+ so state isn't shared.
+ # Return currently unresolved specs that contain the file matching +path+.
- def initialize_copy(other_spec)
- other_ivars = other_spec.instance_variables
- other_ivars = other_ivars.map { |ivar| ivar.intern } if # for 1.9
- other_ivars.any? { |ivar| String === ivar }
+ def self.find_in_unresolved path
+ # TODO: do we need these?? Kill it
+ specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten
- self.class.array_attributes.each do |name|
- name = :"@#{name}"
- next unless other_ivars.include? name
- instance_variable_set name, other_spec.instance_variable_get(name).dup
- end
+ specs.find_all { |spec| spec.contains_requirable_file? path }
end
##
- # Each attribute has a default value (possibly nil). Here, we initialize
- # all attributes to their default value. This is done through the
- # accessor methods, so special behaviours will be honored. Furthermore,
- # we take a _copy_ of the default so each specification instance has its
- # own empty arrays, etc.
+ # Search through all unresolved deps and sub-dependencies and return
+ # specs that contain the file matching +path+.
- def assign_defaults
- @@nil_attributes.each do |name|
- instance_variable_set name, nil
- end
+ def self.find_in_unresolved_tree path
+ specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten
- @@non_nil_attributes.each do |name, default|
- value = case default
- when Time, Numeric, Symbol, true, false, nil then default
- else default.dup
- end
+ specs.reverse_each do |spec|
+ trails = []
+ spec.traverse do |from_spec, dep, to_spec, trail|
+ next unless to_spec.conflicts.empty?
+ trails << trail if to_spec.contains_requirable_file? path
+ end
+
+ next if trails.empty?
- instance_variable_set name, value
+ return trails.map(&:reverse).sort.first.reverse
end
- # HACK
- instance_variable_set :@new_platform, Gem::Platform::RUBY
+ []
end
##
@@ -480,7 +487,7 @@ class Gem::Specification
# routine (#initialize). This method makes up for that and deals with
# gems of different ages.
#
- # 'input' can be anything that YAML.load() accepts: String or IO.
+ # +input+ can be anything that YAML.load() accepts: String or IO.
def self.from_yaml(input)
input = normalize_yaml_input input
@@ -505,6 +512,27 @@ class Gem::Specification
end
##
+ # Return the latest specs, optionally including prerelease specs if
+ # +prerelease+ is true.
+
+ def self.latest_specs prerelease = false
+ result = Hash.new { |h,k| h[k] = {} }
+ native = {}
+
+ Gem::Specification._all.reverse_each do |spec|
+ next if spec.version.prerelease? unless prerelease
+
+ native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY
+ result[spec.name][spec.platform] = spec
+ end
+
+ result.map(&:last).map(&:values).flatten.reject { |spec|
+ minimum = native[spec.name]
+ minimum && spec.version < minimum
+ }
+ end
+
+ ##
# Loads Ruby format gemspec from +file+.
def self.load file
@@ -524,7 +552,7 @@ class Gem::Specification
spec = eval code, binding, file
if Gem::Specification === spec
- spec.loaded_from = file
+ spec.loaded_from = file.to_s
return spec
end
@@ -539,451 +567,472 @@ class Gem::Specification
end
##
+ # Specification attributes that must be non-nil
+
+ def self.non_nil_attributes
+ @@non_nil_attributes.dup
+ end
+
+ ##
# Make sure the YAML specification is properly formatted with dashes
def self.normalize_yaml_input(input)
result = input.respond_to?(:read) ? input.read : input
result = "--- " + result unless result =~ /\A--- /
- result.gsub(/ !!null \n/, " \n")
+ result.gsub!(/ !!null \n/, " \n")
+ # date: 2011-04-26 00:00:00.000000000Z
+ # date: 2011-04-26 00:00:00.000000000 Z
+ result.gsub!(/^(date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+?)Z/, '\1 Z')
+ result
end
##
- # Sets the rubygems_version to the current RubyGems version
+ # Return a list of all outdated specifications. This method is HEAVY
+ # as it must go fetch specifications from the server.
- def mark_version
- @rubygems_version = Gem::VERSION
- end
+ def self.outdated
+ outdateds = []
- ##
- # Ignore unknown attributes while loading
+ # TODO: maybe we should switch to rubygems' version service?
+ fetcher = Gem::SpecFetcher.fetcher
- def method_missing(sym, *a, &b) # :nodoc:
- if @specification_version > CURRENT_SPECIFICATION_VERSION and
- sym.to_s =~ /=$/ then
- warn "ignoring #{sym} loading #{full_name}" if $DEBUG
- else
- super
- end
- end
+ latest_specs.each do |local|
+ dependency = Gem::Dependency.new local.name, ">= #{local.version}"
+ remotes = fetcher.find_matching dependency
+ remotes = remotes.map { |(_, version, _), _| version }
+ latest = remotes.sort.last
- ##
- # Adds a development dependency named +gem+ with +requirements+ to this
- # Gem. For example:
- #
- # spec.add_development_dependency 'jabber4r', '> 0.1', '<= 0.5'
- #
- # Development dependencies aren't installed by default and aren't
- # activated when a gem is required.
+ outdateds << local.name if latest and local.version < latest
+ end
- def add_development_dependency(gem, *requirements)
- add_dependency_with_type(gem, :development, *requirements)
+ outdateds
end
##
- # Adds a runtime dependency named +gem+ with +requirements+ to this Gem.
- # For example:
- #
- # spec.add_runtime_dependency 'jabber4r', '> 0.1', '<= 0.5'
+ # Removes +spec+ from the known specs.
- def add_runtime_dependency(gem, *requirements)
- add_dependency_with_type(gem, :runtime, *requirements)
+ def self.remove_spec spec
+ # TODO: beat on the tests
+ raise "wtf: #{spec.full_name} not in #{all_names.inspect}" unless
+ _all.include? spec
+ _all.delete spec
end
##
- # Adds a runtime dependency
+ # Is +name+ a required attribute?
- alias add_dependency add_runtime_dependency
+ def self.required_attribute?(name)
+ @@required_attributes.include? name.to_sym
+ end
##
- # Returns the full name (name-version) of this Gem. Platform information
- # is included (name-version-platform) if it is specified and not the
- # default Ruby platform.
+ # Required specification attributes
- def full_name
- if platform == Gem::Platform::RUBY or platform.nil? then
- "#{@name}-#{@version}"
- else
- "#{@name}-#{@version}-#{platform}"
- end
+ def self.required_attributes
+ @@required_attributes.dup
end
##
- # Returns the full name (name-version) of this gemspec using the original
- # platform. For use with legacy gems.
+ # Reset the list of known specs, running pre and post reset hooks
+ # registered in Gem.
- def original_name # :nodoc:
- if platform == Gem::Platform::RUBY or platform.nil? then
- "#{@name}-#{@version}"
- else
- "#{@name}-#{@version}-#{@original_platform}"
- end
+ def self.reset
+ @@dirs = nil
+ # from = caller.first(10).reject { |s| s =~ /minitest/ }
+ # warn ""
+ # warn "NOTE: Specification.reset from #{from.inspect}"
+ Gem.pre_reset_hooks.each { |hook| hook.call }
+ @@all = nil
+ Gem.post_reset_hooks.each { |hook| hook.call }
end
##
- # The full path to the gem (install path + full name).
+ # Load custom marshal format, re-initializing defaults as needed
- def full_gem_path
- path = File.join installation_path, 'gems', full_name
- return path if File.directory? path
- File.join installation_path, 'gems', original_name
- end
+ def self._load(str)
+ array = Marshal.load str
- ##
- # The default (generated) file name of the gem. See also #spec_name.
- #
- # spec.file_name # => "example-1.0.gem"
+ spec = Gem::Specification.new
+ spec.instance_variable_set :@specification_version, array[1]
- def file_name
- full_name + '.gem'
- end
+ current_version = CURRENT_SPECIFICATION_VERSION
- ##
- # The directory that this gem was installed into.
+ field_count = if spec.specification_version > current_version then
+ spec.instance_variable_set :@specification_version,
+ current_version
+ MARSHAL_FIELDS[current_version]
+ else
+ MARSHAL_FIELDS[spec.specification_version]
+ end
- def installation_path
- unless @loaded_from then
- raise Gem::Exception, "spec #{full_name} is not from an installed gem"
+ if array.size < field_count then
+ raise TypeError, "invalid Gem::Specification format #{array.inspect}"
end
- File.expand_path File.dirname(File.dirname(@loaded_from))
+ spec.instance_variable_set :@rubygems_version, array[0]
+ # spec version
+ spec.instance_variable_set :@name, array[2]
+ spec.instance_variable_set :@version, array[3]
+ spec.instance_variable_set :@date, array[4]
+ spec.instance_variable_set :@summary, array[5]
+ spec.instance_variable_set :@required_ruby_version, array[6]
+ spec.instance_variable_set :@required_rubygems_version, array[7]
+ spec.instance_variable_set :@original_platform, array[8]
+ spec.instance_variable_set :@dependencies, array[9]
+ spec.instance_variable_set :@rubyforge_project, array[10]
+ spec.instance_variable_set :@email, array[11]
+ spec.instance_variable_set :@authors, array[12]
+ spec.instance_variable_set :@description, array[13]
+ spec.instance_variable_set :@homepage, array[14]
+ spec.instance_variable_set :@has_rdoc, array[15]
+ spec.instance_variable_set :@new_platform, array[16]
+ spec.instance_variable_set :@platform, array[16].to_s
+ spec.instance_variable_set :@license, array[17]
+ spec.instance_variable_set :@loaded, false
+
+ spec
end
- ##
- # Checks if this specification meets the requirement of +dependency+.
+ def <=>(other) # :nodoc:
+ sort_obj <=> other.sort_obj
+ end
- def satisfies_requirement?(dependency)
- return @name == dependency.name &&
- dependency.requirement.satisfied_by?(@version)
+ def == other # :nodoc:
+ self.class === other &&
+ name == other.name &&
+ version == other.version &&
+ platform == other.platform
end
##
- # Returns an object you can use to sort specifications in #sort_by.
+ # Dump only crucial instance variables.
+ #--
+ # MAINTAIN ORDER!
+ # (down with the man)
- def sort_obj
- [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1]
+ def _dump(limit)
+ Marshal.dump [
+ @rubygems_version,
+ @specification_version,
+ @name,
+ @version,
+ date,
+ @summary,
+ @required_ruby_version,
+ @required_rubygems_version,
+ @original_platform,
+ @dependencies,
+ @rubyforge_project,
+ @email,
+ @authors,
+ @description,
+ @homepage,
+ true, # has_rdoc
+ @new_platform,
+ @licenses
+ ]
end
##
- # The default name of the gemspec. See also #file_name
- #
- # spec.spec_name # => "example-1.0.gemspec"
+ # Activate this spec, registering it as a loaded spec and adding
+ # it's lib paths to $LOAD_PATH. Returns true if the spec was
+ # activated, false if it was previously activated. Freaks out if
+ # there are conflicts upon activation.
- def spec_name
- full_name + '.gemspec'
- end
+ def activate
+ raise_if_conflicts
- def <=>(other) # :nodoc:
- sort_obj <=> other.sort_obj
- end
+ return false if Gem.loaded_specs[self.name]
- ##
- # Tests specs for equality (across all attributes).
-
- def ==(other) # :nodoc:
- self.class === other && same_attributes?(other)
- end
+ activate_dependencies
+ add_self_to_load_path
- alias eql? == # :nodoc:
+ Gem.loaded_specs[self.name] = self
+ self.activated = true
- ##
- # A macro to yield cached gem path
- #
- def cache_gem
- cache_name = File.join(Gem.dir, 'cache', file_name)
- return File.exist?(cache_name) ? cache_name : nil
+ return true
end
##
- # True if this gem has the same attributes as +other+.
+ # Activate all unambiguously resolved runtime dependencies of this
+ # spec. Add any ambigous dependencies to the unresolved list to be
+ # resolved later, as needed.
+
+ def activate_dependencies
+ self.runtime_dependencies.each do |spec_dep|
+ # TODO: check for conflicts! not just name!
+ next if Gem.loaded_specs.include? spec_dep.name
+ specs = spec_dep.to_specs
- def same_attributes?(other)
- @@attributes.each do |name, default|
- return false unless self.send(name) == other.send(name)
+ if specs.size == 1 then
+ specs.first.activate
+ else
+ name = spec_dep.name
+ Gem.unresolved_deps[name] = Gem.unresolved_deps[name].merge spec_dep
+ end
end
- true
+
+ Gem.unresolved_deps.delete self.name
end
- private :same_attributes?
+ ##
+ # Returns an array with bindir attached to each executable in the
+ # +executables+ list
- def hash # :nodoc:
- @@attributes.inject(0) { |hash_code, (name, _)|
- hash_code ^ self.send(name).hash
- }
+ def add_bindir(executables)
+ return nil if executables.nil?
+
+ if @bindir then
+ Array(executables).map { |e| File.join(@bindir, e) }
+ else
+ executables
+ end
+ rescue
+ return nil
end
- def encode_with coder # :nodoc:
- mark_version
+ ##
+ # Adds a dependency on gem +dependency+ with type +type+ that requires
+ # +requirements+. Valid types are currently <tt>:runtime</tt> and
+ # <tt>:development</tt>.
- attributes = @@attributes.map { |name,| name.to_s }.sort
- attributes = attributes - %w[name version platform]
+ def add_dependency_with_type(dependency, type, *requirements)
+ requirements = if requirements.empty? then
+ Gem::Requirement.default
+ else
+ requirements.flatten
+ end
- coder.add 'name', @name
- coder.add 'version', @version
- platform = case @original_platform
- when nil, '' then
- 'ruby'
- when String then
- @original_platform
- else
- @original_platform.to_s
- end
- coder.add 'platform', platform
+ unless dependency.respond_to?(:name) &&
+ dependency.respond_to?(:version_requirements)
- attributes.each do |name|
- coder.add name, instance_variable_get("@#{name}")
+ dependency = Gem::Dependency.new(dependency, requirements, type)
end
- end
- def to_yaml(opts = {}) # :nodoc:
- if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? then
- super.gsub(/ !!null \n/, " \n")
- else
- YAML.quick_emit object_id, opts do |out|
- out.map taguri, to_yaml_style do |map|
- encode_with map
- end
- end
- end
+ dependencies << dependency
end
- def init_with coder # :nodoc:
- yaml_initialize coder.tag, coder.map
- end
+ private :add_dependency_with_type
- def yaml_initialize(tag, vals) # :nodoc:
- vals.each do |ivar, val|
- instance_variable_set "@#{ivar}", val
- end
+ ##
+ # Adds a development dependency named +gem+ with +requirements+ to this
+ # Gem. For example:
+ #
+ # spec.add_development_dependency 'example', '~> 1.1', '>= 1.1.4'
+ #
+ # Development dependencies aren't installed by default and aren't
+ # activated when a gem is required.
- @original_platform = @platform # for backwards compatibility
- self.platform = Gem::Platform.new @platform
+ def add_development_dependency(gem, *requirements)
+ add_dependency_with_type(gem, :development, *requirements)
end
##
- # Returns a Ruby code representation of this specification, such that it
- # can be eval'ed and reconstruct the same specification later. Attributes
- # that still have their default values are omitted.
-
- def to_ruby
- mark_version
- result = []
- result << "# -*- encoding: utf-8 -*-"
- result << nil
- result << "Gem::Specification.new do |s|"
+ # Adds a runtime dependency named +gem+ with +requirements+ to this Gem.
+ # For example:
+ #
+ # spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
- result << " s.name = #{ruby_code name}"
- result << " s.version = #{ruby_code version}"
- unless platform.nil? or platform == Gem::Platform::RUBY then
- result << " s.platform = #{ruby_code original_platform}"
- end
- result << ""
- result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version="
+ def add_runtime_dependency(gem, *requirements)
+ add_dependency_with_type(gem, :runtime, *requirements)
+ end
- handled = [
- :dependencies,
- :name,
- :platform,
- :required_rubygems_version,
- :specification_version,
- :version,
- ]
+ alias add_dependency add_runtime_dependency
- attributes = @@attributes.sort_by { |attr_name,| attr_name.to_s }
+ ##
+ # Adds this spec's require paths to LOAD_PATH, in the proper location.
- attributes.each do |attr_name, default|
- next if handled.include? attr_name
- current_value = self.send(attr_name)
- if current_value != default or
- self.class.required_attribute? attr_name then
- result << " s.#{attr_name} = #{ruby_code current_value}"
- end
+ def add_self_to_load_path
+ paths = require_paths.map do |path|
+ File.join full_gem_path, path
end
- result << nil
- result << " if s.respond_to? :specification_version then"
- result << " s.specification_version = #{specification_version}"
- result << nil
-
- result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then"
+ # gem directories must come after -I and ENV['RUBYLIB']
+ insert_index = Gem.load_path_insert_index
- dependencies.each do |dep|
- req = dep.requirements_list.inspect
- dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
- result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})"
+ if insert_index then
+ # 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
- result << " else"
+ ##
+ # Singular reader for #authors
- dependencies.each do |dep|
- version_reqs_param = dep.requirements_list.inspect
- result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
- end
+ def author
+ val = authors and val.first
+ end
- result << ' end'
+ ##
+ # Singular writer for #authors
- result << " else"
- dependencies.each do |dep|
- version_reqs_param = dep.requirements_list.inspect
- result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
- end
- result << " end"
+ def author= o
+ self.authors = [o]
+ end
- result << "end"
- result << nil
+ ##
+ # The list of author names who wrote this gem.
+ #
+ # If you are providing multiple authors and multiple emails they should be
+ # in the same order such that:
+ #
+ # Hash[*spec.authors.zip(spec.emails).flatten]
+ #
+ # Gives a hash of author name to email address.
- result.join "\n"
+ def authors
+ @authors ||= []
end
- def to_ruby_for_cache
- s = dup
- # remove large blobs that aren't used at runtime:
- s.files = nil
- s.extra_rdoc_files = nil
- s.rdoc_options = nil
- s.to_ruby
+ ##
+ # Sets the list of authors, ensuring it is an array.
+
+ def authors= value
+ @authors = Array(value).flatten.grep(String)
end
##
- # Checks that the specification contains all required fields, and does a
- # very basic sanity check.
+ # Returns the full path to the base gem directory.
#
- # Raises InvalidSpecificationException if the spec does not pass the
- # checks..
+ # eg: /usr/local/lib/ruby/gems/1.8
- def validate
- require 'rubygems/user_interaction'
- extend Gem::UserInteraction
- normalize
-
- if rubygems_version != Gem::VERSION then
- raise Gem::InvalidSpecificationException,
- "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
- end
+ def base_dir
+ return Gem.dir unless loaded_from
+ @base_dir ||= File.dirname File.dirname loaded_from
+ end
- @@required_attributes.each do |symbol|
- unless self.send symbol then
- raise Gem::InvalidSpecificationException,
- "missing value for attribute #{symbol}"
- end
- end
+ ##
+ # Returns the full path to installed gem's bin directory.
+ #
+ # NOTE: do not confuse this with +bindir+, which is just 'bin', not
+ # a full path.
- unless String === name then
- raise Gem::InvalidSpecificationException,
- "invalid value for attribute name: \"#{name.inspect}\""
- end
+ def bin_dir
+ @bin_dir ||= File.join gem_dir, bindir # TODO: this is unfortunate
+ end
- if require_paths.empty? then
- raise Gem::InvalidSpecificationException,
- 'specification must have at least one require_path'
- end
+ ##
+ # Returns the full path to an executable named +name+ in this gem.
- @files.delete_if do |file| File.directory? file end
- @test_files.delete_if do |file| File.directory? file end
- @executables.delete_if do |file|
- File.directory? File.join(bindir, file)
- end
- @extra_rdoc_files.delete_if do |file| File.directory? file end
- @extensions.delete_if do |file| File.directory? file end
+ def bin_file name
+ File.join bin_dir, name
+ end
- non_files = files.select do |file|
- !File.file? file
- end
+ ##
+ # Returns the full path to the cache directory containing this
+ # spec's cached gem.
- unless non_files.empty? then
- non_files = non_files.map { |file| file.inspect }
- raise Gem::InvalidSpecificationException,
- "[#{non_files.join ", "}] are not files"
- end
+ def cache_dir
+ @cache_dir ||= File.join base_dir, "cache"
+ end
- unless specification_version.is_a?(Fixnum)
- raise Gem::InvalidSpecificationException,
- 'specification_version must be a Fixnum (did you mean version?)'
- end
+ ##
+ # Returns the full path to the cached gem for this spec.
- case platform
- when Gem::Platform, Gem::Platform::RUBY then # ok
- else
- raise Gem::InvalidSpecificationException,
- "invalid platform #{platform.inspect}, see Gem::Platform"
- end
+ def cache_file
+ @cache_file ||= File.join cache_dir, "#{full_name}.gem"
+ end
- unless Array === authors and
- authors.all? { |author| String === author } then
- raise Gem::InvalidSpecificationException,
- 'authors must be Array of Strings'
- end
+ alias :cache_gem :cache_file
- licenses.each { |license|
- if license.length > 64
- raise Gem::InvalidSpecificationException,
- "each license must be 64 characters or less"
- end
- }
+ ##
+ # Return any possible conflicts against the currently loaded specs.
- # reject FIXME and TODO
+ def conflicts
+ conflicts = {}
+ Gem.loaded_specs.values.each do |spec|
+ bad = self.runtime_dependencies.find_all { |dep|
+ spec.name == dep.name and not spec.satisfies_requirement? dep
+ }
- unless authors.grep(/FIXME|TODO/).empty? then
- raise Gem::InvalidSpecificationException,
- '"FIXME" or "TODO" is not an author'
+ conflicts[spec] = bad unless bad.empty?
end
+ conflicts
+ end
- unless Array(email).grep(/FIXME|TODO/).empty? then
- raise Gem::InvalidSpecificationException,
- '"FIXME" or "TODO" is not an email address'
- end
+ ##
+ # Return true if this spec can require +file+.
- if description =~ /FIXME|TODO/ then
- raise Gem::InvalidSpecificationException,
- '"FIXME" or "TODO" is not a description'
- end
+ def contains_requirable_file? file
+ root = full_gem_path
- if summary =~ /FIXME|TODO/ then
- raise Gem::InvalidSpecificationException,
- '"FIXME" or "TODO" is not a summary'
+ require_paths.each do |lib|
+ base = "#{root}/#{lib}/#{file}"
+ Gem.suffixes.each do |suf|
+ path = "#{base}#{suf}"
+ return true if File.file? path
+ end
end
- if homepage and not homepage.empty? and
- homepage !~ /\A[a-z][a-z\d+.-]*:/i then
- raise Gem::InvalidSpecificationException,
- "\"#{homepage}\" is not a URI"
- end
+ return false
+ end
- # Warnings
+ ##
+ # The date this gem was created. Lazily defaults to TODAY.
- %w[author description email homepage summary].each do |attribute|
- value = self.send attribute
- alert_warning "no #{attribute} specified" if value.nil? or value.empty?
- end
+ def date
+ @date ||= TODAY
+ end
- if summary and not summary.empty? and description == summary then
- alert_warning 'description and summary are identical'
- end
+ ##
+ # The date this gem was created
+ #
+ # Do not set this, it is set automatically when the gem is packaged.
- alert_warning "deprecated autorequire specified" if autorequire
+ def date= date
+ # We want to end up with a Time object with one-day resolution.
+ # This is the cleanest, most-readable, faster-than-using-Date
+ # way to do it.
+ @date = case date
+ when String then
+ if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then
+ Time.utc($1.to_i, $2.to_i, $3.to_i)
+ else
+ raise(Gem::InvalidSpecificationException,
+ "invalid date format in specification: #{date.inspect}")
+ end
+ when Time, Date then
+ Time.utc(date.year, date.month, date.day)
+ else
+ TODAY
+ end
+ end
- executables.each do |executable|
- executable_path = File.join bindir, executable
- shebang = File.read(executable_path, 2) == '#!'
+ ##
+ # The default executable for this gem.
+ #
+ # Deprecated: The name of the gem is assumed to be the name of the
+ # executable now. See Gem.bin_path.
- alert_warning "#{executable_path} is missing #! line" unless shebang
+ def default_executable
+ if defined?(@default_executable) and @default_executable
+ result = @default_executable
+ elsif @executables and @executables.size == 1
+ result = Array(@executables).first
+ else
+ result = nil
end
+ result
+ end
- true
+ ##
+ # The default value for specification attribute +name+
+
+ def default_value name
+ @@default_value[name]
end
##
- # Normalize the list of files so that:
- # * All file lists have redundancies removed.
- # * Files referenced in the extra_rdoc_files are included in the package
- # file list.
+ # A list of Gem::Dependency objects this gem depends on.
+ #
+ # Use #add_dependency or #add_development_dependency to add dependencies to
+ # a gem.
- def normalize
- if defined?(@extra_rdoc_files) and @extra_rdoc_files then
- @extra_rdoc_files.uniq!
- @files ||= []
- @files.concat(@extra_rdoc_files)
- end
- @files.uniq! if @files
+ def dependencies
+ @dependencies ||= []
end
##
@@ -994,436 +1043,493 @@ class Gem::Specification
def dependent_gems
out = []
- Gem.source_index.each do |name,gem|
- gem.dependencies.each do |dep|
+ Gem::Specification.each do |spec|
+ spec.dependencies.each do |dep|
if self.satisfies_requirement?(dep) then
sats = []
find_all_satisfiers(dep) do |sat|
sats << sat
end
- out << [gem, dep, sats]
+ out << [spec, dep, sats]
end
end
end
out
end
- def to_s # :nodoc:
- "#<Gem::Specification name=#{@name} version=#{@version}>"
- end
-
- def pretty_print(q) # :nodoc:
- q.group 2, 'Gem::Specification.new do |s|', 'end' do
- q.breakable
-
- attributes = @@attributes.sort_by { |attr_name,| attr_name.to_s }
+ ##
+ # Returns all specs that matches this spec's runtime dependencies.
- attributes.each do |attr_name, default|
- current_value = self.send attr_name
- if current_value != default or
- self.class.required_attribute? attr_name then
+ def dependent_specs
+ runtime_dependencies.map { |dep| dep.to_specs }.flatten
+ end
- q.text "s.#{attr_name} = "
+ ##
+ # A long description of this gem
- if attr_name == :date then
- current_value = current_value.utc
+ def description= str
+ @description = str.to_s
+ end
- q.text "Time.utc(#{current_value.year}, #{current_value.month}, #{current_value.day})"
- else
- q.pp current_value
- end
+ ##
+ # List of dependencies that are used for development
- q.breakable
- end
- end
- end
+ def development_dependencies
+ dependencies.select { |d| d.type == :development }
end
##
- # Adds a dependency on gem +dependency+ with type +type+ that requires
- # +requirements+. Valid types are currently <tt>:runtime</tt> and
- # <tt>:development</tt>.
+ # Returns the full path to this spec's documentation directory.
- def add_dependency_with_type(dependency, type, *requirements)
- requirements = if requirements.empty? then
- Gem::Requirement.default
- else
- requirements.flatten
- end
+ def doc_dir
+ @doc_dir ||= File.join base_dir, 'doc', full_name
+ end
- unless dependency.respond_to?(:name) &&
- dependency.respond_to?(:version_requirements)
+ def encode_with coder # :nodoc:
+ mark_version
- dependency = Gem::Dependency.new(dependency, requirements, type)
+ coder.add 'name', @name
+ coder.add 'version', @version
+ platform = case @original_platform
+ when nil, '' then
+ 'ruby'
+ when String then
+ @original_platform
+ else
+ @original_platform.to_s
+ end
+ coder.add 'platform', platform
+
+ attributes = @@attributes.map(&:to_s) - %w[name version platform]
+ attributes.each do |name|
+ coder.add name, instance_variable_get("@#{name}")
end
+ end
- dependencies << dependency
+ def eql? other # :nodoc:
+ self.class === other && same_attributes?(other)
end
- private :add_dependency_with_type
+ ##
+ # Singular accessor for #executables
+
+ def executable
+ val = executables and val.first
+ end
##
- # Finds all gems that satisfy +dep+
+ # Singular accessor for #executables
- def find_all_satisfiers(dep)
- Gem.source_index.each do |_, gem|
- yield gem if gem.satisfies_requirement? dep
- end
+ def executable=o
+ self.executables = [o]
end
- private :find_all_satisfiers
+ ##
+ # Executables included in the gem.
+
+ def executables
+ @executables ||= []
+ end
##
- # Return a string containing a Ruby code representation of the given
- # object.
+ # Sets executables to +value+, ensuring it is an array. Don't
+ # use this, push onto the array instead.
- def ruby_code(obj)
- case obj
- when String then '%q{' + obj + '}'
- when Array then obj.inspect
- when Gem::Version then obj.to_s.inspect
- when Date then '%q{' + obj.strftime('%Y-%m-%d') + '}'
- when Time then '%q{' + obj.strftime('%Y-%m-%d') + '}'
- when Numeric then obj.inspect
- when true, false, nil then obj.inspect
- when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
- when Gem::Requirement then "Gem::Requirement.new(#{obj.to_s.inspect})"
- else raise Gem::Exception, "ruby_code case not handled: #{obj.class}"
- end
+ def executables= value
+ # TODO: warn about setting instead of pushing
+ @executables = Array(value)
end
- private :ruby_code
+ ##
+ # Extensions to build when installing the gem. See
+ # Gem::Installer#build_extensions for valid values.
- # :section: Required gemspec attributes
+ def extensions
+ @extensions ||= []
+ end
##
- # :attr_accessor: rubygems_version
- #
- # The version of RubyGems used to create this gem.
- #
- # Do not set this, it is set automatically when the gem is packaged.
+ # Sets extensions to +extensions+, ensuring it is an array. Don't
+ # use this, push onto the array instead.
- required_attribute :rubygems_version, Gem::VERSION
+ def extensions= extensions
+ # TODO: warn about setting instead of pushing
+ @extensions = Array extensions
+ end
##
- # :attr_accessor: specification_version
- #
- # The Gem::Specification version of this gemspec.
- #
- # Do not set this, it is set automatically when the gem is packaged.
+ # Extra files to add to RDoc such as README or doc/examples.txt
- required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION
+ def extra_rdoc_files
+ @extra_rdoc_files ||= []
+ end
##
- # :attr_accessor: name
- #
- # This gem's name
+ # Sets extra_rdoc_files to +files+, ensuring it is an array. Don't
+ # use this, push onto the array instead.
- required_attribute :name
+ def extra_rdoc_files= files
+ # TODO: warn about setting instead of pushing
+ @extra_rdoc_files = Array files
+ end
##
- # :attr_accessor: version
+ # The default (generated) file name of the gem. See also #spec_name.
#
- # This gem's version
+ # spec.file_name # => "example-1.0.gem"
- required_attribute :version
+ def file_name
+ "#{full_name}.gem"
+ end
##
- # :attr_accessor: date
+ # Files included in this gem. You cannot append to this accessor, you must
+ # assign to it.
#
- # The date this gem was created
+ # Only add files you can require to this list, not directories, etc.
#
- # Do not set this, it is set automatically when the gem is packaged.
+ # Directories are automatically stripped from this list when building a gem,
+ # other non-files cause an error.
- required_attribute :date, TODAY
+ def files
+ # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks)
+ @files = [@files,
+ @test_files,
+ add_bindir(@executables),
+ @extra_rdoc_files,
+ @extensions,
+ ].flatten.uniq.compact
+ end
##
- # :attr_accessor: summary
- #
- # A short summary of this gem's description. Displayed in `gem list -d`.
- #
- # The description should be more detailed than the summary. For example,
- # you might wish to copy the entire README into the description.
- #
- # As of RubyGems 1.3.2 newlines are no longer stripped.
+ # Sets files to +files+, ensuring it is an array.
- required_attribute :summary
+ def files= files
+ @files = Array files
+ end
##
- # :attr_accessor: require_paths
- #
- # Paths in the gem to add to $LOAD_PATH when this gem is activated.
- #
- # The default 'lib' is typically sufficient.
+ # Finds all gems that satisfy +dep+
- required_attribute :require_paths, ['lib']
+ def find_all_satisfiers dep
+ Gem::Specification.each do |spec|
+ yield spec if spec.satisfies_requirement? dep
+ end
+ end
- # :section: Optional gemspec attributes
+ private :find_all_satisfiers
##
- # :attr_accessor: email
- #
- # A contact email for this gem
- #
- # If you are providing multiple authors and multiple emails they should be
- # in the same order such that:
- #
- # Hash[*spec.authors.zip(spec.emails).flatten]
- #
- # Gives a hash of author name to email address.
+ # Creates a duplicate spec without large blobs that aren't used at runtime.
- attribute :email
+ def for_cache
+ spec = dup
- ##
- # :attr_accessor: homepage
- #
- # The URL of this gem's home page
+ spec.files = nil
+ spec.test_files = nil
- attribute :homepage
+ spec
+ end
##
- # :attr_accessor: rubyforge_project
- #
- # The rubyforge project this gem lives under. i.e. RubyGems'
- # rubyforge_project is "rubygems".
+ # The full path to the gem (install path + full name).
- attribute :rubyforge_project
+ def full_gem_path
+ # TODO: try to get rid of this... or the awkward
+ # TODO: also, shouldn't it default to full_name if it hasn't been written?
+ return @full_gem_path if defined?(@full_gem_path) && @full_gem_path
- ##
- # :attr_accessor: description
- #
- # A long description of this gem
+ @full_gem_path = File.expand_path File.join(gems_dir, full_name)
+
+ return @full_gem_path if File.directory? @full_gem_path
- attribute :description
+ @full_gem_path = File.expand_path File.join(gems_dir, original_name)
+ end
##
- # :attr_accessor: autorequire
- #
- # Autorequire was used by old RubyGems to automatically require a file.
- # It no longer is supported.
+ # Returns the full name (name-version) of this Gem. Platform information
+ # is included (name-version-platform) if it is specified and not the
+ # default Ruby platform.
- attribute :autorequire
+ def full_name
+ if platform == Gem::Platform::RUBY or platform.nil? then
+ "#{@name}-#{@version}"
+ else
+ "#{@name}-#{@version}-#{platform}"
+ end
+ end
##
- # :attr_accessor: default_executable
- #
- # The default executable for this gem.
- #
- # This is not used.
+ # Returns the full path to this spec's gem directory.
+ # eg: /usr/local/lib/ruby/1.8/gems/mygem-1.0
- attribute :default_executable
+ def gem_dir
+ @gem_dir ||= File.expand_path File.join(gems_dir, full_name)
+ end
##
- # :attr_accessor: bindir
- #
- # The path in the gem for executable scripts
+ # Returns the full path to the gems directory containing this spec's
+ # gem directory. eg: /usr/local/lib/ruby/1.8/gems
- attribute :bindir, 'bin'
+ 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")
+ end
##
- # :attr_accessor: has_rdoc
- #
# Deprecated and ignored, defaults to true.
#
# Formerly used to indicate this gem was RDoc-capable.
- attribute :has_rdoc, true
+ def has_rdoc
+ true
+ end
##
- # True if this gem supports RDoc
+ # Deprecated and ignored.
+ #
+ # Formerly used to indicate this gem was RDoc-capable.
+
+ def has_rdoc= ignored
+ @has_rdoc = true
+ end
alias :has_rdoc? :has_rdoc
##
- # :attr_accessor: required_ruby_version
- #
- # The version of ruby required by this gem
-
- attribute :required_ruby_version, Gem::Requirement.default
+ # True if this gem has files in test_files
- ##
- # :attr_accessor: required_rubygems_version
- #
- # The RubyGems version required by this gem
+ def has_unit_tests?
+ not test_files.empty?
+ end
- attribute :required_rubygems_version, Gem::Requirement.default
+ # :stopdoc:
+ alias has_test_suite? has_unit_tests?
+ # :startdoc:
- ##
- # :attr_accessor: platform
- #
- # The platform this gem runs on. See Gem::Platform for details.
- #
- # Setting this to any value other than Gem::Platform::RUBY or
- # Gem::Platform::CURRENT is probably wrong.
+ def hash # :nodoc:
+ @@attributes.inject(0) { |hash_code, (name, _)|
+ hash_code ^ self.send(name).hash
+ }
+ end
- attribute :platform, Gem::Platform::RUBY
+ def init_with coder # :nodoc:
+ yaml_initialize coder.tag, coder.map
+ end
##
- # :attr_accessor: signing_key
- #
- # The key used to sign this gem. See Gem::Security for details.
+ # Specification constructor. Assigns the default values to the attributes
+ # and yields itself for further initialization. Optionally takes +name+ and
+ # +version+.
- attribute :signing_key, nil
+ def initialize name = nil, version = nil
+ @loaded = false
+ @loaded_from = nil
+ @original_platform = nil
- ##
- # :attr_accessor: cert_chain
- #
- # The certificate chain used to sign this gem. See Gem::Security for
- # details.
+ @@nil_attributes.each do |key|
+ instance_variable_set "@#{key}", nil
+ end
- attribute :cert_chain, []
+ @@non_nil_attributes.each do |key|
+ default = default_value(key)
+ value = case default
+ when Time, Numeric, Symbol, true, false, nil then default
+ else default.dup
+ end
- ##
- # :attr_accessor: post_install_message
- #
- # A message that gets displayed after the gem is installed
+ instance_variable_set "@#{key}", value
+ end
- attribute :post_install_message, nil
+ @new_platform = Gem::Platform::RUBY
- ##
- # :attr_accessor: authors
- #
- # The list of author names who wrote this gem.
- #
- # If you are providing multiple authors and multiple emails they should be
- # in the same order such that:
- #
- # Hash[*spec.authors.zip(spec.emails).flatten]
- #
- # Gives a hash of author name to email address.
+ self.name = name if name
+ self.version = version if version
- array_attribute :authors
+ yield self if block_given?
+ end
##
- # :attr_accessor: licenses
- #
- # The license(s) for the library. Each license must be a short name, no
- # more than 64 characters.
-
- array_attribute :licenses
+ # Duplicates array_attributes from +other_spec+ so state isn't shared.
- ##
- # :attr_accessor: files
- #
- # Files included in this gem. You cannot append to this accessor, you must
- # assign to it.
- #
- # Only add files you can require to this list, not directories, etc.
- #
- # Directories are automatically stripped from this list when building a gem,
- # other non-files cause an error.
+ def initialize_copy other_spec
+ other_ivars = other_spec.instance_variables
+ other_ivars = other_ivars.map { |ivar| ivar.intern } if # for 1.9
+ String === other_ivars.first
- array_attribute :files
+ self.class.array_attributes.each do |name|
+ name = :"@#{name}"
+ next unless other_ivars.include? name
- ##
- # :attr_accessor: test_files
- #
- # Test files included in this gem. You cannot append to this accessor, you
- # must assign to it.
+ begin
+ val = other_spec.instance_variable_get(name)
+ if val then
+ instance_variable_set name, val.dup
+ else
+ warn "WARNING: #{full_name} has an invalid nil value for #{name}"
+ end
+ rescue TypeError
+ e = Gem::FormatException.new \
+ "#{full_name} has an invalid value for #{name}"
- array_attribute :test_files
+ e.file_path = loaded_from
+ raise e
+ end
+ end
+ end
##
- # :attr_accessor: rdoc_options
- #
- # An ARGV style array of options to RDoc
+ # The directory that this gem was installed into.
+ # TODO: rename - horrible. this is the base_dir for a gem path
- array_attribute :rdoc_options
+ def installation_path
+ loaded_from && base_dir
+ end
##
- # :attr_accessor: extra_rdoc_files
- #
- # Extra files to add to RDoc such as README or doc/examples.txt
+ # Returns a string usable in Dir.glob to match all requirable paths
+ # for this spec.
- array_attribute :extra_rdoc_files
+ def lib_dirs_glob
+ dirs = if self.require_paths.size > 1 then
+ "{#{self.require_paths.join(',')}}"
+ else
+ self.require_paths.first
+ end
+
+ "#{self.full_gem_path}/#{dirs}"
+ end
##
- # :attr_accessor: executables
- #
- # Executables included in the gem.
+ # Files in the Gem under one of the require_paths
- array_attribute :executables
+ def lib_files
+ @files.select do |file|
+ require_paths.any? do |path|
+ file.index(path) == 0
+ end
+ end
+ end
##
- # :attr_accessor: extensions
- #
- # Extensions to build when installing the gem. See
- # Gem::Installer#build_extensions for valid values.
+ # Singular accessor for #licenses
- array_attribute :extensions
+ def license
+ val = licenses and val.first
+ end
##
- # :attr_accessor: requirements
- #
- # An array or things required by this gem. Not used by anything
- # presently.
+ # Singular accessor for #licenses
- array_attribute :requirements
+ def license=o
+ self.licenses = [o]
+ end
##
- # :attr_reader: dependencies
- #
- # A list of Gem::Dependency objects this gem depends on.
- #
- # Use #add_dependency or #add_development_dependency to add dependencies to
- # a gem.
+ # The license(s) for the library. Each license must be a short name, no
+ # more than 64 characters.
- array_attribute :dependencies
+ def licenses
+ @licenses ||= []
+ end
- read_only :dependencies
+ ##
+ # Set licenses to +licenses+, ensuring it is an array.
- # :section: Aliased gemspec attributes
+ def licenses= licenses
+ @licenses = Array licenses
+ end
##
- # Singular accessor for #executables
+ # Set the location a Specification was loaded from. +obj+ is converted
+ # to a String.
- attribute_alias_singular :executable, :executables
+ def loaded_from= path
+ @loaded_from = path.to_s
+ end
##
- # Singular accessor for #authors
+ # Sets the rubygems_version to the current RubyGems version.
- attribute_alias_singular :author, :authors
+ def mark_version
+ @rubygems_version = Gem::VERSION
+ end
##
- # Singular accessor for #licenses
+ # Return all files in this gem that match for +glob+.
- attribute_alias_singular :license, :licenses
+ def matches_for_glob glob # TODO: rename?
+ # TODO: do we need these?? Kill it
+ glob = File.join(self.lib_dirs_glob, glob)
+
+ Dir[glob].map { |f| f.untaint } # FIX our tests are brokey, run w/ SAFE=1
+ end
##
- # Singular accessor for #require_paths
+ # Warn about unknown attributes while loading a spec.
- attribute_alias_singular :require_path, :require_paths
+ def method_missing(sym, *a, &b) # :nodoc:
+ if @specification_version > CURRENT_SPECIFICATION_VERSION and
+ sym.to_s =~ /=$/ then
+ warn "ignoring #{sym} loading #{full_name}" if $DEBUG
+ else
+ super
+ end
+ end
##
- # Singular accessor for #test_files
+ # Normalize the list of files so that:
+ # * All file lists have redundancies removed.
+ # * Files referenced in the extra_rdoc_files are included in the package
+ # file list.
+
+ def normalize
+ if defined?(@extra_rdoc_files) and @extra_rdoc_files then
+ @extra_rdoc_files.uniq!
+ @files ||= []
+ @files.concat(@extra_rdoc_files)
+ end
- attribute_alias_singular :test_file, :test_files
+ @files = @files.uniq if @files
+ @extensions = @extensions.uniq if @extensions
+ @test_files = @test_files.uniq if @test_files
+ @executables = @executables.uniq if @executables
+ @extra_rdoc_files = @extra_rdoc_files.uniq if @extra_rdoc_files
+ end
##
- # has_rdoc is now ignored
+ # Returns the full name (name-version) of this gemspec using the original
+ # platform. For use with legacy gems.
- overwrite_accessor :has_rdoc do
- true
+ def original_name # :nodoc:
+ if platform == Gem::Platform::RUBY or platform.nil? then
+ "#{@name}-#{@version}"
+ else
+ "#{@name}-#{@version}-#{@original_platform}"
+ end
end
##
- # has_rdoc is now ignored
+ # Cruft. Use +platform+.
- overwrite_accessor :has_rdoc= do |value|
- @has_rdoc = true
+ def original_platform # :nodoc:
+ @original_platform ||= platform
end
- overwrite_accessor :version= do |version|
- @version = Gem::Version.create(version)
- self.required_rubygems_version = '> 1.3.1' if @version.prerelease?
- return @version
- end
+ ##
+ # The platform this gem runs on. See Gem::Platform for details.
- overwrite_accessor :platform do
- @new_platform
+ def platform
+ @new_platform ||= Gem::Platform::RUBY
end
- overwrite_accessor :platform= do |platform|
+ ##
+ # The platform this gem runs on. See Gem::Platform for details.
+ #
+ # Setting this to any value other than Gem::Platform::RUBY or
+ # Gem::Platform::CURRENT is probably wrong.
+
+ def platform= platform
if @original_platform.nil? or
@original_platform == Gem::Platform::RUBY then
@original_platform = platform
@@ -1455,68 +1561,237 @@ class Gem::Specification
@new_platform
end
- overwrite_accessor :required_ruby_version= do |value|
- @required_ruby_version = Gem::Requirement.create(value)
- end
+ def pretty_print(q) # :nodoc:
+ q.group 2, 'Gem::Specification.new do |s|', 'end' do
+ q.breakable
+
+ # REFACTOR: each_attr - use in to_yaml as well
+ @@attributes.each do |attr_name|
+ current_value = self.send attr_name
+ if current_value != default_value(attr_name) or
+ self.class.required_attribute? attr_name then
+
+ q.text "s.#{attr_name} = "
- overwrite_accessor :required_rubygems_version= do |value|
- @required_rubygems_version = Gem::Requirement.create(value)
+ if attr_name == :date then
+ current_value = current_value.utc
+
+ q.text "Time.utc(#{current_value.year}, #{current_value.month}, #{current_value.day})"
+ else
+ q.pp current_value
+ end
+
+ q.breakable
+ end
+ end
+ end
end
- overwrite_accessor :date= do |date|
- # We want to end up with a Time object with one-day resolution.
- # This is the cleanest, most-readable, faster-than-using-Date
- # way to do it.
- case date
- when String then
- @date = if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then
- Time.local($1.to_i, $2.to_i, $3.to_i)
- else
- require 'time'
- Time.parse date
- end
- when Time then
- @date = Time.local(date.year, date.month, date.day)
- when Date then
- @date = Time.local(date.year, date.month, date.day)
- else
- @date = TODAY
+ ##
+ # Check the spec for possible conflicts and freak out if there are any.
+
+ def raise_if_conflicts
+ other = Gem.loaded_specs[self.name]
+
+ if other and self.version != other.version then
+ # This gem is already loaded. If the currently loaded gem is not in the
+ # list of candidate gems, then we have a version conflict.
+
+ msg = "can't activate #{full_name}, already activated #{other.full_name}"
+
+ e = Gem::LoadError.new msg
+ e.name = self.name
+ # TODO: e.requirement = dep.requirement
+
+ raise e
+ end
+
+ conf = self.conflicts
+
+ unless conf.empty? then
+ y = conf.map { |act,con|
+ "#{act.full_name} conflicts with #{con.join(", ")}"
+ }.join ", "
+
+ # TODO: improve message by saying who activated `con`
+
+ raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}"
end
end
- overwrite_accessor :date do
- self.date = nil if @date.nil? # HACK Sets the default value for date
- @date
+ ##
+ # An ARGV style array of options to RDoc
+
+ def rdoc_options
+ @rdoc_options ||= []
end
- overwrite_accessor :summary= do |str|
- @summary = if str then
- str.strip.
- gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').
- gsub(/\n[ \t]*/, " ")
- end
+ ##
+ # Sets rdoc_options to +value+, ensuring it is an array. Don't
+ # use this, push onto the array instead.
+
+ def rdoc_options= options
+ # TODO: warn about setting instead of pushing
+ @rdoc_options = Array options
end
- overwrite_accessor :description= do |str|
- @description = str.to_s
+ ##
+ # Singular accessor for #require_paths
+
+ def require_path
+ val = require_paths and val.first
end
- overwrite_accessor :default_executable do
- begin
- if defined?(@default_executable) and @default_executable
- result = @default_executable
- elsif @executables and @executables.size == 1
- result = Array(@executables).first
- else
- result = nil
- end
- result
- rescue
- nil
+ ##
+ # Singular accessor for #require_paths
+
+ def require_path= path
+ self.require_paths = [path]
+ end
+
+ ##
+ # The version of ruby required by this gem
+
+ def required_ruby_version= req
+ @required_ruby_version = Gem::Requirement.create req
+ end
+
+ ##
+ # The RubyGems version required by this gem
+
+ def required_rubygems_version= req
+ @required_rubygems_version = Gem::Requirement.create req
+ end
+
+ ##
+ # An array or things required by this gem. Not used by anything
+ # presently.
+
+ def requirements
+ @requirements ||= []
+ end
+
+ ##
+ # Set requirements to +req+, ensuring it is an array. Don't
+ # use this, push onto the array instead.
+
+ def requirements= req
+ # TODO: warn about setting instead of pushing
+ @requirements = Array req
+ end
+
+ ##
+ # Returns the full path to this spec's ri directory.
+
+ def ri_dir
+ @ri_dir ||= File.join base_dir, 'ri', full_name
+ end
+
+ ##
+ # Return a string containing a Ruby code representation of the given
+ # object.
+
+ def ruby_code(obj)
+ case obj
+ when String then '%q{' + obj + '}'
+ when Array then '[' + obj.map { |x| ruby_code x }.join(", ") + ']'
+ when Gem::Version then obj.to_s.inspect
+ when Date then '%q{' + obj.strftime('%Y-%m-%d') + '}'
+ when Time then '%q{' + obj.strftime('%Y-%m-%d') + '}'
+ when Numeric then obj.inspect
+ when true, false, nil then obj.inspect
+ when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
+ when Gem::Requirement then "Gem::Requirement.new(#{obj.to_s.inspect})"
+ else raise Gem::Exception, "ruby_code case not handled: #{obj.class}"
end
end
- overwrite_accessor :test_files do
+ private :ruby_code
+
+ ##
+ # List of dependencies that will automatically be activated at runtime.
+
+ def runtime_dependencies
+ dependencies.select { |d| d.type == :runtime }
+ end
+
+ ##
+ # True if this gem has the same attributes as +other+.
+
+ def same_attributes? spec
+ @@attributes.all? { |name, default| self.send(name) == spec.send(name) }
+ end
+
+ private :same_attributes?
+
+ ##
+ # Checks if this specification meets the requirement of +dependency+.
+
+ def satisfies_requirement? dependency
+ return @name == dependency.name &&
+ dependency.requirement.satisfied_by?(@version)
+ end
+
+ ##
+ # Returns an object you can use to sort specifications in #sort_by.
+
+ def sort_obj
+ # TODO: this is horrible. Deprecate it.
+ [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1]
+ end
+
+ ##
+ # Returns the full path to the directory containing this spec's
+ # gemspec file. eg: /usr/local/lib/ruby/gems/1.8/specifications
+
+ def spec_dir
+ @spec_dir ||= File.join base_dir, "specifications"
+ end
+
+ ##
+ # Returns the full path to this spec's gemspec file.
+ # eg: /usr/local/lib/ruby/gems/1.8/specifications/mygem-1.0.gemspec
+
+ def spec_file
+ @spec_file ||= File.join spec_dir, "#{full_name}.gemspec"
+ end
+
+ ##
+ # The default name of the gemspec. See also #file_name
+ #
+ # spec.spec_name # => "example-1.0.gemspec"
+
+ def spec_name
+ "#{full_name}.gemspec"
+ end
+
+ ##
+ # A short summary of this gem's description.
+
+ def summary= str
+ @summary = str.to_s.strip.
+ gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird.
+ end
+
+ ##
+ # Singular accessor for #test_files
+
+ def test_file
+ val = test_files and val.first
+ end
+
+ ##
+ # Singular accessor for #test_files
+
+ def test_file= file
+ self.test_files = [file]
+ end
+
+ ##
+ # Test files included in this gem. You cannot append to this accessor, you
+ # must assign to it.
+
+ def test_files
# Handle the possibility that we have @test_suite_file but not
# @test_files. This will happen when an old gem is loaded via
# YAML.
@@ -1531,41 +1806,323 @@ class Gem::Specification
end
end
- overwrite_accessor :files do
- # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks)
- @files = [@files,
- @test_files,
- add_bindir(@executables),
- @extra_rdoc_files,
- @extensions,
- ].flatten.uniq.compact
+ ##
+ # Set test_files to +files+, ensuring it is an array.
+
+ def test_files= files
+ @test_files = Array files
end
- def conflicts
- conflicts = {}
- Gem.loaded_specs.values.each do |spec|
- bad = self.runtime_dependencies.find_all { |dep|
- spec.name == dep.name and not spec.satisfies_requirement? dep
- }
+ def test_suite_file # :nodoc:
+ # TODO: deprecate
+ test_files.first
+ end
- conflicts[spec] = bad unless bad.empty?
+ def test_suite_file= file # :nodoc:
+ # TODO: deprecate
+ @test_files = [] unless defined? @test_files
+ @test_files << file
+ end
+
+ ##
+ # Returns a Ruby code representation of this specification, such that it can
+ # be eval'ed and reconstruct the same specification later. Attributes that
+ # still have their default values are omitted.
+
+ def to_ruby
+ mark_version
+ result = []
+ result << "# -*- encoding: utf-8 -*-"
+ result << nil
+ result << "Gem::Specification.new do |s|"
+
+ result << " s.name = #{ruby_code name}"
+ result << " s.version = #{ruby_code version}"
+ unless platform.nil? or platform == Gem::Platform::RUBY then
+ result << " s.platform = #{ruby_code original_platform}"
end
- conflicts
+ result << ""
+ result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version="
+
+ handled = [
+ :dependencies,
+ :name,
+ :platform,
+ :required_rubygems_version,
+ :specification_version,
+ :version,
+ :has_rdoc,
+ :default_executable,
+ ]
+
+ @@attributes.each do |attr_name|
+ next if handled.include? attr_name
+ current_value = self.send(attr_name)
+ if current_value != default_value(attr_name) or
+ self.class.required_attribute? attr_name then
+ result << " s.#{attr_name} = #{ruby_code current_value}"
+ end
+ end
+
+ result << nil
+ result << " if s.respond_to? :specification_version then"
+ result << " s.specification_version = #{specification_version}"
+ result << nil
+
+ result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then"
+
+ dependencies.each do |dep|
+ req = dep.requirements_list.inspect
+ dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
+ result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})"
+ end
+
+ result << " else"
+
+ dependencies.each do |dep|
+ version_reqs_param = dep.requirements_list.inspect
+ result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
+ end
+
+ result << ' end'
+
+ result << " else"
+ dependencies.each do |dep|
+ version_reqs_param = dep.requirements_list.inspect
+ result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
+ end
+ result << " end"
+
+ result << "end"
+ result << nil
+
+ result.join "\n"
end
- def traverse trail = [], &b
+ ##
+ # Returns a Ruby lighter-weight code representation of this specification,
+ # used for indexing only.
+ #
+ # See #to_ruby.
+
+ def to_ruby_for_cache
+ for_cache.to_ruby
+ end
+
+ def to_s # :nodoc:
+ "#<Gem::Specification name=#{@name} version=#{@version}>"
+ end
+
+ def to_yaml(opts = {}) # :nodoc:
+ if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? then
+ super.gsub(/ !!null \n/, " \n")
+ else
+ YAML.quick_emit object_id, opts do |out|
+ out.map taguri, to_yaml_style do |map|
+ encode_with map
+ end
+ end
+ end
+ end
+
+ ##
+ # Recursively walk dependencies of this spec, executing the +block+ for each
+ # hop.
+
+ def traverse trail = [], &block
trail = trail + [self]
runtime_dependencies.each do |dep|
- dep_specs = Gem.source_index.search dep, true
- dep_specs.each do |dep_spec|
- b[self, dep, dep_spec, trail + [dep_spec]]
- dep_spec.traverse(trail, &b) unless
+ dep.to_specs.each do |dep_spec|
+ block[self, dep, dep_spec, trail + [dep_spec]]
+ dep_spec.traverse(trail, &block) unless
trail.map(&:name).include? dep_spec.name
end
end
end
- def dependent_specs
- runtime_dependencies.map { |dep| Gem.source_index.search dep, true }.flatten
+ ##
+ # Checks that the specification contains all required fields, and does a
+ # very basic sanity check.
+ #
+ # Raises InvalidSpecificationException if the spec does not pass the
+ # checks..
+
+ def validate packaging = true
+ require 'rubygems/user_interaction'
+ extend Gem::UserInteraction
+ normalize
+
+ nil_attributes = self.class.non_nil_attributes.find_all do |name|
+ instance_variable_get("@#{name}").nil?
+ end
+
+ unless nil_attributes.empty? then
+ raise Gem::InvalidSpecificationException,
+ "#{nil_attributes.join ', '} must not be nil"
+ end
+
+ if packaging and rubygems_version != Gem::VERSION then
+ raise Gem::InvalidSpecificationException,
+ "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
+ end
+
+ @@required_attributes.each do |symbol|
+ unless self.send symbol then
+ raise Gem::InvalidSpecificationException,
+ "missing value for attribute #{symbol}"
+ end
+ end
+
+ unless String === name then
+ raise Gem::InvalidSpecificationException,
+ "invalid value for attribute name: \"#{name.inspect}\""
+ end
+
+ if require_paths.empty? then
+ raise Gem::InvalidSpecificationException,
+ 'specification must have at least one require_path'
+ end
+
+ @files.delete_if { |x| File.directory?(x) }
+ @test_files.delete_if { |x| File.directory?(x) }
+ @executables.delete_if { |x| File.directory?(File.join(@bindir, x)) }
+ @extra_rdoc_files.delete_if { |x| File.directory?(x) }
+ @extensions.delete_if { |x| File.directory?(x) }
+
+ non_files = files.reject { |x| File.file?(x) }
+
+ unless not packaging or non_files.empty? then
+ raise Gem::InvalidSpecificationException,
+ "[\"#{non_files.join "\", \""}\"] are not files"
+ end
+
+ unless specification_version.is_a?(Fixnum)
+ raise Gem::InvalidSpecificationException,
+ 'specification_version must be a Fixnum (did you mean version?)'
+ end
+
+ case platform
+ when Gem::Platform, Gem::Platform::RUBY then # ok
+ else
+ raise Gem::InvalidSpecificationException,
+ "invalid platform #{platform.inspect}, see Gem::Platform"
+ end
+
+ self.class.array_attributes.each do |field|
+ val = self.send field
+ klass = case field
+ when :dependencies
+ Gem::Dependency
+ else
+ String
+ end
+
+ unless Array === val and val.all? { |x| x.kind_of?(klass) } then
+ raise(Gem::InvalidSpecificationException,
+ "#{field} must be an Array of #{klass}")
+ end
+ end
+
+ [:authors].each do |field|
+ val = self.send field
+ raise Gem::InvalidSpecificationException, "#{field} may not be empty" if
+ val.empty?
+ end
+
+ licenses.each { |license|
+ if license.length > 64
+ raise Gem::InvalidSpecificationException,
+ "each license must be 64 characters or less"
+ end
+ }
+
+ # reject lazy developers:
+
+ lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')
+
+ unless authors.grep(/FI XME|TO DO/x).empty? then
+ raise Gem::InvalidSpecificationException, "#{lazy} is not an author"
+ end
+
+ unless Array(email).grep(/FI XME|TO DO/x).empty? then
+ raise Gem::InvalidSpecificationException, "#{lazy} is not an email"
+ end
+
+ if description =~ /FI XME|TO DO/x then
+ raise Gem::InvalidSpecificationException, "#{lazy} is not a description"
+ end
+
+ if summary =~ /FI XME|TO DO/x then
+ raise Gem::InvalidSpecificationException, "#{lazy} is not a summary"
+ end
+
+ if homepage and not homepage.empty? and
+ homepage !~ /\A[a-z][a-z\d+.-]*:/i then
+ raise Gem::InvalidSpecificationException,
+ "\"#{homepage}\" is not a URI"
+ end
+
+ # Warnings
+
+ %w[author description email homepage summary].each do |attribute|
+ value = self.send attribute
+ alert_warning "no #{attribute} specified" if value.nil? or value.empty?
+ end
+
+ if description == summary then
+ alert_warning 'description and summary are identical'
+ end
+
+ # TODO: raise at some given date
+ alert_warning "deprecated autorequire specified" if autorequire
+
+ executables.each do |executable|
+ executable_path = File.join(bindir, executable)
+ shebang = File.read(executable_path, 2) == '#!'
+
+ alert_warning "#{executable_path} is missing #! line" unless shebang
+ end
+
+ true
end
+
+ ##
+ # Set the version to +version+, potentially also setting
+ # required_rubygems_version if +version+ indicates it is a
+ # prerelease.
+
+ def version= version
+ @version = Gem::Version.create(version)
+ self.required_rubygems_version = '> 1.3.1' if @version.prerelease?
+ return @version
+ end
+
+ # FIX: have this handle the platform/new_platform/original_platform bullshit
+ def yaml_initialize(tag, vals) # :nodoc:
+ vals.each do |ivar, val|
+ instance_variable_set "@#{ivar}", val
+ end
+
+ @original_platform = @platform # for backwards compatibility
+ self.platform = Gem::Platform.new @platform
+ end
+
+ extend Deprecate
+
+ deprecate :test_suite_file, :test_file, 2011, 10
+ deprecate :test_suite_file=, :test_file=, 2011, 10
+ deprecate :loaded, :activated, 2011, 10
+ deprecate :loaded?, :activated?, 2011, 10
+ deprecate :loaded=, :activated=, 2011, 10
+ deprecate :installation_path, :base_dir, 2011, 10
+ deprecate :cache_gem, :cache_file, 2011, 10
+ # TODO:
+ # deprecate :has_rdoc, :none, 2011, 10
+ # deprecate :has_rdoc?, :none, 2011, 10
+ # deprecate :has_rdoc=, :none, 2011, 10
+ # deprecate :default_executable, :none, 2011, 10
+ # deprecate :default_executable=, :none, 2011, 10
+ # deprecate :spec_name, :spec_file, 2011, 10
+ # deprecate :file_name, :cache_file, 2011, 10
+ # deprecate :full_gem_path, :cache_file, 2011, 10
end
diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb
index 895002d..3b26d31 100644
--- a/lib/rubygems/test_case.rb
+++ b/lib/rubygems/test_case.rb
@@ -17,6 +17,7 @@ begin
rescue Gem::LoadError
end
+require "rubygems/deprecate"
require 'minitest/autorun'
require 'fileutils'
require 'tmpdir'
@@ -25,6 +26,7 @@ require 'rubygems/package'
require 'rubygems/test_utilities'
require 'pp'
require 'zlib'
+require 'pathname'
Gem.load_yaml
require 'rubygems/mock_gem_ui'
@@ -44,6 +46,8 @@ module Gem
# requiring 'rubygems/test_case'
def self.source_index=(si)
+ raise "This method is not supported"
+ Gem::Specification.reset if si # HACK
@@source_index = si
end
@@ -82,12 +86,24 @@ end
class Gem::TestCase < MiniTest::Unit::TestCase
+ # TODO: move to minitest
+ def assert_path_exists path, msg = nil
+ msg = message(msg) { "Expected path '#{path}' to exist" }
+ assert File.exist?(path), msg
+ end
+
+ # TODO: move to minitest
+ def refute_path_exists path, msg = nil
+ msg = message(msg) { "Expected path '#{path}' to not exist" }
+ refute File.exist?(path), msg
+ end
+
include Gem::DefaultUserInteraction
undef_method :default_test if instance_methods.include? 'default_test' or
instance_methods.include? :default_test
- @@project_dir = Dir.pwd unless defined?(@@project_dir)
+ @@project_dir = Dir.pwd
##
# #setup prepares a sandboxed location to install gems. All installs are
@@ -106,14 +122,15 @@ class Gem::TestCase < MiniTest::Unit::TestCase
@orig_gem_home = ENV['GEM_HOME']
@orig_gem_path = ENV['GEM_PATH']
- @current_dir = Dir.pwd
@ui = Gem::MockGemUi.new
+
tmpdir = nil
Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
+
if ENV['KEEP_FILES'] then
- @tempdir = File.join tmpdir, "test_rubygems_#{$$}.#{Time.now.to_i}"
+ @tempdir = File.join(tmpdir, "test_rubygems_#{$$}.#{Time.now.to_i}")
else
- @tempdir = File.join tmpdir, "test_rubygems_#{$$}"
+ @tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
end
@tempdir.untaint
@gemhome = File.join @tempdir, 'gemhome'
@@ -126,6 +143,9 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem.ensure_gem_subdirectories @gemhome
+ @orig_LOAD_PATH = $LOAD_PATH.dup
+ $LOAD_PATH.map! { |s| File.expand_path s }
+
Dir.chdir @tempdir
@orig_ENV_HOME = ENV['HOME']
@@ -136,6 +156,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
FileUtils.mkdir_p @userhome
Gem.use_paths(@gemhome)
+
Gem.loaded_specs.clear
Gem.unresolved_deps.clear
@@ -191,8 +212,6 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem.pre_uninstall do |uninstaller|
@pre_uninstall_hook_arg = uninstaller
end
-
- @orig_LOAD_PATH = $LOAD_PATH.dup
end
##
@@ -209,15 +228,13 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem::RemoteFetcher.fetcher = nil
end
- Dir.chdir @current_dir
+ Dir.chdir @@project_dir
FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES']
ENV['GEM_HOME'] = @orig_gem_home
ENV['GEM_PATH'] = @orig_gem_path
- Gem.clear_paths
-
_ = @orig_ruby
Gem.class_eval { @ruby = _ } if _
@@ -240,7 +257,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
end
end
- gem = File.join(@tempdir, spec.file_name).untaint
+ gem = File.join(@tempdir, File.basename(spec.cache_file)).untaint
Gem::Installer.new(gem, :wrappers => true).install
end
@@ -250,9 +267,19 @@ class Gem::TestCase < MiniTest::Unit::TestCase
def uninstall_gem spec
require 'rubygems/uninstaller'
- uninstaller = Gem::Uninstaller.new spec.name, :executables => true,
- :user_install => true
- uninstaller.uninstall
+ Gem::Uninstaller.new(spec.name,
+ :executables => true, :user_install => true).uninstall
+ end
+
+ ##
+ # creates a temporary directory with hax
+
+ 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
##
@@ -285,7 +312,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# Writes a binary file to +path+ which is relative to +@gemhome+
def write_file(path)
- path = File.join @gemhome, path
+ path = File.join @gemhome, path unless Pathname.new(path).absolute?
dir = File.dirname path
FileUtils.mkdir_p dir
@@ -296,6 +323,10 @@ class Gem::TestCase < MiniTest::Unit::TestCase
path
end
+ def all_spec_names
+ Gem::Specification.map(&:full_name)
+ end
+
##
# Creates a Gem::Specification with a minimum of extra work. +name+ and
# +version+ are the gem's name and version, platform, author, email,
@@ -317,26 +348,27 @@ class Gem::TestCase < MiniTest::Unit::TestCase
s.author = 'A User'
s.email = 'example@example.com'
s.homepage = 'http://example.com'
- s.has_rdoc = true
s.summary = "this is a summary"
s.description = "This is a test description"
yield(s) if block_given?
end
- path = File.join "specifications", spec.spec_name
- written_path = write_file path do |io|
- io.write(spec.to_ruby)
+ Gem::Specification.map # HACK: force specs to (re-)load before we write
+
+ written_path = write_file spec.spec_file do |io|
+ io.write spec.to_ruby_for_cache
end
- spec.loaded_from = written_path
+ spec.loaded_from = spec.loaded_from = written_path
- Gem.source_index.add_spec spec
+ Gem::Specification.add_spec spec.for_cache
return spec
end
def quick_spec name, version = '2'
+ # TODO: deprecate
require 'rubygems/specification'
spec = Gem::Specification.new do |s|
@@ -346,16 +378,15 @@ class Gem::TestCase < MiniTest::Unit::TestCase
s.author = 'A User'
s.email = 'example@example.com'
s.homepage = 'http://example.com'
- s.has_rdoc = true
s.summary = "this is a summary"
s.description = "This is a test description"
yield(s) if block_given?
end
- spec.loaded_from = @gemhome
+ spec.loaded_from = spec.spec_file
- Gem.source_index.add_spec spec
+ Gem::Specification.add_spec spec
return spec
end
@@ -365,7 +396,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# 'cache'</tt>. Automatically creates files based on +spec.files+
def util_build_gem(spec)
- dir = File.join(@gemhome, 'gems', spec.full_name)
+ dir = spec.gem_dir
FileUtils.mkdir_p dir
Dir.chdir dir do
@@ -379,8 +410,8 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem::Builder.new(spec).build
end
- FileUtils.mv spec.file_name,
- Gem.cache_gem("#{spec.original_name}.gem")
+ cache = spec.cache_file
+ FileUtils.mv File.basename(cache), cache
end
end
@@ -388,19 +419,16 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# Removes all installed gems from +@gemhome+.
def util_clear_gems
- FileUtils.rm_rf File.join(@gemhome, 'gems')
- FileUtils.rm_rf File.join(@gemhome, 'specifications')
- Gem.source_index.refresh!
+ FileUtils.rm_rf File.join(@gemhome, "gems") # TODO: use Gem::Dirs
+ FileUtils.rm_rf File.join(@gemhome, "specifications")
+ Gem::Specification.reset
end
##
# Install the provided specs
def install_specs(*specs)
- specs.each do |spec|
- # TODO: inverted responsibility
- Gem.source_index.add_spec spec
- end
+ Gem::Specification.add_specs(*specs)
Gem.searcher = nil
end
@@ -409,19 +437,42 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# up properly. Use this instead of util_spec and util_gem.
def new_spec name, version, deps = nil, *files
- # TODO: unfactor and deprecate util_gem and util_spec
- spec, = unless files.empty? then
- util_gem name, version do |s|
- Array(deps).each do |n,v|
- s.add_dependency n, v
- end
- s.files.push(*files)
- end
- else
- util_spec name, version, deps
- end
- spec.loaded_from = File.join @gemhome, 'specifications', spec.spec_name
- spec.loaded = false
+ 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? then
+ 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
@@ -429,6 +480,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# Creates a spec with +name+, +version+ and +deps+.
def util_spec(name, version, deps = nil, &block)
+ # TODO: deprecate
raise "deps or block, not both" if deps and block
if deps then
@@ -449,6 +501,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# location are returned.
def util_gem(name, version, deps = nil, &block)
+ # TODO: deprecate
raise "deps or block, not both" if deps and block
if deps then
@@ -465,11 +518,10 @@ class Gem::TestCase < MiniTest::Unit::TestCase
cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
FileUtils.mkdir_p File.dirname cache_file
- FileUtils.mv Gem.cache_gem("#{spec.original_name}.gem"), cache_file
- FileUtils.rm File.join(@gemhome, 'specifications', spec.spec_name)
+ FileUtils.mv spec.cache_file, cache_file
+ FileUtils.rm spec.spec_file
spec.loaded_from = nil
- spec.loaded = false
[spec, cache_file]
end
@@ -517,8 +569,8 @@ class Gem::TestCase < MiniTest::Unit::TestCase
This line is really, really long. So long, in fact, that it is more than eighty characters long! The purpose of this line is for testing wrapping behavior because sometimes people don't wrap their text to eighty characters. Without the wrapping, the text might not look good in the RSS feed.
Also, a list:
- * An entry that's actually kind of sort
- * an entry that's really long, which will probably get wrapped funny. That's ok, somebody wasn't thinking straight when they made it more than eighty characters.
+ * An entry that\'s actually kind of sort
+ * an entry that\'s really long, which will probably get wrapped funny. That's ok, somebody wasn't thinking straight when they made it more than eighty characters.
DESC
end
@@ -557,9 +609,7 @@ Also, a list:
util_build_gem spec
end
- FileUtils.rm_r File.join(@gemhome, 'gems', @pl1.original_name)
-
- Gem.source_index = nil
+ FileUtils.rm_r File.join(@gemhome, "gems", @pl1.original_name)
end
##
@@ -589,6 +639,7 @@ Also, a list:
@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 }
@@ -596,14 +647,6 @@ Also, a list:
gem_names = [@a1.full_name, @a2.full_name, @a3a.full_name, @b2.full_name]
@gem_names = gem_names.sort.join("\n")
- @source_index = Gem::SourceIndex.new
- @source_index.add_spec @a1
- @source_index.add_spec @a2
- @source_index.add_spec @a3a
- @source_index.add_spec @a_evil9
- @source_index.add_spec @c1_2
- @source_index.add_spec @a2_pre if prerelease
-
Gem::RemoteFetcher.fetcher = @fetcher
end
@@ -612,37 +655,42 @@ Also, a list:
# Best used with +@all_gems+ from #util_setup_fake_fetcher.
def util_setup_spec_fetcher(*specs)
- specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
- si = Gem::SourceIndex.new specs
+ specs -= Gem::Specification._all
+ Gem::Specification.add_specs(*specs)
spec_fetcher = Gem::SpecFetcher.fetcher
+ prerelease, _ = Gem::Specification.partition { |spec|
+ spec.version.prerelease?
+ }
+
spec_fetcher.specs[@uri] = []
- si.gems.sort_by { |_, spec| spec }.each do |_, spec|
+ Gem::Specification.each do |spec|
spec_tuple = [spec.name, spec.version, spec.original_platform]
spec_fetcher.specs[@uri] << spec_tuple
end
spec_fetcher.latest_specs[@uri] = []
- si.latest_specs.sort.each do |spec|
+ Gem::Specification.latest_specs.each do |spec|
spec_tuple = [spec.name, spec.version, spec.original_platform]
spec_fetcher.latest_specs[@uri] << spec_tuple
end
spec_fetcher.prerelease_specs[@uri] = []
- si.prerelease_specs.sort.each do |spec|
+ prerelease.each do |spec|
spec_tuple = [spec.name, spec.version, spec.original_platform]
spec_fetcher.prerelease_specs[@uri] << spec_tuple
end
- (si.gems.merge si.prerelease_gems).sort_by { |_,spec| spec }.each do |_, spec|
- path = "#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{spec.original_name}.gemspec.rz"
+ v = Gem.marshal_version
+ Gem::Specification.each do |spec|
+ path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
data = Marshal.dump spec
data_deflate = Zlib::Deflate.deflate data
@fetcher.data[path] = data_deflate
end
- si
+ nil # force errors
end
##
diff --git a/lib/rubygems/test_utilities.rb b/lib/rubygems/test_utilities.rb
index 43f905f..1e43fe5 100644
--- a/lib/rubygems/test_utilities.rb
+++ b/lib/rubygems/test_utilities.rb
@@ -103,8 +103,8 @@ class Gem::FakeFetcher
end
def download spec, source_uri, install_dir = Gem.dir
- name = spec.file_name
- path = Gem.cache_gem(name, install_dir)
+ name = File.basename spec.cache_file
+ path = File.join install_dir, "cache", name
Gem.ensure_gem_subdirectories install_dir
@@ -120,7 +120,8 @@ class Gem::FakeFetcher
end
def download_to_cache dependency
- found = Gem::SpecFetcher.fetcher.fetch dependency
+ found = Gem::SpecFetcher.fetcher.fetch dependency, true, true,
+ dependency.prerelease?
return if found.empty?
diff --git a/lib/rubygems/text.rb b/lib/rubygems/text.rb
index ddf1e82..a4642f9 100644
--- a/lib/rubygems/text.rb
+++ b/lib/rubygems/text.rb
@@ -21,7 +21,7 @@ module Gem::Text
while work.length > wrap do
if work =~ /^(.{0,#{wrap}})[ \n]/ then
- result << $1
+ result << $1.rstrip
work.slice!(0, $&.length)
else
result << work.slice!(0, wrap)
diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb
index 0297686..1e370c3 100644
--- a/lib/rubygems/uninstaller.rb
+++ b/lib/rubygems/uninstaller.rb
@@ -48,26 +48,23 @@ class Gem::Uninstaller
# Constructs an uninstaller that will uninstall +gem+
def initialize(gem, options = {})
- @gem = gem
- @version = options[:version] || Gem::Requirement.default
- gem_home = options[:install_dir] || Gem.dir
- @gem_home = File.expand_path gem_home
+ @gem = gem
+ @version = options[:version] || Gem::Requirement.default
+ @gem_home = File.expand_path(options[:install_dir] || Gem.dir)
@force_executables = options[:executables]
- @force_all = options[:all]
- @force_ignore = options[:ignore]
- @bin_dir = options[:bin_dir]
+ @force_all = options[:all]
+ @force_ignore = options[:ignore]
+ @bin_dir = options[:bin_dir]
@format_executable = options[:format_executable]
# only add user directory if install_dir is not set
@user_install = false
@user_install = options[:user_install] unless options[:install_dir]
- spec_dir = File.join @gem_home, 'specifications'
- @source_index = Gem::SourceIndex.from_gems_in spec_dir
-
if @user_install then
- user_dir = File.join Gem.user_dir, 'specifications'
- @user_index = Gem::SourceIndex.from_gems_in user_dir
+ Gem.use_paths Gem.user_dir, @gem_home
+ else
+ Gem.use_paths @gem_home
end
end
@@ -76,14 +73,13 @@ class Gem::Uninstaller
# directory, and the cached .gem file.
def uninstall
- list = @source_index.find_name @gem, @version
- list += @user_index.find_name @gem, @version if @user_install
+ list = Gem::Specification.find_all_by_name(@gem, @version)
if list.empty? then
raise Gem::InstallError, "cannot uninstall, check `gem list -d #{@gem}`"
elsif list.size > 1 and @force_all then
- remove_all list.dup
+ remove_all list
elsif list.size > 1 then
gem_names = list.collect {|gem| gem.full_name} + ["All versions"]
@@ -92,21 +88,21 @@ class Gem::Uninstaller
_, index = choose_from_list "Select gem to uninstall:", gem_names
if index == list.size then
- remove_all list.dup
+ remove_all list
elsif index >= 0 && index < list.size then
- uninstall_gem list[index], list.dup
+ uninstall_gem list[index]
else
say "Error: must enter a number [1-#{list.size+1}]"
end
else
- uninstall_gem list.first, list.dup
+ uninstall_gem list.first
end
end
##
# Uninstalls gem +spec+
- def uninstall_gem(spec, specs)
+ def uninstall_gem(spec)
@spec = spec
unless dependencies_ok? spec
@@ -121,7 +117,7 @@ class Gem::Uninstaller
end
remove_executables @spec
- remove @spec, specs
+ remove @spec
Gem.post_uninstall_hooks.each do |hook|
hook.call self
@@ -137,10 +133,8 @@ class Gem::Uninstaller
def remove_executables(spec)
return if spec.nil? or spec.executables.empty?
- bindir = @bin_dir ? @bin_dir : Gem.bindir(spec.installation_path)
-
- list = @source_index.find_name(spec.name).delete_if { |s|
- s.version == spec.version
+ list = Gem::Specification.find_all { |s|
+ s.name == spec.name && s.version != spec.version
}
executables = spec.executables.clone
@@ -165,6 +159,8 @@ class Gem::Uninstaller
unless remove then
say "Executables and scripts will remain installed."
else
+ bindir = @bin_dir || Gem.bindir(spec.base_dir)
+
raise Gem::FilePermissionError, bindir unless File.writable? bindir
spec.executables.each do |exe_name|
@@ -181,7 +177,7 @@ class Gem::Uninstaller
# NOTE: removes uninstalled gems from +list+.
def remove_all(list)
- list.dup.each { |spec| uninstall_gem spec, list }
+ list.each { |spec| uninstall_gem spec }
end
##
@@ -191,7 +187,7 @@ class Gem::Uninstaller
# Warning: this method modifies the +list+ parameter. Once it has
# uninstalled a gem, it is removed from that list.
- def remove(spec, list)
+ def remove(spec)
unless path_ok?(@gem_home, spec) or
(@user_install and path_ok?(Gem.user_dir, spec)) then
e = Gem::GemNotInHomeException.new \
@@ -201,28 +197,27 @@ class Gem::Uninstaller
raise e
end
- raise Gem::FilePermissionError, spec.installation_path unless
- File.writable?(spec.installation_path)
+ raise Gem::FilePermissionError, spec.base_dir unless
+ File.writable?(spec.base_dir)
FileUtils.rm_rf spec.full_gem_path
- original_platform_name = [
- spec.name, spec.version, spec.original_platform].join '-'
+ # TODO: should this be moved to spec?... I vote eww (also exists in docmgr)
+ old_platform_name = [spec.name,
+ spec.version,
+ spec.original_platform].join '-'
- spec_dir = File.join spec.installation_path, 'specifications'
- gemspec = File.join spec_dir, spec.spec_name
+ gemspec = spec.spec_file
unless File.exist? gemspec then
- gemspec = File.join spec_dir, "#{original_platform_name}.gemspec"
+ gemspec = File.join(File.dirname(gemspec), "#{old_platform_name}.gemspec")
end
FileUtils.rm_rf gemspec
- gem = Gem.cache_gem(spec.file_name, spec.installation_path)
-
- unless File.exist? gem then
- gem = Gem.cache_gem("#{original_platform_name}.gem", spec.installation_path)
- end
+ gem = spec.cache_file
+ gem = File.join(spec.cache_dir, "#{old_platform_name}.gem") unless
+ File.exist? gem
FileUtils.rm_rf gem
@@ -230,14 +225,14 @@ class Gem::Uninstaller
say "Successfully uninstalled #{spec.full_name}"
- list.delete spec
+ Gem::Specification.remove_spec spec
end
##
# Is +spec+ in +gem_dir+?
def path_ok?(gem_dir, spec)
- full_path = File.join gem_dir, 'gems', spec.full_name
+ full_path = File.join gem_dir, 'gems', spec.full_name
original_path = File.join gem_dir, 'gems', spec.original_name
full_path == spec.full_gem_path || original_path == spec.full_gem_path
@@ -246,8 +241,7 @@ class Gem::Uninstaller
def dependencies_ok?(spec)
return true if @force_ignore
- deplist = Gem::DependencyList.from_source_index @source_index
- deplist.add(*@user_index.gems.values) if @user_install
+ deplist = Gem::DependencyList.from_specs
deplist.ok_to_remove?(spec.full_name)
end
@@ -255,11 +249,13 @@ class Gem::Uninstaller
msg = ['']
msg << 'You have requested to uninstall the gem:'
msg << "\t#{spec.full_name}"
- spec.dependent_gems.each do |gem,dep,satlist|
+
+ spec.dependent_gems.each do |dep_spec, dep, satlist|
msg <<
- ("#{gem.name}-#{gem.version} depends on " +
- "[#{dep.name} (#{dep.requirement})]")
+ ("#{dep_spec.name}-#{dep_spec.version} depends on " +
+ "[#{dep.name} (#{dep.requirement})]")
end
+
msg << 'If you remove this gems, one or more dependencies will not be met.'
msg << 'Continue with Uninstall?'
return ask_yes_no(msg.join("\n"), true)
@@ -272,7 +268,4 @@ class Gem::Uninstaller
filename
end
end
-
-
end
-
diff --git a/lib/rubygems/user_interaction.rb b/lib/rubygems/user_interaction.rb
index 87d13da..1dbcf38 100644
--- a/lib/rubygems/user_interaction.rb
+++ b/lib/rubygems/user_interaction.rb
@@ -90,44 +90,40 @@ module Gem::UserInteraction
include Gem::DefaultUserInteraction
- ##
- # :method: alert
+ def alert(*args)
+ ui.alert(*args)
+ end
- ##
- # :method: alert_error
+ def alert_error(*args)
+ ui.alert_error(*args)
+ end
- ##
- # :method: alert_warning
+ def alert_warning(*args)
+ ui.alert_warning(*args)
+ end
- ##
- # :method: ask
+ def ask(*args)
+ ui.ask(*args)
+ end
- ##
- # :method: ask_yes_no
+ def ask_for_password(*args)
+ ui.ask_for_password(*args)
+ end
- ##
- # :method: choose_from_list
+ def ask_yes_no(*args)
+ ui.ask_yes_no(*args)
+ end
- ##
- # :method: say
+ def choose_from_list(*args)
+ ui.choose_from_list(*args)
+ end
- ##
- # :method: terminate_interaction
-
- [:alert,
- :alert_error,
- :alert_warning,
- :ask,
- :ask_for_password,
- :ask_yes_no,
- :choose_from_list,
- :say,
- :terminate_interaction ].each do |methname|
- class_eval %{
- def #{methname}(*args)
- ui.#{methname}(*args)
- end
- }, __FILE__, __LINE__
+ def say(*args)
+ ui.say(*args)
+ end
+
+ def terminate_interaction(*args)
+ ui.terminate_interaction(*args)
end
end
diff --git a/test/rubygems/functional.rb b/test/rubygems/functional.rb
deleted file mode 100644
index 6b7131f..0000000
--- a/test/rubygems/functional.rb
+++ /dev/null
@@ -1,98 +0,0 @@
-######################################################################
-# This file is imported from the rubygems project.
-# DO NOT make modifications in this repo. They _will_ be reverted!
-# File a patch instead and assign it to Ryan Davis or Eric Hodel.
-######################################################################
-
-require 'rubygems'
-require 'minitest/unit'
-require 'test/insure_session'
-require 'rubygems/format'
-require 'rubygems/command_manager'
-
-class FunctionalTest < MiniTest::Unit::TestCase
-
- def setup
- @gem_path = File.expand_path("bin/gem")
- lib_path = File.expand_path("lib")
- @ruby_options = "-I#{lib_path} -I."
- @verbose = false
- end
-
- def test_gem_help_options
- gem_nossl 'help options'
- assert_match(/Usage:/, @out, @err)
- assert_status
- end
-
- def test_gem_help_commands
- gem_nossl 'help commands'
- assert_match(/gem install/, @out)
- assert_status
- end
-
- def test_gem_no_args_shows_help
- gem_nossl
- assert_match(/Usage:/, @out)
- assert_status 1
- end
-
- # This test is disabled because of the insanely long time it takes
- # to time out.
- def xtest_bogus_source_hoses_up_remote_install_but_gem_command_gives_decent_error_message
- @ruby_options << " -rtest/bogussources"
- gem_nossl "install asdf --remote"
- assert_match(/error/im, @err)
- assert_status 1
- end
-
- def test_all_command_helps
- mgr = Gem::CommandManager.new
- mgr.command_names.each do |cmdname|
- gem_nossl "help #{cmdname}"
- assert_match(/Usage: gem #{cmdname}/, @out,
- "should see help for #{cmdname}")
- end
- end
-
- # :section: Help Methods
-
- # Run a gem command without the SSL library.
- def gem_nossl(options="")
- old_options = @ruby_options.dup
- @ruby_options << " -Itest/fake_certlib"
- gem(options)
- ensure
- @ruby_options = old_options
- end
-
- # Run a gem command with the SSL library.
- def gem_withssl(options="")
- gem(options)
- end
-
- # Run a gem command for the functional test.
- def gem(options="")
- shell = Session::Shell.new
- options = options + " --config-file missing_file" if options !~ /--config-file/
- command = "#{Gem.ruby} #{@ruby_options} #{@gem_path} #{options}"
- puts "\n\nCOMMAND: [#{command}]" if @verbose
- @out, @err = shell.execute command
- @status = shell.exit_status
- puts "STATUS: [#{@status}]" if @verbose
- puts "OUTPUT: [#{@out}]" if @verbose
- puts "ERROR: [#{@err}]" if @verbose
- puts "PWD: [#{Dir.pwd}]" if @verbose
- shell.close
- end
-
- private
-
- def assert_status(expected_status=0)
- assert_equal expected_status, @status
- end
-
-end
-
-MiniTest::Unit.autorun
-
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index 118066b..9607711 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -29,12 +29,12 @@ class TestGem < Gem::TestCase
def assert_activate expected, *specs
specs.each do |spec|
case spec
- when Array
- Gem.activate(*spec)
- when String
- Gem.activate spec
+ when String then
+ Gem::Specification.find_by_name(spec).activate
+ when Gem::Specification then
+ spec.activate
else
- Gem.activate spec.name
+ flunk spec.inspect
end
end
@@ -57,17 +57,21 @@ class TestGem < Gem::TestCase
Gem.unresolved_deps.values.map(&:to_s).sort
end
+ # TODO: move these to specification
def test_self_activate_via_require
- new_spec "a", "1", "b" => "= 1"
- new_spec "b", "1", nil, "lib/b/c.rb"
- new_spec "b", "2", nil, "lib/b/c.rb"
+ a1 = new_spec "a", "1", "b" => "= 1"
+ b1 = new_spec "b", "1", nil, "lib/b/c.rb"
+ b2 = new_spec "b", "2", nil, "lib/b/c.rb"
+
+ install_specs a1, b1, b2
- Gem.activate "a", "= 1"
+ a1.activate
require "b/c"
assert_equal %w(a-1 b-1), loaded_spec_names
end
+ # TODO: move these to specification
def test_self_activate_deep_unambiguous
a1 = new_spec "a", "1", "b" => "= 1"
b1 = new_spec "b", "1", "c" => "= 1"
@@ -77,7 +81,7 @@ class TestGem < Gem::TestCase
install_specs a1, b1, b2, c1, c2
- Gem.activate "a", "= 1"
+ a1.activate
assert_equal %w(a-1 b-1 c-1), loaded_spec_names
end
@@ -88,6 +92,7 @@ class TestGem < Gem::TestCase
$LOADED_FEATURES.replace old_loaded_features
end
+ # TODO: move these to specification
def test_self_activate_ambiguous_direct
save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0"
@@ -96,9 +101,10 @@ class TestGem < Gem::TestCase
c1 = new_spec "c", "1"
c2 = new_spec "c", "2"
+ Gem::Specification.reset
install_specs a1, b1, b2, c1, c2
- Gem.activate "a", "= 1"
+ a1.activate
assert_equal %w(a-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names
@@ -109,6 +115,7 @@ class TestGem < Gem::TestCase
end
end
+ # TODO: move these to specification
def test_self_activate_ambiguous_indirect
save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0"
@@ -119,7 +126,7 @@ class TestGem < Gem::TestCase
install_specs a1, b1, b2, c1, c2
- Gem.activate "a", "= 1"
+ a1.activate
assert_equal %w(a-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names
@@ -130,6 +137,7 @@ class TestGem < Gem::TestCase
end
end
+ # TODO: move these to specification
def test_self_activate_ambiguous_unrelated
save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0"
@@ -141,7 +149,7 @@ class TestGem < Gem::TestCase
install_specs a1, b1, b2, c1, c2, d1
- Gem.activate "a", "= 1"
+ a1.activate
assert_equal %w(a-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names
@@ -152,6 +160,7 @@ class TestGem < Gem::TestCase
end
end
+ # TODO: move these to specification
def test_self_activate_ambiguous_indirect_conflict
save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0"
@@ -163,7 +172,7 @@ class TestGem < Gem::TestCase
install_specs a1, a2, b1, b2, c1, c2
- Gem.activate "a", "= 2"
+ a2.activate
assert_equal %w(a-2), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names
@@ -174,13 +183,14 @@ class TestGem < Gem::TestCase
end
end
+ # TODO: move these to specification
def test_require_already_activated
save_loaded_features do
a1 = new_spec "a", "1", nil, "lib/d.rb"
install_specs a1 # , a2, b1, b2, c1, c2
- Gem.activate "a", "= 1"
+ a1.activate
assert_equal %w(a-1), loaded_spec_names
assert_equal [], unresolved_names
@@ -191,6 +201,7 @@ class TestGem < Gem::TestCase
end
end
+ # TODO: move these to specification
def test_require_already_activated_indirect_conflict
save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0"
@@ -202,8 +213,8 @@ class TestGem < Gem::TestCase
install_specs a1, a2, b1, b2, c1, c2
- Gem.activate "a", "= 1"
- Gem.activate "c", "= 1"
+ a1.activate
+ c1.activate
assert_equal %w(a-1 c-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names
@@ -222,11 +233,26 @@ class TestGem < Gem::TestCase
end
end
+ def test_require_does_not_glob
+ save_loaded_features do
+ a1 = new_spec "a", "1", nil, "lib/a1.rb"
+
+ install_specs a1
+
+ assert_raises ::LoadError do
+ require "a*"
+ end
+
+ assert_equal [], loaded_spec_names
+ end
+ end
+
+ # TODO: move these to specification
def test_self_activate_loaded
- util_spec 'foo', '1'
+ foo = util_spec 'foo', '1'
- assert Gem.activate 'foo'
- refute Gem.activate 'foo'
+ assert foo.activate
+ refute foo.activate
end
##
@@ -249,15 +275,16 @@ class TestGem < Gem::TestCase
# [B] ~> 1.0
#
# and should resolve using b-1.0
+ # TODO: move these to specification
def test_self_activate_over
- util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0'
+ a = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0'
util_spec 'b', '1.0'
util_spec 'b', '1.1'
util_spec 'b', '2.0'
util_spec 'c', '1.0', 'b' => '~> 1.0'
- Gem.activate "a"
+ a.activate
assert_equal %w[a-1.0 c-1.0], loaded_spec_names
assert_equal ["b (>= 1.0, ~> 1.0)"], unresolved_names
@@ -412,28 +439,22 @@ class TestGem < Gem::TestCase
assert_activate %w[d-1 e-1], e1, "d"
end
- def test_self_all_load_paths
+ def test_self_available?
util_make_gems
-
- expected = [
- File.join(@gemhome, *%W[gems #{@a1.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@a2.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@a3a.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@b2.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]),
- ]
-
- assert_equal expected, Gem.all_load_paths.sort
+ Deprecate.skip_during do
+ assert(Gem.available?("a"))
+ assert(Gem.available?("a", "1"))
+ assert(Gem.available?("a", ">1"))
+ assert(!Gem.available?("monkeys"))
+ end
end
- def test_self_available?
- util_make_gems
- assert(Gem.available?("a"))
- assert(Gem.available?("a", "1"))
- assert(Gem.available?("a", ">1"))
- assert(!Gem.available?("monkeys"))
+ def test_self_bin_path_no_exec_name
+ e = assert_raises ArgumentError do
+ Gem.bin_path 'a'
+ end
+
+ assert_equal 'you must supply exec_name', e.message
end
def test_self_bin_path_bin_name
@@ -446,16 +467,6 @@ class TestGem < Gem::TestCase
assert_equal @abin_path, Gem.bin_path('a', 'abin', '4')
end
- def test_self_bin_path_name
- util_exec_gem
- assert_equal @exec_path, Gem.bin_path('a')
- end
-
- def test_self_bin_path_name_version
- util_exec_gem
- assert_equal @exec_path, Gem.bin_path('a', nil, '4')
- end
-
def test_self_bin_path_nonexistent_binfile
quick_spec 'a', '2' do |s|
s.executables = ['exec']
@@ -467,14 +478,14 @@ class TestGem < Gem::TestCase
def test_self_bin_path_no_bin_file
quick_spec 'a', '1'
- assert_raises(Gem::Exception) do
+ assert_raises(ArgumentError) do
Gem.bin_path('a', nil, '1')
end
end
def test_self_bin_path_not_found
assert_raises(Gem::GemNotFoundException) do
- Gem.bin_path('non-existent')
+ Gem.bin_path('non-existent', 'blah')
end
end
@@ -482,7 +493,6 @@ class TestGem < Gem::TestCase
util_exec_gem
quick_spec 'a', '10' do |s|
s.executables = []
- s.default_executable = nil
end
# Should not find a-10's non-abin (bug)
assert_equal @abin_path, Gem.bin_path('a', 'abin')
@@ -507,17 +517,12 @@ class TestGem < Gem::TestCase
end
def test_self_clear_paths
- Gem.dir
- Gem.path
- searcher = Gem.searcher
- source_index = Gem.source_index
+ assert_match(/gemhome$/, Gem.dir)
+ assert_match(/gemhome$/, Gem.path.first)
Gem.clear_paths
- assert_equal nil, Gem.instance_variable_get(:@gem_home)
- assert_equal nil, Gem.instance_variable_get(:@gem_path)
- refute_equal searcher, Gem.searcher
- refute_equal source_index.object_id, Gem.source_index.object_id
+ assert_nil Gem::Specification.send(:class_variable_get, :@@all)
end
def test_self_configuration
@@ -540,8 +545,6 @@ class TestGem < Gem::TestCase
install_gem foo
end
- Gem.source_index = nil
-
gem 'foo'
expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo'
@@ -598,7 +601,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories @gemhome
- assert File.directory?(Gem.cache_dir(@gemhome))
+ assert File.directory? File.join(@gemhome, "cache")
end
def test_self_ensure_gem_directories_missing_parents
@@ -610,7 +613,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories gemdir
- assert File.directory?(Gem.cache_dir(gemdir))
+ assert File.directory?(util_cache_dir)
end
unless win_platform? then # only for FS that support write protection
@@ -624,7 +627,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories gemdir
- refute File.exist?(Gem.cache_dir(gemdir))
+ refute File.exist?(util_cache_dir)
ensure
FileUtils.chmod 0600, gemdir
end
@@ -641,7 +644,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories gemdir
- refute File.exist?(Gem.cache_dir(gemdir))
+ refute File.exist? File.join(gemdir, "gems")
ensure
FileUtils.chmod 0600, parent
end
@@ -661,30 +664,26 @@ class TestGem < Gem::TestCase
end
def test_self_find_files
- discover_path = File.join 'lib', 'sff', 'discover.rb'
cwd = File.expand_path("test/rubygems", @@project_dir)
$LOAD_PATH.unshift cwd
- foo1 = quick_gem 'sff', '1' do |s|
- s.files << discover_path
- end
-
- foo2 = quick_gem 'sff', '2' do |s|
- s.files << discover_path
- end
-
- path = File.join 'gems', foo1.full_name, discover_path
- write_file(path) { |fp| fp.puts "# #{path}" }
+ discover_path = File.join 'lib', 'sff', 'discover.rb'
- path = File.join 'gems', foo2.full_name, discover_path
- write_file(path) { |fp| fp.puts "# #{path}" }
+ foo1, foo2 = %w(1 2).map { |version|
+ spec = quick_gem 'sff', version do |s|
+ s.files << discover_path
+ end
- @fetcher = Gem::FakeFetcher.new
- Gem::RemoteFetcher.fetcher = @fetcher
+ write_file(File.join 'gems', spec.full_name, discover_path) do |fp|
+ fp.puts "# #{spec.full_name}"
+ end
- Gem.source_index = util_setup_spec_fetcher foo1, foo2
+ spec
+ }
+ # HACK should be Gem.refresh
Gem.searcher = nil
+ Gem::Specification.reset
expected = [
File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
@@ -698,26 +697,11 @@ class TestGem < Gem::TestCase
assert_equal cwd, $LOAD_PATH.shift
end
- def test_self_latest_load_paths
- util_make_gems
-
- expected = [
- File.join(@gemhome, *%W[gems #{@a3a.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@b2.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]),
- File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]),
- ]
-
- assert_equal expected, Gem.latest_load_paths.sort
- end
-
def test_self_loaded_specs
foo = quick_spec 'foo'
install_gem foo
- Gem.source_index = nil
- Gem.activate 'foo'
+ foo.activate
assert_equal true, Gem.loaded_specs.keys.include?('foo')
end
@@ -738,9 +722,10 @@ class TestGem < Gem::TestCase
orig_APPLE_GEM_HOME = APPLE_GEM_HOME
Object.send :remove_const, :APPLE_GEM_HOME
end
- Gem.instance_variable_set :@gem_path, nil
- assert_equal [Gem.default_path, Gem.dir].flatten, Gem.path
+ Gem.instance_variable_set :@paths, nil
+
+ assert_equal [Gem.default_path, Gem.dir].flatten.uniq, Gem.path
ensure
Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME
end
@@ -771,7 +756,6 @@ class TestGem < Gem::TestCase
end
def test_self_path_ENV_PATH
- Gem.send :set_paths, nil
path_count = Gem.path.size
Gem.clear_paths
@@ -840,29 +824,20 @@ class TestGem < Gem::TestCase
def test_self_refresh
util_make_gems
- a1_spec = File.join @gemhome, "specifications", @a1.spec_name
-
- FileUtils.mv a1_spec, @tempdir
+ a1_spec = @a1.spec_file
+ moved_path = File.join @tempdir, File.basename(a1_spec)
- refute Gem.source_index.gems.include?(@a1.full_name)
-
- FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
+ FileUtils.mv a1_spec, moved_path
Gem.refresh
- assert_includes Gem.source_index.gems, @a1.full_name
- assert_equal nil, Gem.instance_variable_get(:@searcher)
- end
+ refute_includes Gem::Specification.all_names, @a1.full_name
- def test_self_required_location
- util_make_gems
+ FileUtils.mv moved_path, a1_spec
+
+ Gem.refresh
- assert_equal File.join(@tempdir, *%w[gemhome gems c-1.2 lib code.rb]),
- Gem.required_location("c", "code.rb")
- assert_equal File.join(@tempdir, *%w[gemhome gems a-1 lib code.rb]),
- Gem.required_location("a", "code.rb", "< 2")
- assert_equal File.join(@tempdir, *%w[gemhome gems a-2 lib code.rb]),
- Gem.required_location("a", "code.rb", "= 2")
+ assert_includes Gem::Specification.all_names, @a1.full_name
end
def test_self_ruby_escaping_spaces_in_path
@@ -927,19 +902,20 @@ class TestGem < Gem::TestCase
util_restore_RUBY_VERSION
end
- def test_self_searcher
- assert_kind_of Gem::GemPathSearcher, Gem.searcher
- end
-
- def test_self_set_paths
+ def test_self_paths_eq
other = File.join @tempdir, 'other'
path = [@userhome, other].join File::PATH_SEPARATOR
- Gem.send :set_paths, path
+
+ #
+ # FIXME remove after fixing test_case
+ #
+ ENV["GEM_HOME"] = @gemhome
+ Gem.paths = { "GEM_PATH" => path }
assert_equal [@userhome, other, @gemhome], Gem.path
end
- def test_self_set_paths_nonexistent_home
+ def test_self_paths_eq_nonexistent_home
ENV['GEM_HOME'] = @gemhome
Gem.clear_paths
@@ -947,19 +923,37 @@ class TestGem < Gem::TestCase
ENV['HOME'] = other
- Gem.send :set_paths, other
+ Gem.paths = { "GEM_PATH" => other }
assert_equal [other, @gemhome], Gem.path
end
def test_self_source_index
- assert_kind_of Gem::SourceIndex, Gem.source_index
+ Deprecate.skip_during do
+ assert_kind_of Gem::SourceIndex, Gem.source_index
+ end
end
def test_self_sources
assert_equal %w[http://gems.example.com/], Gem.sources
end
+ def test_self_try_activate_missing_dep
+ a = util_spec 'a', '1.0', 'b' => '>= 1.0'
+
+ a_file = File.join a.gem_dir, 'lib', 'a_file.rb'
+
+ write_file a_file do |io|
+ io.puts '# a_file.rb'
+ end
+
+ e = assert_raises Gem::LoadError do
+ Gem.try_activate 'a_file'
+ end
+
+ assert_match %r%Could not find b %, e.message
+ end
+
def test_ssl_available_eh
orig_Gem_ssl_available = Gem.ssl_available?
@@ -994,20 +988,6 @@ class TestGem < Gem::TestCase
end
end
- def test_self_cache_dir
- util_ensure_gem_dirs
-
- assert_equal File.join(@gemhome, 'cache'), Gem.cache_dir
- assert_equal File.join(@userhome, '.gem', Gem.ruby_engine, Gem::ConfigMap[:ruby_version], 'cache'), Gem.cache_dir(Gem.user_dir)
- end
-
- def test_self_cache_gem
- util_ensure_gem_dirs
-
- assert_equal File.join(@gemhome, 'cache', 'test.gem'), Gem.cache_gem('test.gem')
- assert_equal File.join(@userhome, '.gem', Gem.ruby_engine, Gem::ConfigMap[:ruby_version], 'cache', 'test.gem'), Gem.cache_gem('test.gem', Gem.user_dir)
- end
-
if Gem.win_platform? then
def test_self_user_home_userprofile
skip 'Ruby 1.9 properly handles ~ path expansion' unless '1.9' > RUBY_VERSION
@@ -1069,8 +1049,8 @@ class TestGem < Gem::TestCase
install_gem foo
end
- Gem.source_index = nil
Gem.searcher = nil
+ Gem::Specification.reset
gem 'foo'
@@ -1114,6 +1094,10 @@ class TestGem < Gem::TestCase
def util_ensure_gem_dirs
Gem.ensure_gem_subdirectories @gemhome
+
+ #
+ # FIXME what does this solve precisely? -ebh
+ #
@additional.each do |dir|
Gem.ensure_gem_subdirectories @gemhome
end
@@ -1121,7 +1105,6 @@ class TestGem < Gem::TestCase
def util_exec_gem
spec, _ = quick_spec 'a', '4' do |s|
- s.default_executable = 'exec'
s.executables = ['exec', 'abin']
end
@@ -1164,5 +1147,9 @@ class TestGem < Gem::TestCase
Gem::Commands.send :remove_const, :InterruptCommand if
Gem::Commands.const_defined? :InterruptCommand
end
+
+ def util_cache_dir
+ File.join Gem.dir, "cache"
+ end
end
diff --git a/test/rubygems/test_gem_builder.rb b/test/rubygems/test_gem_builder.rb
index f95472f..5895b5f 100644
--- a/test/rubygems/test_gem_builder.rb
+++ b/test/rubygems/test_gem_builder.rb
@@ -6,6 +6,7 @@
require 'rubygems/test_case'
require 'rubygems/builder'
+require 'rubygems/package'
class TestGemBuilder < Gem::TestCase
@@ -29,5 +30,21 @@ class TestGemBuilder < Gem::TestCase
end
end
-end
+ def test_build_specification_result
+ util_make_gems
+
+ spec = build_gem_and_yield_spec @a1
+
+ assert_operator @a1, :eql?, spec
+ end
+ def build_gem_and_yield_spec(spec)
+ builder = Gem::Builder.new spec
+
+ spec = Dir.chdir @tempdir do
+ FileUtils.mkdir 'lib'
+ File.open('lib/code.rb', 'w') { |f| f << "something" }
+ Gem::Package.open(File.open(builder.build, 'rb')) { |x| x.metadata }
+ end
+ end
+end
diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb
index 3769c25..54b26e1 100644
--- a/test/rubygems/test_gem_command_manager.rb
+++ b/test/rubygems/test_gem_command_manager.rb
@@ -29,6 +29,7 @@ class TestGemCommandManager < Gem::TestCase
end
ensure
$:.replace old_load_path
+ Gem::CommandManager.reset
end
def test_run_crash_command
@@ -46,6 +47,7 @@ class TestGemCommandManager < Gem::TestCase
end
ensure
$:.replace old_load_path
+ @command_manager.unregister_command :crash
end
def test_process_args_bad_arg
diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb
index 5c38a1a..d4d7c29 100644
--- a/test/rubygems/test_gem_commands_build_command.rb
+++ b/test/rubygems/test_gem_commands_build_command.rb
@@ -40,10 +40,38 @@ class TestGemCommandsBuildCommand < Gem::TestCase
util_test_build_gem @gem, gemspec_file
end
- def test_execute_bad_gem
+ def test_execute_bad_spec
+ @gem.date = "2010-11-08"
+
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ File.open gemspec_file, 'w' do |gs|
+ gs.write @gem.to_ruby.sub(/11-08/, "11-8")
+ end
+
+ @cmd.options[:args] = [gemspec_file]
+
+ out, err = use_ui @ui do
+ capture_io do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+ end
+
+ assert_equal "", out
+ assert_match(/invalid date format in specification/, err)
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: Error loading gemspec. Aborting.\n", @ui.error
+ end
+
+ def test_execute_missing_file
@cmd.options[:args] = %w[some_gem]
use_ui @ui do
- @cmd.execute
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
end
assert_equal '', @ui.output
@@ -67,7 +95,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
assert_equal [], output
assert_equal '', @ui.error
- gem_file = File.join @tempdir, gem.file_name
+ gem_file = File.join @tempdir, File.basename(gem.cache_file)
assert File.exist?(gem_file)
spec = Gem::Format.from_file_by_path(gem_file).spec
diff --git a/test/rubygems/test_gem_commands_cleanup_command.rb b/test/rubygems/test_gem_commands_cleanup_command.rb
new file mode 100644
index 0000000..14224c4
--- /dev/null
+++ b/test/rubygems/test_gem_commands_cleanup_command.rb
@@ -0,0 +1,57 @@
+######################################################################
+# This file is imported from the rubygems project.
+# DO NOT make modifications in this repo. They _will_ be reverted!
+# File a patch instead and assign it to Ryan Davis or Eric Hodel.
+######################################################################
+
+require 'rubygems/test_case'
+require 'rubygems/commands/cleanup_command'
+
+class TestGemCommandsCleanupCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::CleanupCommand.new
+
+ @a_1 = quick_spec 'a', 1
+ @a_2 = quick_spec 'a', 2
+
+ install_gem @a_1
+ install_gem @a_2
+ end
+
+ def test_execute
+ @cmd.options[:args] = %w[a]
+
+ @cmd.execute
+
+ refute_path_exists @a_1.gem_dir
+ end
+
+ def test_execute_all
+ @b_1 = quick_spec 'b', 1
+ @b_2 = quick_spec 'b', 2
+
+ install_gem @b_1
+ install_gem @b_2
+
+ @cmd.options[:args] = []
+
+ @cmd.execute
+
+ refute_path_exists @a_1.gem_dir
+ refute_path_exists @b_1.gem_dir
+ end
+
+ def test_execute_dry_run
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:dryrun] = true
+
+ @cmd.execute
+
+ assert_path_exists @a_1.gem_dir
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb
index 6b9750e..cf927e7 100644
--- a/test/rubygems/test_gem_commands_contents_command.rb
+++ b/test/rubygems/test_gem_commands_contents_command.rb
@@ -15,11 +15,18 @@ class TestGemCommandsContentsCommand < Gem::TestCase
@cmd = Gem::Commands::ContentsCommand.new
end
+ def gem name
+ spec = quick_gem name do |gem|
+ gem.files = %W[lib/#{name}.rb Rakefile]
+ end
+ write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
+ write_file File.join(*%W[gems #{spec.full_name} Rakefile])
+ end
+
def test_execute
@cmd.options[:args] = %w[foo]
- quick_gem 'foo' do |gem|
- gem.files = %w[lib/foo.rb Rakefile]
- end
+
+ gem 'foo'
use_ui @ui do
@cmd.execute
@@ -33,13 +40,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase
def test_execute_all
@cmd.options[:all] = true
- quick_gem 'foo' do |gem|
- gem.files = %w[lib/foo.rb Rakefile]
- end
-
- quick_gem 'bar' do |gem|
- gem.files = %w[lib/bar.rb Rakefile]
- end
+ gem 'foo'
+ gem 'bar'
use_ui @ui do
@cmd.execute
@@ -67,13 +69,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase
def test_execute_exact_match
@cmd.options[:args] = %w[foo]
- quick_gem 'foo' do |gem|
- gem.files = %w[lib/foo.rb Rakefile]
- end
-
- quick_gem 'foo_bar' do |gem|
- gem.files = %w[lib/foo_bar.rb Rakefile]
- end
+ gem 'foo'
+ gem 'bar'
use_ui @ui do
@cmd.execute
@@ -88,9 +85,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
@cmd.options[:args] = %w[foo]
@cmd.options[:lib_only] = true
- quick_gem 'foo' do |gem|
- gem.files = %w[lib/foo.rb Rakefile]
- end
+ gem 'foo'
use_ui @ui do
@cmd.execute
@@ -104,13 +99,9 @@ class TestGemCommandsContentsCommand < Gem::TestCase
def test_execute_multiple
@cmd.options[:args] = %w[foo bar]
- quick_gem 'foo' do |gem|
- gem.files = %w[lib/foo.rb Rakefile]
- end
- quick_gem 'bar' do |gem|
- gem.files = %w[lib/bar.rb Rakefile]
- end
+ gem 'foo'
+ gem 'bar'
use_ui @ui do
@cmd.execute
@@ -126,17 +117,15 @@ class TestGemCommandsContentsCommand < Gem::TestCase
@cmd.options[:args] = %w[foo]
@cmd.options[:prefix] = false
- quick_gem 'foo' do |gem|
- gem.files = %w[lib/foo.rb Rakefile]
- end
+ gem 'foo'
use_ui @ui do
@cmd.execute
end
expected = <<-EOF
-lib/foo.rb
Rakefile
+lib/foo.rb
EOF
assert_equal expected, @ui.output
diff --git a/test/rubygems/test_gem_commands_dependency_command.rb b/test/rubygems/test_gem_commands_dependency_command.rb
index 665cd98..d3f2b68 100644
--- a/test/rubygems/test_gem_commands_dependency_command.rb
+++ b/test/rubygems/test_gem_commands_dependency_command.rb
@@ -24,8 +24,6 @@ class TestGemCommandsDependencyCommand < Gem::TestCase
gem.add_dependency 'baz', '> 1'
end
- Gem.source_index = nil
-
@cmd.options[:args] = %w[foo]
use_ui @ui do
@@ -38,8 +36,6 @@ class TestGemCommandsDependencyCommand < Gem::TestCase
end
def test_execute_no_args
- Gem.source_index = nil
-
@cmd.options[:args] = []
use_ui @ui do
@@ -99,8 +95,6 @@ Gem pl-1-x86-linux
end
def test_execute_regexp
- Gem.source_index = nil
-
@cmd.options[:args] = %w[/[ab]/]
use_ui @ui do
@@ -136,8 +130,6 @@ Gem b-2
gem.add_dependency 'foo'
end
- Gem.source_index = nil
-
@cmd.options[:args] = %w[foo]
@cmd.options[:reverse_dependencies] = true
@@ -199,14 +191,31 @@ ERROR: Only reverse dependencies for local gems are supported.
assert_equal '', @ui.error
end
+ def test_execute_remote_version
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher @a1, @a2
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:domain] = :remote
+ @cmd.options[:version] = req '= 1'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem a-1\n\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
def test_execute_prerelease
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
+ util_clear_gems
util_setup_spec_fetcher @a2_pre
- FileUtils.rm File.join(@gemhome, 'specifications', @a2_pre.spec_name)
-
@cmd.options[:args] = %w[a]
@cmd.options[:domain] = :remote
@cmd.options[:prerelease] = true
diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb
index 173a335..926e9e9 100644
--- a/test/rubygems/test_gem_commands_fetch_command.rb
+++ b/test/rubygems/test_gem_commands_fetch_command.rb
@@ -22,7 +22,7 @@ class TestGemCommandsFetchCommand < Gem::TestCase
util_setup_spec_fetcher @a2
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
- File.read(Gem.cache_gem(@a2.file_name, @gemhome))
+ File.read(@a2.cache_file)
@cmd.options[:args] = [@a2.name]
@@ -38,12 +38,13 @@ class TestGemCommandsFetchCommand < Gem::TestCase
def test_execute_prerelease
util_setup_fake_fetcher true
+ util_clear_gems
util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
- File.read(Gem.cache_gem(@a2.file_name, @gemhome))
+ File.read(@a2.cache_file)
@fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
- File.read(Gem.cache_gem(@a2_pre.file_name, @gemhome))
+ File.read(@a2_pre.cache_file)
@cmd.options[:args] = [@a2.name]
@cmd.options[:prerelease] = true
@@ -63,7 +64,7 @@ class TestGemCommandsFetchCommand < Gem::TestCase
util_setup_spec_fetcher @a1, @a2
@fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] =
- File.read(Gem.cache_gem(@a1.file_name, @gemhome))
+ File.read(@a1.cache_file)
@cmd.options[:args] = [@a2.name]
@cmd.options[:version] = Gem::Requirement.new '1'
diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb
new file mode 100644
index 0000000..acfc2da
--- /dev/null
+++ b/test/rubygems/test_gem_commands_help_command.rb
@@ -0,0 +1,64 @@
+######################################################################
+# This file is imported from the rubygems project.
+# DO NOT make modifications in this repo. They _will_ be reverted!
+# File a patch instead and assign it to Ryan Davis or Eric Hodel.
+######################################################################
+
+require "rubygems"
+require "rubygems/test_case"
+require "rubygems/commands/help_command"
+require "rubygems/format"
+require "rubygems/command_manager"
+
+class TestGemCommandsHelpCommand < Gem::TestCase
+ def setup
+ super
+
+ @cmd = Gem::Commands::HelpCommand.new
+ end
+
+ def test_gem_help_bad
+ util_gem 'bad' do |out, err|
+ assert_equal('', out)
+ assert_match(/Unknown command bad. Try gem help commands\n/, err)
+ end
+ end
+
+ def test_gem_help_platforms
+ util_gem 'platforms' do |out, err|
+ assert_match(/x86-freebsd/, out)
+ assert_equal '', err
+ end
+ end
+
+ def test_gem_help_commands
+ mgr = Gem::CommandManager.new
+
+ util_gem 'commands' do |out, err|
+ mgr.command_names.each do |cmd|
+ assert_match(/\s+#{cmd}\s+\S+/, out)
+ end
+ assert_equal '', err
+ end
+ end
+
+ def test_gem_no_args_shows_help
+ util_gem do |out, err|
+ assert_match(/Usage:/, out)
+ assert_match(/gem install/, out)
+ assert_equal '', err
+ end
+ end
+
+ def util_gem *args
+ @cmd.options[:args] = args
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ yield @ui.output, @ui.error
+ end
+end
diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb
index adc66aa..522731b 100644
--- a/test/rubygems/test_gem_commands_install_command.rb
+++ b/test/rubygems/test_gem_commands_install_command.rb
@@ -24,13 +24,13 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
def test_execute_exclude_prerelease
- util_setup_fake_fetcher(:prerelease)
- util_setup_spec_fetcher @a2, @a2_pre
+ util_setup_fake_fetcher :prerelease
+ util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
- read_binary(Gem.cache_gem(@a2.file_name, @gemhome))
+ read_binary(@a2.cache_file)
@fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
- read_binary(Gem.cache_gem(@a2_pre.file_name, @gemhome))
+ read_binary(@a2_pre.cache_file)
@cmd.options[:args] = [@a2.name]
@@ -46,13 +46,13 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
def test_execute_explicit_version_includes_prerelease
- util_setup_fake_fetcher(:prerelease)
- util_setup_spec_fetcher @a2, @a2_pre
+ util_setup_fake_fetcher :prerelease
+ util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
- read_binary(Gem.cache_gem(@a2.file_name, @gemhome))
+ read_binary(@a2.cache_file)
@fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
- read_binary(Gem.cache_gem(@a2_pre.file_name, @gemhome))
+ read_binary(@a2_pre.cache_file)
@cmd.handle_options [@a2_pre.name, '--version', @a2_pre.version.to_s,
"--no-ri", "--no-rdoc"]
@@ -92,7 +92,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
util_setup_fake_fetcher
@cmd.options[:domain] = :local
- FileUtils.mv Gem.cache_gem(@a2.file_name, @gemhome), @tempdir
+ FileUtils.mv @a2.cache_file, @tempdir
@cmd.options[:args] = [@a2.name]
@@ -121,15 +121,15 @@ class TestGemCommandsInstallCommand < Gem::TestCase
util_setup_fake_fetcher
@cmd.options[:user_install] = false
- FileUtils.mv Gem.cache_gem(@a2.file_name, @gemhome), @tempdir
+ FileUtils.mv @a2.cache_file, @tempdir
@cmd.options[:args] = [@a2.name]
use_ui @ui do
orig_dir = Dir.pwd
begin
- File.chmod 0755, @userhome
- File.chmod 0555, @gemhome
+ FileUtils.chmod 0755, @userhome
+ FileUtils.chmod 0555, @gemhome
Dir.chdir @tempdir
assert_raises Gem::FilePermissionError do
@@ -137,7 +137,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
ensure
Dir.chdir orig_dir
- File.chmod 0755, @gemhome
+ FileUtils.chmod 0755, @gemhome
end
end
end
@@ -208,13 +208,14 @@ ERROR: Possible alternatives: non_existent_with_hint
end
def test_execute_prerelease
- util_setup_fake_fetcher(:prerelease)
+ util_setup_fake_fetcher :prerelease
+ util_clear_gems
util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
- read_binary(Gem.cache_gem(@a2.file_name, @gemhome))
+ read_binary(@a2.cache_file)
@fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
- read_binary(Gem.cache_gem(@a2_pre.file_name, @gemhome))
+ read_binary(@a2_pre.cache_file)
@cmd.options[:prerelease] = true
@cmd.options[:args] = [@a2_pre.name]
@@ -235,10 +236,10 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.options[:generate_ri] = true
util_setup_fake_fetcher
- util_setup_spec_fetcher @a2
+ util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
- read_binary(Gem.cache_gem(@a2.file_name, @gemhome))
+ read_binary(@a2.cache_file)
@cmd.options[:args] = [@a2.name]
@@ -265,9 +266,9 @@ ERROR: Possible alternatives: non_existent_with_hint
util_setup_fake_fetcher
@cmd.options[:domain] = :local
- FileUtils.mv Gem.cache_gem(@a2.file_name, @gemhome), @tempdir
+ FileUtils.mv @a2.cache_file, @tempdir
- FileUtils.mv Gem.cache_gem(@b2.file_name, @gemhome), @tempdir
+ FileUtils.mv @b2.cache_file, @tempdir
@cmd.options[:args] = [@a2.name, @b2.name]
@@ -293,10 +294,10 @@ ERROR: Possible alternatives: non_existent_with_hint
def test_execute_conservative
util_setup_fake_fetcher
- util_setup_spec_fetcher @b2
+ util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@b2.file_name}"] =
- read_binary(Gem.cache_gem(@b2.file_name, @gemhome))
+ read_binary(@b2.cache_file)
uninstall_gem(@b2)
@@ -308,16 +309,16 @@ ERROR: Possible alternatives: non_existent_with_hint
orig_dir = Dir.pwd
begin
Dir.chdir @tempdir
- e = assert_raises Gem::SystemExitException do
+ assert_raises Gem::SystemExitException do
@cmd.execute
end
- assert_equal 0, e.exit_code
ensure
Dir.chdir orig_dir
end
end
out = @ui.output.split "\n"
+ assert_equal "", @ui.error
assert_equal "Successfully installed #{@b2.full_name}", out.shift
assert_equal "1 gem installed", out.shift
assert out.empty?, out.inspect
diff --git a/test/rubygems/test_gem_commands_list_command.rb b/test/rubygems/test_gem_commands_list_command.rb
index 9a56ebc..1339737 100644
--- a/test/rubygems/test_gem_commands_list_command.rb
+++ b/test/rubygems/test_gem_commands_list_command.rb
@@ -26,16 +26,13 @@ class TestGemCommandsListCommand < Gem::TestCase
def test_execute_installed
@cmd.handle_options %w[c --installed]
- e = assert_raises Gem::SystemExitException do
+ assert_raises Gem::MockGemUi::SystemExitException do
use_ui @ui do
@cmd.execute
end
end
- assert_equal 0, e.exit_code
-
assert_equal "true\n", @ui.output
-
assert_equal '', @ui.error
end
diff --git a/test/rubygems/test_gem_commands_outdated_command.rb b/test/rubygems/test_gem_commands_outdated_command.rb
index 632e9a5..ae15efe 100644
--- a/test/rubygems/test_gem_commands_outdated_command.rb
+++ b/test/rubygems/test_gem_commands_outdated_command.rb
@@ -20,24 +20,25 @@ class TestGemCommandsOutdatedCommand < Gem::TestCase
end
def test_execute
- quick_gem 'foo', '0.1'
- quick_gem 'foo', '0.2'
remote_10 = quick_spec 'foo', '1.0'
remote_20 = quick_spec 'foo', '2.0'
- remote_spec_file = File.join @gemhome, 'specifications', remote_10.spec_name
- remote_spec_file = File.join @gemhome, 'specifications', remote_20.spec_name
-
- @fetcher = Gem::FakeFetcher.new
- Gem::RemoteFetcher.fetcher = @fetcher
+ Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
+ util_clear_gems
util_setup_spec_fetcher remote_10, remote_20
- use_ui @ui do @cmd.execute end
+ quick_gem 'foo', '0.1'
+ quick_gem 'foo', '0.2'
+
+ Gem::Specification.reset
+
+ use_ui @ui do
+ @cmd.execute
+ end
assert_equal "foo (0.2 < 2.0)\n", @ui.output
assert_equal "", @ui.error
end
-
end
diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb
index 4decdf8..aa1f3bf 100644
--- a/test/rubygems/test_gem_commands_pristine_command.rb
+++ b/test/rubygems/test_gem_commands_pristine_command.rb
@@ -16,8 +16,8 @@ class TestGemCommandsPristineCommand < Gem::TestCase
def test_execute
a = quick_spec 'a' do |s| s.executables = %w[foo] end
- FileUtils.mkdir_p File.join(@tempdir, 'bin')
- File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp|
+
+ write_file File.join(@tempdir, 'bin', 'foo') do |fp|
fp.puts "#!/usr/bin/ruby"
end
@@ -25,7 +25,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
foo_path = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo'
- File.open foo_path, 'w' do |io|
+ write_file foo_path do |io|
io.puts 'I changed it!'
end
@@ -39,15 +39,14 @@ class TestGemCommandsPristineCommand < Gem::TestCase
out = @ui.output.split "\n"
- assert_equal "Restoring gem(s) to pristine condition...", out.shift
+ assert_equal "Restoring gems to pristine condition...", out.shift
assert_equal "Restored #{a.full_name}", out.shift
assert_empty out, out.inspect
end
def test_execute_all
a = quick_spec 'a' do |s| s.executables = %w[foo] end
- FileUtils.mkdir_p File.join(@tempdir, 'bin')
- File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp|
+ write_file File.join(@tempdir, 'bin', 'foo') do |fp|
fp.puts "#!/usr/bin/ruby"
end
@@ -67,35 +66,106 @@ class TestGemCommandsPristineCommand < Gem::TestCase
out = @ui.output.split "\n"
- assert_equal "Restoring gem(s) to pristine condition...", out.shift
+ assert_equal "Restoring gems to pristine condition...", out.shift
assert_equal "Restored #{a.full_name}", out.shift
assert_empty out, out.inspect
end
- def test_execute_missing_cache_gem
- a = quick_spec 'a' do |s|
- s.executables = %w[foo]
+ def test_execute_no_exetension
+ a = quick_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end
+
+ ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb'
+ write_file ext_path do |io|
+ io.write '# extconf.rb'
end
- FileUtils.mkdir_p File.join(@tempdir, 'bin')
+ util_build_gem a
- File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp|
- fp.puts "#!/usr/bin/ruby"
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:extensions] = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal 'Restoring gems to pristine condition...', out.shift
+ assert_equal "Skipped #{a.full_name}, it needs to compile an extension",
+ out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_many
+ a = quick_spec 'a'
+ b = quick_spec 'b'
+
+ install_gem a
+ install_gem b
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ @cmd.execute
end
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gems to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_equal "Restored #{b.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_many_multi_repo
+ a = quick_spec 'a'
install_gem a
- a_data = nil
- open File.join(@gemhome, 'cache', a.file_name), 'rb' do |fp|
- a_data = fp.read
+ Gem.clear_paths
+ gemhome2 = File.join @tempdir, 'gemhome2'
+ Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
+
+ b = quick_spec 'b'
+ install_gem b
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gems to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_equal "Restored #{b.full_name}", out.shift
+ assert_empty out, out.inspect
+
+ assert_path_exists File.join(@gemhome, "gems", 'a-2')
+ refute_path_exists File.join(gemhome2, "gems", 'a-2')
+ assert_path_exists File.join(gemhome2, "gems", 'b-2')
+ refute_path_exists File.join(@gemhome, "gems", 'b-2')
+ end
+
+ def test_execute_missing_cache_gem
+ a_2 = quick_spec 'a', 2
+ a_3 = quick_spec 'a', 3
+
+ install_gem a_2
+ install_gem a_3
+
+ a_2_data = nil
+ open File.join(@gemhome, 'cache', a_2.file_name), 'rb' do |fp|
+ a_2_data = fp.read
end
util_setup_fake_fetcher
- util_setup_spec_fetcher a
+ util_setup_spec_fetcher a_2
- Gem::RemoteFetcher.fetcher.data["http://gems.example.com/gems/#{a.file_name}"] = a_data
+ url = "http://gems.example.com/gems/#{a_2.file_name}"
+ Gem::RemoteFetcher.fetcher.data[url] = a_2_data
- FileUtils.rm Gem.cache_gem(a.file_name, @gemhome)
+ FileUtils.rm a_2.cache_file
@cmd.options[:args] = %w[a]
@@ -106,11 +176,12 @@ class TestGemCommandsPristineCommand < Gem::TestCase
out = @ui.output.split "\n"
[
- "Restoring gem\(s\) to pristine condition...",
+ "Restoring gems to pristine condition...",
"Restored a-1",
"Cached gem for a-2 not found, attempting to fetch...",
"Restored a-2",
- "Restored a-3.a"
+ "Restored a-3.a",
+ "Restored a-3",
].each do |line|
assert_equal line, out.shift
end
@@ -127,7 +198,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
end
end
- assert_match %r|specify a gem name|, e.message
+ assert_match %r|at least one gem name|, e.message
end
end
diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb
index 917407d..7aa7109 100644
--- a/test/rubygems/test_gem_commands_push_command.rb
+++ b/test/rubygems/test_gem_commands_push_command.rb
@@ -21,7 +21,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
super
@gems_dir = File.join @tempdir, 'gems'
- @cache_dir = Gem.cache_dir @gemhome
+ @cache_dir = File.join @gemhome, "cache"
FileUtils.mkdir @gems_dir
diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb
index 91868b8..4f06968 100644
--- a/test/rubygems/test_gem_commands_query_command.rb
+++ b/test/rubygems/test_gem_commands_query_command.rb
@@ -15,8 +15,8 @@ class TestGemCommandsQueryCommand < Gem::TestCase
@cmd = Gem::Commands::QueryCommand.new
util_setup_fake_fetcher
-
- @si = util_setup_spec_fetcher @a1, @a2, @pl1, @a3a
+ util_clear_gems
+ util_setup_spec_fetcher @a1, @a2, @pl1, @a3a
@fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
raise Gem::RemoteFetcher::FetchError
@@ -48,7 +48,8 @@ pl (1 i386-linux)
@a1.platform = 'x86-linux'
@a2.platform = 'universal-darwin'
- @si = util_setup_spec_fetcher @a1, @a1r, @a2, @b2, @pl1
+ util_clear_gems
+ util_setup_spec_fetcher @a1, @a1r, @a2, @b2, @pl1
@cmd.handle_options %w[-r -a]
@@ -113,7 +114,8 @@ pl (1 i386-linux)
@a2.homepage = 'http://a.example.com/'
@a2.rubyforge_project = 'rubygems'
- @si = util_setup_spec_fetcher @a1, @a2, @pl1
+ util_clear_gems
+ util_setup_spec_fetcher @a1, @a2, @pl1
@cmd.handle_options %w[-r -d]
@@ -154,7 +156,8 @@ pl (1)
@a2.rubyforge_project = 'rubygems'
@a2.platform = 'universal-darwin'
- @si = util_setup_spec_fetcher @a1, @a2, @pl1
+ util_clear_gems
+ util_setup_spec_fetcher @a1, @a2, @pl1
@cmd.handle_options %w[-r -d]
@@ -190,25 +193,22 @@ pl (1)
end
def test_execute_installed
- @cmd.handle_options %w[-n c --installed]
+ @cmd.handle_options %w[-n a --installed]
- e = assert_raises Gem::SystemExitException do
+ assert_raises Gem::MockGemUi::SystemExitException do
use_ui @ui do
@cmd.execute
end
end
- assert_equal 0, e.exit_code
-
assert_equal "true\n", @ui.output
-
assert_equal '', @ui.error
end
def test_execute_installed_no_name
@cmd.handle_options %w[--installed]
- e = assert_raises Gem::SystemExitException do
+ e = assert_raises Gem::MockGemUi::TermError do
use_ui @ui do
@cmd.execute
end
@@ -223,7 +223,7 @@ pl (1)
def test_execute_installed_not_installed
@cmd.handle_options %w[-n not_installed --installed]
- e = assert_raises Gem::SystemExitException do
+ e = assert_raises Gem::MockGemUi::TermError do
use_ui @ui do
@cmd.execute
end
@@ -236,9 +236,9 @@ pl (1)
end
def test_execute_installed_version
- @cmd.handle_options %w[-n c --installed --version 1.2]
+ @cmd.handle_options %w[-n a --installed --version 2]
- e = assert_raises Gem::SystemExitException do
+ assert_raises Gem::MockGemUi::SystemExitException do
use_ui @ui do
@cmd.execute
end
@@ -246,14 +246,12 @@ pl (1)
assert_equal "true\n", @ui.output
assert_equal '', @ui.error
-
- assert_equal 0, e.exit_code
end
def test_execute_installed_version_not_installed
@cmd.handle_options %w[-n c --installed --version 2]
- e = assert_raises Gem::SystemExitException do
+ e = assert_raises Gem::MockGemUi::TermError do
use_ui @ui do
@cmd.execute
end
@@ -265,65 +263,6 @@ pl (1)
assert_equal 1, e.exit_code
end
- def test_execute_local_details
- @a3a.summary = 'This is a lot of text. ' * 4
- @a3a.authors = ['Abraham Lincoln', 'Hirohito']
- @a3a.homepage = 'http://a.example.com/'
- @a3a.rubyforge_project = 'rubygems'
-
- @cmd.handle_options %w[--local --details]
-
- use_ui @ui do
- @cmd.execute
- end
-
- expected = <<-EOF
-
-*** LOCAL GEMS ***
-
-a (3.a, 2, 1)
- Author: A User
- Homepage: http://example.com
- Installed at (3.a): #{@gemhome}
- (2): #{@gemhome}
- (1): #{@gemhome}
-
- this is a summary
-
-a_evil (9)
- Author: A User
- Homepage: http://example.com
- Installed at: #{@gemhome}
-
- this is a summary
-
-b (2)
- Author: A User
- Homepage: http://example.com
- Installed at: #{@gemhome}
-
- this is a summary
-
-c (1.2)
- Author: A User
- Homepage: http://example.com
- Installed at: #{@gemhome}
-
- this is a summary
-
-pl (1)
- Platform: i386-linux
- Author: A User
- Homepage: http://example.com
- Installed at: #{@gemhome}
-
- this is a summary
- EOF
-
- assert_equal expected, @ui.output
- assert_equal '', @ui.error
- end
-
def test_execute_local_notty
@cmd.handle_options %w[]
@@ -335,9 +274,6 @@ pl (1)
expected = <<-EOF
a (3.a, 2, 1)
-a_evil (9)
-b (2)
-c (1.2)
pl (1 i386-linux)
EOF
@@ -412,9 +348,6 @@ a (3.a)
*** LOCAL GEMS ***
a (3.a, 2, 1)
-a_evil (9)
-b (2)
-c (1.2)
pl (1 i386-linux)
EOF
diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb
index 40449be..7dea797 100644
--- a/test/rubygems/test_gem_commands_sources_command.rb
+++ b/test/rubygems/test_gem_commands_sources_command.rb
@@ -42,12 +42,11 @@ class TestGemCommandsSourcesCommand < Gem::TestCase
def test_execute_add
util_setup_fake_fetcher
- si = Gem::SourceIndex.new
- si.add_spec @a1
+ install_specs @a1
- specs = si.map do |_, spec|
+ specs = Gem::Specification.map { |spec|
[spec.name, spec.version, spec.original_platform]
- end
+ }
specs_dump_gz = StringIO.new
Zlib::GzipWriter.wrap specs_dump_gz do |io|
@@ -187,18 +186,18 @@ beta-gems.example.com is not a URI
@cmd.handle_options %w[--update]
util_setup_fake_fetcher
- source_index = util_setup_spec_fetcher @a1
+ util_setup_spec_fetcher @a1
- specs = source_index.map do |name, spec|
+ specs = Gem::Specification.map { |spec|
[spec.name, spec.version, spec.original_platform]
- end
+ }
@fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] =
util_gzip Marshal.dump(specs)
- latest_specs = source_index.latest_specs.map do |spec|
+ latest_specs = Gem::Specification.latest_specs.map { |spec|
[spec.name, spec.version, spec.original_platform]
- end
+ }
@fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
util_gzip Marshal.dump(latest_specs)
diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb
index 767992f..512b9f5 100644
--- a/test/rubygems/test_gem_commands_specification_command.rb
+++ b/test/rubygems/test_gem_commands_specification_command.rb
@@ -17,7 +17,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
def test_execute
foo = quick_spec 'foo'
- Gem.source_index.add_spec foo
+
+ install_specs foo
@cmd.options[:args] = %w[foo]
@@ -77,8 +78,9 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
def test_execute_field
- foo = quick_spec 'foo'
- Gem.source_index.add_spec foo
+ foo = new_spec 'foo', '2'
+
+ install_specs foo
@cmd.options[:args] = %w[foo name]
@@ -90,8 +92,9 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
def test_execute_marshal
- foo = quick_spec 'foo'
- Gem.source_index.add_spec foo
+ foo = new_spec 'foo', '2'
+
+ install_specs foo
@cmd.options[:args] = %w[foo]
@cmd.options[:format] = :marshal
@@ -127,7 +130,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
def test_execute_ruby
foo = quick_spec 'foo'
- Gem.source_index.add_spec foo
+
+ install_specs foo
@cmd.options[:args] = %w[foo]
@cmd.options[:format] = :ruby
diff --git a/test/rubygems/test_gem_commands_stale_command.rb b/test/rubygems/test_gem_commands_stale_command.rb
index d5aad6c..05cc9d2 100644
--- a/test/rubygems/test_gem_commands_stale_command.rb
+++ b/test/rubygems/test_gem_commands_stale_command.rb
@@ -25,12 +25,12 @@ class TestGemCommandsStaleCommand < Gem::TestCase
end
files.each do |file|
- filename = bar_baz.full_gem_path + "/#{file}"
- FileUtils.mkdir_p(File.dirname(filename))
+ filename = File.join(bar_baz.full_gem_path, file)
+ FileUtils.mkdir_p File.dirname filename
FileUtils.touch(filename, :mtime => Time.now)
- filename = foo_bar.full_gem_path + "/#{file}"
- FileUtils.mkdir_p(File.dirname(filename))
+ filename = File.join(foo_bar.full_gem_path, file)
+ FileUtils.mkdir_p File.dirname filename
FileUtils.touch(filename, :mtime => Time.now - 86400)
end
diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb
index 8764a40..3f07227 100644
--- a/test/rubygems/test_gem_commands_unpack_command.rb
+++ b/test/rubygems/test_gem_commands_unpack_command.rb
@@ -21,20 +21,20 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
util_make_gems
assert_equal(
- @cmd.find_in_cache(@a1.file_name),
- Gem.cache_gem(@a1.file_name, @gemhome),
+ @cmd.find_in_cache(File.basename @a1.cache_file),
+ @a1.cache_file,
'found a-1.gem in the cache'
)
end
def test_get_path
- util_make_gems
util_setup_fake_fetcher
+ util_clear_gems
util_setup_spec_fetcher @a1
a1_data = nil
- open Gem.cache_gem(@a1.file_name, @gemhome), 'rb' do |fp|
+ open @a1.cache_file, 'rb' do |fp|
a1_data = fp.read
end
@@ -44,15 +44,15 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
dep = Gem::Dependency.new(@a1.name, @a1.version)
assert_equal(
@cmd.get_path(dep),
- Gem.cache_gem(@a1.file_name, @gemhome),
+ @a1.cache_file,
'fetches a-1 and returns the cache path'
)
- FileUtils.rm Gem.cache_gem(@a1.file_name, @gemhome)
+ FileUtils.rm @a1.cache_file
assert_equal(
@cmd.get_path(dep),
- Gem.cache_gem(@a1.file_name, @gemhome),
+ @a1.cache_file,
'when removed from cache, refetches a-1'
)
end
@@ -73,16 +73,14 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
end
def test_execute_gem_path
- util_make_gems
- util_setup_spec_fetcher
util_setup_fake_fetcher
+ util_setup_spec_fetcher
Gem.clear_paths
gemhome2 = File.join @tempdir, 'gemhome2'
- Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR)
- Gem.send :set_home, gemhome2
+ Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
@cmd.options[:args] = %w[a]
@@ -96,15 +94,14 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
end
def test_execute_gem_path_missing
- util_make_gems
+ util_setup_fake_fetcher
util_setup_spec_fetcher
Gem.clear_paths
gemhome2 = File.join @tempdir, 'gemhome2'
- Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR)
- Gem.send :set_home, gemhome2
+ Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
@cmd.options[:args] = %w[z]
@@ -123,7 +120,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
util_clear_gems
a2_data = nil
- open Gem.cache_gem(@a2.file_name, @gemhome), 'rb' do |fp|
+ open @a2.cache_file, 'rb' do |fp|
a2_data = fp.read
end
@@ -142,10 +139,28 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
assert File.exist?(File.join(@tempdir, 'a-2')), 'a should be unpacked'
end
+ def test_execute_spec
+ util_make_gems
+
+ @cmd.options[:args] = %w[a b]
+ @cmd.options[:spec] = true
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-3.a.gemspec'))
+ assert File.exist?(File.join(@tempdir, 'b-2.gemspec'))
+ end
+
def test_execute_sudo
+ skip 'Cannot perform this test on windows (chmod)' if win_platform?
+
util_make_gems
- File.chmod 0555, @gemhome
+ FileUtils.chmod 0555, @gemhome
@cmd.options[:args] = %w[b]
@@ -157,7 +172,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked'
ensure
- File.chmod 0755, @gemhome
+ FileUtils.chmod 0755, @gemhome
end
def test_execute_with_target_option
@@ -203,5 +218,13 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
assert File.exist?(File.join(@tempdir, foo_spec.full_name))
end
+ def test_handle_options_metadata
+ refute @cmd.options[:spec]
+
+ @cmd.send :handle_options, %w[--spec a]
+
+ assert @cmd.options[:spec]
+ end
+
end
diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb
index 24966a3..b43be11 100644
--- a/test/rubygems/test_gem_commands_update_command.rb
+++ b/test/rubygems/test_gem_commands_update_command.rb
@@ -24,15 +24,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@cmd.options[:generate_ri] = false
util_setup_fake_fetcher
-
- @a1_path = Gem.cache_gem(@a1.file_name, @gemhome)
- @a2_path = Gem.cache_gem(@a2.file_name, @gemhome)
-
+ util_clear_gems
util_setup_spec_fetcher @a1, @a2
- @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] =
+ @a1_path = @a1.cache_file
+ @a2_path = @a2.cache_file
+
+ @fetcher.data["#{@gem_repo}gems/#{File.basename @a1_path}"] =
read_binary @a1_path
- @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
+ @fetcher.data["#{@gem_repo}gems/#{File.basename @a2_path}"] =
read_binary @a2_path
end
@@ -81,18 +81,19 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
def util_add_to_fetcher *specs
specs.each do |spec|
- gem_file = Gem.cache_gem(spec.file_name, @gemhome)
+ gem_file = spec.cache_file
+ file_name = File.basename gem_file
- @fetcher.data["http://gems.example.com/gems/#{spec.file_name}"] =
+ @fetcher.data["http://gems.example.com/gems/#{file_name}"] =
Gem.read_binary gem_file
end
end
def test_execute_system
+ util_clear_gems
util_setup_rubygem9
util_setup_spec_fetcher @rubygem9
util_add_to_fetcher @rubygem9
- util_clear_gems
@cmd.options[:args] = []
@cmd.options[:system] = true
@@ -113,17 +114,17 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
def test_execute_system_at_latest
+ util_clear_gems
util_setup_rubygem_current
util_setup_spec_fetcher @rubygem_current
util_add_to_fetcher @rubygem_current
- util_clear_gems
@cmd.options[:args] = []
@cmd.options[:system] = true
@cmd.options[:generate_rdoc] = false
@cmd.options[:generate_ri] = false
- assert_raises Gem::SystemExitException do
+ assert_raises Gem::MockGemUi::SystemExitException do
use_ui @ui do
@cmd.execute
end
@@ -135,11 +136,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
def test_execute_system_multiple
+ util_clear_gems
util_setup_rubygem9
util_setup_rubygem8
util_setup_spec_fetcher @rubygem8, @rubygem9
util_add_to_fetcher @rubygem8, @rubygem9
- util_clear_gems
@cmd.options[:args] = []
@cmd.options[:system] = true
@@ -184,6 +185,31 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty out
end
+ def test_execute_system_specifically_to_latest_version
+ util_clear_gems
+ util_setup_rubygem9
+ util_setup_rubygem8
+ util_setup_spec_fetcher @rubygem8, @rubygem9
+ util_add_to_fetcher @rubygem8, @rubygem9
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = "9"
+ @cmd.options[:generate_rdoc] = false
+ @cmd.options[:generate_ri] = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating rubygems-update", out.shift
+ assert_equal "Successfully installed rubygems-update-9", out.shift
+ assert_equal "Installing RubyGems 9", out.shift
+ assert_equal "RubyGems system software updated", out.shift
+
+ assert_empty out
+ end
+
def test_execute_system_with_gems
@cmd.options[:args] = %w[gem]
@cmd.options[:system] = true
@@ -218,16 +244,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@a2.add_dependency 'c', '2'
@a2.add_dependency 'b', '2'
- @b2_path = Gem.cache_gem(@b2.file_name, @gemhome)
- @c1_2_path = Gem.cache_gem(@c1_2.file_name, @gemhome)
- @c2_path = Gem.cache_gem(@c2.file_name, @gemhome)
+ @b2_path = @b2.cache_file
+ @c1_2_path = @c1_2.cache_file
+ @c2_path = @c2.cache_file
- @source_index = Gem::SourceIndex.new
- @source_index.add_spec @a1
- @source_index.add_spec @a2
- @source_index.add_spec @b2
- @source_index.add_spec @c1_2
- @source_index.add_spec @c2
+ install_specs @a1, @a2, @b2, @c1_2, @c2
util_build_gem @a1
util_build_gem @a2
@@ -236,16 +257,16 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = read_binary @a1_path
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = read_binary @a2_path
@fetcher.data["#{@gem_repo}gems/#{@b2.file_name}"] = read_binary @b2_path
- @fetcher.data["#{@gem_repo}gems/#{@c1_2.file_name}"] =
- read_binary @c1_2_path
+ @fetcher.data["#{@gem_repo}gems/#{@c1_2.file_name}"] = read_binary @c1_2_path
@fetcher.data["#{@gem_repo}gems/#{@c2.file_name}"] = read_binary @c2_path
util_setup_spec_fetcher @a1, @a2, @b2, @c1_2, @c2
- util_clear_gems
Gem::Installer.new(@c1_2_path).install
Gem::Installer.new(@a1_path).install
+ Gem::Specification.reset
+
@cmd.options[:args] = []
use_ui @ui do
diff --git a/test/rubygems/test_gem_commands_which_command.rb b/test/rubygems/test_gem_commands_which_command.rb
index 8f9a292..7a21f7c 100644
--- a/test/rubygems/test_gem_commands_which_command.rb
+++ b/test/rubygems/test_gem_commands_which_command.rb
@@ -11,6 +11,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
def setup
super
+ Gem::Specification.reset
@cmd = Gem::Commands::WhichCommand.new
end
@@ -28,6 +29,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
def test_execute_one_missing
+ # TODO: this test fails in isolation
+
util_foo_bar
@cmd.handle_options %w[foo_bar missing]
@@ -37,7 +40,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
- assert_match %r%Can't find ruby library file or shared library missing\n%,
+ assert_match %r%Can.t find ruby library file or shared library missing\n%,
@ui.error
end
@@ -51,7 +54,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal '', @ui.output
- assert_match %r%Can't find ruby library file or shared library missing\n%,
+ assert_match %r%Can.t find ruby library file or shared library missing\n%,
@ui.error
end
@@ -62,8 +65,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
files.each do |file|
- filename = @foo_bar.full_gem_path + "/#{file}"
- FileUtils.mkdir_p File.dirname(filename)
+ filename = File.join(@foo_bar.full_gem_path, file)
+ FileUtils.mkdir_p File.dirname filename
FileUtils.touch filename
end
end
diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb
index b4a21b8..a77ddf5 100644
--- a/test/rubygems/test_gem_dependency.rb
+++ b/test/rubygems/test_gem_dependency.rb
@@ -67,16 +67,20 @@ class TestGemDependency < Gem::TestCase
assert_match d, d, "match self"
assert_match dep("a", ">= 0"), d, "match version exact"
assert_match dep("a", ">= 0"), dep("a", "1"), "match version"
- assert_match dep(/a/, ">= 0"), d, "match simple regexp"
- assert_match dep(/a|b/, ">= 0"), d, "match scary regexp"
-
- refute_match dep(/a/), dep("b")
refute_match dep("a"), Object.new
+
+ Deprecate.skip_during do
+ assert_match dep(/a/, ">= 0"), d, "match simple regexp"
+ assert_match dep(/a|b/, ">= 0"), d, "match scary regexp"
+ refute_match dep(/a/), dep("b")
+ end
end
def test_equals_tilde_escape
refute_match dep("a|b"), dep("a", "1")
- assert_match dep(/a|b/), dep("a", "1")
+ Deprecate.skip_during do
+ assert_match dep(/a|b/), dep("a", "1")
+ end
end
def test_equals_tilde_object
@@ -90,9 +94,11 @@ class TestGemDependency < Gem::TestCase
def test_equals_tilde_spec
assert_match dep("a", ">= 0"), spec("a", "0")
assert_match dep("a", "1"), spec("a", "1")
- assert_match dep(/a/, ">= 0"), spec("a", "0")
- assert_match dep(/a|b/, ">= 0"), spec("b", "0")
- refute_match dep(/a/, ">= 0"), spec("b", "0")
+ Deprecate.skip_during do
+ assert_match dep(/a/, ">= 0"), spec("a", "0")
+ assert_match dep(/a|b/, ">= 0"), spec("b", "0")
+ refute_match dep(/a/, ">= 0"), spec("b", "0")
+ end
end
def test_hash
@@ -166,5 +172,12 @@ class TestGemDependency < Gem::TestCase
assert d.prerelease?
end
+
+ def test_specific
+ refute dep('a', '> 1').specific?
+
+ assert dep('a', '= 1').specific?
+ end
+
end
diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb
index 5cf79d3..48d85b8 100644
--- a/test/rubygems/test_gem_dependency_installer.rb
+++ b/test/rubygems/test_gem_dependency_installer.rb
@@ -14,10 +14,14 @@ class TestGemDependencyInstaller < Gem::TestCase
super
@gems_dir = File.join @tempdir, 'gems'
- @cache_dir = Gem.cache_dir(@gemhome)
+ @cache_dir = File.join @gemhome, 'cache'
FileUtils.mkdir @gems_dir
+ Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
+ end
+
+ def util_setup_gems
@a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end
@a1_pre, @a1_pre_gem = util_gem 'a', '1.a'
@b1, @b1_gem = util_gem 'b', '1' do |s|
@@ -25,12 +29,13 @@ class TestGemDependencyInstaller < Gem::TestCase
s.add_development_dependency 'aa'
end
- Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
-
+ util_clear_gems
util_reset_gems
end
def test_install
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
inst = nil
@@ -39,13 +44,13 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install 'a'
end
- assert_equal Gem::SourceIndex.new(@a1.full_name => @a1),
- Gem::SourceIndex.from_installed_gems
-
+ assert_equal %w[a-1], Gem::Specification.map(&:full_name)
assert_equal [@a1], inst.installed_gems
end
def test_install_all_dependencies
+ util_setup_gems
+
_, e1_gem = util_gem 'e', '1' do |s|
s.add_dependency 'b'
end
@@ -71,6 +76,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_cache_dir
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir
inst = nil
@@ -82,15 +89,18 @@ class TestGemDependencyInstaller < Gem::TestCase
assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
- assert Gem.cache_gem(@a1.file_name, @gemhome)
- assert Gem.cache_gem(@b1.file_name, @gemhome)
+ assert File.exist? File.join(@gemhome, "cache", @a1.file_name)
+ assert File.exist? File.join(@gemhome, "cache", @b1.file_name)
end
def test_install_dependencies_satisfied
+ util_setup_gems
+
a2, a2_gem = util_gem 'a', '2'
FileUtils.rm_rf File.join(@gemhome, 'gems')
- Gem.source_index.refresh!
+
+ Gem::Specification.reset
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv a2_gem, @tempdir # not in index
@@ -109,14 +119,13 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install 'b'
end
- installed = Gem::SourceIndex.from_installed_gems.map { |n,s| s.full_name }
-
- assert_equal %w[a-2 b-1], installed.sort
-
+ assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
end
def test_install_dependency
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir
inst = nil
@@ -130,6 +139,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_dependency_development
+ util_setup_gems
+
@aa1, @aa1_gem = util_gem 'aa', '1'
util_reset_gems
@@ -148,6 +159,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_dependency_existing
+ util_setup_gems
+
Gem::Installer.new(@a1_gem).install
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir
@@ -180,6 +193,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_local
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
inst = nil
@@ -192,6 +207,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_local_dependency
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir
@@ -206,6 +223,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_local_dependency_installed
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir
@@ -222,6 +241,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_local_subdir
+ util_setup_gems
+
inst = nil
Dir.chdir @tempdir do
@@ -233,11 +254,13 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_env_shebang
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true
+ inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true, :format_executable => false
inst.install 'a'
end
@@ -248,6 +271,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_force
+ util_setup_gems
+
FileUtils.mv @b1_gem, @tempdir
si = util_setup_spec_fetcher @b1
@fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
@@ -262,6 +287,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_ignore_dependencies
+ util_setup_gems
+
FileUtils.mv @b1_gem, @tempdir
inst = nil
@@ -274,6 +301,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_install_dir
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
gemhome2 = File.join @tempdir, 'gemhome2'
Dir.mkdir gemhome2
@@ -287,10 +316,12 @@ class TestGemDependencyInstaller < Gem::TestCase
assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name))
- assert File.exist?(Gem.cache_gem(@a1.file_name, gemhome2))
+ assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name))
end
def test_install_domain_both
+ util_setup_gems
+
a1_data = nil
File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read
@@ -309,14 +340,13 @@ class TestGemDependencyInstaller < Gem::TestCase
assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
a1, b1 = inst.installed_gems
- a1_expected = File.join(@gemhome, 'specifications', a1.spec_name)
- b1_expected = File.join(@gemhome, 'specifications', b1.spec_name)
-
- assert_equal a1_expected, a1.loaded_from
- assert_equal b1_expected, b1.loaded_from
+ assert_equal a1.spec_file, a1.loaded_from
+ assert_equal b1.spec_file, b1.loaded_from
end
def test_install_domain_both_no_network
+ util_setup_gems
+
@fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] =
proc do
raise Gem::RemoteFetcher::FetchError
@@ -335,12 +365,11 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_domain_local
+ util_setup_gems
+
FileUtils.mv @b1_gem, @tempdir
inst = nil
- Gem.source_index.remove_spec @a1.full_name
- Gem.source_index.remove_spec @a1_pre.full_name
-
Dir.chdir @tempdir do
e = assert_raises Gem::DependencyError do
inst = Gem::DependencyInstaller.new :domain => :local
@@ -355,6 +384,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_domain_remote
+ util_setup_gems
+
a1_data = nil
File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read
@@ -369,6 +400,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_dual_repository
+ util_setup_gems
+
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir
inst = nil
@@ -393,6 +426,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_reinstall
+ util_setup_gems
+
Gem::Installer.new(@a1_gem).install
FileUtils.mv @a1_gem, @tempdir
inst = nil
@@ -402,13 +437,13 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install 'a'
end
- assert_equal Gem::SourceIndex.new(@a1.full_name => @a1),
- Gem::SourceIndex.from_installed_gems
-
- assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ assert_equal %w[a-1], Gem::Specification.map(&:full_name)
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
end
def test_install_remote
+ util_setup_gems
+
a1_data = nil
File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read
@@ -426,6 +461,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_remote_dep
+ util_setup_gems
+
a1_data = nil
File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read
@@ -444,6 +481,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_install_remote_platform_newer
+ util_setup_gems
+
a2_o, a2_o_gem = util_gem 'a', '2' do |s|
s.platform = Gem::Platform.new %w[cpu other_platform 1]
end
@@ -473,6 +512,8 @@ class TestGemDependencyInstaller < Gem::TestCase
if defined? OpenSSL then
def test_install_security_policy
+ util_setup_gems
+
data = File.open(@a1_gem, 'rb') { |f| f.read }
@fetcher.data['http://gems.example.com/gems/a-1.gem'] = data
@@ -495,9 +536,11 @@ class TestGemDependencyInstaller < Gem::TestCase
# Wrappers don't work on mswin
unless win_platform? then
def test_install_no_wrappers
+ util_setup_gems
+
@fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem)
- inst = Gem::DependencyInstaller.new :wrappers => false
+ inst = Gem::DependencyInstaller.new :wrappers => false, :format_executable => false
inst.install 'a'
refute_match(%r|This file was generated by RubyGems.|,
@@ -537,14 +580,19 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_find_gems_gems_with_sources
+ util_setup_gems
+
inst = Gem::DependencyInstaller.new
dep = Gem::Dependency.new 'b', '>= 0'
- assert_equal [[@b1, @gem_repo]],
- inst.find_gems_with_sources(dep)
+ Gem::Specification.reset
+
+ assert_equal [[@b1, @gem_repo]], inst.find_gems_with_sources(dep)
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'
@@ -566,6 +614,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_find_gems_with_sources_prerelease
+ util_setup_gems
+
installer = Gem::DependencyInstaller.new
dependency = Gem::Dependency.new('a', Gem::Requirement.default)
@@ -586,8 +636,8 @@ class TestGemDependencyInstaller < Gem::TestCase
def assert_resolve expected, *specs
util_clear_gems
-
util_setup_spec_fetcher(*specs)
+ Gem::Specification.reset
inst = Gem::DependencyInstaller.new
inst.find_spec_by_name_and_version specs.first.name
@@ -601,6 +651,7 @@ class TestGemDependencyInstaller < Gem::TestCase
util_clear_gems
util_setup_spec_fetcher(*specs)
+ Gem::Specification.reset
spec = specs.first
@@ -613,6 +664,9 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_gather_dependencies
+ util_setup_gems
+ util_reset_gems
+
inst = Gem::DependencyInstaller.new
inst.find_spec_by_name_and_version 'b'
inst.gather_dependencies
@@ -725,6 +779,7 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def test_gather_dependencies_prerelease
+ util_setup_gems
util_setup_c1_pre
assert_resolve_pre %w[a-1.a b-1 c-1.a], @c1_pre, @a1_pre, @b1
@@ -782,6 +837,9 @@ class TestGemDependencyInstaller < Gem::TestCase
end
def util_reset_gems
+ @a1 ||= nil
+ @b1 ||= nil
+ @a1_pre ||= nil
@c1_pre ||= nil
@d1 ||= nil
@d2 ||= nil
diff --git a/test/rubygems/test_gem_dependency_list.rb b/test/rubygems/test_gem_dependency_list.rb
index 4201a31..348f111 100644
--- a/test/rubygems/test_gem_dependency_list.rb
+++ b/test/rubygems/test_gem_dependency_list.rb
@@ -12,8 +12,11 @@ class TestGemDependencyList < Gem::TestCase
def setup
super
+ util_clear_gems
+
@deplist = Gem::DependencyList.new
+ # TODO: switch to new_spec
@a1 = quick_spec 'a', '1'
@a2 = quick_spec 'a', '2'
@a3 = quick_spec 'a', '3'
@@ -28,13 +31,10 @@ class TestGemDependencyList < Gem::TestCase
end
def test_self_from_source_index
- hash = {
- 'a-1' => @a1,
- 'b-2' => @b2,
- }
+ util_clear_gems
+ install_specs @a1, @b2
- si = Gem::SourceIndex.new hash
- deps = Gem::DependencyList.from_source_index si
+ deps = Deprecate.skip_during { Gem::DependencyList.from_source_index }
assert_equal %w[b-2 a-1], deps.dependency_order.map { |s| s.full_name }
end
diff --git a/test/rubygems/test_gem_doc_manager.rb b/test/rubygems/test_gem_doc_manager.rb
index f52f1f8..f7ab641 100644
--- a/test/rubygems/test_gem_doc_manager.rb
+++ b/test/rubygems/test_gem_doc_manager.rb
@@ -17,21 +17,21 @@ class TestGemDocManager < Gem::TestCase
end
def test_uninstall_doc_unwritable
- path = @spec.installation_path
+ path = @spec.base_dir
orig_mode = File.stat(path).mode
# File.chmod has no effect on MS Windows directories (it needs ACL).
if win_platform?
skip("test_uninstall_doc_unwritable skipped on MS Windows")
else
- File.chmod 0000, path
+ FileUtils.chmod 0000, path
end
assert_raises Gem::FilePermissionError do
@manager.uninstall_doc
end
ensure
- File.chmod orig_mode, path
+ FileUtils.chmod orig_mode, path
end
end
diff --git a/test/rubygems/test_gem_format.rb b/test/rubygems/test_gem_format.rb
index 6f16958..85fb521 100644
--- a/test/rubygems/test_gem_format.rb
+++ b/test/rubygems/test_gem_format.rb
@@ -20,7 +20,7 @@ class TestGemFormat < Gem::Package::TarTestCase
def test_class_from_file_by_path
util_make_gems
- gems = Dir[Gem.cache_gem('*.gem', @gemhome)]
+ gems = Dir[File.join(@gemhome, "cache", "*.gem")]
names = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1].map do |spec|
spec.original_name
diff --git a/test/rubygems/test_gem_gem_path_searcher.rb b/test/rubygems/test_gem_gem_path_searcher.rb
index cb4516e..c7f5af7 100644
--- a/test/rubygems/test_gem_gem_path_searcher.rb
+++ b/test/rubygems/test_gem_gem_path_searcher.rb
@@ -13,72 +13,88 @@ class Gem::GemPathSearcher
end
class TestGemGemPathSearcher < Gem::TestCase
-
def setup
super
- @foo1 = quick_gem 'foo', '0.1' do |s|
- s.require_paths << 'lib2'
- s.files << 'lib/foo.rb'
- end
-
+ @foo1 = new_spec 'foo', '0.1', nil, "lib/foo.rb"
+ @foo1.require_paths << 'lib2'
path = File.join 'gems', @foo1.full_name, 'lib', 'foo.rb'
write_file(path) { |fp| fp.puts "# #{path}" }
- @foo2 = quick_gem 'foo', '0.2'
- @bar1 = quick_gem 'bar', '0.1'
- @bar2 = quick_gem 'bar', '0.2'
- @nrp = quick_gem 'nil_require_paths', '0.1'
- @nrp.require_paths = nil
+ @foo2 = new_spec 'foo', '0.2'
+ @bar1 = new_spec 'bar', '0.1'
+ @bar2 = new_spec 'bar', '0.2'
+ @nrp = new_spec 'nil_require_paths', '0.1' do |s|
+ s.require_paths = nil
+ end
+ util_setup_fake_fetcher
+ Gem::Specification.reset
+ util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
- Gem.source_index = util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2
-
- @gps = Gem::GemPathSearcher.new
+ @gps = Deprecate.skip_during { Gem::GemPathSearcher.new }
end
def test_find
- assert_equal @foo1, @gps.find('foo')
+ Deprecate.skip_during do
+ assert_equal @foo1, @gps.find('foo')
+ end
end
def test_find_all
- assert_equal [@foo1], @gps.find_all('foo')
+ Deprecate.skip_during do
+ assert_equal [@foo1], @gps.find_all('foo')
+ end
end
def test_init_gemspecs
- assert_equal [@bar2, @bar1, @foo2, @foo1], @gps.init_gemspecs
+ Deprecate.skip_during do
+ util_clear_gems
+ util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2
+ expected = [@bar2, @bar1, @foo2, @foo1].map(&:full_name)
+ actual = @gps.init_gemspecs.map(&:full_name)
+ assert_equal expected, actual
+ end
end
def test_lib_dirs_for
- lib_dirs = @gps.lib_dirs_for(@foo1)
- expected = File.join @gemhome, 'gems', @foo1.full_name, '{lib,lib2}'
+ Deprecate.skip_during do
+ lib_dirs = @gps.lib_dirs_for(@foo1)
+ expected = File.join @gemhome, 'gems', @foo1.full_name, '{lib,lib2}'
- assert_equal expected, lib_dirs
+ assert_equal expected, lib_dirs
+ end
end
def test_lib_dirs_for_nil_require_paths
- assert_nil @gps.lib_dirs_for(@nrp)
+ Deprecate.skip_during do
+ assert_nil @gps.lib_dirs_for(@nrp)
+ end
end
def test_matching_file_eh
- refute @gps.matching_file?(@foo1, 'bar')
- assert @gps.matching_file?(@foo1, 'foo')
+ Deprecate.skip_during do
+ refute @gps.matching_file?(@foo1, 'bar')
+ assert @gps.matching_file?(@foo1, 'foo')
+ end
end
def test_matching_files
- assert_equal [], @gps.matching_files(@foo1, 'bar')
+ Deprecate.skip_during do
+ assert_equal [], @gps.matching_files(@foo1, 'bar')
- expected = File.join @foo1.full_gem_path, 'lib', 'foo.rb'
+ expected = File.join @foo1.full_gem_path, 'lib', 'foo.rb'
- assert_equal [expected], @gps.matching_files(@foo1, 'foo')
+ assert_equal [expected], @gps.matching_files(@foo1, 'foo')
+ end
end
def test_matching_files_nil_require_paths
- assert_empty @gps.matching_files(@nrp, 'foo')
+ Deprecate.skip_during do
+ assert_empty @gps.matching_files(@nrp, 'foo')
+ end
end
-
end
-
diff --git a/test/rubygems/test_gem_gem_runner.rb b/test/rubygems/test_gem_gem_runner.rb
index 177c715..3cb8410 100644
--- a/test/rubygems/test_gem_gem_runner.rb
+++ b/test/rubygems/test_gem_gem_runner.rb
@@ -39,10 +39,7 @@ class TestGemGemRunner < Gem::TestCase
def test_build_args__are_handled
Gem.clear_paths
- gr = Gem::GemRunner.new
- assert_raises(Gem::SystemExitException) do
- gr.run(%W[--help -- --build_arg1 --build_arg2])
- end
+ Gem::GemRunner.new.run(%W[help -- --build_arg1 --build_arg2])
assert_equal %w[--build_arg1 --build_arg2], Gem::Command.build_args
end
diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb
index e3c78ec..a4f9bd4 100644
--- a/test/rubygems/test_gem_indexer.rb
+++ b/test/rubygems/test_gem_indexer.rb
@@ -16,6 +16,7 @@ class TestGemIndexer < Gem::TestCase
def setup
super
+ util_clear_gems
util_make_gems
@d2_0 = quick_spec 'd', '2.0' do |s|
@@ -33,11 +34,12 @@ class TestGemIndexer < Gem::TestCase
gems = File.join(@tempdir, 'gems')
FileUtils.mkdir_p gems
- FileUtils.mv Dir[Gem.cache_gem('*.gem', @gemhome)], gems
+ FileUtils.mv Dir[File.join(@gemhome, "cache", '*.gem')], gems
- @indexer = Gem::Indexer.new @tempdir, :rss_title => 'ExampleForge gems',
- :rss_host => 'example.com',
- :rss_gems_host => 'gems.example.com'
+ @indexer = Gem::Indexer.new(@tempdir,
+ :rss_title => 'ExampleForge gems',
+ :rss_host => 'example.com',
+ :rss_gems_host => 'gems.example.com')
end
def test_initialize
@@ -61,36 +63,37 @@ class TestGemIndexer < Gem::TestCase
end
def test_build_indicies
- spec = quick_spec 'd', '2.0'
- spec.instance_variable_set :@original_platform, ''
-
@indexer.make_temp_directories
- index = Gem::SourceIndex.new
- index.add_spec spec
-
use_ui @ui do
- @indexer.build_indicies index
+ @indexer.build_indicies
end
specs_path = File.join @indexer.directory, "specs.#{@marshal_version}"
specs_dump = Gem.read_binary specs_path
specs = Marshal.load specs_dump
- expected = [
- ['d', Gem::Version.new('2.0'), 'ruby'],
- ]
+ expected = [["a", Gem::Version.new("1"), "ruby"],
+ ["a", Gem::Version.new("2"), "ruby"],
+ ["a_evil", Gem::Version.new("9"), "ruby"],
+ ["b", Gem::Version.new("2"), "ruby"],
+ ["c", Gem::Version.new("1.2"), "ruby"],
+ ["d", Gem::Version.new("2.0"), "ruby"],
+ ["pl", Gem::Version.new("1"), "i386-linux"]]
- assert_equal expected, specs, 'specs'
+ assert_equal expected, specs
- latest_specs_path = File.join @indexer.directory,
- "latest_specs.#{@marshal_version}"
+ latest_specs_path = File.join(@indexer.directory,
+ "latest_specs.#{@marshal_version}")
latest_specs_dump = Gem.read_binary latest_specs_path
latest_specs = Marshal.load latest_specs_dump
- expected = [
- ['d', Gem::Version.new('2.0'), 'ruby'],
- ]
+ expected = [["a", Gem::Version.new("2"), "ruby"],
+ ["a_evil", Gem::Version.new("9"), "ruby"],
+ ["b", Gem::Version.new("2"), "ruby"],
+ ["c", Gem::Version.new("1.2"), "ruby"],
+ ["d", Gem::Version.new("2.0"), "ruby"],
+ ["pl", Gem::Version.new("1"), "i386-linux"]]
assert_equal expected, latest_specs, 'latest_specs'
end
@@ -109,10 +112,10 @@ class TestGemIndexer < Gem::TestCase
assert File.directory?(quickdir)
assert File.directory?(marshal_quickdir)
- assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
- assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
- refute_indexed marshal_quickdir, @c1_2.spec_name
+ refute_indexed marshal_quickdir, File.basename(@c1_2.spec_file)
assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@@ -230,12 +233,12 @@ class TestGemIndexer < Gem::TestCase
<description>
&lt;pre&gt;This line is really, really long. So long, in fact, that it is more than
eighty characters long! The purpose of this line is for testing wrapping
-behavior because sometimes people don't wrap their text to eighty characters.
+behavior because sometimes people don't wrap their text to eighty characters.
Without the wrapping, the text might not look good in the RSS feed.
Also, a list:
* An entry that's actually kind of sort
- * an entry that's really long, which will probably get wrapped funny.
+ * an entry that's really long, which will probably get wrapped funny.
That's ok, somebody wasn't thinking straight when they made it more than
eighty characters.&lt;/pre&gt;
</description>
@@ -272,10 +275,10 @@ eighty characters.&lt;/pre&gt;
assert File.directory?(quickdir)
assert File.directory?(marshal_quickdir)
- assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
- assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
- refute_indexed marshal_quickdir, "#{@c1_2.spec_name}"
+ refute_indexed marshal_quickdir, "#{File.basename(@c1_2.spec_file)}"
refute_indexed @tempdir, "specs.#{@marshal_version}"
refute_indexed @tempdir, "specs.#{@marshal_version}.gz"
@@ -308,8 +311,8 @@ eighty characters.&lt;/pre&gt;
assert File.directory?(marshal_quickdir)
- assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
- assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@@ -343,19 +346,19 @@ eighty characters.&lt;/pre&gt;
refute_indexed quickdir, "latest_index"
refute_indexed quickdir, "latest_index.rz"
- refute_indexed quickdir, "#{@a1.spec_name}.rz"
- refute_indexed quickdir, "#{@a2.spec_name}.rz"
- refute_indexed quickdir, "#{@b2.spec_name}.rz"
- refute_indexed quickdir, "#{@c1_2.spec_name}.rz"
+ refute_indexed quickdir, "#{File.basename(@a1.spec_file)}.rz"
+ refute_indexed quickdir, "#{File.basename(@a2.spec_file)}.rz"
+ refute_indexed quickdir, "#{File.basename(@b2.spec_file)}.rz"
+ refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}.rz"
refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
- refute_indexed quickdir, "#{@pl1.spec_name}.rz"
+ refute_indexed quickdir, "#{File.basename(@pl1.spec_file)}.rz"
- assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
- assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
- refute_indexed quickdir, "#{@c1_2.spec_name}"
- refute_indexed marshal_quickdir, "#{@c1_2.spec_name}"
+ refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}"
+ refute_indexed marshal_quickdir, "#{File.basename(@c1_2.spec_file)}"
assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@@ -389,8 +392,8 @@ eighty characters.&lt;/pre&gt;
assert File.directory?(quickdir)
assert File.directory?(marshal_quickdir)
- assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
- assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@@ -404,10 +407,7 @@ eighty characters.&lt;/pre&gt;
@indexer.generate_index
end
- assert_match %r%^Loading 10 gems from #{Regexp.escape @tempdir}$%,
- @ui.output
assert_match %r%^\.\.\.\.\.\.\.\.\.\.$%, @ui.output
- assert_match %r%^Loaded all gems$%, @ui.output
assert_match %r%^Generating Marshal quick index gemspecs for 10 gems$%,
@ui.output
assert_match %r%^Complete$%, @ui.output
@@ -520,14 +520,15 @@ eighty characters.&lt;/pre&gt;
@d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform]
gems = File.join @tempdir, 'gems'
- FileUtils.mv Gem.cache_gem(@d2_1.file_name, @gemhome), gems
- FileUtils.mv Gem.cache_gem(@d2_1_a.file_name, @gemhome), gems
+
+ FileUtils.mv @d2_1.cache_file, gems
+ FileUtils.mv @d2_1_a.cache_file, gems
use_ui @ui do
@indexer.update_index
end
- assert_indexed marshal_quickdir, "#{@d2_1.spec_name}.rz"
+ assert_indexed marshal_quickdir, "#{File.basename(@d2_1.spec_file)}.rz"
specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index)
diff --git a/test/rubygems/test_gem_install_update_options.rb b/test/rubygems/test_gem_install_update_options.rb
index fe10fd4..2f0b911 100644
--- a/test/rubygems/test_gem_install_update_options.rb
+++ b/test/rubygems/test_gem_install_update_options.rb
@@ -46,9 +46,8 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
@installer = Gem::Installer.new @gem, @cmd.options
@installer.install
- assert File.exist?(File.join(Gem.user_dir, 'gems'))
- assert File.exist?(File.join(Gem.user_dir, 'gems',
- @spec.full_name))
+ assert_path_exists File.join(Gem.user_dir, 'gems')
+ assert_path_exists File.join(Gem.user_dir, 'gems', @spec.full_name)
end
def test_user_install_disabled_read_only
@@ -59,11 +58,13 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
refute @cmd.options[:user_install]
- File.chmod 0755, @userhome
+ FileUtils.chmod 0755, @userhome
FileUtils.chmod 0000, @gemhome
+ Gem.use_paths @gemhome, @userhome
+
assert_raises(Gem::FilePermissionError) do
- @installer = Gem::Installer.new @gem, @cmd.options
+ Gem::Installer.new(@gem, @cmd.options).install
end
end
ensure
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index 554865d..249b195 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -8,6 +8,25 @@ require 'rubygems/installer_test_case'
class TestGemInstaller < Gem::InstallerTestCase
+ def setup
+ super
+
+ if __name__ !~ /^test_install(_|$)/ then
+ @gemhome = @installer_tmp
+ Gem.use_paths @installer_tmp
+
+ @spec = Gem::Specification.find_by_name 'a'
+ @user_spec = Gem::Specification.find_by_name 'b'
+
+ @installer.spec = @spec
+ @installer.gem_home = @installer_tmp
+ @installer.gem_dir = @spec.gem_dir
+ @user_installer.spec = @user_spec
+ @user_installer.gem_home = @installer_tmp
+ end
+ end
+
+
def test_app_script_text
@spec.version = 2
util_make_exec @spec, ''
@@ -108,7 +127,7 @@ load Gem.bin_path('a', 'executable', version)
def test_extract_files
format = Object.new
def format.file_entries
- [[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'thefile']]
+ [[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'content']]
end
@installer.format = format
@@ -116,7 +135,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.extract_files
thefile_path = File.join(util_gem_dir, 'thefile')
- assert_equal 'thefile', File.read(thefile_path)
+ assert_equal 'content', File.read(thefile_path)
unless Gem.win_platform? then
assert_equal 0400, File.stat(thefile_path).mode & 0777
@@ -145,8 +164,9 @@ load Gem.bin_path('a', 'executable', version)
@installer.extract_files
end
- assert_equal "attempt to install file into \"../thefile\" under #{util_gem_dir.inspect}",
- e.message
+ dir = util_gem_dir
+ expected = "attempt to install file into \"../thefile\" under #{dir}"
+ assert_equal expected, e.message
assert_equal false, File.file?(File.join(@tempdir, '../thefile')),
"You may need to remove this file if you broke the test once"
end
@@ -163,7 +183,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.extract_files
end
- assert_equal 'attempt to install file into "/thefile"', e.message
+ assert_equal 'attempt to install file into /thefile', e.message
assert_equal false, File.file?(File.join('/thefile')),
"You may need to remove this file if you broke the test once"
end
@@ -241,7 +261,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.wrappers = true
@spec.executables = %w[executable]
- gem_dir = File.join "#{@gemhome}2", 'gems', @spec.full_name
+ gem_dir = File.join("#{@gemhome}2", "gems", @spec.full_name)
gem_bindir = File.join gem_dir, 'bin'
FileUtils.mkdir_p gem_bindir
File.open File.join(gem_bindir, 'executable'), 'w' do |f|
@@ -253,7 +273,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.generate_bin
- installed_exec = File.join("#{@gemhome}2", 'bin', 'executable')
+ installed_exec = File.join("#{@gemhome}2", "bin", 'executable')
assert_equal true, File.exist?(installed_exec)
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
@@ -279,14 +299,14 @@ load Gem.bin_path('a', 'executable', version)
if win_platform?
skip('test_generate_bin_script_no_perms skipped on MS Windows')
else
- File.chmod 0000, util_inst_bindir
+ FileUtils.chmod 0000, util_inst_bindir
assert_raises Gem::FilePermissionError do
@installer.generate_bin
end
end
ensure
- File.chmod 0700, util_inst_bindir unless $DEBUG
+ FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
end
def test_generate_bin_script_no_shebang
@@ -346,7 +366,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.generate_bin
assert_equal true, File.directory?(util_inst_bindir)
- installed_exec = File.join(util_inst_bindir, 'executable')
+ installed_exec = File.join util_inst_bindir, 'executable'
assert_equal true, File.symlink?(installed_exec)
assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
File.readlink(installed_exec))
@@ -371,14 +391,14 @@ load Gem.bin_path('a', 'executable', version)
if win_platform?
skip('test_generate_bin_symlink_no_perms skipped on MS Windows')
else
- File.chmod 0000, util_inst_bindir
+ FileUtils.chmod 0000, util_inst_bindir
assert_raises Gem::FilePermissionError do
@installer.generate_bin
end
end
ensure
- File.chmod 0700, util_inst_bindir unless $DEBUG
+ FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
end
def test_generate_bin_symlink_update_newer
@@ -404,10 +424,10 @@ load Gem.bin_path('a', 'executable', version)
@spec.version = 3
util_make_exec
- @installer.gem_dir = File.join util_gem_dir @spec
+ @installer.gem_dir = util_gem_dir @spec
@installer.generate_bin
installed_exec = File.join(util_inst_bindir, 'executable')
- assert_equal(File.join(util_gem_bindir(@spec), 'executable'),
+ assert_equal(@spec.bin_file('executable'),
File.readlink(installed_exec),
"Ensure symlink moved to latest version")
end
@@ -441,8 +461,9 @@ load Gem.bin_path('a', 'executable', version)
@installer.generate_bin
- installed_exec = File.join(util_inst_bindir, 'executable')
- assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
+ installed_exec = File.join util_inst_bindir, 'executable'
+ expected = File.join util_gem_dir, 'bin', 'executable'
+ assert_equal(expected,
File.readlink(installed_exec),
"Ensure symlink not moved")
end
@@ -455,7 +476,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.gem_dir = util_gem_dir
@installer.generate_bin
- installed_exec = File.join(util_inst_bindir, 'executable')
+ installed_exec = File.join util_inst_bindir, 'executable'
assert_equal true, File.exist?(installed_exec)
@spec = Gem::Specification.new do |s|
@@ -522,7 +543,7 @@ load Gem.bin_path('a', 'executable', version)
Dir.mkdir util_inst_bindir
util_build_gem spec
- FileUtils.mv Gem.cache_gem(spec.file_name, @gemhome), @tempdir
+ FileUtils.mv spec.cache_file, @tempdir
installer = Gem::Installer.new gem
@@ -535,7 +556,7 @@ load Gem.bin_path('a', 'executable', version)
util_clear_gems
gemdir = File.join @gemhome, 'gems', @spec.full_name
- cache_file = Gem.cache_gem(@spec.file_name, @gemhome)
+ cache_file = File.join @gemhome, 'cache', @spec.file_name
stub_exe = File.join @gemhome, 'bin', 'executable'
rakefile = File.join gemdir, 'ext', 'a', 'Rakefile'
@@ -555,12 +576,14 @@ load Gem.bin_path('a', 'executable', version)
assert File.exist?(cache_file), 'cache file must exist'
end
+ @newspec = nil
build_rake_in do
use_ui @ui do
- assert_equal @spec, @installer.install
+ @newspec = @installer.install
end
end
+ assert_equal @spec, @newspec
assert File.exist? gemdir
assert File.exist?(stub_exe), 'gem executable must exist'
@@ -576,7 +599,7 @@ load Gem.bin_path('a', 'executable', version)
spec_file = File.join(@gemhome, 'specifications', @spec.spec_name)
- assert_equal spec_file, @spec.loaded_from
+ assert_equal spec_file, @newspec.loaded_from
assert File.exist?(spec_file)
assert_same @installer, @post_build_hook_arg
@@ -656,17 +679,17 @@ load Gem.bin_path('a', 'executable', version)
gemhome2 = "#{@gemhome}2"
@spec.add_dependency 'b'
- b2 = quick_spec 'b', 2
+ quick_gem 'b', 2
FileUtils.mv @gemhome, gemhome2
- Gem.source_index.gems.delete b2.full_name
- source_index = Gem::SourceIndex.from_gems_in File.join(gemhome2,
- 'specifications')
+
+ Gem::Specification.dirs = [gemhome2] # TODO: switch all dirs= to use_paths
util_setup_gem
- @installer = Gem::Installer.new @gem, :install_dir => gemhome2,
- :source_index => source_index
+ @installer = Gem::Installer.new @gem, :install_dir => gemhome2
+
+ gem_home = Gem.dir
build_rake_in do
use_ui @ui do
@@ -675,6 +698,7 @@ load Gem.bin_path('a', 'executable', version)
end
assert File.exist?(File.join(gemhome2, 'gems', @spec.full_name))
+ assert_equal gem_home, Gem.dir
end
def test_install_force
@@ -712,7 +736,7 @@ load Gem.bin_path('a', 'executable', version)
end
def test_install_missing_dirs
- FileUtils.rm_f Gem.cache_dir
+ FileUtils.rm_f File.join(Gem.dir, 'cache')
FileUtils.rm_f File.join(Gem.dir, 'docs')
FileUtils.rm_f File.join(Gem.dir, 'specifications')
@@ -722,11 +746,11 @@ load Gem.bin_path('a', 'executable', version)
@installer.install
end
- File.directory? Gem.cache_dir
+ File.directory? File.join(Gem.dir, 'cache')
File.directory? File.join(Gem.dir, 'docs')
File.directory? File.join(Gem.dir, 'specifications')
- assert File.exist?(Gem.cache_gem(@spec.file_name, @gemhome))
+ assert File.exist?(File.join(@gemhome, 'cache', @spec.file_name))
assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
end
@@ -812,8 +836,9 @@ load Gem.bin_path('a', 'executable', version)
@spec.post_install_message = 'I am a shiny gem!'
use_ui @ui do
- Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
+ path = Gem::Builder.new(@spec).build
+ @installer = Gem::Installer.new path
@installer.install
end
@@ -838,7 +863,7 @@ load Gem.bin_path('a', 'executable', version)
util_build_gem spec
- gem = Gem.cache_gem(spec.file_name, @gemhome)
+ gem = File.join(@gemhome, 'cache', spec.file_name)
use_ui @ui do
@installer = Gem::Installer.new gem
@@ -1002,6 +1027,10 @@ load Gem.bin_path('a', 'executable', version)
assert_equal @spec, eval(File.read(spec_file))
end
+ def test_dir
+ assert_match @installer.dir, %r!/installer/gems/a-2$!
+ end
+
def old_ruby_required
spec = quick_spec 'old_ruby_required', '1' do |s|
s.required_ruby_version = '= 1.4.6'
@@ -1009,20 +1038,17 @@ load Gem.bin_path('a', 'executable', version)
util_build_gem spec
- Gem.cache_gem(spec.file_name, @gemhome)
+ spec.cache_file
end
def util_execless
@spec = quick_spec 'z'
+ util_build_gem @spec
- gem = File.join @tempdir, @spec.file_name
-
- @installer = util_installer @spec, gem, @gemhome
+ @installer = util_installer @spec, @gemhome
end
def mask
0100755 & (~File.umask)
end
-
end
-
diff --git a/test/rubygems/test_gem_package_tar_output.rb b/test/rubygems/test_gem_package_tar_output.rb
index 77f3185..01b4a0f 100644
--- a/test/rubygems/test_gem_package_tar_output.rb
+++ b/test/rubygems/test_gem_package_tar_output.rb
@@ -6,6 +6,7 @@
require 'rubygems/package/tar_test_case'
require 'rubygems/package/tar_output'
+require 'rubygems/security'
class TestGemPackageTarOutput < Gem::Package::TarTestCase
diff --git a/test/rubygems/test_gem_path_support.rb b/test/rubygems/test_gem_path_support.rb
new file mode 100644
index 0000000..7fb0cca
--- /dev/null
+++ b/test/rubygems/test_gem_path_support.rb
@@ -0,0 +1,64 @@
+######################################################################
+# This file is imported from the rubygems project.
+# DO NOT make modifications in this repo. They _will_ be reverted!
+# File a patch instead and assign it to Ryan Davis or Eric Hodel.
+######################################################################
+
+require 'rubygems/test_case'
+require 'rubygems'
+require 'fileutils'
+
+class TestGemPathSupport < Gem::TestCase
+ def setup
+ super
+
+ ENV["GEM_HOME"] = @tempdir
+ ENV["GEM_PATH"] = [@tempdir, "something"].join(File::PATH_SEPARATOR)
+ end
+
+ def test_initialize
+ ps = Gem::PathSupport.new
+
+ assert_equal ENV["GEM_HOME"], ps.home
+
+ expected = util_path
+ assert_equal expected, ps.path, "defaults to GEM_PATH"
+ end
+
+ def test_initialize_home
+ ps = Gem::PathSupport.new "GEM_HOME" => "#{@tempdir}/foo"
+
+ assert_equal File.join(@tempdir, "foo"), ps.home
+
+ expected = util_path + [File.join(@tempdir, 'foo')]
+ assert_equal expected, ps.path
+ end
+
+ def test_initialize_path
+ ps = Gem::PathSupport.new "GEM_PATH" => %W[#{@tempdir}/foo #{@tempdir}/bar]
+
+ assert_equal ENV["GEM_HOME"], ps.home
+
+ expected = [
+ File.join(@tempdir, 'foo'),
+ File.join(@tempdir, 'bar'),
+ ENV["GEM_HOME"],
+ ]
+
+ assert_equal expected, ps.path
+ end
+
+ def test_initialize_home_path
+ ps = Gem::PathSupport.new("GEM_HOME" => "#{@tempdir}/foo",
+ "GEM_PATH" => %W[#{@tempdir}/foo #{@tempdir}/bar])
+
+ assert_equal File.join(@tempdir, "foo"), ps.home
+
+ expected = [File.join(@tempdir, 'foo'), File.join(@tempdir, 'bar')]
+ assert_equal expected, ps.path
+ end
+
+ def util_path
+ ENV["GEM_PATH"].split(File::PATH_SEPARATOR)
+ end
+end
diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb
index 485bab7..f46a20f 100644
--- a/test/rubygems/test_gem_platform.rb
+++ b/test/rubygems/test_gem_platform.rb
@@ -144,7 +144,7 @@ class TestGemPlatform < Gem::TestCase
def test_empty
platform = Gem::Platform.new 'cpu-other_platform1'
assert_respond_to platform, :empty?
- assert_equal false, platform.empty?
+ assert_equal false, Deprecate.skip_during { platform.empty? }
end
def test_to_s
diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb
index 66fb682..e039bb7 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -99,7 +99,7 @@ gems:
# REFACTOR: copied from test_gem_dependency_installer.rb
@gems_dir = File.join @tempdir, 'gems'
- @cache_dir = Gem.cache_dir(@gemhome)
+ @cache_dir = File.join @gemhome, "cache"
FileUtils.mkdir @gems_dir
# TODO: why does the remote fetcher need it written to disk?
@@ -152,7 +152,7 @@ gems:
fetcher.fetch_size 'gems.example.com/yaml'
end
- assert_equal 'uri scheme is invalid', e.message
+ assert_equal 'uri scheme is invalid: nil', e.message
end
def test_fetch_size_socket_error
@@ -209,7 +209,7 @@ gems:
fetcher = util_fuck_with_fetcher a1_data
- a1_cache_gem = Gem.cache_gem(@a1.file_name, @gemhome)
+ a1_cache_gem = @a1.cache_file
assert_equal a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com')
assert_equal("http://gems.example.com/gems/a-1.gem",
fetcher.instance_variable_get(:@test_arg).to_s)
@@ -221,8 +221,7 @@ gems:
inst = Gem::RemoteFetcher.fetcher
- assert_equal Gem.cache_gem(@a1.file_name, @gemhome),
- inst.download(@a1, 'http://gems.example.com')
+ assert_equal @a1.cache_file, inst.download(@a1, 'http://gems.example.com')
end
def test_download_local
@@ -234,8 +233,7 @@ gems:
inst = Gem::RemoteFetcher.fetcher
end
- assert_equal Gem.cache_gem(@a1.file_name, @gemhome),
- inst.download(@a1, local_path)
+ assert_equal @a1.cache_file, inst.download(@a1, local_path)
end
def test_download_local_space
@@ -249,21 +247,19 @@ gems:
inst = Gem::RemoteFetcher.fetcher
end
- assert_equal Gem.cache_gem(@a1.file_name, @gemhome),
- inst.download(@a1, local_path)
+ assert_equal @a1.cache_file, inst.download(@a1, local_path)
end
def test_download_install_dir
- a1_data = nil
- File.open @a1_gem, 'rb' do |fp|
- a1_data = fp.read
+ a1_data = File.open @a1_gem, 'rb' do |fp|
+ fp.read
end
fetcher = util_fuck_with_fetcher a1_data
install_dir = File.join @tempdir, 'more_gems'
- a1_cache_gem = Gem.cache_gem(@a1.file_name, install_dir)
+ a1_cache_gem = File.join install_dir, "cache", @a1.file_name
FileUtils.mkdir_p(File.dirname(a1_cache_gem))
actual = fetcher.download(@a1, 'http://gems.example.com', install_dir)
@@ -279,7 +275,7 @@ gems:
FileUtils.mv @a1_gem, @tempdir
local_path = File.join @tempdir, @a1.file_name
inst = nil
- File.chmod 0555, Gem.cache_dir(@gemhome)
+ FileUtils.chmod 0555, @a1.cache_dir
Dir.chdir @tempdir do
inst = Gem::RemoteFetcher.fetcher
@@ -288,19 +284,20 @@ gems:
assert_equal File.join(@tempdir, @a1.file_name),
inst.download(@a1, local_path)
ensure
- File.chmod 0755, Gem.cache_dir(@gemhome)
+ FileUtils.chmod 0755, @a1.cache_dir
end
def test_download_read_only
- File.chmod 0555, Gem.cache_dir(@gemhome)
- File.chmod 0555, File.join(@gemhome)
+ FileUtils.chmod 0555, @a1.cache_dir
+ FileUtils.chmod 0555, @gemhome
fetcher = util_fuck_with_fetcher File.read(@a1_gem)
fetcher.download(@a1, 'http://gems.example.com')
- assert File.exist?(Gem.cache_gem(@a1.file_name, Gem.user_dir))
+ a1_cache_gem = File.join Gem.user_dir, "cache", @a1.file_name
+ assert File.exist? a1_cache_gem
ensure
- File.chmod 0755, @gemhome
- File.chmod 0755, Gem.cache_dir(@gemhome)
+ FileUtils.chmod 0755, @gemhome
+ FileUtils.chmod 0755, @a1.cache_dir
end
end
@@ -319,7 +316,7 @@ gems:
fetcher = util_fuck_with_fetcher e1_data, :blow_chunks
- e1_cache_gem = Gem.cache_gem(e1.file_name, @gemhome)
+ e1_cache_gem = e1.cache_file
assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com')
@@ -337,7 +334,7 @@ gems:
inst = Gem::RemoteFetcher.fetcher
end
- cache_path = Gem.cache_gem(@a1.file_name, @gemhome)
+ cache_path = @a1.cache_file
FileUtils.mv local_path, cache_path
gem = Gem::Format.from_file_by_path cache_path
@@ -422,7 +419,7 @@ gems:
def test_fetch_path_gzip
fetcher = Gem::RemoteFetcher.new nil
- def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ def fetcher.fetch_http(uri, mtime, head = nil)
Gem.gzip 'foo'
end
@@ -432,7 +429,7 @@ gems:
def test_fetch_path_gzip_unmodified
fetcher = Gem::RemoteFetcher.new nil
- def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ def fetcher.fetch_http(uri, mtime, head = nil)
nil
end
@@ -442,53 +439,59 @@ gems:
def test_fetch_path_io_error
fetcher = Gem::RemoteFetcher.new nil
- def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ def fetcher.fetch_http(*)
raise EOFError
end
+ url = 'http://example.com/uri'
+
e = assert_raises Gem::RemoteFetcher::FetchError do
- fetcher.fetch_path 'uri'
+ fetcher.fetch_path url
end
- assert_equal 'EOFError: EOFError (uri)', e.message
- assert_equal 'uri', e.uri
+ assert_equal "EOFError: EOFError (#{url})", e.message
+ assert_equal url, e.uri
end
def test_fetch_path_socket_error
fetcher = Gem::RemoteFetcher.new nil
- def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ def fetcher.fetch_http(uri, mtime, head = nil)
raise SocketError
end
+ url = 'http://example.com/uri'
+
e = assert_raises Gem::RemoteFetcher::FetchError do
- fetcher.fetch_path 'uri'
+ fetcher.fetch_path url
end
- assert_equal 'SocketError: SocketError (uri)', e.message
- assert_equal 'uri', e.uri
+ assert_equal "SocketError: SocketError (#{url})", e.message
+ assert_equal url, e.uri
end
def test_fetch_path_system_call_error
fetcher = Gem::RemoteFetcher.new nil
- def fetcher.open_uri_or_path(uri, mtime = nil, head = nil)
+ def fetcher.fetch_http(uri, mtime = nil, head = nil)
raise Errno::ECONNREFUSED, 'connect(2)'
end
+ url = 'http://example.com/uri'
+
e = assert_raises Gem::RemoteFetcher::FetchError do
- fetcher.fetch_path 'uri'
+ fetcher.fetch_path url
end
- assert_match %r|ECONNREFUSED:.*connect\(2\) \(uri\)\z|,
+ assert_match %r|ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z|,
e.message
- assert_equal 'uri', e.uri
+ assert_equal url, e.uri
end
def test_fetch_path_unmodified
fetcher = Gem::RemoteFetcher.new nil
- def fetcher.open_uri_or_path(uri, mtime, head = nil)
+ def fetcher.fetch_http(uri, mtime, head = nil)
nil
end
@@ -551,16 +554,18 @@ gems:
end
end
- def test_open_uri_or_path
+ def test_fetch_http
fetcher = Gem::RemoteFetcher.new nil
+ url = 'http://gems.example.com/redirect'
conn = Object.new
def conn.started?() true end
def conn.request(req)
+ url = 'http://gems.example.com/redirect'
unless defined? @requested then
@requested = true
res = Net::HTTPMovedPermanently.new nil, 301, nil
- res.add_field 'Location', 'http://gems.example.com/real_path'
+ res.add_field 'Location', url
res
else
res = Net::HTTPOK.new nil, 200, nil
@@ -572,19 +577,21 @@ gems:
conn = { "#{Thread.current.object_id}:gems.example.com:80" => conn }
fetcher.instance_variable_set :@connections, conn
- data = fetcher.open_uri_or_path 'http://gems.example.com/redirect'
+ data = fetcher.fetch_http URI.parse(url)
assert_equal 'real_path', data
end
- def test_open_uri_or_path_limited_redirects
+ def test_fetch_http_redirects
fetcher = Gem::RemoteFetcher.new nil
+ url = 'http://gems.example.com/redirect'
conn = Object.new
def conn.started?() true end
def conn.request(req)
+ url = 'http://gems.example.com/redirect'
res = Net::HTTPMovedPermanently.new nil, 301, nil
- res.add_field 'Location', 'http://gems.example.com/redirect'
+ res.add_field 'Location', url
res
end
@@ -592,11 +599,10 @@ gems:
fetcher.instance_variable_set :@connections, conn
e = assert_raises Gem::RemoteFetcher::FetchError do
- fetcher.open_uri_or_path 'http://gems.example.com/redirect'
+ fetcher.fetch_http URI.parse(url)
end
- assert_equal 'too many redirects (http://gems.example.com/redirect)',
- e.message
+ assert_equal "too many redirects (#{url})", e.message
end
def test_request
@@ -631,6 +637,85 @@ gems:
assert_equal t.rfc2822, conn.payload['if-modified-since']
end
+ def test_user_agent
+ ua = @fetcher.user_agent
+
+ assert_match %r%^RubyGems/\S+ \S+ Ruby/\S+ \(.*?\)%, ua
+ assert_match %r%RubyGems/#{Regexp.escape Gem::VERSION}%, ua
+ assert_match %r% #{Regexp.escape Gem::Platform.local.to_s} %, ua
+ assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}%, ua
+ assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE} %, ua
+ end
+
+ def test_user_agent_engine
+ util_save_version
+
+ Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE)
+ Object.send :const_set, :RUBY_ENGINE, 'vroom'
+
+ ua = @fetcher.user_agent
+
+ assert_match %r%\) vroom%, ua
+ ensure
+ util_restore_version
+ end
+
+ def test_user_agent_engine_ruby
+ util_save_version
+
+ Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE)
+ Object.send :const_set, :RUBY_ENGINE, 'ruby'
+
+ ua = @fetcher.user_agent
+
+ assert_match %r%\)%, ua
+ ensure
+ util_restore_version
+ end
+
+ def test_user_agent_patchlevel
+ util_save_version
+
+ Object.send :remove_const, :RUBY_PATCHLEVEL
+ Object.send :const_set, :RUBY_PATCHLEVEL, 5
+
+ ua = @fetcher.user_agent
+
+ assert_match %r% patchlevel 5\)%, ua
+ ensure
+ util_restore_version
+ end
+
+ def test_user_agent_revision
+ util_save_version
+
+ Object.send :remove_const, :RUBY_PATCHLEVEL
+ Object.send :const_set, :RUBY_PATCHLEVEL, -1
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+ Object.send :const_set, :RUBY_REVISION, 6
+
+ ua = @fetcher.user_agent
+
+ assert_match %r% revision 6\)%, ua
+ assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}dev%, ua
+ ensure
+ util_restore_version
+ end
+
+ def test_user_agent_revision_missing
+ util_save_version
+
+ Object.send :remove_const, :RUBY_PATCHLEVEL
+ Object.send :const_set, :RUBY_PATCHLEVEL, -1
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+
+ ua = @fetcher.user_agent
+
+ assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE}\)%, ua
+ ensure
+ util_restore_version
+ end
+
def test_yaml_error_on_size
use_ui @ui do
self.class.enable_yaml = false
@@ -753,5 +838,24 @@ gems:
assert_equal "/home/skillet", @fetcher.correct_for_windows_path(path)
end
+ def util_save_version
+ @orig_RUBY_ENGINE = RUBY_ENGINE if defined? RUBY_ENGINE
+ @orig_RUBY_PATCHLEVEL = RUBY_PATCHLEVEL
+ @orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION
+ end
+
+ def util_restore_version
+ Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE)
+ Object.send :const_set, :RUBY_ENGINE, @orig_RUBY_ENGINE if
+ defined?(@orig_RUBY_ENGINE)
+
+ Object.send :remove_const, :RUBY_PATCHLEVEL
+ Object.send :const_set, :RUBY_PATCHLEVEL, @orig_RUBY_PATCHLEVEL
+
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+ Object.send :const_set, :RUBY_REVISION, @orig_RUBY_REVISION if
+ defined?(@orig_RUBY_REVISION)
+ end
+
end
diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb
index c8490de..b646171 100644
--- a/test/rubygems/test_gem_requirement.rb
+++ b/test/rubygems/test_gem_requirement.rb
@@ -256,6 +256,19 @@ class TestGemRequirement < Gem::TestCase
refute_satisfied_by "2.0", "~> 1.4.4"
end
+ def test_specific
+ refute req('> 1') .specific?
+ refute req('>= 1').specific?
+
+ assert req('!= 1').specific?
+ assert req('< 1') .specific?
+ assert req('<= 1').specific?
+ assert req('= 1') .specific?
+ assert req('~> 1').specific?
+
+ assert req('> 1', '> 2').specific? # GIGO
+ end
+
def test_bad
refute_satisfied_by "", "> 0.1"
refute_satisfied_by "1.2.3", "!= 1.2.3"
diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb
index 3fad8c4..bd4d960 100644
--- a/test/rubygems/test_gem_server.rb
+++ b/test/rubygems/test_gem_server.rb
@@ -9,12 +9,10 @@ require 'rubygems/server'
require 'stringio'
class Gem::Server
- attr_accessor :source_index
attr_reader :server
end
class TestGemServer < Gem::TestCase
-
def setup
super
@@ -41,52 +39,64 @@ class TestGemServer < Gem::TestCase
data = StringIO.new "GET /Marshal.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
@req.parse data
- @server.Marshal @req, @res
+ Deprecate.skip_during do
+ @server.Marshal @req, @res
+ end
assert_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date']
assert_equal 'application/octet-stream', @res['content-type']
- si = Gem::SourceIndex.new
- si.add_specs @a1, @a2
+ Deprecate.skip_during do
+ si = Gem::SourceIndex.new
+ si.add_specs @a1, @a2
- assert_equal si, Marshal.load(@res.body)
+ assert_equal si, Marshal.load(@res.body)
+ end
end
def test_Marshal_Z
data = StringIO.new "GET /Marshal.#{Gem.marshal_version}.Z HTTP/1.0\r\n\r\n"
@req.parse data
- @server.Marshal @req, @res
+ Deprecate.skip_during do
+ @server.Marshal @req, @res
+ end
assert_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date']
assert_equal 'application/x-deflate', @res['content-type']
- si = Gem::SourceIndex.new
- si.add_specs @a1, @a2
+ Deprecate.skip_during do
+ si = Gem::SourceIndex.new
+ si.add_specs @a1, @a2
- assert_equal si, Marshal.load(Gem.inflate(@res.body))
+ assert_equal si, Marshal.load(Gem.inflate(@res.body))
+ end
end
def test_latest_specs
data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
@req.parse data
- @server.latest_specs @req, @res
+ Deprecate.skip_during do
+ @server.latest_specs @req, @res
+ end
assert_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date']
assert_equal 'application/octet-stream', @res['content-type']
assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
- Marshal.load(@res.body)
+ Marshal.load(@res.body)
end
def test_latest_specs_gz
data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
@req.parse data
- @server.latest_specs @req, @res
+ Deprecate.skip_during do
+ @server.latest_specs @req, @res
+ end
assert_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date']
@@ -227,6 +237,4 @@ class TestGemServer < Gem::TestCase
@server.instance_variable_set :@server, webrick
end
-
end
-
diff --git a/test/rubygems/test_gem_silent_ui.rb b/test/rubygems/test_gem_silent_ui.rb
index 8005b3b..1968a89 100644
--- a/test/rubygems/test_gem_silent_ui.rb
+++ b/test/rubygems/test_gem_silent_ui.rb
@@ -55,7 +55,7 @@ class TestGemSilentUI < Gem::TestCase
assert_empty out, 'No output'
assert_empty err, 'No output'
-
+
out, err = capture_io do
use_ui @sui do
value = @sui.ask_yes_no 'Problem?', true
@@ -66,7 +66,7 @@ class TestGemSilentUI < Gem::TestCase
assert_empty err, 'No output'
assert value, 'Value is true'
-
+
out, err = capture_io do
use_ui @sui do
value = @sui.ask_yes_no 'Problem?', false
diff --git a/test/rubygems/test_gem_source_index.rb b/test/rubygems/test_gem_source_index.rb
index 89e2ea3..462ecbe 100644
--- a/test/rubygems/test_gem_source_index.rb
+++ b/test/rubygems/test_gem_source_index.rb
@@ -7,397 +7,250 @@
require 'rubygems/test_case'
require 'rubygems/source_index'
require 'rubygems/config_file'
+require 'rubygems/deprecate'
class TestGemSourceIndex < Gem::TestCase
-
def setup
super
util_setup_fake_fetcher
- end
-
- def test_self_from_gems_in
- spec_dir = File.join @gemhome, 'specifications'
-
- FileUtils.rm_r spec_dir
-
- FileUtils.mkdir_p spec_dir
-
- a1 = quick_spec 'a', '1' do |spec| spec.author = 'author 1' end
-
- spec_file = File.join spec_dir, a1.spec_name
-
- File.open spec_file, 'w' do |fp|
- fp.write a1.to_ruby
- end
-
- si = Gem::SourceIndex.from_gems_in spec_dir
-
- assert_equal [spec_dir], si.spec_dirs
- assert_equal [a1.full_name], si.gems.keys
- end
-
- def test_self_load_specification
- spec_dir = File.join @gemhome, 'specifications'
-
- FileUtils.rm_r spec_dir
-
- FileUtils.mkdir_p spec_dir
- a1 = quick_spec 'a', '1' do |spec| spec.author = 'author 1' end
-
- spec_file = File.join spec_dir, a1.spec_name
-
- File.open spec_file, 'w' do |fp|
- fp.write a1.to_ruby
- end
-
- spec = Gem::SourceIndex.load_specification spec_file
-
- assert_equal a1.author, spec.author
+ @source_index = Deprecate.skip_during { Gem.source_index }
end
- def test_self_load_specification_utf_8
- spec_dir = File.join @gemhome, 'specifications'
-
- FileUtils.rm_r spec_dir
-
- FileUtils.mkdir_p spec_dir
-
- spec_file = File.join spec_dir, "utf-8.gemspec"
- spec_data = <<-SPEC
-Gem::Specification.new do |s|
- s.name = %q{utf}
- s.version = "8"
+ def test_find_name
+ Deprecate.skip_during do
+ assert_equal [@a1, @a2, @a3a], @source_index.find_name('a')
+ assert_equal [@a2], @source_index.find_name('a', '= 2')
+ assert_equal [], @source_index.find_name('bogusstring')
+ assert_equal [], @source_index.find_name('a', '= 3')
- s.required_rubygems_version = Gem::Requirement.new(">= 0")
- s.authors = ["\317\200"]
- s.date = %q{2008-09-10}
- s.description = %q{This is a test description}
- s.email = %q{example@example.com}
- s.has_rdoc = true
- s.homepage = %q{http://example.com}
- s.require_paths = ["lib"]
- s.rubygems_version = %q{1.2.0}
- s.summary = %q{this is a summary}
+ source_index = Gem::SourceIndex.new
+ source_index.add_spec @a1
+ source_index.add_spec @a2
- if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
- s.specification_version = 2
+ assert_equal [@a1], source_index.find_name(@a1.name, '= 1')
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
- else
+ r1 = Gem::Requirement.create '= 1'
+ assert_equal [@a1], source_index.find_name(@a1.name, r1)
end
- else
end
-end
- SPEC
-
- spec_data.force_encoding 'UTF-8'
-
- File.open spec_file, 'w' do |io| io.write spec_data end
-
- spec = Gem::SourceIndex.load_specification spec_file
-
- pi = "\317\200"
- pi.force_encoding 'UTF-8' if pi.respond_to? :force_encoding
-
- assert_equal pi, spec.author
- end if Gem.ruby_version > Gem::Version.new('1.9')
- def test_self_load_specification_exception
- spec_dir = File.join @gemhome, 'specifications'
-
- FileUtils.mkdir_p spec_dir
-
- spec_file = File.join spec_dir, 'a-1.gemspec'
-
- File.open spec_file, 'w' do |fp|
- fp.write 'raise Exception, "epic fail"'
- end
-
- out, err = capture_io do
- assert_equal nil, Gem::SourceIndex.load_specification(spec_file)
+ def test_find_name_empty_cache
+ Deprecate.skip_during do
+ empty_source_index = Gem::SourceIndex.new
+ assert_equal [], empty_source_index.find_name("foo")
end
-
- assert_equal '', out
-
- expected = "Invalid gemspec in [#{spec_file}]: epic fail\n"
- assert_equal expected, err
end
- def test_self_load_specification_interrupt
- spec_dir = File.join @gemhome, 'specifications'
-
- FileUtils.mkdir_p spec_dir
-
- spec_file = File.join spec_dir, 'a-1.gemspec'
-
- File.open spec_file, 'w' do |fp|
- fp.write 'raise Interrupt, "^C"'
- end
-
- use_ui @ui do
- assert_raises Interrupt do
- Gem::SourceIndex.load_specification(spec_file)
+ # HACK: deprecated impl is failing tests, but I may want to port it over
+ def test_latest_specs
+ Deprecate.skip_during do
+ p1_ruby = quick_spec 'p', '1'
+ p1_platform = quick_spec 'p', '1' do |spec|
+ spec.platform = Gem::Platform::CURRENT
end
- end
-
- assert_equal '', @ui.output
- assert_equal '', @ui.error
- end
-
- def test_self_load_specification_syntax_error
- spec_dir = File.join @gemhome, 'specifications'
-
- FileUtils.mkdir_p spec_dir
-
- spec_file = File.join spec_dir, 'a-1.gemspec'
-
- File.open spec_file, 'w' do |fp|
- fp.write '1 +'
- end
-
- out, err = capture_io do
- assert_equal nil, Gem::SourceIndex.load_specification(spec_file)
- end
-
- assert_equal '', out
-
- assert_match(/syntax error/, err)
- end
-
- def test_self_load_specification_system_exit
- spec_dir = File.join @gemhome, 'specifications'
-
- FileUtils.mkdir_p spec_dir
- spec_file = File.join spec_dir, 'a-1.gemspec'
-
- File.open spec_file, 'w' do |fp|
- fp.write 'raise SystemExit, "bye-bye"'
- end
-
- use_ui @ui do
- assert_raises SystemExit do
- Gem::SourceIndex.load_specification(spec_file)
+ a1_platform = quick_spec @a1.name, (@a1.version) do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
end
- end
-
- assert_equal '', @ui.output
- assert_equal '', @ui.error
- end
-
- def test_create_from_directory
- # TODO
- end
- def test_find_name
- assert_equal [@a1, @a2, @a3a], @source_index.find_name('a')
- assert_equal [@a2], @source_index.find_name('a', '= 2')
- assert_equal [], @source_index.find_name('bogusstring')
- assert_equal [], @source_index.find_name('a', '= 3')
-
- source_index = Gem::SourceIndex.new
- source_index.add_spec @a1
- source_index.add_spec @a2
-
- assert_equal [@a1], source_index.find_name(@a1.name, '= 1')
-
- r1 = Gem::Requirement.create '= 1'
- assert_equal [@a1], source_index.find_name(@a1.name, r1)
- end
-
- def test_find_name_empty_cache
- empty_source_index = Gem::SourceIndex.new({})
- assert_equal [], empty_source_index.find_name("foo")
- end
-
- def test_latest_specs
- p1_ruby = quick_spec 'p', '1'
- p1_platform = quick_spec 'p', '1' do |spec|
- spec.platform = Gem::Platform::CURRENT
- end
-
- a1_platform = quick_spec @a1.name, (@a1.version) do |s|
- s.platform = Gem::Platform.new 'x86-my_platform1'
- end
+ a2_platform = quick_spec @a2.name, (@a2.version) do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
- a2_platform = quick_spec @a2.name, (@a2.version) do |s|
- s.platform = Gem::Platform.new 'x86-my_platform1'
- end
+ a2_platform_other = quick_spec @a2.name, (@a2.version) do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
- a2_platform_other = quick_spec @a2.name, (@a2.version) do |s|
- s.platform = Gem::Platform.new 'x86-other_platform1'
- end
+ a3_platform_other = quick_spec @a2.name, (@a2.version.bump) do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
- a3_platform_other = quick_spec @a2.name, (@a2.version.bump) do |s|
- s.platform = Gem::Platform.new 'x86-other_platform1'
+ @source_index.add_spec p1_ruby
+ @source_index.add_spec p1_platform
+ @source_index.add_spec a1_platform
+ @source_index.add_spec a2_platform
+ @source_index.add_spec a2_platform_other
+ @source_index.add_spec a3_platform_other
+
+ expected = [
+ @a2.full_name,
+ a2_platform.full_name,
+ a3_platform_other.full_name,
+ @b2.full_name,
+ @c1_2.full_name,
+ @a_evil9.full_name,
+ p1_ruby.full_name,
+ p1_platform.full_name,
+ @pl1.full_name
+ ].sort
+
+ latest_specs = @source_index.latest_specs.map { |s| s.full_name }.sort
+
+ assert_equal expected, latest_specs
end
-
- @source_index.add_spec p1_ruby
- @source_index.add_spec p1_platform
- @source_index.add_spec a1_platform
- @source_index.add_spec a2_platform
- @source_index.add_spec a2_platform_other
- @source_index.add_spec a3_platform_other
-
- expected = [
- @a2.full_name,
- a2_platform.full_name,
- a3_platform_other.full_name,
- @c1_2.full_name,
- @a_evil9.full_name,
- p1_ruby.full_name,
- p1_platform.full_name,
- ].sort
-
- latest_specs = @source_index.latest_specs.map { |s| s.full_name }.sort
-
- assert_equal expected, latest_specs
end
def test_load_gems_in
- spec_dir1 = File.join @gemhome, 'specifications'
- spec_dir2 = File.join @tempdir, 'gemhome2', 'specifications'
+ Deprecate.skip_during do
+ spec_dir1 = File.join @gemhome, 'specifications'
+ spec_dir2 = File.join @tempdir, 'gemhome2', 'specifications'
- FileUtils.rm_r spec_dir1
+ FileUtils.rm_r spec_dir1
- FileUtils.mkdir_p spec_dir1
- FileUtils.mkdir_p spec_dir2
+ FileUtils.mkdir_p spec_dir1
+ FileUtils.mkdir_p spec_dir2
- a1 = quick_spec 'a', '1' do |spec| spec.author = 'author 1' end
- a2 = quick_spec 'a', '1' do |spec| spec.author = 'author 2' end
+ a1 = quick_spec 'a', '1' do |spec| spec.author = 'author 1' end
+ a2 = quick_spec 'a', '1' do |spec| spec.author = 'author 2' end
- File.open File.join(spec_dir1, a1.spec_name), 'w' do |fp|
- fp.write a1.to_ruby
- end
+ path1 = File.join(spec_dir1, a1.spec_name)
+ path2 = File.join(spec_dir2, a2.spec_name)
- File.open File.join(spec_dir2, a2.spec_name), 'w' do |fp|
- fp.write a2.to_ruby
- end
+ File.open path1, 'w' do |fp|
+ fp.write a1.to_ruby
+ end
+
+ File.open path2, 'w' do |fp|
+ fp.write a2.to_ruby
+ end
- @source_index.load_gems_in spec_dir1, spec_dir2
+ @source_index.load_gems_in File.dirname(path1), File.dirname(path2)
- assert_equal a1.author, @source_index.specification(a1.full_name).author
+ assert_equal a1.author, @source_index.specification(a1.full_name).author
+ end
end
+ # REFACTOR: move to test_gem_commands_outdated_command.rb
def test_outdated
- util_setup_spec_fetcher
+ Deprecate.skip_during do
+ util_setup_spec_fetcher
- assert_equal [], @source_index.outdated
+ assert_equal [], @source_index.outdated
- updated = quick_spec @a2.name, (@a2.version.bump)
- util_setup_spec_fetcher updated
+ updated = quick_spec @a2.name, (@a2.version.bump)
+ util_setup_spec_fetcher updated
- assert_equal [updated.name], @source_index.outdated
+ assert_equal [updated.name], @source_index.outdated
- updated_platform = quick_spec @a2.name, (updated.version.bump) do |s|
- s.platform = Gem::Platform.new 'x86-other_platform1'
- end
+ updated_platform = quick_spec @a2.name, (updated.version.bump) do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
- util_setup_spec_fetcher updated, updated_platform
+ util_setup_spec_fetcher updated, updated_platform
- assert_equal [updated_platform.name], @source_index.outdated
+ assert_equal [updated_platform.name], @source_index.outdated
+ end
end
def test_prerelease_specs_kept_in_right_place
- gem_a1_alpha = quick_spec 'abba', '1.a'
- @source_index.add_spec gem_a1_alpha
-
- refute @source_index.latest_specs.include?(gem_a1_alpha)
- assert @source_index.latest_specs(true).include?(gem_a1_alpha)
- assert @source_index.find_name(gem_a1_alpha.full_name).empty?
- assert @source_index.prerelease_specs.include?(gem_a1_alpha)
+ Deprecate.skip_during do
+ gem_a1_alpha = quick_spec 'abba', '1.a'
+ @source_index.add_spec gem_a1_alpha
+
+ refute_includes @source_index.latest_specs, gem_a1_alpha
+ assert_includes @source_index.latest_specs(true), gem_a1_alpha
+ assert_empty @source_index.find_name gem_a1_alpha.full_name
+ assert_includes @source_index.prerelease_specs, gem_a1_alpha
+ end
end
def test_refresh_bang
- a1_spec = File.join @gemhome, "specifications", @a1.spec_name
-
- FileUtils.mv a1_spec, @tempdir
+ Deprecate.skip_during do
+ a1_spec = File.join @gemhome, "specifications", @a1.spec_name
- source_index = Gem::SourceIndex.from_installed_gems
+ FileUtils.mv a1_spec, @tempdir
- refute source_index.gems.include?(@a1.full_name)
+ Gem::Specification.reset
+ Gem.send :class_variable_set, :@@source_index, nil
+ source_index = Gem.source_index
- FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
+ refute_includes source_index.gems.keys.sort, @a1.full_name
- source_index.refresh!
-
- assert source_index.gems.include?(@a1.full_name)
- end
+ FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
- def test_refresh_bang_not_from_dir
- source_index = Gem::SourceIndex.new
-
- e = assert_raises RuntimeError do
source_index.refresh!
- end
- assert_equal 'source index not created from disk', e.message
+ assert source_index.gems.include?(@a1.full_name)
+ end
end
def test_remove_spec
- deleted = @source_index.remove_spec 'a-1'
+ Deprecate.skip_during do
+ si = Gem.source_index
- assert_equal %w[a-2 a-3.a a_evil-9 c-1.2],
- @source_index.all_gems.values.map { |s| s.full_name }.sort
+ expected = si.gems.keys.sort
- deleted = @source_index.remove_spec 'a-3.a'
+ expected.delete "a-1"
+ @source_index.remove_spec 'a-1'
- assert_equal %w[a-2 a_evil-9 c-1.2],
- @source_index.all_gems.values.map { |s| s.full_name }.sort
+ assert_equal expected, si.gems.keys.sort
+
+ expected.delete "a-3.a"
+ @source_index.remove_spec 'a-3.a'
+
+ assert_equal expected, si.gems.keys.sort
+ end
end
def test_search
- requirement = Gem::Requirement.create '= 9'
- with_version = Gem::Dependency.new(/^a/, requirement)
- assert_equal [@a_evil9], @source_index.search(with_version)
+ Deprecate.skip_during do
+ requirement = Gem::Requirement.create '= 9'
+ with_version = Gem::Dependency.new(/^a/, requirement)
+ assert_equal [@a_evil9], @source_index.search(with_version)
- with_default = Gem::Dependency.new(/^a/, Gem::Requirement.default)
- assert_equal [@a1, @a2, @a3a, @a_evil9], @source_index.search(with_default)
+ with_default = Gem::Dependency.new(/^a/, Gem::Requirement.default)
+ assert_equal [@a1, @a2, @a3a, @a_evil9], @source_index.search(with_default)
- c1_1_dep = Gem::Dependency.new 'c', '~> 1.1'
- assert_equal [@c1_2], @source_index.search(c1_1_dep)
+ c1_1_dep = Gem::Dependency.new 'c', '~> 1.1'
+ assert_equal [@c1_2], @source_index.search(c1_1_dep)
+ end
end
def test_search_platform
- util_set_arch 'x86-my_platform1'
+ Deprecate.skip_during do
+ util_set_arch 'x86-my_platform1'
- a1 = quick_spec 'a', '1'
- a1_mine = quick_spec 'a', '1' do |s|
- s.platform = Gem::Platform.new 'x86-my_platform1'
- end
- a1_other = quick_spec 'a', '1' do |s|
- s.platform = Gem::Platform.new 'x86-other_platform1'
- end
+ a1 = quick_spec 'a', '1'
+ a1_mine = quick_spec 'a', '1' do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
+ a1_other = quick_spec 'a', '1' do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
- si = Gem::SourceIndex.new(a1.full_name => a1, a1_mine.full_name => a1_mine,
- a1_other.full_name => a1_other)
+ si = Gem::SourceIndex.new
+ si.add_specs a1, a1_mine, a1_other
- dep = Gem::Dependency.new 'a', Gem::Requirement.new('1')
+ dep = Gem::Dependency.new 'a', Gem::Requirement.new('1')
- gems = si.search dep, true
+ gems = si.search dep, true
- assert_equal [a1, a1_mine], gems.sort
+ assert_equal [a1, a1_mine], gems.sort
+ end
end
def test_signature
- sig = @source_index.gem_signature('foo-1.2.3')
- assert_equal 64, sig.length
- assert_match(/^[a-f0-9]{64}$/, sig)
+ Deprecate.skip_during do
+ sig = @source_index.gem_signature('foo-1.2.3')
+ assert_equal 64, sig.length
+ assert_match(/^[a-f0-9]{64}$/, sig)
+ end
end
def test_specification
- assert_equal @a1, @source_index.specification(@a1.full_name)
+ Deprecate.skip_during do
+ assert_equal @a1, @source_index.specification(@a1.full_name)
- assert_nil @source_index.specification("foo-1.2.4")
+ assert_nil @source_index.specification("foo-1.2.4")
+ end
end
def test_index_signature
- sig = @source_index.index_signature
- assert_match(/^[a-f0-9]{64}$/, sig)
+ Deprecate.skip_during do
+ sig = @source_index.index_signature
+ assert_match(/^[a-f0-9]{64}$/, sig)
+ end
end
-
end
-
diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb
index de7bd9a..073b082 100644
--- a/test/rubygems/test_gem_spec_fetcher.rb
+++ b/test/rubygems/test_gem_spec_fetcher.rb
@@ -16,43 +16,43 @@ class TestGemSpecFetcher < Gem::TestCase
util_setup_fake_fetcher
- @a_pre = quick_spec 'a', '1.a'
- @source_index.add_spec @pl1
- @source_index.add_spec @a_pre
+ @a_pre = new_spec 'a', '1.a'
- @specs = @source_index.gems.sort.map do |name, spec|
- [spec.name, spec.version, spec.original_platform]
- end.sort
+ install_specs @a_pre
- @latest_specs = @source_index.latest_specs.sort.map do |spec|
- [spec.name, spec.version, spec.original_platform]
- end
+ Gem::Specification.remove_spec @b2
- @prerelease_specs = @source_index.prerelease_gems.sort.map do |name, spec|
+ @specs = Gem::Specification.map { |spec|
[spec.name, spec.version, spec.original_platform]
- end.sort
+ }.sort
- @fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] =
- util_gzip(Marshal.dump(@specs))
+ # TODO: couldn't all of this come from the fake spec fetcher?
+ @latest_specs = Gem::Specification.latest_specs.sort.map { |spec|
+ [spec.name, spec.version, spec.original_platform]
+ }
- @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
- util_gzip(Marshal.dump(@latest_specs))
+ prerelease = Gem::Specification.find_all { |s| s.version.prerelease? }
+ @prerelease_specs = prerelease.map { |spec|
+ [spec.name, spec.version, spec.original_platform]
+ }.sort
- @fetcher.data["#{@gem_repo}prerelease_specs.#{Gem.marshal_version}.gz"] =
- util_gzip(Marshal.dump(@prerelease_specs))
+ v = Gem.marshal_version
+ s_zip = util_gzip(Marshal.dump(@specs))
+ l_zip = util_gzip(Marshal.dump(@latest_specs))
+ p_zip = util_gzip(Marshal.dump(@prerelease_specs))
+ @fetcher.data["#{@gem_repo}specs.#{v}.gz"] = s_zip
+ @fetcher.data["#{@gem_repo}latest_specs.#{v}.gz"] = l_zip
+ @fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip
@sf = Gem::SpecFetcher.new
end
def test_fetch_all
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] =
- util_zip(Marshal.dump(@a1))
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] =
- util_zip(Marshal.dump(@a2))
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
- util_zip(Marshal.dump(@a_pre))
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a3a.spec_name}.rz"] =
- util_zip(Marshal.dump(@a3a))
+ d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}"
+ @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1))
+ @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2))
+ @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre))
+ @fetcher.data["#{d}#{@a3a.spec_name}.rz"] = util_zip(Marshal.dump(@a3a))
dep = Gem::Dependency.new 'a', 1
@@ -70,12 +70,10 @@ class TestGemSpecFetcher < Gem::TestCase
end
def test_fetch_latest
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] =
- util_zip(Marshal.dump(@a1))
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] =
- util_zip(Marshal.dump(@a2))
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
- util_zip(Marshal.dump(@a_pre))
+ d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}"
+ @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1))
+ @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2))
+ @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre))
dep = Gem::Dependency.new 'a', 1
specs_and_sources = @sf.fetch dep
@@ -88,15 +86,12 @@ class TestGemSpecFetcher < Gem::TestCase
end
def test_fetch_prerelease
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] =
- util_zip(Marshal.dump(@a1))
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] =
- util_zip(Marshal.dump(@a2))
- @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
- util_zip(Marshal.dump(@a_pre))
+ d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}"
+ @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1))
+ @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2))
+ @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre))
- dep = Gem::Dependency.new 'a', '1.a'
- specs_and_sources = @sf.fetch dep, false, true, true
+ specs_and_sources = @sf.fetch dep('a', '1.a'), false, true, true
spec_names = specs_and_sources.map do |spec, source_uri|
[spec.full_name, source_uri]
@@ -293,11 +288,11 @@ class TestGemSpecFetcher < Gem::TestCase
assert_equal [@uri], specs.keys
- assert_equal([["a", Gem::Version.new("1"), "ruby"],
- ["a", Gem::Version.new("2"), "ruby"],
- ["a_evil", Gem::Version.new("9"), "ruby"],
- ["c", Gem::Version.new("1.2"), "ruby"],
- ["pl", Gem::Version.new("1"), "i386-linux"]],
+ assert_equal([["a", Gem::Version.new("1"), "ruby"],
+ ["a", Gem::Version.new("2"), "ruby"],
+ ["a_evil", Gem::Version.new("9"), "ruby"],
+ ["c", Gem::Version.new("1.2"), "ruby"],
+ ["pl", Gem::Version.new("1"), "i386-linux"]],
specs[@uri].sort)
end
@@ -347,19 +342,17 @@ class TestGemSpecFetcher < Gem::TestCase
end
def test_load_specs
- specs = @sf.load_specs @uri, 'specs'
-
expected = [
- ['a', Gem::Version.new('1.a'), Gem::Platform::RUBY],
+ ['a', Gem::Version.new('1.a'), Gem::Platform::RUBY],
['a', Gem::Version.new(1), Gem::Platform::RUBY],
['a', Gem::Version.new(2), Gem::Platform::RUBY],
- ['a', Gem::Version.new('3.a'), Gem::Platform::RUBY],
+ ['a', Gem::Version.new('3.a'), Gem::Platform::RUBY],
['a_evil', Gem::Version.new(9), Gem::Platform::RUBY],
['c', Gem::Version.new('1.2'), Gem::Platform::RUBY],
['pl', Gem::Version.new(1), 'i386-linux'],
]
- assert_equal expected, specs
+ assert_equal expected, @sf.load_specs(@uri, 'specs')
cache_dir = File.join Gem.user_home, '.gem', 'specs', 'gems.example.com%80'
assert File.exist?(cache_dir), "#{cache_dir} does not exist"
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
index d7f5772..ef52f0a 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -35,8 +35,8 @@ Gem::Specification.new do |s|
s.version = %q{0.4.0}
s.has_rdoc = true
s.summary = %q{A Hash which automatically computes keys.}
- s.files = ["lib/keyedlist.rb"]
- s.require_paths = ["lib"]
+ s.files = [%q{lib/keyedlist.rb}]
+ s.require_paths = [%q{lib}]
s.autorequire = %q{keyedlist}
s.author = %q{Florian Gross}
s.email = %q{flgr@ccan.de}
@@ -46,11 +46,9 @@ end
def setup
super
- # TODO: there is no reason why the spec tests need to write to disk
- @a1 = quick_gem 'a', '1' do |s|
+ @a1 = quick_spec 'a', '1' do |s|
s.executable = 'exec'
s.extensions << 'ext/a/extconf.rb'
- s.has_rdoc = 'true'
s.test_file = 'test/suite.rb'
s.requirements << 'A working computer'
s.rubyforge_project = 'example'
@@ -64,15 +62,10 @@ end
s.files = %w[lib/code.rb]
end
- @a2 = quick_gem 'a', '2' do |s|
+ @a2 = quick_spec 'a', '2' do |s|
s.files = %w[lib/code.rb]
end
- FileUtils.mkdir_p File.join(@tempdir, 'bin')
- File.open File.join(@tempdir, 'bin', 'exec'), 'w' do |fp|
- fp.puts "#!#{Gem.ruby}"
- end
-
@current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
end
@@ -83,7 +76,6 @@ end
bindir
cert_chain
date
- default_executable
dependencies
description
email
@@ -91,7 +83,6 @@ end
extensions
extra_rdoc_files
files
- has_rdoc
homepage
licenses
name
@@ -129,18 +120,39 @@ end
assert_equal @current_version, new_spec.specification_version
end
+ def test_self_from_yaml_syck_bug
+ # This is equivalent to (and totally valid) psych 1.0 output and
+ # causes parse errors on syck.
+ yaml = @a1.to_yaml
+ yaml.sub!(/^date:.*/, "date: 2011-04-26 00:00:00.000000000Z")
+
+ new_spec = with_syck do
+ Gem::Specification.from_yaml yaml
+ end
+
+ assert_kind_of Time, @a1.date
+ assert_kind_of Time, new_spec.date
+ end
+
def test_self_load
- spec = File.join @gemhome, 'specifications', @a2.spec_name
- gs = Gem::Specification.load spec
+ full_path = @a2.spec_file
+ write_file full_path do |io|
+ io.write @a2.to_ruby_for_cache
+ end
+
+ spec = Gem::Specification.load full_path
+
+ @a2.files.clear
- assert_equal @a2, gs
+ assert_equal @a2, spec
end
def test_self_load_legacy_ruby
- spec = eval LEGACY_RUBY_SPEC
+ spec = Deprecate.skip_during do
+ eval LEGACY_RUBY_SPEC
+ end
assert_equal 'keyedlist', spec.name
assert_equal '0.4.0', spec.version.to_s
- assert_equal true, spec.has_rdoc?
assert_equal Gem::Specification::TODAY, spec.date
assert spec.required_ruby_version.satisfied_by?(Gem::Version.new('1'))
assert_equal false, spec.has_unit_tests?
@@ -195,8 +207,6 @@ end
assert_equal [], spec.requirements
assert_equal [], spec.dependencies
assert_equal 'bin', spec.bindir
- assert_equal true, spec.has_rdoc
- assert_equal true, spec.has_rdoc?
assert_equal '>= 0', spec.required_ruby_version.to_s
assert_equal '>= 0', spec.required_rubygems_version.to_s
end
@@ -279,9 +289,6 @@ end
assert_equal 'bin', spec.bindir
assert_same spec.bindir, new_spec.bindir
- assert_equal true, spec.has_rdoc
- assert_same spec.has_rdoc, new_spec.has_rdoc
-
assert_equal '>= 0', spec.required_ruby_version.to_s
assert_same spec.required_ruby_version, new_spec.required_ruby_version
@@ -290,6 +297,23 @@ end
new_spec.required_rubygems_version
end
+ def test_initialize_copy_broken
+ spec = Gem::Specification.new do |s|
+ s.name = 'a'
+ s.version = '1'
+ end
+
+ spec.instance_variable_set :@licenses, :blah
+ spec.loaded_from = '/path/to/file'
+
+ e = assert_raises Gem::FormatException do
+ spec.dup
+ end
+
+ assert_equal 'a-1 has an invalid value for @licenses', e.message
+ assert_equal '/path/to/file', e.file_path
+ end
+
def test__dump
@a2.platform = Gem::Platform.local
@a2.instance_variable_set :@original_platform, 'old_platform'
@@ -338,37 +362,33 @@ end
def test_date_equals_date
@a1.date = Date.new(2003, 9, 17)
- assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date
end
def test_date_equals_string
@a1.date = '2003-09-17'
- assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date
+ end
+
+ def test_date_equals_string_bad
+ assert_raises Gem::InvalidSpecificationException do
+ @a1.date = '9/11/2003'
+ end
end
def test_date_equals_time
@a1.date = Time.local(2003, 9, 17, 0,0,0)
- assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date
end
def test_date_equals_time_local
- # HACK PDT
- @a1.date = Time.local(2003, 9, 17, 19,50,0)
- assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
+ @a1.date = Time.local(2003, 9, 17, 19,50,0) # may not pass in utc >= +4
+ assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date
end
def test_date_equals_time_utc
- # HACK PDT
- @a1.date = Time.local(2003, 9, 17, 19,50,0)
- assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
- end
-
- def test_default_executable
- assert_equal 'exec', @a1.default_executable
-
- @a1.default_executable = nil
- @a1.instance_variable_set :@executables, nil
- assert_equal nil, @a1.default_executable
+ @a1.date = Time.utc(2003, 9, 17, 19,50,0)
+ assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date
end
def test_dependencies
@@ -391,60 +411,20 @@ end
end
def test_eql_eh
- g1 = quick_spec 'gem'
- g2 = quick_spec 'gem'
+ g1 = new_spec 'gem', 1
+ g2 = new_spec 'gem', 1
assert_equal g1, g2
assert_equal g1.hash, g2.hash
assert_equal true, g1.eql?(g2)
end
- def test_equals2
- assert_equal @a1, @a1
- assert_equal @a1, @a1.dup
- refute_equal @a1, @a2
- refute_equal @a1, Object.new
- end
-
- # The cgikit specification was reported to be causing trouble in at least
- # one version of RubyGems, so we test explicitly for it.
- def test_equals2_cgikit
- cgikit = Gem::Specification.new do |s|
- s.name = %q{cgikit}
- s.version = "1.1.0"
- s.date = %q{2004-03-13}
- s.summary = %q{CGIKit is a componented-oriented web application } +
- %q{framework like Apple Computers WebObjects. } +
- %{This framework services Model-View-Controller architecture } +
- %q{programming by components based on a HTML file, a definition } +
- %q{file and a Ruby source. }
- s.email = %q{info@spice-of-life.net}
- s.homepage = %q{http://www.spice-of-life.net/download/cgikit/}
- s.autorequire = %q{cgikit}
- s.bindir = nil
- s.has_rdoc = true
- s.required_ruby_version = nil
- s.platform = nil
- s.files = ["lib/cgikit", "lib/cgikit.rb", "lib/cgikit/components", "..."]
- end
-
- assert_equal cgikit, cgikit
- end
-
- def test_equals2_default_executable
- spec = @a1.dup
- spec.default_executable = 'xx'
-
- refute_equal @a1, spec
- refute_equal spec, @a1
- end
-
- def test_equals2_extensions
+ def test_eql_eh_extensions
spec = @a1.dup
spec.extensions = 'xx'
- refute_equal @a1, spec
- refute_equal spec, @a1
+ refute_operator @a1, :eql?, spec
+ refute_operator spec, :eql?, @a1
end
def test_executables
@@ -542,9 +522,26 @@ end
assert_kind_of Integer, @a1.hash
end
+ def test_for_cache
+ @a2.add_runtime_dependency 'b', '1'
+ @a2.dependencies.first.instance_variable_set :@type, nil
+ @a2.required_rubygems_version = Gem::Requirement.new '> 0'
+ @a2.test_files = %w[test/test_b.rb]
+
+ refute_empty @a2.files
+ refute_empty @a2.test_files
+
+ spec = @a2.for_cache
+
+ assert_empty spec.files
+ assert_empty spec.test_files
+
+ refute_empty @a2.files
+ refute_empty @a2.test_files
+ end
+
def test_full_gem_path
- assert_equal File.join(@gemhome, 'gems', @a1.full_name),
- @a1.full_gem_path
+ assert_equal File.join(@gemhome, 'gems', @a1.full_name), @a1.full_gem_path
@a1.original_platform = 'mswin32'
@@ -553,11 +550,11 @@ end
end
def test_full_gem_path_double_slash
- gemhome = @gemhome.sub(/\w\//, '\&/')
- @a1.loaded_from = File.join gemhome, 'specifications', @a1.spec_name
+ gemhome = @gemhome.to_s.sub(/\w\//, '\&/')
+ @a1.loaded_from = File.join gemhome, "specifications", @a1.spec_name
- assert_equal File.join(@gemhome, 'gems', @a1.full_name),
- @a1.full_gem_path
+ expected = File.join @gemhome, "gems", @a1.full_name
+ assert_equal expected, @a1.full_gem_path
end
def test_full_name
@@ -589,21 +586,6 @@ end
end
end
- def test_has_rdoc_eh
- assert @a1.has_rdoc?
- end
-
- def test_has_rdoc_equals
-
- use_ui @ui do
- @a1.has_rdoc = false
- end
-
- assert_equal '', @ui.output
-
- assert_equal true, @a1.has_rdoc
- end
-
def test_hash
assert_equal @a1.hash, @a1.hash
assert_equal @a1.hash, @a1.dup.hash
@@ -611,15 +593,14 @@ end
end
def test_installation_path
- assert_equal @gemhome, @a1.installation_path
+ Deprecate.skip_during do
+ assert_equal @gemhome, @a1.installation_path
- @a1.instance_variable_set :@loaded_from, nil
+ @a1.instance_variable_set :@loaded_from, nil
+ @a1.instance_variable_set :@loaded, false
- e = assert_raises Gem::Exception do
- @a1.installation_path
+ assert_nil @a1.installation_path
end
-
- assert_equal 'spec a-1 is not from an installed gem', e.message
end
def test_lib_files
@@ -717,8 +698,8 @@ end
end
def test_spaceship_name
- s1 = quick_spec 'a', '1'
- s2 = quick_spec 'b', '1'
+ s1 = new_spec 'a', '1'
+ s2 = new_spec 'b', '1'
assert_equal(-1, (s1 <=> s2))
assert_equal( 0, (s1 <=> s1))
@@ -726,8 +707,8 @@ end
end
def test_spaceship_platform
- s1 = quick_spec 'a', '1'
- s2 = quick_spec 'a', '1' do |s|
+ s1 = new_spec 'a', '1'
+ s2 = new_spec 'a', '1' do |s|
s.platform = Gem::Platform.new 'x86-my_platform1'
end
@@ -737,8 +718,8 @@ end
end
def test_spaceship_version
- s1 = quick_spec 'a', '1'
- s2 = quick_spec 'a', '2'
+ s1 = new_spec 'a', '1'
+ s2 = new_spec 'a', '2'
assert_equal( -1, (s1 <=> s2))
assert_equal( 0, (s1 <=> s1))
@@ -773,13 +754,13 @@ Gem::Specification.new do |s|
s.version = \"2\"
s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version=
- s.authors = [\"A User\"]
+ s.authors = [%q{A User}]
s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
s.description = %q{This is a test description}
s.email = %q{example@example.com}
- s.files = [\"lib/code.rb\"]
+ s.files = [%q{lib/code.rb}]
s.homepage = %q{http://example.com}
- s.require_paths = [\"lib\"]
+ s.require_paths = [%q{lib}]
s.rubygems_version = %q{#{Gem::VERSION}}
s.summary = %q{this is a summary}
@@ -820,12 +801,12 @@ Gem::Specification.new do |s|
s.version = \"2\"
s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version=
- s.authors = [\"A User\"]
+ s.authors = [%q{A User}]
s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
s.description = %q{This is a test description}
s.email = %q{example@example.com}
s.homepage = %q{http://example.com}
- s.require_paths = [\"lib\"]
+ s.require_paths = [%q{lib}]
s.rubygems_version = %q{#{Gem::VERSION}}
s.summary = %q{this is a summary}
@@ -868,22 +849,21 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform.new(#{expected_platform})
s.required_rubygems_version = Gem::Requirement.new(\">= 0\") if s.respond_to? :required_rubygems_version=
- s.authors = [\"A User\"]
+ s.authors = [%q{A User}]
s.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
- s.default_executable = %q{exec}
s.description = %q{This is a test description}
s.email = %q{example@example.com}
- s.executables = [\"exec\"]
- s.extensions = [\"ext/a/extconf.rb\"]
- s.files = [\"lib/code.rb\", \"test/suite.rb\", \"bin/exec\", \"ext/a/extconf.rb\"]
+ s.executables = [%q{exec}]
+ s.extensions = [%q{ext/a/extconf.rb}]
+ s.files = [%q{lib/code.rb}, %q{test/suite.rb}, %q{bin/exec}, %q{ext/a/extconf.rb}]
s.homepage = %q{http://example.com}
- s.licenses = [\"MIT\"]
- s.require_paths = [\"lib\"]
- s.requirements = [\"A working computer\"]
+ s.licenses = [%q{MIT}]
+ s.require_paths = [%q{lib}]
+ s.requirements = [%q{A working computer}]
s.rubyforge_project = %q{example}
s.rubygems_version = %q{#{Gem::VERSION}}
s.summary = %q{this is a summary}
- s.test_files = [\"test/suite.rb\"]
+ s.test_files = [%q{test/suite.rb}]
if s.respond_to? :specification_version then
s.specification_version = 3
@@ -913,7 +893,9 @@ end
end
def test_to_ruby_legacy
- gemspec1 = eval LEGACY_RUBY_SPEC
+ gemspec1 = Deprecate.skip_during do
+ eval LEGACY_RUBY_SPEC
+ end
ruby_code = gemspec1.to_ruby
gemspec2 = eval ruby_code
@@ -936,7 +918,7 @@ end
refute_match '!!null', yaml_str
- same_spec = YAML.load(yaml_str)
+ same_spec = Gem::Specification.from_yaml(yaml_str)
assert_equal @a1, same_spec
end
@@ -945,7 +927,7 @@ end
@a1.platform = Gem::Platform.local
yaml_str = @a1.to_yaml
- same_spec = YAML.load(yaml_str)
+ same_spec = Gem::Specification.from_yaml(yaml_str)
assert_equal Gem::Platform.local, same_spec.platform
@@ -984,41 +966,48 @@ end
end
end
+ def x s; s.gsub(/xxx/, ''); end
+ def w; x "WARxxxNING"; end
+ def t; x "TOxxxDO"; end
+ def f; x "FxxxIXME"; end
+
def test_validate_authors
util_setup_validate
Dir.chdir @tempdir do
- @a1.authors = []
+ @a1.authors = [""]
use_ui @ui do
@a1.validate
end
- assert_equal "WARNING: no author specified\n", @ui.error, 'error'
+ assert_equal "#{w}: no author specified\n", @ui.error, 'error'
@a1.authors = [Object.new]
+ assert_equal [], @a1.authors
+
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal 'authors must be Array of Strings', e.message
+ assert_equal "authors may not be empty", e.message
- @a1.authors = ['FIXME (who is writing this software)']
+ @a1.authors = ["#{f} (who is writing this software)"]
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not an author', e.message
+ assert_equal %{"#{f}" or "#{t}" is not an author}, e.message
- @a1.authors = ['TODO (who is writing this software)']
+ @a1.authors = ["#{t} (who is writing this software)"]
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not an author', e.message
+ assert_equal %{"#{f}" or "#{t}" is not an author}, e.message
end
end
@@ -1032,7 +1021,7 @@ end
@a1.validate
end
- assert_equal "WARNING: deprecated autorequire specified\n",
+ assert_equal "#{w}: deprecated autorequire specified\n",
@ui.error, 'error'
end
end
@@ -1047,34 +1036,34 @@ end
@a1.validate
end
- assert_equal "WARNING: no description specified\n", @ui.error, 'error'
+ assert_equal "#{w}: no description specified\n", @ui.error, "error"
@ui = Gem::MockGemUi.new
- @a1.summary = 'this is my summary'
+ @a1.summary = "this is my summary"
@a1.description = @a1.summary
use_ui @ui do
@a1.validate
end
- assert_equal "WARNING: description and summary are identical\n",
- @ui.error, 'error'
+ assert_equal "#{w}: description and summary are identical\n",
+ @ui.error, "error"
- @a1.description = 'FIXME (describe your package)'
+ @a1.description = "#{f} (describe your package)"
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not a description', e.message
+ assert_equal %{"#{f}" or "#{t}" is not a description}, e.message
- @a1.description = 'TODO (describe your package)'
+ @a1.description = "#{t} (describe your package)"
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not a description', e.message
+ assert_equal %{"#{f}" or "#{t}" is not a description}, e.message
end
end
@@ -1082,35 +1071,33 @@ end
util_setup_validate
Dir.chdir @tempdir do
- @a1.email = ''
+ @a1.email = ""
use_ui @ui do
@a1.validate
end
- assert_equal "WARNING: no email specified\n", @ui.error, 'error'
+ assert_equal "#{w}: no email specified\n", @ui.error, "error"
- @a1.email = 'FIXME (your e-mail)'
+ @a1.email = "FIxxxXME (your e-mail)".sub(/xxx/, "")
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not an email address', e.message
+ assert_equal %{"#{f}" or "#{t}" is not an email}, e.message
- @a1.email = 'TODO (your e-mail)'
+ @a1.email = "#{t} (your e-mail)"
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not an email address', e.message
+ assert_equal %{"#{f}" or "#{t}" is not an email}, e.message
end
end
def test_validate_empty
- util_setup_validate
-
e = assert_raises Gem::InvalidSpecificationException do
Gem::Specification.new.validate
end
@@ -1134,7 +1121,7 @@ end
assert_equal %w[exec], @a1.executables
assert_equal '', @ui.output, 'output'
- assert_equal "WARNING: bin/exec is missing #! line\n", @ui.error, 'error'
+ assert_equal "#{w}: bin/exec is missing #! line\n", @ui.error, 'error'
end
def test_validate_empty_require_paths
@@ -1183,7 +1170,7 @@ end
@a1.validate
end
- assert_equal "WARNING: no homepage specified\n", @ui.error, 'error'
+ assert_equal "#{w}: no homepage specified\n", @ui.error, 'error'
@ui = Gem::MockGemUi.new
@@ -1193,7 +1180,7 @@ end
@a1.validate
end
- assert_equal "WARNING: no homepage specified\n", @ui.error, 'error'
+ assert_equal "#{w}: no homepage specified\n", @ui.error, 'error'
@a1.homepage = 'over at my cool site'
@@ -1216,6 +1203,26 @@ end
assert_equal 'invalid value for attribute name: ":json"', e.message
end
+ def test_validate_non_nil
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ assert @a1.validate
+
+ Gem::Specification.non_nil_attributes.each do |name|
+ next if name == :files # set by #normalize
+ spec = @a1.dup
+ spec.instance_variable_set "@#{name}", nil
+
+ e = assert_raises Gem::InvalidSpecificationException do
+ spec.validate
+ end
+
+ assert_match %r%^#{name}%, e.message
+ end
+ end
+ end
+
def test_validate_platform_legacy
util_setup_validate
@@ -1270,23 +1277,23 @@ end
@a1.validate
end
- assert_equal "WARNING: no summary specified\n", @ui.error, 'error'
+ assert_equal "#{w}: no summary specified\n", @ui.error, 'error'
- @a1.summary = 'FIXME (describe your package)'
+ @a1.summary = "#{f} (describe your package)"
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not a summary', e.message
+ assert_equal %{"#{f}" or "#{t}" is not a summary}, e.message
- @a1.summary = 'TODO (describe your package)'
+ @a1.summary = "#{t} (describe your package)"
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
- assert_equal '"FIXME" or "TODO" is not a summary', e.message
+ assert_equal %{"#{f}" or "#{t}" is not a summary}, e.message
end
end
@@ -1310,6 +1317,67 @@ end
specfile.delete
end
+ ##
+ # KEEP p-1-x86-darwin-8
+ # KEEP p-1
+ # KEEP c-1.2
+ # KEEP a_evil-9
+ # a-1
+ # a-1-x86-my_platform-1
+ # KEEP a-2
+ # a-2-x86-other_platform-1
+ # KEEP a-2-x86-my_platform-1
+ # a-3.a
+ # KEEP a-3-x86-other_platform-1
+
+ def test_latest_specs
+ util_clear_gems
+ util_setup_fake_fetcher
+
+ quick_spec 'p', '1'
+
+ p1_curr = quick_spec 'p', '1' do |spec|
+ spec.platform = Gem::Platform::CURRENT
+ end
+
+ quick_spec @a1.name, @a1.version do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
+
+ quick_spec @a1.name, @a1.version do |s|
+ s.platform = Gem::Platform.new 'x86-third_platform1'
+ end
+
+ quick_spec @a2.name, @a2.version do |s|
+ s.platform = Gem::Platform.new 'x86-my_platform1'
+ end
+
+ quick_spec @a2.name, @a2.version do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
+
+ quick_spec @a2.name, @a2.version.bump do |s|
+ s.platform = Gem::Platform.new 'x86-other_platform1'
+ end
+
+ Gem::Specification.remove_spec @b2
+ Gem::Specification.remove_spec @pl1
+
+ expected = %W[
+ a-2
+ a-2-x86-my_platform-1
+ a-3-x86-other_platform-1
+ a_evil-9
+ c-1.2
+ p-1
+ #{p1_curr.full_name}
+ ]
+
+ latest_specs = Gem::Specification.latest_specs.map(&:full_name).sort
+
+ assert_equal expected, latest_specs
+ end
+
def util_setup_deps
@gem = quick_spec "awesome", "1.0" do |awesome|
awesome.add_runtime_dependency "bonobo", []
@@ -1322,13 +1390,36 @@ end
def util_setup_validate
Dir.chdir @tempdir do
- FileUtils.mkdir_p File.join('ext', 'a')
- FileUtils.mkdir_p 'lib'
- FileUtils.mkdir_p 'test'
+ FileUtils.mkdir_p File.join("ext", "a")
+ FileUtils.mkdir_p "lib"
+ FileUtils.mkdir_p "test"
+ FileUtils.mkdir_p "bin"
+
+ FileUtils.touch File.join("ext", "a", "extconf.rb")
+ FileUtils.touch File.join("lib", "code.rb")
+ FileUtils.touch File.join("test", "suite.rb")
- FileUtils.touch File.join('ext', 'a', 'extconf.rb')
- FileUtils.touch File.join('lib', 'code.rb')
- FileUtils.touch File.join('test', 'suite.rb')
+ File.open "bin/exec", "w" do |fp|
+ fp.puts "#!#{Gem.ruby}"
+ end
+ end
+ end
+
+ def with_syck
+ begin
+ require "yaml"
+ old_engine = YAML::ENGINE.yamler
+ YAML::ENGINE.yamler = 'syck'
+ rescue NameError
+ # probably on 1.8, ignore
+ end
+
+ yield
+ ensure
+ begin
+ YAML::ENGINE.yamler = old_engine
+ rescue NameError
+ # ignore
end
end
end
diff --git a/test/rubygems/test_gem_text.rb b/test/rubygems/test_gem_text.rb
index 775f1e9..7324e42 100644
--- a/test/rubygems/test_gem_text.rb
+++ b/test/rubygems/test_gem_text.rb
@@ -26,6 +26,21 @@ class TestGemText < Gem::TestCase
assert_equal " text to wrap", format_text("text to wrap", 40, 2)
end
+ def test_format_text_trailing # for two spaces after .
+ text = <<-TEXT
+This line is really, really long. So long, in fact, that it is more than eighty characters long! The purpose of this line is for testing wrapping behavior because sometimes people don't wrap their text to eighty characters. Without the wrapping, the text might not look good in the RSS feed.
+ TEXT
+
+ expected = <<-EXPECTED
+This line is really, really long. So long, in fact, that it is more than
+eighty characters long! The purpose of this line is for testing wrapping
+behavior because sometimes people don't wrap their text to eighty characters.
+Without the wrapping, the text might not look good in the RSS feed.
+ EXPECTED
+
+ assert_equal expected, format_text(text, 78)
+ end
+
def test_levenshtein_distance_add
assert_equal 2, levenshtein_distance("zentest", "zntst")
assert_equal 2, levenshtein_distance("zntst", "zentest")
diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb
index 0c08f42..93a6f65 100644
--- a/test/rubygems/test_gem_uninstaller.rb
+++ b/test/rubygems/test_gem_uninstaller.rb
@@ -14,26 +14,15 @@ class TestGemUninstaller < Gem::InstallerTestCase
@user_spec.executables = ["executable"]
- # HACK util_make_exec
- user_bin_dir = File.join Gem.user_dir, 'gems', @user_spec.full_name, 'bin'
- FileUtils.mkdir_p user_bin_dir
- exec_path = File.join user_bin_dir, "executable"
- open exec_path, 'w' do |f|
- f.puts "#!/usr/bin/ruby"
- end
-
- user_bin_dir = File.join Gem.user_dir, 'bin'
- FileUtils.mkdir_p user_bin_dir
- exec_path = File.join user_bin_dir, "executable"
- open exec_path, 'w' do |f|
- f.puts "#!/usr/bin/ruby"
- end
-
build_rake_in do
use_ui ui do
@installer.install
@user_installer.install
- Gem::Uninstaller.new(@user_spec.name, :executables => false).uninstall
+
+ Gem.use_paths @gemhome, Gem.user_dir
+
+ @spec = Gem::Specification.find_by_name 'a'
+ @user_spec = Gem::Specification.find_by_name 'b'
end
end
end
@@ -44,6 +33,18 @@ class TestGemUninstaller < Gem::InstallerTestCase
assert_match %r|/foo/bar$|, uninstaller.instance_variable_get(:@gem_home)
end
+ def test_remove_all
+ uninstaller = Gem::Uninstaller.new nil
+
+ ui = Gem::MockGemUi.new "y\n"
+
+ use_ui ui do
+ uninstaller.remove_all [@spec]
+ end
+
+ refute_path_exists @spec.gem_dir
+ end
+
def test_remove_executables_force_keep
uninstaller = Gem::Uninstaller.new nil, :executables => false
@@ -114,14 +115,13 @@ class TestGemUninstaller < Gem::InstallerTestCase
end
exec_path = File.join Gem.user_dir, 'bin', 'executable'
- assert_equal false, File.exist?(exec_path), 'removed exec from bin dir'
+ refute File.exist?(exec_path), 'removed exec from bin dir'
assert_equal "Removing executable\n", @ui.output
ensure
Gem::Installer.exec_format = nil
end
-
def test_path_ok_eh
uninstaller = Gem::Uninstaller.new nil
@@ -131,7 +131,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
def test_path_ok_eh_legacy
uninstaller = Gem::Uninstaller.new nil
- @spec.loaded_from.gsub! @spec.full_name, '\&-legacy'
+ @spec.loaded_from = @spec.loaded_from.gsub @spec.full_name, '\&-legacy'
@spec.platform = 'legacy'
assert_equal true, uninstaller.path_ok?(@gemhome, @spec)
@@ -190,26 +190,42 @@ class TestGemUninstaller < Gem::InstallerTestCase
end
def test_uninstall_user
- uninstaller = Gem::Uninstaller.new @user_spec.name, :executables => true,
- :user_install => true
+ @user_spec = Gem::Specification.find_by_name 'b'
+
+ uninstaller = Gem::Uninstaller.new(@user_spec.name,
+ :executables => true,
+ :user_install => true)
gem_dir = File.join Gem.user_dir, 'gems', @user_spec.full_name
Gem.pre_uninstall do
- assert File.exist?(gem_dir), 'gem_dir should exist'
+ assert_path_exists gem_dir
end
Gem.post_uninstall do
- refute File.exist?(gem_dir), 'gem_dir should not exist'
+ refute_path_exists gem_dir
end
uninstaller.uninstall
- refute File.exist?(gem_dir)
+ refute_path_exists gem_dir
assert_same uninstaller, @pre_uninstall_hook_arg
assert_same uninstaller, @post_uninstall_hook_arg
end
-end
+ def test_uninstall_selection_greater_than_one
+ util_make_gems
+
+ list = Gem::Specification.find_all_by_name('a')
+
+ uninstaller = Gem::Uninstaller.new('a')
+
+ use_ui Gem::MockGemUi.new("2\n") do
+ uninstaller.uninstall
+ end
+ updated_list = Gem::Specification.find_all_by_name('a')
+ assert_equal list.length - 1, updated_list.length
+ end
+end
diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb
index d3714a2..32658c5 100644
--- a/test/rubygems/test_kernel.rb
+++ b/test/rubygems/test_kernel.rb
@@ -46,10 +46,9 @@ class TestKernel < Gem::TestCase
gem 'a', '= 2'
end
- assert_match(/activate a \(= 2\)/, ex.message)
+ assert_equal "can't activate a-2, already activated a-1", ex.message
assert_match(/activated a-1/, ex.message)
assert_equal 'a', ex.name
- assert_equal Gem::Requirement.new('= 2'), ex.requirement
assert $:.any? { |p| %r{a-1/lib} =~ p }
refute $:.any? { |p| %r{a-2/lib} =~ p }