1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Import rubygems 1.8.5 (released @ 137c80f)

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31885 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ryan 2011-06-01 03:45:05 +00:00
parent 4752539e3f
commit d22130922e
103 changed files with 4890 additions and 3599 deletions

View file

@ -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> Wed Jun 1 12:34:00 2011 Kenta Murata <mrkn@mrkn.jp>
* NEWS: add new features of bigdecimal. * NEWS: add new features of bigdecimal.

View file

@ -33,7 +33,9 @@ end
require 'rubygems/defaults' require 'rubygems/defaults'
require "rubygems/dependency_list" require "rubygems/dependency_list"
require 'rubygems/path_support'
require 'rbconfig' require 'rbconfig'
require "rubygems/deprecate"
## ##
# RubyGems is the Ruby standard for publishing and managing third party # RubyGems is the Ruby standard for publishing and managing third party
@ -124,7 +126,7 @@ require 'rbconfig'
# -The RubyGems Team # -The RubyGems Team
module Gem module Gem
VERSION = '1.6.2' VERSION = '1.8.5'
## ##
# Raised when RubyGems is unable to load or activate a gem. Contains the # Raised when RubyGems is unable to load or activate a gem. Contains the
@ -160,11 +162,6 @@ module Gem
end end
end end
##
# Default directories in a gem repository
DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
RubyGemsPackageVersion = VERSION RubyGemsPackageVersion = VERSION
RUBYGEMS_DIR = File.dirname File.expand_path(__FILE__) RUBYGEMS_DIR = File.dirname File.expand_path(__FILE__)
@ -188,16 +185,17 @@ module Gem
@configuration = nil @configuration = nil
@loaded_specs = {} @loaded_specs = {}
@loaded_stacks = {}
@platforms = [] @platforms = []
@ruby = nil @ruby = nil
@sources = [] @sources = nil
@post_build_hooks ||= [] @post_build_hooks ||= []
@post_install_hooks ||= [] @post_install_hooks ||= []
@post_uninstall_hooks ||= [] @post_uninstall_hooks ||= []
@pre_uninstall_hooks ||= [] @pre_uninstall_hooks ||= []
@pre_install_hooks ||= [] @pre_install_hooks ||= []
@pre_reset_hooks ||= []
@post_reset_hooks ||= []
## ##
# Try to activate a gem containing +path+. Returns true if # 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. # activated. Returns false if it can't find the path in a gem.
def self.try_activate path def self.try_activate path
# TODO: deprecate when 1.9.3 comes out.
# finds the _latest_ version... regardless of loaded specs and their deps # finds the _latest_ version... regardless of loaded specs and their deps
# TODO: use find_all and bork if ambiguous # TODO: use find_all and bork if ambiguous
spec = Gem.searcher.find path spec = Gem::Specification.find_by_path path
return false unless spec return false unless spec
begin begin
Gem.activate spec.name, "= #{spec.version}" spec.activate
rescue Gem::LoadError # this could fail due to gem dep collisions, go lax 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 end
return true return true
@ -238,94 +237,18 @@ module Gem
# Gem::Requirement and Gem::Version documentation. # Gem::Requirement and Gem::Version documentation.
def self.activate(dep, *requirements) def self.activate(dep, *requirements)
# TODO: remove options entirely raise ArgumentError, "Deprecated use of Gem.activate(dep)" if
if requirements.last.is_a?(Hash) Gem::Dependency === dep
options = requirements.pop
else
options = {}
end
requirements = Gem::Requirement.default if requirements.empty? Gem::Specification.find_by_name(dep, *requirements).activate
dep = Gem::Dependency.new(dep, requirements) unless Gem::Dependency === dep end
# TODO: remove sources entirely def self.activate_dep dep, *requirements # :nodoc:
sources = options[:sources] || [] dep.to_spec.activate
matches = Gem.source_index.search dep, true end
report_activate_error(dep) if matches.empty?
if @loaded_specs[dep.name] then def self.activate_spec spec # :nodoc:
# This gem is already loaded. If the currently loaded gem is not in the spec.activate
# 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
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
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
return true
end end
def self.unresolved_deps def self.unresolved_deps
@ -341,7 +264,7 @@ module Gem
Gem.path.each do |gemdir| Gem.path.each do |gemdir|
each_load_path all_partials(gemdir) do |load_path| each_load_path all_partials(gemdir) do |load_path|
result << load_path result << gemdir.add(load_path).expand_path
end end
end end
@ -352,7 +275,7 @@ module Gem
# Return all the partial paths in +gemdir+. # Return all the partial paths in +gemdir+.
def self.all_partials(gemdir) def self.all_partials(gemdir)
Dir[File.join(gemdir, 'gems/*')] Dir[File.join(gemdir, "gems/*")]
end end
private_class_method :all_partials private_class_method :all_partials
@ -360,15 +283,14 @@ module Gem
## ##
# See if a given gem is available. # See if a given gem is available.
def self.available?(gem, *requirements) def self.available?(dep, *requirements)
requirements = Gem::Requirement.default if requirements.empty? requirements = Gem::Requirement.default if requirements.empty?
unless gem.respond_to?(:name) and unless dep.respond_to?(:name) and dep.respond_to?(:requirement) then
gem.respond_to?(:requirement) then dep = Gem::Dependency.new dep, requirements
gem = Gem::Dependency.new gem, requirements
end end
!Gem.source_index.search(gem).empty? not dep.matching_specs(true).empty?
end end
## ##
@ -378,30 +300,29 @@ module Gem
# you to specify specific gem versions. # you to specify specific gem versions.
def self.bin_path(name, exec_name = nil, *requirements) 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 = Gem::Requirement.default if
requirements.empty? requirements.empty?
specs = Gem.source_index.find_name(name, requirements)
specs = Gem::Dependency.new(name, requirements).matching_specs(true)
raise Gem::GemNotFoundException, raise Gem::GemNotFoundException,
"can't find gem #{name} (#{requirements})" if specs.empty? "can't find gem #{name} (#{requirements})" if specs.empty?
specs = specs.find_all do |spec| specs = specs.find_all { |spec|
spec.executables.include?(exec_name) spec.executables.include? exec_name
end if exec_name } if exec_name
unless spec = specs.last unless spec = specs.last
msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}" msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
raise Gem::GemNotFoundException, msg raise Gem::GemNotFoundException, msg
end end
exec_name ||= spec.default_executable spec.bin_file exec_name
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)
end end
## ##
@ -415,8 +336,9 @@ module Gem
# The path where gem executables are to be installed. # The path where gem executables are to be installed.
def self.bindir(install_dir=Gem.dir) def self.bindir(install_dir=Gem.dir)
return File.join(install_dir, 'bin') unless # TODO: move to Gem::Dirs
install_dir.to_s == Gem.default_dir return File.join install_dir, 'bin' unless
install_dir.to_s == Gem.default_dir.to_s
Gem.default_bindir Gem.default_bindir
end end
@ -426,20 +348,18 @@ module Gem
# mainly used by the unit tests to provide test isolation. # mainly used by the unit tests to provide test isolation.
def self.clear_paths def self.clear_paths
@gem_home = nil
@gem_path = nil
@user_home = nil
@@source_index = nil @@source_index = nil
@paths = nil
@searcher = nil @user_home = nil
@searcher = nil
Gem::Specification.reset
end end
## ##
# The path to standard location of the user's .gemrc file. # The path to standard location of the user's .gemrc file.
def self.config_file def self.config_file
File.join Gem.user_home, '.gemrc' @config_file ||= File.join Gem.user_home, '.gemrc'
end end
## ##
@ -462,9 +382,10 @@ module Gem
# package is not available as a gem, return nil. # package is not available as a gem, return nil.
def self.datadir(gem_name) def self.datadir(gem_name)
# TODO: deprecate
spec = @loaded_specs[gem_name] spec = @loaded_specs[gem_name]
return nil if spec.nil? return nil if spec.nil?
File.join(spec.full_gem_path, 'data', gem_name) File.join spec.full_gem_path, "data", gem_name
end end
## ##
@ -475,13 +396,29 @@ module Gem
Zlib::Deflate.deflate data Zlib::Deflate.deflate data
end 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. # The path where gems are to be installed.
#--
# FIXME deprecate these once everything else has been done -ebh
def self.dir def self.dir
@gem_home ||= nil # TODO: raise "no"
set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home paths.home
@gem_home end
def self.path
# TODO: raise "no"
paths.path
end end
## ##
@ -490,33 +427,35 @@ module Gem
def self.each_load_path(partials) def self.each_load_path(partials)
partials.each do |gp| partials.each do |gp|
base = File.basename(gp) base = File.basename gp
specfn = File.join(dir, "specifications", base + ".gemspec") specfn = dir.specifications.add(base + ".gemspec")
if File.exist?(specfn) if specfn.exist?
spec = eval(File.read(specfn)) spec = eval(specfn.read)
spec.require_paths.each do |rp| spec.require_paths.each do |rp|
yield(File.join(gp, rp)) yield(gp.add(rp))
end end
else else
filename = File.join(gp, 'lib') filename = dir.add(gp, 'lib')
yield(filename) if File.exist?(filename) yield(filename) if filename.exist?
end end
end end
end end
private_class_method :each_load_path private_class_method :each_load_path
## ##
# Quietly ensure the named Gem directory contains all the proper # Quietly ensure the named Gem directory contains all the proper
# subdirectories. If we can't create a directory due to a permission # subdirectories. If we can't create a directory due to a permission
# problem, then we will silently continue. # problem, then we will silently continue.
def self.ensure_gem_subdirectories(gemdir) def self.ensure_gem_subdirectories dir = Gem.dir
require 'fileutils' require 'fileutils'
Gem::DIRECTORIES.each do |filename| %w[cache doc gems specifications].each do |name|
fn = File.join gemdir, filename subdir = File.join dir, name
FileUtils.mkdir_p fn rescue nil unless File.exist? fn next if File.exist? subdir
FileUtils.mkdir_p subdir rescue nil # in case of perms issues -- lame
end end
end end
@ -541,11 +480,9 @@ module Gem
}.flatten.select { |file| File.file? file.untaint } }.flatten.select { |file| File.file? file.untaint }
end end
specs = searcher.find_all glob files.concat Gem::Specification.map { |spec|
spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
specs.each do |spec| }.flatten
files.concat searcher.matching_files(spec, glob)
end
# $LOAD_PATH might contain duplicate entries or reference # $LOAD_PATH might contain duplicate entries or reference
# the spec dirs directly, so we prune. # the spec dirs directly, so we prune.
@ -565,25 +502,30 @@ module Gem
# it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at # it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
# least on Win32). # least on Win32).
#++ #++
#--
#
# FIXME move to pathsupport
#
#++
def self.find_home def self.find_home
unless RUBY_VERSION > '1.9' then windows = File::ALT_SEPARATOR
['HOME', 'USERPROFILE'].each do |homekey| if not windows or RUBY_VERSION >= '1.9' then
return File.expand_path(ENV[homekey]) if ENV[homekey] File.expand_path "~"
else
['HOME', 'USERPROFILE'].each do |key|
return File.expand_path ENV[key] if ENV[key]
end end
if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
return File.expand_path("#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}") File.expand_path "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
end end
end end
File.expand_path "~"
rescue rescue
if File::ALT_SEPARATOR then if windows then
drive = ENV['HOMEDRIVE'] || ENV['SystemDrive'] File.expand_path File.join(ENV['HOMEDRIVE'] || ENV['SystemDrive'], '/')
File.join(drive.to_s, '/')
else else
"/" File.expand_path "/"
end end
end end
@ -593,6 +535,7 @@ module Gem
# Zlib::GzipReader wrapper that unzips +data+. # Zlib::GzipReader wrapper that unzips +data+.
def self.gunzip(data) def self.gunzip(data)
# TODO: move to utils
require 'stringio' require 'stringio'
require 'zlib' require 'zlib'
data = StringIO.new data data = StringIO.new data
@ -604,6 +547,7 @@ module Gem
# Zlib::GzipWriter wrapper that zips +data+. # Zlib::GzipWriter wrapper that zips +data+.
def self.gzip(data) def self.gzip(data)
# TODO: move to utils
require 'stringio' require 'stringio'
require 'zlib' require 'zlib'
zipped = StringIO.new zipped = StringIO.new
@ -617,6 +561,7 @@ module Gem
# A Zlib::Inflate#inflate wrapper # A Zlib::Inflate#inflate wrapper
def self.inflate(data) def self.inflate(data)
# TODO: move to utils
require 'zlib' require 'zlib'
Zlib::Inflate.inflate data Zlib::Inflate.inflate data
end end
@ -626,12 +571,14 @@ module Gem
# <tt>https://rubygems.org</tt>. # <tt>https://rubygems.org</tt>.
def self.host def self.host
# TODO: move to utils
@host ||= "https://rubygems.org" @host ||= "https://rubygems.org"
end end
## Set the default RubyGems API host. ## Set the default RubyGems API host.
def self.host= host def self.host= host
# TODO: move to utils
@host = host @host = host
end end
@ -644,7 +591,7 @@ module Gem
Gem.path.each do |gemdir| Gem.path.each do |gemdir|
each_load_path(latest_partials(gemdir)) do |load_path| each_load_path(latest_partials(gemdir)) do |load_path|
result << load_path result << gemdir.add(load_path).expand_path
end end
end end
@ -657,8 +604,9 @@ module Gem
def self.latest_partials(gemdir) def self.latest_partials(gemdir)
latest = {} latest = {}
all_partials(gemdir).each do |gp| all_partials(gemdir).each do |gp|
base = File.basename(gp) base = File.basename gp
if base =~ /(.*)-((\d+\.)*\d+)/ then
if base.to_s =~ /(.*)-((\d+\.)*\d+)/ then
name, version = $1, $2 name, version = $1, $2
ver = Gem::Version.new(version) ver = Gem::Version.new(version)
if latest[name].nil? || ver > latest[name][0] if latest[name].nil? || ver > latest[name][0]
@ -712,6 +660,7 @@ module Gem
file = $1 file = $1
lineno = $2.to_i lineno = $2.to_i
# TODO: it is ALWAYS joined! STUPID!
[file, lineno] [file, lineno]
end end
@ -722,25 +671,6 @@ module Gem
"#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
end 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. # Get the appropriate cache path.
# #
@ -749,7 +679,7 @@ module Gem
# #
def self.cache_dir(custom_dir=false) def self.cache_dir(custom_dir=false)
File.join(custom_dir ? custom_dir : Gem.dir, 'cache') File.join(custom_dir || Gem.dir, "cache")
end end
## ##
@ -759,7 +689,7 @@ module Gem
# nil/false (default) for Gem.dir. # nil/false (default) for Gem.dir.
def self.cache_gem(filename, user_dir=false) def self.cache_gem(filename, user_dir=false)
File.join(cache_dir(user_dir), filename) cache_dir(user_dir).add(filename)
end end
## ##
@ -799,6 +729,14 @@ module Gem
@post_install_hooks << hook @post_install_hooks << hook
end 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 # Adds a post-uninstall hook that will be passed a Gem::Uninstaller instance
# and the spec that was uninstalled when Gem::Uninstaller#uninstall is # and the spec that was uninstalled when Gem::Uninstaller#uninstall is
@ -817,6 +755,14 @@ module Gem
@pre_install_hooks << hook @pre_install_hooks << hook
end 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 # 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 # and the spec that will be uninstalled when Gem::Uninstaller#uninstall is
@ -853,10 +799,10 @@ module Gem
raise ArgumentError, "gem #{gem_name} is not activated" if gem.nil? raise ArgumentError, "gem #{gem_name} is not activated" if gem.nil?
raise ArgumentError, "gem #{over_name} is not activated" if over.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| 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 end
over_paths.each do |path| over_paths.each do |path|
@ -872,8 +818,8 @@ module Gem
# Refresh source_index from disk and clear searcher. # Refresh source_index from disk and clear searcher.
def self.refresh def self.refresh
source_index.refresh! Gem::Specification.reset
@source_index = nil
@searcher = nil @searcher = nil
end end
@ -890,7 +836,7 @@ module Gem
# any version by the requested name. # any version by the requested name.
def self.report_activate_error(gem) 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 if matches.empty? then
error = Gem::LoadError.new( error = Gem::LoadError.new(
@ -915,14 +861,14 @@ module Gem
def self.required_location(gemname, libfile, *requirements) def self.required_location(gemname, libfile, *requirements)
requirements = Gem::Requirement.default if requirements.empty? 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? return nil if matches.empty?
spec = matches.last spec = matches.last
spec.require_paths.each do |path| spec.require_paths.each do |path|
result = File.join spec.full_gem_path, path, libfile result = Gem::Path.path(spec.full_gem_path).add(path, libfile)
return result if File.exist? result return result if result.exist?
end end
nil nil
@ -934,11 +880,9 @@ module Gem
def self.ruby def self.ruby
if @ruby.nil? then if @ruby.nil? then
@ruby = File.join(ConfigMap[:bindir], @ruby = File.join(ConfigMap[:bindir],
ConfigMap[:ruby_install_name]) "#{ConfigMap[:ruby_install_name]}#{ConfigMap[:EXEEXT]}")
@ruby << ConfigMap[:EXEEXT]
# escape string in case path to ruby executable contain spaces. @ruby = "\"#{@ruby}\"" if @ruby =~ /\s/
@ruby.sub!(/.*\s.*/m, '"\&"')
end end
@ruby @ruby
@ -990,45 +934,13 @@ module Gem
@searcher ||= Gem::GemPathSearcher.new @searcher ||= Gem::GemPathSearcher.new
end 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 # Returns the Gem::SourceIndex of specifications that are in the Gem.path
def self.source_index def self.source_index
@@source_index ||= SourceIndex.from_installed_gems @@source_index ||= Deprecate.skip_during do
SourceIndex.new Gem::Specification.dirs
end
end end
## ##
@ -1037,23 +949,14 @@ module Gem
# default_sources if it is not installed. # default_sources if it is not installed.
def self.sources def self.sources
if @sources.empty? then @sources ||= default_sources
begin
gem 'sources', '> 0.0.1'
require 'sources'
rescue LoadError
@sources = default_sources
end
end
@sources
end end
## ##
# Need to be able to set the sources without calling # Need to be able to set the sources without calling
# Gem.sources.replace since that would cause an infinite loop. # Gem.sources.replace since that would cause an infinite loop.
def self.sources=(new_sources) def self.sources= new_sources
@sources = new_sources @sources = new_sources
end end
@ -1115,9 +1018,8 @@ module Gem
# by the unit tests to provide environment isolation. # by the unit tests to provide environment isolation.
def self.use_paths(home, paths=[]) def self.use_paths(home, paths=[])
clear_paths self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths }
set_home(home) if home # TODO: self.paths = home, paths
set_paths(paths.join(File::PATH_SEPARATOR)) if paths
end end
## ##
@ -1201,6 +1103,11 @@ module Gem
attr_reader :post_install_hooks 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 # The list of hooks to be run before Gem::Uninstall#uninstall does any
# work # work
@ -1212,19 +1119,18 @@ module Gem
attr_reader :pre_install_hooks 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 # The list of hooks to be run after Gem::Uninstall#uninstall is finished
attr_reader :pre_uninstall_hooks attr_reader :pre_uninstall_hooks
end end
def self.cache # :nodoc: 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 source_index
end end
@ -1233,17 +1139,17 @@ module Gem
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/" MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
autoload :Version, 'rubygems/version' autoload :Version, 'rubygems/version'
autoload :Requirement, 'rubygems/requirement' autoload :Requirement, 'rubygems/requirement'
autoload :Dependency, 'rubygems/dependency' autoload :Dependency, 'rubygems/dependency'
autoload :GemPathSearcher, 'rubygems/gem_path_searcher' autoload :GemPathSearcher, 'rubygems/gem_path_searcher'
autoload :SpecFetcher, 'rubygems/spec_fetcher' autoload :SpecFetcher, 'rubygems/spec_fetcher'
autoload :Specification, 'rubygems/specification' autoload :Specification, 'rubygems/specification'
autoload :Cache, 'rubygems/source_index' autoload :Cache, 'rubygems/source_index'
autoload :SourceIndex, 'rubygems/source_index' autoload :SourceIndex, 'rubygems/source_index'
autoload :Platform, 'rubygems/platform' autoload :Platform, 'rubygems/platform'
autoload :Builder, 'rubygems/builder' autoload :Builder, 'rubygems/builder'
autoload :ConfigFile, 'rubygems/config_file' autoload :ConfigFile, 'rubygems/config_file'
end end
module Kernel module Kernel
@ -1279,7 +1185,8 @@ module Kernel
def gem(gem_name, *requirements) # :doc: def gem(gem_name, *requirements) # :doc:
skip_list = (ENV['GEM_SKIP'] || "").split(/:/) skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name 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 end
private :gem private :gem
@ -1300,8 +1207,7 @@ def RbConfig.datadir(package_name)
require 'rbconfig/datadir' require 'rbconfig/datadir'
Gem.datadir(package_name) || Gem.datadir(package_name) || File.join(Gem::ConfigMap[:datadir], package_name)
File.join(Gem::ConfigMap[:datadir], package_name)
end end
require 'rubygems/exceptions' require 'rubygems/exceptions'
@ -1334,3 +1240,25 @@ require 'rubygems/custom_require'
Gem.clear_paths 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

View file

@ -44,7 +44,7 @@ class Gem::Builder
@signer = sign @signer = sign
write_package write_package
say success if Gem.configuration.verbose say success if Gem.configuration.verbose
@spec.file_name File.basename @spec.cache_file
end end
def success def success
@ -52,7 +52,7 @@ class Gem::Builder
Successfully built RubyGem Successfully built RubyGem
Name: #{@spec.name} Name: #{@spec.name}
Version: #{@spec.version} Version: #{@spec.version}
File: #{@spec.file_name} File: #{File.basename @spec.cache_file}
EOM EOM
end end
@ -79,16 +79,17 @@ EOM
end end
def write_package 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| Gem::Package.open gem_io, 'w', @signer do |pkg|
yaml = @spec.to_yaml yaml = @spec.to_yaml
pkg.metadata = yaml pkg.metadata = yaml
@spec.files.each do |file| @spec.files.each do |file|
next if File.directory? file next if File.directory?(file)
next if file == @spec.file_name # Don't add gem onto itself next if file == file_name # Don't add gem onto itself
stat = File.stat file stat = File.stat(file)
mode = stat.mode & 0777 mode = stat.mode & 0777
size = stat.size size = stat.size

View file

@ -410,10 +410,12 @@ class Gem::Command
end end
end end
@parser.separator nil if @summary then
@parser.separator " Summary:" @parser.separator nil
wrap(@summary, 80 - 4).split("\n").each do |line| @parser.separator " Summary:"
@parser.separator " #{line.strip}" wrap(@summary, 80 - 4).split("\n").each do |line|
@parser.separator " #{line.strip}"
end
end end
if description then if description then

View file

@ -43,6 +43,13 @@ class Gem::CommandManager
@command_manager ||= new @command_manager ||= new
end 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. # Register all the subcommands supported by the gem command.
@ -86,6 +93,13 @@ class Gem::CommandManager
@commands[command] = false @commands[command] = false
end 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. # Return the registered command from the command name.
@ -166,7 +180,7 @@ class Gem::CommandManager
retried = false retried = false
begin begin
commands.const_get const_name commands.const_get(const_name).new
rescue NameError rescue NameError
raise if retried raise if retried
@ -179,7 +193,7 @@ class Gem::CommandManager
Gem.configuration.backtrace Gem.configuration.backtrace
end end
retry retry
end.new end
end end
end end

View file

@ -23,32 +23,34 @@ class Gem::Commands::BuildCommand < Gem::Command
def execute def execute
gemspec = get_one_gem_name gemspec = get_one_gem_name
if File.exist?(gemspec)
specs = load_gemspecs(gemspec) if File.exist? gemspec
specs.each do |spec| spec = load_gemspec gemspec
if spec then
Gem::Builder.new(spec).build Gem::Builder.new(spec).build
else
alert_error "Error loading gemspec. Aborting."
terminate_interaction 1
end end
else else
alert_error "Gemspec file not found: #{gemspec}" alert_error "Gemspec file not found: #{gemspec}"
terminate_interaction 1
end end
end end
def load_gemspecs(filename) def load_gemspec filename
if yaml?(filename) if yaml?(filename)
result = []
open(filename) do |f| open(filename) do |f|
begin begin
while not f.eof? and spec = Gem::Specification.from_yaml(f) Gem::Specification.from_yaml(f)
result << spec
end
rescue Gem::EndOfYAMLException rescue Gem::EndOfYAMLException
# OK nil
end end
end end
else else
result = [Gem::Specification.load(filename)] Gem::Specification.load(filename) # can return nil
end end
result
end end
def yaml?(filename) def yaml?(filename)

View file

@ -56,7 +56,7 @@ class Gem::Commands::CertCommand < Gem::Command
'Build private key and self-signed', 'Build private key and self-signed',
'certificate for EMAIL_ADDR.') do |value, options| 'certificate for EMAIL_ADDR.') do |value, options|
vals = Gem::Security.build_self_signed_cert(value) 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 "Public Cert: #{vals[:cert_path]}"
say "Private Key: #{vals[:key_path]}" say "Private Key: #{vals[:key_path]}"
say "Don't forget to move the key file to somewhere private..." say "Don't forget to move the key file to somewhere private..."

View file

@ -5,7 +5,6 @@
###################################################################### ######################################################################
require 'rubygems/command' require 'rubygems/command'
require 'rubygems/source_index'
require 'rubygems/dependency_list' require 'rubygems/dependency_list'
require 'rubygems/uninstaller' require 'rubygems/uninstaller'
@ -44,28 +43,20 @@ installed elsewhere in GEM_PATH the cleanup command won't touch it.
say "Cleaning up installed gems..." say "Cleaning up installed gems..."
primary_gems = {} primary_gems = {}
Gem.source_index.each do |name, spec| Gem::Specification.each do |spec|
if primary_gems[spec.name].nil? or if primary_gems[spec.name].nil? or
primary_gems[spec.name].version < spec.version then primary_gems[spec.name].version < spec.version then
primary_gems[spec.name] = spec primary_gems[spec.name] = spec
end end
end end
gems_to_cleanup = [] gems_to_cleanup = unless options[:args].empty? then
options[:args].map do |gem_name|
unless options[:args].empty? then Gem::Specification.find_all_by_name gem_name
options[:args].each do |gem_name| end.flatten
dep = Gem::Dependency.new gem_name, Gem::Requirement.default else
specs = Gem.source_index.search dep Gem::Specification.to_a
specs.each do |spec| end
gems_to_cleanup << spec
end
end
else
Gem.source_index.each do |name, spec|
gems_to_cleanup << spec
end
end
gems_to_cleanup = gems_to_cleanup.select { |spec| gems_to_cleanup = gems_to_cleanup.select { |spec|
primary_gems[spec.name].version != spec.version 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}", :version => "= #{spec.version}",
} }
if Gem.user_dir == spec.installation_path then if Gem.user_dir == spec.base_dir then
uninstall_options[:install_dir] = spec.installation_path uninstall_options[:install_dir] = spec.base_dir
end end
uninstaller = Gem::Uninstaller.new spec.name, uninstall_options uninstaller = Gem::Uninstaller.new spec.name, uninstall_options

View file

@ -58,24 +58,24 @@ class Gem::Commands::ContentsCommand < Gem::Command
end.flatten end.flatten
path_kind = if spec_dirs.empty? then path_kind = if spec_dirs.empty? then
spec_dirs = Gem::SourceIndex.installed_spec_directories spec_dirs = Gem::Specification.dirs
"default gem paths" "default gem paths"
else else
"specified path" "specified path"
end end
si = Gem::SourceIndex.from_gems_in(*spec_dirs)
gem_names = if options[:all] then gem_names = if options[:all] then
si.map { |_, spec| spec.name } Gem::Specification.map(&:name)
else else
get_all_gem_names get_all_gem_names
end end
gem_names.each do |name| 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}" say "Unable to find gem '#{name}' in #{path_kind}"
if Gem.configuration.verbose then if Gem.configuration.verbose then
@ -86,16 +86,19 @@ class Gem::Commands::ContentsCommand < Gem::Command
terminate_interaction 1 if gem_names.length == 1 terminate_interaction 1 if gem_names.length == 1
end 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]
files.each do |f| gem_path = File.join gem_path, '' # add trailing / if missing
path = if options[:prefix] then
File.join gem_spec.full_gem_path, f
else
f
end
say path files.sort.each do |file|
next if File.directory? file
file = file.sub gem_path, '' unless options[:prefix]
say file
end end
end end
end end

View file

@ -49,13 +49,13 @@ class Gem::Commands::DependencyCommand < Gem::Command
end end
def execute def execute
options[:args] << '' if options[:args].empty? if options[:reverse_dependencies] and remote? and not local? then
specs = {} alert_error 'Only reverse dependencies for local gems are supported.'
terminate_interaction 1
source_indexes = Hash.new do |h, source_uri|
h[source_uri] = Gem::SourceIndex.new
end end
options[:args] << '' if options[:args].empty?
pattern = if options[:args].length == 1 and pattern = if options[:args].length == 1 and
options[:args].first =~ /\A\/(.*)\/(i)?\z/m then options[:args].first =~ /\A\/(.*)\/(i)?\z/m then
flags = $2 ? Regexp::IGNORECASE : nil flags = $2 ? Regexp::IGNORECASE : nil
@ -64,34 +64,30 @@ class Gem::Commands::DependencyCommand < Gem::Command
/\A#{Regexp.union(*options[:args])}/ /\A#{Regexp.union(*options[:args])}/
end 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] dependency.prerelease = options[:prerelease]
if options[:reverse_dependencies] and remote? and not local? then specs = []
alert_error 'Only reverse dependencies for local gems are supported.'
terminate_interaction 1
end
if local? then specs.concat dependency.matching_specs if local?
Gem.source_index.search(dependency).each do |spec|
source_indexes[:local].add_spec spec
end
end
if remote? and not options[:reverse_dependencies] then if remote? and not options[:reverse_dependencies] then
fetcher = Gem::SpecFetcher.fetcher 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?) dependency.prerelease?)
specs_and_sources.each do |spec_tuple, source_uri| specs.concat specs_and_sources.map { |spec_tuple, source_uri|
spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri) fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
}
source_indexes[source_uri].add_spec spec
end
end end
if source_indexes.empty? then if specs.empty? then
patterns = options[:args].join ',' patterns = options[:args].join ','
say "No gems found matching #{patterns} (#{options[:version]})" if say "No gems found matching #{patterns} (#{options[:version]})" if
Gem.configuration.verbose Gem.configuration.verbose
@ -99,24 +95,18 @@ class Gem::Commands::DependencyCommand < Gem::Command
terminate_interaction 1 terminate_interaction 1
end end
specs = {} specs = specs.uniq.sort
source_indexes.values.each do |source_index|
source_index.gems.each do |name, spec|
specs[spec.full_name] = [source_index, spec]
end
end
reverse = Hash.new { |h, k| h[k] = [] } reverse = Hash.new { |h, k| h[k] = [] }
if options[:reverse_dependencies] then if options[:reverse_dependencies] then
specs.values.each do |_, spec| specs.each do |spec|
reverse[spec.full_name] = find_reverse_dependencies spec reverse[spec.full_name] = find_reverse_dependencies spec
end end
end end
if options[:pipe_format] then if options[:pipe_format] then
specs.values.sort_by { |_, spec| spec }.each do |_, spec| specs.each do |spec|
unless spec.dependencies.empty? unless spec.dependencies.empty?
spec.dependencies.sort_by { |dep| dep.name }.each do |dep| spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
say "#{dep.name} --version '#{dep.requirement}'" say "#{dep.name} --version '#{dep.requirement}'"
@ -126,7 +116,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
else else
response = '' response = ''
specs.values.sort_by { |_, spec| spec }.each do |_, spec| specs.each do |spec|
response << print_dependencies(spec) response << print_dependencies(spec)
unless reverse[spec.full_name].empty? then unless reverse[spec.full_name].empty? then
response << " Used by\n" response << " Used by\n"
@ -158,7 +148,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
def find_reverse_dependencies(spec) def find_reverse_dependencies(spec)
result = [] result = []
Gem.source_index.each do |name, sp| Gem::Specification.each do |sp|
sp.dependencies.each do |dep| sp.dependencies.each do |dep|
dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep
@ -172,17 +162,5 @@ class Gem::Commands::DependencyCommand < Gem::Command
result result
end 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 end

View file

@ -41,19 +41,22 @@ class Gem::Commands::FetchCommand < Gem::Command
version = options[:version] || Gem::Requirement.default version = options[:version] || Gem::Requirement.default
all = Gem::Requirement.default != version all = Gem::Requirement.default != version
platform = Gem.platforms.last
gem_names = get_all_gem_names gem_names = get_all_gem_names
gem_names.each do |gem_name| gem_names.each do |gem_name|
dep = Gem::Dependency.new gem_name, version dep = Gem::Dependency.new gem_name, version
dep.prerelease = options[:prerelease] dep.prerelease = options[:prerelease]
specs_and_sources = Gem::SpecFetcher.fetcher.fetch(dep, all, true,
dep.prerelease?)
specs_and_sources, errors = specs_and_sources, errors =
Gem::SpecFetcher.fetcher.fetch_with_errors(dep, all, true, Gem::SpecFetcher.fetcher.fetch_with_errors(dep, all, true,
dep.prerelease?) 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 spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last
if spec.nil? then if spec.nil? then
@ -62,7 +65,7 @@ class Gem::Commands::FetchCommand < Gem::Command
end end
path = Gem::RemoteFetcher.fetcher.download spec, source_uri 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}" say "Downloaded #{spec.full_name}"
end end

View file

@ -120,7 +120,8 @@ to write the specification by hand. For example:
get_all_gem_names.each do |gem_name| get_all_gem_names.each do |gem_name|
begin 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 = Gem::DependencyInstaller.new options
inst.install gem_name, options[:version] inst.install gem_name, options[:version]

View file

@ -93,7 +93,7 @@ lock it down to the exact version.
spec.runtime_dependencies.each do |dep| spec.runtime_dependencies.each do |dep|
next if locked[dep.name] next if locked[dep.name]
candidates = Gem.source_index.search dep candidates = dep.matching_specs
if candidates.empty? then if candidates.empty? then
complain "Unable to satisfy '#{dep}' from currently installed gems" complain "Unable to satisfy '#{dep}' from currently installed gems"
@ -105,11 +105,11 @@ lock it down to the exact version.
end end
def spec_path(gem_full_name) 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" File.join path, "specifications", "#{gem_full_name}.gemspec"
end }
gemspecs.find { |gemspec| File.exist? gemspec } gemspecs.find { |path| File.exist? path }
end end
end end

View file

@ -22,10 +22,8 @@ class Gem::Commands::OutdatedCommand < Gem::Command
end end
def execute def execute
locals = Gem::SourceIndex.from_installed_gems Gem::Specification.outdated.sort.each do |name|
local = Gem::Specification.find_all_by_name(name).max
locals.outdated.sort.each do |name|
local = locals.find_name(name).last
dep = Gem::Dependency.new local.name, ">= #{local.version}" dep = Gem::Dependency.new local.name, ">= #{local.version}"
remotes = Gem::SpecFetcher.fetcher.fetch dep remotes = Gem::SpecFetcher.fetcher.fetch dep
@ -35,6 +33,4 @@ class Gem::Commands::OutdatedCommand < Gem::Command
say "#{local.name} (#{local.version} < #{remote.version})" say "#{local.name} (#{local.version} < #{remote.version})"
end end
end end
end end

View file

@ -16,7 +16,8 @@ class Gem::Commands::PristineCommand < Gem::Command
def initialize def initialize
super 'pristine', super 'pristine',
'Restores installed gems to pristine condition from files located in the gem cache', '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', add_option('--all',
'Restore all installed gems to pristine', 'Restore all installed gems to pristine',
@ -24,6 +25,11 @@ class Gem::Commands::PristineCommand < Gem::Command
options[:all] = value options[:all] = value
end end
add_option('--[no-]extensions',
'Restore gems with extensions') do |value, options|
options[:extensions] = value
end
add_version_option('restore to', 'pristine condition') add_version_option('restore to', 'pristine condition')
end end
@ -32,7 +38,7 @@ class Gem::Commands::PristineCommand < Gem::Command
end end
def defaults_str # :nodoc: def defaults_str # :nodoc:
"--all" "--all --extensions"
end end
def description # :nodoc: 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 If the cached gem cannot be found, you will need to use `gem install` to
revert the gem. revert the gem.
If --no-extensions is provided pristine will not attempt to restore gems with
extensions.
EOF EOF
end end
@ -54,21 +63,17 @@ revert the gem.
end end
def execute def execute
gem_name = nil
specs = if options[:all] then specs = if options[:all] then
Gem::SourceIndex.from_installed_gems.map do |name, spec| Gem::Specification.map
spec
end
else else
gem_name = get_one_gem_name get_all_gem_names.map do |gem_name|
Gem::SourceIndex.from_installed_gems.find_name(gem_name, Gem::Specification.find_all_by_name gem_name, options[:version]
options[:version]) end.flatten
end end
if specs.empty? then if specs.to_a.empty? then
raise Gem::Exception, raise Gem::Exception,
"Failed to find gem #{gem_name} #{options[:version]}" "Failed to find gems #{options[:args]} #{options[:version]}"
end end
install_dir = Gem.dir # TODO use installer option install_dir = Gem.dir # TODO use installer option
@ -76,25 +81,32 @@ revert the gem.
raise Gem::FilePermissionError.new(install_dir) unless raise Gem::FilePermissionError.new(install_dir) unless
File.writable?(install_dir) File.writable?(install_dir)
say "Restoring gem(s) to pristine condition..." say "Restoring gems to pristine condition..."
specs.each do |spec| 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..." say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
dep = Gem::Dependency.new spec.name, spec.version dep = Gem::Dependency.new spec.name, spec.version
Gem::RemoteFetcher.fetcher.download_to_cache dep Gem::RemoteFetcher.fetcher.download_to_cache dep
gem = spec.cache_gem
end end
# TODO use installer options # 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 installer.install
say "Restored #{spec.full_name}" say "Restored #{spec.full_name}"
end end
end end
end end

View file

@ -80,10 +80,12 @@ class Gem::Commands::QueryCommand < Gem::Command
exit_code |= 1 exit_code |= 1
end end
raise Gem::SystemExitException, exit_code terminate_interaction exit_code
end 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 local? then
if prerelease and not both? then if prerelease and not both? then
@ -96,7 +98,9 @@ class Gem::Commands::QueryCommand < Gem::Command
say say
end 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_tuples = specs.map do |spec|
[[spec.name, spec.version, spec.original_platform, spec], :local] [[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. # Check if gem +name+ version +version+ is installed.
def installed?(name, version = Gem::Requirement.default) def installed?(name, req = Gem::Requirement.default)
dep = Gem::Dependency.new name, version Gem::Specification.any? { |s| s.name =~ name and req =~ s.version }
!Gem.source_index.search(dep).empty?
end end
def output_query_results(spec_tuples) def output_query_results(spec_tuples)

View file

@ -50,7 +50,7 @@ class Gem::Commands::ServerCommand < Gem::Command
options[:addresses].push(*address) options[:addresses].push(*address)
end end
add_option '-l', '--launch[=COMMAND]', add_option '-l', '--launch[=COMMAND]',
'launches a browser window', 'launches a browser window',
"COMMAND defaults to 'start' on Windows", "COMMAND defaults to 'start' on Windows",
"and 'open' on all other platforms" do |launch, options| "and 'open' on all other platforms" do |launch, options|

View file

@ -338,7 +338,7 @@ abort "#{deprecation_message}"
args << '--main' << 'README.rdoc' << '--quiet' args << '--main' << 'README.rdoc' << '--quiet'
args << '.' args << '.'
args << 'README.rdoc' << 'UPGRADING.rdoc' args << 'README.rdoc' << 'UPGRADING.rdoc'
args << 'LICENSE.txt' << 'GPL.txt' << 'History.txt' args << 'LICENSE.txt' << 'MIT.txt' << 'History.txt'
r = RDoc::RDoc.new r = RDoc::RDoc.new
r.document args r.document args

View file

@ -72,18 +72,8 @@ FIELD name of gemspec field to show
field = get_one_optional_argument field = get_one_optional_argument
if field then raise Gem::CommandLineError, "--ruby and FIELD are mutually exclusive" if
field = field.intern field and options[:format] == :ruby
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
if local? then if local? then
if File.exist? gem then if File.exist? gem then
@ -91,7 +81,7 @@ FIELD name of gemspec field to show
end end
if specs.empty? then if specs.empty? then
specs.push(*Gem.source_index.search(dep)) specs.push(*dep.matching_specs)
end end
end end
@ -106,7 +96,11 @@ FIELD name of gemspec field to show
terminate_interaction 1 terminate_interaction 1
end 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 s = s.send field if field
say case options[:format] say case options[:format]
@ -117,14 +111,5 @@ FIELD name of gemspec field to show
say "\n" say "\n"
end end
if options[:all] then
specs.each(&output)
else
spec = specs.sort_by { |s| s.version }.last
output[spec]
end
end end
end end

View file

@ -17,7 +17,8 @@ class Gem::Commands::StaleCommand < Gem::Command
def execute def execute
gem_to_atime = {} 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| Dir["#{spec.full_gem_path}/**/*.*"].each do |file|
next if File.directory?(file) next if File.directory?(file)
stat = File.stat(file) stat = File.stat(file)

View file

@ -25,6 +25,10 @@ class Gem::Commands::UnpackCommand < Gem::Command
options[:target] = value options[:target] = value
end end
add_option('--spec', 'unpack the gem specification') do |value, options|
options[:spec] = true
end
add_version_option add_version_option
end end
@ -50,14 +54,30 @@ class Gem::Commands::UnpackCommand < Gem::Command
dependency = Gem::Dependency.new name, options[:version] dependency = Gem::Dependency.new name, options[:version]
path = get_path dependency 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' basename = File.basename path, '.gem'
target_dir = File.expand_path basename, options[:target] target_dir = File.expand_path basename, options[:target]
FileUtils.mkdir_p target_dir FileUtils.mkdir_p target_dir
Gem::Installer.new(path, :unpack => true).unpack target_dir Gem::Installer.new(path, :unpack => true).unpack target_dir
say "Unpacked gem: '#{target_dir}'" say "Unpacked gem: '#{target_dir}'"
else
alert_error "Gem '#{name}' not installed."
end end
end end
end end
@ -70,9 +90,8 @@ class Gem::Commands::UnpackCommand < Gem::Command
# TODO: see comments in get_path() about general service. # TODO: see comments in get_path() about general service.
def find_in_cache(filename) def find_in_cache(filename)
Gem.path.each do |path| 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 return this_path if File.exist? this_path
end end
@ -99,9 +118,9 @@ class Gem::Commands::UnpackCommand < Gem::Command
def get_path dependency def get_path dependency
return dependency.name if dependency.name =~ /\.gem$/i 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 return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless
selected selected
@ -111,12 +130,37 @@ class Gem::Commands::UnpackCommand < Gem::Command
# We expect to find (basename).gem in the 'cache' directory. Furthermore, # We expect to find (basename).gem in the 'cache' directory. Furthermore,
# the name match must be exact (ignoring case). # 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 return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path
path path
end 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 end

View file

@ -71,14 +71,14 @@ class Gem::Commands::UpdateCommand < Gem::Command
hig = {} # highest installed gems 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 if hig[spec.name].nil? or hig[spec.name].version < spec.version then
hig[spec.name] = spec hig[spec.name] = spec
end end
end 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 updated = update_gems gems_to_update
@ -123,8 +123,8 @@ class Gem::Commands::UpdateCommand < Gem::Command
end end
def update_gems gems_to_update def update_gems gems_to_update
gems_to_update.uniq.sort.each do |name| gems_to_update.uniq.sort.each do |(name, version)|
update_gem name update_gem name, version
end end
@updated @updated
@ -141,6 +141,9 @@ class Gem::Commands::UpdateCommand < Gem::Command
options[:user_install] = false 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] version = options[:system]
if version == true then if version == true then
version = Gem::Version.new Gem::VERSION version = Gem::Version.new Gem::VERSION
@ -158,18 +161,25 @@ class Gem::Commands::UpdateCommand < Gem::Command
'rubygems-update' => rubygems_update '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
if gems_to_update.empty? then target = if options[:system] == true then
up_ver
else
version
end
if current_ver == target then
# if options[:system] != true and version == current_ver then
say "Latest version currently installed. Aborting." say "Latest version currently installed. Aborting."
terminate_interaction terminate_interaction
end end
update_gem gems_to_update.first, requirement update_gem name, target
Gem.source_index.refresh! installed_gems = Gem::Specification.find_all_by_name 'rubygems-update', requirement
installed_gems = Gem.source_index.find_name 'rubygems-update', requirement
version = installed_gems.last.version version = installed_gems.last.version
args = [] args = []
@ -193,7 +203,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
end end
end end
def which_to_update(highest_installed_gems, gem_names) def which_to_update highest_installed_gems, gem_names, system = false
result = [] result = []
highest_installed_gems.each do |l_name, l_spec| highest_installed_gems.each do |l_name, l_spec|
@ -213,9 +223,11 @@ class Gem::Commands::UpdateCommand < Gem::Command
version version
end.last end.last
if highest_remote_gem and highest_remote_gem ||= [[nil, Gem::Version.new(0), nil]] # "null" object
l_spec.version < highest_remote_gem.first[1] then highest_remote_ver = highest_remote_gem.first[1]
result << l_name
if system or (l_spec.version < highest_remote_ver) then
result << [l_spec.name, [l_spec.version, highest_remote_ver].max]
end end
end end

View file

@ -5,12 +5,8 @@
###################################################################### ######################################################################
require 'rubygems/command' require 'rubygems/command'
require 'rubygems/gem_path_searcher'
class Gem::Commands::WhichCommand < Gem::Command class Gem::Commands::WhichCommand < Gem::Command
EXT = %w[.rb .rbw .so .dll .bundle] # HACK
def initialize def initialize
super 'which', 'Find the location of a library file you can require', super 'which', 'Find the location of a library file you can require',
:search_gems_first => false, :show_all => false :search_gems_first => false, :show_all => false
@ -34,14 +30,13 @@ class Gem::Commands::WhichCommand < Gem::Command
end end
def execute def execute
searcher = Gem::GemPathSearcher.new
found = false found = false
options[:args].each do |arg| options[:args].each do |arg|
arg = arg.sub(/#{Regexp.union(*EXT)}$/, '') arg = arg.sub(/#{Regexp.union(*Gem.suffixes)}$/, '')
dirs = $LOAD_PATH dirs = $LOAD_PATH
spec = searcher.find arg
spec = Gem::Specification.find_by_path arg
if spec then if spec then
if options[:search_gems_first] then if options[:search_gems_first] then
@ -51,6 +46,7 @@ class Gem::Commands::WhichCommand < Gem::Command
end end
end end
# TODO: this is totally redundant and stupid
paths = find_paths arg, dirs paths = find_paths arg, dirs
if paths.empty? then if paths.empty? then
@ -68,7 +64,7 @@ class Gem::Commands::WhichCommand < Gem::Command
result = [] result = []
dirs.each do |dir| dirs.each do |dir|
EXT.each do |ext| Gem.suffixes.each do |ext|
full_path = File.join dir, "#{package_name}#{ext}" full_path = File.join dir, "#{package_name}#{ext}"
if File.exist? full_path then if File.exist? full_path then
result << full_path result << full_path

View file

@ -207,11 +207,15 @@ class Gem::ConfigFile
# Location of RubyGems.org credentials # Location of RubyGems.org credentials
def credentials_path def credentials_path
File.join(Gem.user_home, '.gem', 'credentials') File.join Gem.user_home, '.gem', 'credentials'
end end
def load_api_keys 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 if @api_keys.key? :rubygems_api_key then
@rubygems_api_key = @api_keys[:rubygems_api_key] @rubygems_api_key = @api_keys[:rubygems_api_key]
@api_keys[:rubygems] = @api_keys.delete :rubygems_api_key unless @api_keys.key? :rubygems @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) def rubygems_api_key=(api_key)
config = load_file(credentials_path).merge(:rubygems_api_key => api_key) config = load_file(credentials_path).merge(:rubygems_api_key => api_key)
dirname = File.dirname(credentials_path) dirname = File.dirname credentials_path
Dir.mkdir(dirname) unless File.exists?(dirname) Dir.mkdir(dirname) unless File.exist? dirname
Gem.load_yaml Gem.load_yaml
@ -236,7 +240,7 @@ class Gem::ConfigFile
def load_file(filename) def load_file(filename)
Gem.load_yaml Gem.load_yaml
return {} unless filename and File.exists?(filename) return {} unless filename and File.exist? filename
begin begin
YAML.load(File.read(filename)) YAML.load(File.read(filename))
rescue ArgumentError rescue ArgumentError
@ -360,6 +364,4 @@ class Gem::ConfigFile
protected protected
attr_reader :hash attr_reader :hash
end end

View file

@ -41,19 +41,20 @@ module Kernel
if Gem.unresolved_deps.empty? or Gem.loaded_path? path then if Gem.unresolved_deps.empty? or Gem.loaded_path? path then
gem_original_require path gem_original_require path
else else
spec = Gem.searcher.find_active path spec = Gem::Specification.find { |s|
s.activated? and s.contains_requirable_file? path
}
unless spec then unless spec then
found_specs = Gem.searcher.find_in_unresolved path found_specs = Gem::Specification.find_in_unresolved path
unless found_specs.empty? then unless found_specs.empty? then
found_specs = [found_specs.last] found_specs = [found_specs.last]
else else
found_specs = Gem.searcher.find_in_unresolved_tree path found_specs = Gem::Specification.find_in_unresolved_tree path
end end
found_specs.each do |found_spec| found_specs.each do |found_spec|
# FIX: this is dumb, activate a spec instead of name/version found_spec.activate
Gem.activate found_spec.name, found_spec.version
end end
end end

View file

@ -6,6 +6,8 @@
module Gem module Gem
# TODO: move this whole file back into rubygems.rb
@post_install_hooks ||= [] @post_install_hooks ||= []
@post_uninstall_hooks ||= [] @post_uninstall_hooks ||= []
@pre_uninstall_hooks ||= [] @pre_uninstall_hooks ||= []
@ -23,16 +25,28 @@ module Gem
# specified in the environment # specified in the environment
def self.default_dir def self.default_dir
if defined? RUBY_FRAMEWORK_VERSION then path = if defined? RUBY_FRAMEWORK_VERSION then
File.join File.dirname(ConfigMap[:sitedir]), 'Gems', [
ConfigMap[:ruby_version] File.dirname(ConfigMap[:sitedir]),
elsif ConfigMap[:rubylibprefix] then 'Gems',
File.join(ConfigMap[:rubylibprefix], 'gems', ConfigMap[:ruby_version]
ConfigMap[:ruby_version]) ]
else elsif ConfigMap[:rubylibprefix] then
File.join(ConfigMap[:libdir], ruby_engine, 'gems', [
ConfigMap[:ruby_version]) ConfigMap[:rubylibprefix],
end 'gems',
ConfigMap[:ruby_version]
]
else
[
ConfigMap[:libdir],
ruby_engine,
'gems',
ConfigMap[:ruby_version]
]
end
@default_dir ||= File.join(*path)
end end
## ##
@ -82,14 +96,18 @@ module Gem
# The default system-wide source info cache directory # The default system-wide source info cache directory
def self.default_system_source_cache_dir def self.default_system_source_cache_dir
File.join Gem.dir, 'source_cache' File.join(Gem.dir, 'source_cache')
end end
## ##
# The default user-specific source info cache directory # The default user-specific source info cache directory
def self.default_user_source_cache_dir 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 end
## ##
@ -102,6 +120,4 @@ module Gem
'ruby' 'ruby'
end end
end end
end end

View file

@ -38,6 +38,12 @@ class Gem::Dependency
# <tt>:runtime</tt>. # <tt>:runtime</tt>.
def initialize name, *requirements 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 type = Symbol === requirements.last ? requirements.pop : :runtime
requirements = requirements.first if 1 == requirements.length # unpack 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) self.class.new name, self_req.as_list.concat(other_req.as_list)
end 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

View file

@ -21,14 +21,14 @@ class Gem::DependencyInstaller
attr_reader :installed_gems attr_reader :installed_gems
DEFAULT_OPTIONS = { DEFAULT_OPTIONS = {
:env_shebang => false, :env_shebang => false,
:domain => :both, # HACK dup :domain => :both, # HACK dup
:force => false, :force => false,
:format_executable => false, # HACK dup :format_executable => false, # HACK dup
:ignore_dependencies => false, :ignore_dependencies => false,
:prerelease => false, :prerelease => false,
:security_policy => nil, # HACK NoSecurity requires OpenSSL. AlmostNo? Low? :security_policy => nil, # HACK NoSecurity requires OpenSSL. AlmostNo? Low?
:wrappers => true, :wrappers => true,
} }
## ##
@ -51,25 +51,26 @@ class Gem::DependencyInstaller
def initialize(options = {}) def initialize(options = {})
if options[:install_dir] then if options[:install_dir] then
spec_dir = options[:install_dir], 'specifications' @gem_home = options[:install_dir]
@source_index = Gem::SourceIndex.from_gems_in spec_dir
else Gem::Specification.dirs = @gem_home
@source_index = Gem.source_index Gem.ensure_gem_subdirectories @gem_home
options[:install_dir] = @gem_home # FIX: because we suck and reuse below
end end
options = DEFAULT_OPTIONS.merge options options = DEFAULT_OPTIONS.merge options
@bin_dir = options[:bin_dir] @bin_dir = options[:bin_dir]
@development = options[:development] @development = options[:development]
@domain = options[:domain] @domain = options[:domain]
@env_shebang = options[:env_shebang] @env_shebang = options[:env_shebang]
@force = options[:force] @force = options[:force]
@format_executable = options[:format_executable] @format_executable = options[:format_executable]
@ignore_dependencies = options[:ignore_dependencies] @ignore_dependencies = options[:ignore_dependencies]
@prerelease = options[:prerelease] @prerelease = options[:prerelease]
@security_policy = options[:security_policy] @security_policy = options[:security_policy]
@user_install = options[:user_install] @user_install = options[:user_install]
@wrappers = options[:wrappers] @wrappers = options[:wrappers]
@installed_gems = [] @installed_gems = []
@ -101,6 +102,7 @@ class Gem::DependencyInstaller
if @domain == :both or @domain == :remote then if @domain == :both or @domain == :remote then
begin begin
# REFACTOR: all = dep.requirement.needs_all?
requirements = dep.requirement.requirements.map do |req, ver| requirements = dep.requirement.requirements.map do |req, ver|
req req
end end
@ -146,8 +148,8 @@ class Gem::DependencyInstaller
add_found_dependencies to_do, dependency_list unless @ignore_dependencies add_found_dependencies to_do, dependency_list unless @ignore_dependencies
dependency_list.specs.reject! { |spec| dependency_list.specs.reject! { |spec|
! keep_names.include? spec.full_name and not keep_names.include?(spec.full_name) and
@source_index.any? { |n,_| n == spec.full_name } Gem::Specification.include?(spec)
} }
unless dependency_list.ok? or @ignore_dependencies or @force then unless dependency_list.ok? or @ignore_dependencies or @force then
@ -181,7 +183,7 @@ class Gem::DependencyInstaller
to_do.push dep_spec to_do.push dep_spec
# already locally installed # already locally installed
@source_index.any? do |_, installed_spec| Gem::Specification.any? do |installed_spec|
dep.name == installed_spec.name and dep.name == installed_spec.name and
dep.requirement.satisfied_by? installed_spec.version dep.requirement.satisfied_by? installed_spec.version
end end
@ -216,23 +218,20 @@ class Gem::DependencyInstaller
local_gems = Dir["#{glob}*"].sort.reverse local_gems = Dir["#{glob}*"].sort.reverse
unless local_gems.empty? then local_gems.each do |gem_file|
local_gems.each do |gem_file| next unless gem_file =~ /gem$/
next unless gem_file =~ /gem$/ begin
begin spec = Gem::Format.from_file_by_path(gem_file).spec
spec = Gem::Format.from_file_by_path(gem_file).spec spec_and_source = [spec, gem_file]
spec_and_source = [spec, gem_file] break
break rescue SystemCallError, Gem::Package::FormatError
rescue SystemCallError, Gem::Package::FormatError
end
end end
end end
if spec_and_source.nil? then unless spec_and_source then
dep = Gem::Dependency.new gem_name, version dep = Gem::Dependency.new gem_name, version
dep.prerelease = true if prerelease dep.prerelease = true if prerelease
spec_and_sources = find_gems_with_sources(dep).reverse spec_and_sources = find_gems_with_sources(dep).reverse
spec_and_source = spec_and_sources.find { |spec, source| spec_and_source = spec_and_sources.find { |spec, source|
Gem::Platform.match spec.platform Gem::Platform.match spec.platform
} }
@ -273,9 +272,9 @@ class Gem::DependencyInstaller
gather_dependencies gather_dependencies
@gems_to_install.each do |spec| last = @gems_to_install.size - 1
last = spec == @gems_to_install.last @gems_to_install.each_with_index do |spec, index|
next if @source_index.any? { |n,_| n == spec.full_name } and not last next if Gem::Specification.include?(spec) and index != last
# TODO: make this sorta_verbose so other users can benefit from it # TODO: make this sorta_verbose so other users can benefit from it
say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose
@ -298,7 +297,6 @@ class Gem::DependencyInstaller
:ignore_dependencies => @ignore_dependencies, :ignore_dependencies => @ignore_dependencies,
:install_dir => @install_dir, :install_dir => @install_dir,
:security_policy => @security_policy, :security_policy => @security_policy,
:source_index => @source_index,
:user_install => @user_install, :user_install => @user_install,
:wrappers => @wrappers :wrappers => @wrappers
@ -309,6 +307,4 @@ class Gem::DependencyInstaller
@installed_gems @installed_gems
end end
end end

View file

@ -11,6 +11,7 @@
#++ #++
require 'tsort' require 'tsort'
require 'rubygems/deprecate'
## ##
# Gem::DependencyList is used for installing and uninstalling gems in the # Gem::DependencyList is used for installing and uninstalling gems in the
@ -27,17 +28,22 @@ class Gem::DependencyList
attr_accessor :development attr_accessor :development
##
# Creates a DependencyList from the current specs.
def self.from_specs
list = new
list.add(*Gem::Specification.map)
list
end
## ##
# Creates a DependencyList from a Gem::SourceIndex +source_index+ # Creates a DependencyList from a Gem::SourceIndex +source_index+
def self.from_source_index(source_index) def self.from_source_index(ignored=nil)
list = new warn "NOTE: DependencyList.from_source_index ignores it's arg" if ignored
source_index.each do |full_name, spec| from_specs
list.add spec
end
list
end end
## ##
@ -120,10 +126,9 @@ class Gem::DependencyList
def why_not_ok? quick = false def why_not_ok? quick = false
unsatisfied = Hash.new { |h,k| h[k] = [] } unsatisfied = Hash.new { |h,k| h[k] = [] }
source_index = Gem.source_index
each do |spec| each do |spec|
spec.runtime_dependencies.each do |dep| 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.name == installed_spec.name and
dep.requirement.satisfied_by? installed_spec.version dep.requirement.satisfied_by? installed_spec.version
} }
@ -134,6 +139,7 @@ class Gem::DependencyList
end end
end end
end end
unsatisfied unsatisfied
end end
@ -242,6 +248,11 @@ class Gem::DependencyList
def active_count(specs, ignored) def active_count(specs, ignored)
specs.count { |spec| ignored[spec.full_name].nil? } specs.count { |spec| ignored[spec.full_name].nil? }
end end
end end
class Gem::DependencyList
class << self
extend Deprecate
deprecate :from_source_index, "from_specs", 2011, 11
end
end

74
lib/rubygems/deprecate.rb Normal file
View file

@ -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

View file

@ -92,7 +92,7 @@ class Gem::DocManager
def initialize(spec, rdoc_args="") def initialize(spec, rdoc_args="")
require 'fileutils' require 'fileutils'
@spec = spec @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 @rdoc_args = rdoc_args.nil? ? [] : rdoc_args.split
end end
@ -224,25 +224,24 @@ class Gem::DocManager
# Remove RDoc and RI documentation # Remove RDoc and RI documentation
def uninstall_doc def uninstall_doc
raise Gem::FilePermissionError.new(@spec.installation_path) unless base_dir = @spec.base_dir
File.writable? @spec.installation_path 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 '-' @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 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
ri_dir = @spec.ri_dir
unless File.directory? ri_dir then
ri_dir = File.join File.dirname(ri_dir), old_name
end end
FileUtils.rm_rf doc_dir FileUtils.rm_rf doc_dir
ri_dir = File.join @spec.installation_path, 'ri', @spec.full_name
unless File.directory? ri_dir then
ri_dir = File.join @spec.installation_path, 'ri', original_name
end
FileUtils.rm_rf ri_dir FileUtils.rm_rf ri_dir
end end

View file

@ -19,7 +19,7 @@ class Gem::Ext::Builder
def self.make(dest_path, results) def self.make(dest_path, results)
unless File.exist? 'Makefile' then 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 end
mf = File.read('Makefile') mf = File.read('Makefile')

View file

@ -23,12 +23,12 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
end end
# Deal with possible spaces in the path, e.g. C:/Program Files # 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 = ENV['rake']
rake ||= begin rake ||= begin
"\"#{Gem.ruby}\" -rubygems #{Gem.bin_path('rake')}" "\"#{Gem.ruby}\" -rubygems #{Gem.bin_path('rake', 'rake')}"
rescue Gem::Exception rescue Gem::Exception
end end

View file

@ -4,6 +4,9 @@
# File a patch instead and assign it to Ryan Davis or Eric Hodel. # 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 # GemPathSearcher has the capability to find loadable files inside
# gems. It generates data up front to speed up searches later. # gems. It generates data up front to speed up searches later.
@ -56,6 +59,15 @@ class Gem::GemPathSearcher
end end
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) def find_active(glob)
# HACK violation of encapsulation # HACK violation of encapsulation
@gemspecs.find do |spec| @gemspecs.find do |spec|
@ -138,9 +150,7 @@ class Gem::GemPathSearcher
# in reverse version order. (bar-2, bar-1, foo-2) # in reverse version order. (bar-2, bar-1, foo-2)
def init_gemspecs def init_gemspecs
specs = Gem.source_index.map { |_, spec| spec } Gem::Specification.sort { |a, b|
specs.sort { |a, b|
names = a.name <=> b.name names = a.name <=> b.name
next names if names.nonzero? next names if names.nonzero?
b.version <=> a.version b.version <=> a.version
@ -156,5 +166,13 @@ class Gem::GemPathSearcher
spec.require_paths spec.require_paths
end 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

View file

@ -10,6 +10,7 @@
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require "rubygems"
require 'rubygems/command_manager' require 'rubygems/command_manager'
require 'rubygems/config_file' require 'rubygems/config_file'
require 'rubygems/doc_manager' require 'rubygems/doc_manager'
@ -31,6 +32,7 @@ Gem.load_env_plugins rescue nil
class Gem::GemRunner class Gem::GemRunner
def initialize(options={}) def initialize(options={})
# TODO: nuke these options
@command_manager_class = options[:command_manager] || Gem::CommandManager @command_manager_class = options[:command_manager] || Gem::CommandManager
@config_file_class = options[:config_file] || Gem::ConfigFile @config_file_class = options[:config_file] || Gem::ConfigFile
@doc_manager_class = options[:doc_manager] || Gem::DocManager @doc_manager_class = options[:doc_manager] || Gem::DocManager
@ -80,7 +82,7 @@ class Gem::GemRunner
def do_configuration(args) def do_configuration(args)
Gem.configuration = @config_file_class.new(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] Gem::Command.extra_args = Gem.configuration[:gem]
@doc_manager_class.configured_args = Gem.configuration[:rdoc] @doc_manager_class.configured_args = Gem.configuration[:rdoc]
end end

View file

@ -79,7 +79,7 @@ class Gem::Indexer
@rss_gems_host = options[:rss_gems_host] @rss_gems_host = options[:rss_gems_host]
@dest_directory = directory @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}" marshal_name = "Marshal.#{Gem.marshal_version}"
@ -87,24 +87,23 @@ class Gem::Indexer
@marshal_index = File.join @directory, marshal_name @marshal_index = File.join @directory, marshal_name
@quick_dir = File.join @directory, 'quick' @quick_dir = File.join @directory, 'quick'
@quick_marshal_dir = File.join @quick_dir, marshal_name @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' @quick_index = File.join @quick_dir, 'index'
@latest_index = File.join @quick_dir, 'latest_index' @latest_index = File.join @quick_dir, 'latest_index'
@specs_index = File.join @directory, "specs.#{Gem.marshal_version}" @specs_index = File.join @directory, "specs.#{Gem.marshal_version}"
@latest_specs_index = File.join @directory, @latest_specs_index =
"latest_specs.#{Gem.marshal_version}" File.join(@directory, "latest_specs.#{Gem.marshal_version}")
@prerelease_specs_index = File.join(@directory, @prerelease_specs_index =
"prerelease_specs.#{Gem.marshal_version}") File.join(@directory, "prerelease_specs.#{Gem.marshal_version}")
@dest_specs_index =
@dest_specs_index = File.join @dest_directory, File.join(@dest_directory, "specs.#{Gem.marshal_version}")
"specs.#{Gem.marshal_version}" @dest_latest_specs_index =
@dest_latest_specs_index = File.join @dest_directory, File.join(@dest_directory, "latest_specs.#{Gem.marshal_version}")
"latest_specs.#{Gem.marshal_version}" @dest_prerelease_specs_index =
@dest_prerelease_specs_index = File.join @dest_directory, File.join(@dest_directory, "prerelease_specs.#{Gem.marshal_version}")
"prerelease_specs.#{Gem.marshal_version}"
@rss_index = File.join @directory, 'index.rss' @rss_index = File.join @directory, 'index.rss'
@ -129,12 +128,16 @@ class Gem::Indexer
## ##
# Build various indicies # Build various indicies
def build_indicies(index) def build_indicies
# Marshal gemspecs are used by both modern and legacy RubyGems # Marshal gemspecs are used by both modern and legacy RubyGems
build_marshal_gemspecs index
build_legacy_indicies index if @build_legacy Gem::Specification.dirs = []
build_modern_indicies index if @build_modern Gem::Specification.add_specs(*map_gems_to_specs(gem_file_list))
build_rss index
build_marshal_gemspecs
build_legacy_indicies if @build_legacy
build_modern_indicies if @build_modern
build_rss
compress_indicies compress_indicies
end end
@ -142,7 +145,9 @@ class Gem::Indexer
## ##
# Builds indicies for RubyGems older than 1.2.x # 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" say "Generating Marshal master index"
Gem.time 'Generated Marshal master index' do Gem.time 'Generated Marshal master index' do
@ -158,16 +163,17 @@ class Gem::Indexer
## ##
# Builds Marshal quick index gemspecs. # Builds Marshal quick index gemspecs.
def build_marshal_gemspecs(index) def build_marshal_gemspecs
progress = ui.progress_reporter index.size, count = Gem::Specification.count
"Generating Marshal quick index gemspecs for #{index.size} gems", progress = ui.progress_reporter count,
"Generating Marshal quick index gemspecs for #{count} gems",
"Complete" "Complete"
files = [] files = []
Gem.time 'Generated Marshal quick index gemspecs' do Gem.time 'Generated Marshal quick index gemspecs' do
index.gems.each do |original_name, spec| Gem::Specification.each do |spec|
spec_file_name = "#{original_name}.gemspec.rz" spec_file_name = "#{spec.original_name}.gemspec.rz"
marshal_name = File.join @quick_marshal_dir, spec_file_name marshal_name = File.join @quick_marshal_dir, spec_file_name
marshal_zipped = Gem.deflate Marshal.dump(spec) marshal_zipped = Gem.deflate Marshal.dump(spec)
@ -175,7 +181,7 @@ class Gem::Indexer
files << marshal_name files << marshal_name
progress.updated original_name progress.updated spec.original_name
end end
progress.done progress.done
@ -195,8 +201,8 @@ class Gem::Indexer
Gem.time "Generated #{name} index" do Gem.time "Generated #{name} index" do
open(file, 'wb') do |io| open(file, 'wb') do |io|
specs = index.map do |*spec| specs = index.map do |*spec|
# We have to splat here because latest_specs is an array, # We have to splat here because latest_specs is an array, while the
# while the others are hashes. See the TODO in source_index.rb # others are hashes.
spec = spec.flatten.last spec = spec.flatten.last
platform = spec.original_platform platform = spec.original_platform
@ -219,13 +225,15 @@ class Gem::Indexer
## ##
# Builds indicies for RubyGems 1.2 and newer. Handles full, latest, prerelease # Builds indicies for RubyGems 1.2 and newer. Handles full, latest, prerelease
def build_modern_indicies(index) def build_modern_indicies
build_modern_index(index.released_specs.sort, @specs_index, 'specs') prerelease, released = Gem::Specification.partition { |s|
build_modern_index(index.latest_specs.sort, s.version.prerelease?
@latest_specs_index, }
'latest specs') latest_specs = Gem::Specification.latest_specs
build_modern_index(index.prerelease_specs.sort,
@prerelease_specs_index, 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') 'prerelease specs')
@files += [@specs_index, @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 # Builds an RSS feed for past two days gem releases according to the gem's
# date. # date.
def build_rss(index) def build_rss
if @rss_host.nil? or @rss_gems_host.nil? then if @rss_host.nil? or @rss_gems_host.nil? then
if Gem.configuration.really_verbose then if Gem.configuration.really_verbose then
alert_warning "no --rss-host or --rss-gems-host, RSS generation disabled" alert_warning "no --rss-host or --rss-gems-host, RSS generation disabled"
@ -272,31 +280,18 @@ class Gem::Indexer
today = Gem::Specification::TODAY today = Gem::Specification::TODAY
yesterday = today - 86400 yesterday = today - 86400
index = index.select do |_, spec| index = Gem::Specification.select do |spec|
spec_date = spec.date 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 spec_date >= yesterday && spec_date <= today
when Date
Time.parse(spec_date.to_s) >= yesterday
when Time
spec_date >= yesterday
end
end end
index = index.select do |_, spec| index.sort_by { |spec| [-spec.date.to_i, spec] }.each do |spec|
spec_date = spec.date file_name = File.basename spec.cache_file
gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{file_name}"
case spec_date size = File.stat(spec.loaded_from).size # rescue next
when Date
Time.parse(spec_date.to_s) <= today
when Time
spec_date <= today
end
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
description = spec.description || spec.summary || '' description = spec.description || spec.summary || ''
authors = Array spec.authors authors = Array spec.authors
@ -347,54 +342,56 @@ class Gem::Indexer
@files << @rss_index @files << @rss_index
end 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. # Collect specifications from .gem files from the gem directory.
def collect_specs(gems = gem_file_list) def collect_specs(gems = gem_file_list)
index = Gem::SourceIndex.new Deprecate.skip_during do
index = Gem::SourceIndex.new
progress = ui.progress_reporter gems.size, map_gems_to_specs(gems).each do |spec|
"Loading #{gems.size} gems from #{@dest_directory}", index.add_spec spec, spec.original_name
"Loaded all gems"
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
end end
progress.done index
end end
index
end end
## ##
@ -454,7 +451,7 @@ class Gem::Indexer
# List of gem file names to index. # List of gem file names to index.
def gem_file_list def gem_file_list
Dir.glob(File.join(@dest_directory, "gems", "*.gem")) Dir[File.join(@dest_directory, "gems", '*.gem')]
end end
## ##
@ -462,8 +459,7 @@ class Gem::Indexer
def generate_index def generate_index
make_temp_directories make_temp_directories
index = collect_specs build_indicies
build_indicies index
install_indicies install_indicies
rescue SignalException rescue SignalException
ensure ensure
@ -487,24 +483,22 @@ class Gem::Indexer
say "Moving index into production dir #{@dest_directory}" if verbose 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 files.delete @quick_marshal_dir if files.include? @quick_dir
if files.include? @quick_marshal_dir and if files.include? @quick_marshal_dir and not files.include? @quick_dir then
not files.include? @quick_dir then
files.delete @quick_marshal_dir 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.mkdir_p File.dirname(dst_name), :verbose => verbose
FileUtils.rm_rf dst_name, :verbose => verbose FileUtils.rm_rf dst_name, :verbose => verbose
FileUtils.mv @quick_marshal_dir, dst_name, :verbose => verbose, FileUtils.mv(@quick_marshal_dir, dst_name,
:force => true :verbose => verbose, :force => true)
end end
files = files.map do |path| files = files.map do |path|
path.sub @directory, '' path.sub(/^#{Regexp.escape @directory}\/?/, '') # HACK?
end end
files.each do |file| files.each do |file|
@ -512,8 +506,8 @@ class Gem::Indexer
dst_name = File.join @dest_directory, file dst_name = File.join @dest_directory, file
FileUtils.rm_rf dst_name, :verbose => verbose FileUtils.rm_rf dst_name, :verbose => verbose
FileUtils.mv src_name, @dest_directory, :verbose => verbose, FileUtils.mv(src_name, @dest_directory,
:force => true :verbose => verbose, :force => true)
end end
end end
@ -544,10 +538,10 @@ class Gem::Indexer
# be replaced by their XML entity equivalent. # be replaced by their XML entity equivalent.
def sanitize(spec) def sanitize(spec)
spec.summary = sanitize_string(spec.summary) spec.summary = sanitize_string(spec.summary)
spec.description = sanitize_string(spec.description) spec.description = sanitize_string(spec.description)
spec.post_install_message = sanitize_string(spec.post_install_message) 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 spec
end end
@ -593,14 +587,16 @@ class Gem::Indexer
terminate_interaction 0 terminate_interaction 0
end 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 Gem.time 'Updated indexes' do
update_specs_index index.released_gems, @dest_specs_index, @specs_index update_specs_index released, @dest_specs_index, @specs_index
update_specs_index index.released_gems, @dest_latest_specs_index, @latest_specs_index update_specs_index released, @dest_latest_specs_index, @latest_specs_index
update_specs_index(index.prerelease_gems, @dest_prerelease_specs_index, update_specs_index(prerelease,
@dest_prerelease_specs_index,
@prerelease_specs_index) @prerelease_specs_index)
end end
@ -618,12 +614,12 @@ class Gem::Indexer
files << "#{@prerelease_specs_index}.gz" files << "#{@prerelease_specs_index}.gz"
files = files.map do |path| files = files.map do |path|
path.sub @directory, '' path.sub(/^#{Regexp.escape @directory}\/?/, '') # HACK?
end end
files.each do |file| files.each do |file|
src_name = File.join @directory, 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, FileUtils.mv src_name, dst_name, :verbose => verbose,
:force => true :force => true
@ -639,7 +635,7 @@ class Gem::Indexer
def update_specs_index(index, source, dest) def update_specs_index(index, source, dest)
specs_index = Marshal.load Gem.read_binary(source) specs_index = Marshal.load Gem.read_binary(source)
index.each do |_, spec| index.each do |spec|
platform = spec.original_platform platform = spec.original_platform
platform = Gem::Platform::RUBY if platform.nil? or platform.empty? platform = Gem::Platform::RUBY if platform.nil? or platform.empty?
specs_index << [spec.name, spec.version, platform] specs_index << [spec.name, spec.version, platform]
@ -651,6 +647,4 @@ class Gem::Indexer
Marshal.dump specs_index, io Marshal.dump specs_index, io
end end
end end
end end

View file

@ -47,6 +47,8 @@ class Gem::Installer
include Gem::RequirePathsBuilder if Gem::QUICKLOADER_SUCKAGE include Gem::RequirePathsBuilder if Gem::QUICKLOADER_SUCKAGE
attr_reader :gem
## ##
# The directory a gem's executables will be installed into # The directory a gem's executables will be installed into
@ -57,11 +59,6 @@ class Gem::Installer
attr_reader :gem_home attr_reader :gem_home
##
# The Gem::Specification for the gem being installed
attr_reader :spec
## ##
# The options passed when the Gem::Installer was instantiated. # The options passed when the Gem::Installer was instantiated.
@ -106,18 +103,36 @@ class Gem::Installer
@gem = gem @gem = gem
@options = options @options = options
process_options process_options
load_gem_file
if options[:user_install] and not options[:unpack] then if options[:user_install] and not options[:unpack] then
@gem_home = Gem.user_dir @gem_home = Gem.user_dir
check_that_user_bin_dir_is_in_path check_that_user_bin_dir_is_in_path
end end
end
verify_gem_home(options[:unpack]) ##
# Lazy accessor for the spec's gem directory.
@spec = @format.spec def gem_dir
@gem_dir ||= spec.gem_dir.dup.untaint
end
@gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint ##
# 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
##
# Lazy accessor for the installer's spec.
def spec
@spec ||= format.spec
end end
## ##
@ -132,6 +147,12 @@ class Gem::Installer
# specifications/<gem-version>.gemspec #=> the Gem::Specification # specifications/<gem-version>.gemspec #=> the Gem::Specification
def install 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 # If we're forcing the install then disable security unless the security
# policy says that we only install signed gems. # policy says that we only install signed gems.
@security_policy = nil if @force and @security_policy and @security_policy = nil if @force and @security_policy and
@ -149,17 +170,17 @@ class Gem::Installer
if result == false then if result == false then
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/ 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 raise Gem::InstallError, message
end end
end end
Gem.ensure_gem_subdirectories @gem_home Gem.ensure_gem_subdirectories gem_home
# Completely remove any previous gem files # 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 extract_files
build_extensions build_extensions
@ -168,11 +189,11 @@ class Gem::Installer
result = hook.call self result = hook.call self
if result == false then if result == false then
FileUtils.rm_rf @gem_dir FileUtils.rm_rf gem_dir
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/ 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 raise Gem::InstallError, message
end end
end end
@ -182,24 +203,27 @@ class Gem::Installer
write_require_paths_file_if_needed if Gem::QUICKLOADER_SUCKAGE write_require_paths_file_if_needed if Gem::QUICKLOADER_SUCKAGE
cached_gem = Gem.cache_gem(File.basename(@gem), @gem_home) cache_file = spec.cache_file
unless File.exist? cached_gem then FileUtils.cp gem, cache_file unless File.exist? cache_file
FileUtils.cp @gem, Gem.cache_dir(@gem_home)
end
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| Gem.post_install_hooks.each do |hook|
hook.call self hook.call self
end end
return @spec return spec
rescue Zlib::GzipFile::Error 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 end
## ##
@ -220,7 +244,7 @@ class Gem::Installer
# True if the gems in the source_index satisfy +dependency+. # True if the gems in the source_index satisfy +dependency+.
def installation_satisfies_dependency?(dependency) def installation_satisfies_dependency?(dependency)
@source_index.find_name(dependency.name, dependency.requirement).size > 0 not dependency.matching_specs.empty?
end end
## ##
@ -228,7 +252,7 @@ class Gem::Installer
def unpack(directory) def unpack(directory)
@gem_dir = 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 extract_files
end end
@ -237,14 +261,10 @@ class Gem::Installer
# specifications directory. # specifications directory.
def write_spec def write_spec
rubycode = @spec.to_ruby_for_cache file_name = spec.spec_file.untaint
file_name = File.join @gem_home, 'specifications', @spec.spec_name
file_name.untaint
File.open(file_name, "w") do |file| File.open(file_name, "w") do |file|
file.puts rubycode file.puts spec.to_ruby_for_cache
end end
end end
@ -264,24 +284,28 @@ class Gem::Installer
end end
def generate_bin 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 # 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 # the system gem directory, then use the system bin directory, else create
# (or use) a new bin dir under the gem_home. # (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 Dir.mkdir bindir unless File.exist? bindir
raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir
@spec.executables.each do |filename| spec.executables.each do |filename|
filename.untaint filename.untaint
bin_path = File.expand_path "#{@spec.bindir}/#{filename}", @gem_dir bin_path = File.expand_path File.join(gem_dir, spec.bindir, filename)
if File.exist?(bin_path)
mode = File.stat(bin_path).mode | 0111 unless File.exist? bin_path
File.chmod mode, bin_path warn "Hey?!?! Where did #{bin_path} go??"
next
end end
mode = File.stat(bin_path).mode | 0111
FileUtils.chmod mode, bin_path
if @wrappers then if @wrappers then
generate_bin_script filename, bindir generate_bin_script filename, bindir
else else
@ -322,14 +346,14 @@ class Gem::Installer
return return
end end
src = File.join @gem_dir, 'bin', filename src = File.join gem_dir, spec.bindir, filename
dst = File.join bindir, formatted_program_filename(filename) dst = File.join bindir, formatted_program_filename(filename)
if File.exist? dst then if File.exist? dst then
if File.symlink? dst then if File.symlink? dst then
link = File.readlink(dst).split File::SEPARATOR link = File.readlink(dst).split File::SEPARATOR
cur_version = Gem::Version.create(link[-3].sub(/^.*-/, '')) cur_version = Gem::Version.create(link[-3].sub(/^.*-/, ''))
return if @spec.version < cur_version return if spec.version < cur_version
end end
File.unlink dst File.unlink dst
end end
@ -343,7 +367,7 @@ class Gem::Installer
def shebang(bin_file_name) def shebang(bin_file_name)
ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang 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} first_line = File.open(path, "rb") {|file| file.gets}
if /\A#!/ =~ first_line then if /\A#!/ =~ first_line then
@ -365,29 +389,29 @@ class Gem::Installer
end end
def ensure_required_ruby_version_met 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 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 end
end end
def ensure_required_rubygems_version_met 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 unless rrgv.satisfied_by? Gem::Version.new(Gem::VERSION) then
raise Gem::InstallError, raise Gem::InstallError,
"#{@spec.name} requires RubyGems version #{rrgv}. " + "#{spec.name} requires RubyGems version #{rrgv}. " +
"Try 'gem update --system' to update RubyGems itself." "Try 'gem update --system' to update RubyGems itself."
end end
end end
end end
def ensure_dependencies_met def ensure_dependencies_met
deps = @spec.runtime_dependencies deps = spec.runtime_dependencies
deps |= @spec.development_dependencies if @development deps |= spec.development_dependencies if @development
deps.each do |dep_gem| deps.each do |dep_gem|
ensure_dependency @spec, dep_gem ensure_dependency spec, dep_gem
end end
end end
@ -398,32 +422,24 @@ class Gem::Installer
:exec_format => false, :exec_format => false,
:force => false, :force => false,
:install_dir => Gem.dir, :install_dir => Gem.dir,
:source_index => Gem.source_index,
}.merge options }.merge options
@env_shebang = options[:env_shebang] @env_shebang = options[:env_shebang]
@force = options[:force] @force = options[:force]
gem_home = options[:install_dir] @gem_home = options[:install_dir]
@gem_home = File.expand_path(gem_home)
@ignore_dependencies = options[:ignore_dependencies] @ignore_dependencies = options[:ignore_dependencies]
@format_executable = options[:format_executable] @format_executable = options[:format_executable]
@security_policy = options[:security_policy] @security_policy = options[:security_policy]
@wrappers = options[:wrappers] @wrappers = options[:wrappers]
@bin_dir = options[:bin_dir] @bin_dir = options[:bin_dir]
@development = options[:development] @development = options[:development]
@source_index = options[:source_index]
end
def load_gem_file raise "NOTE: Installer option :source_index is dead" if
begin options[:source_index]
@format = Gem::Format.from_file_by_path @gem, @security_policy
rescue Gem::Package::FormatError
raise Gem::InstallError, "invalid gem format for #{@gem}"
end
end end
def check_that_user_bin_dir_is_in_path 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 ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
unless self.class.path_warning 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." 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 end
def verify_gem_home(unpack = false) def verify_gem_home(unpack = false)
FileUtils.mkdir_p @gem_home FileUtils.mkdir_p gem_home
raise Gem::FilePermissionError, @gem_home unless raise Gem::FilePermissionError, gem_home unless
unpack or File.writable? @gem_home unpack or File.writable?(gem_home)
end end
## ##
# Return the text for an application file. # Return the text for an application file.
def app_script_text(bin_file_name) def app_script_text(bin_file_name)
<<-TEXT return <<-TEXT
#{shebang bin_file_name} #{shebang bin_file_name}
# #
# This file was generated by RubyGems. # 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. # this file is here to facilitate running it.
# #
@ -460,8 +476,8 @@ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
ARGV.shift ARGV.shift
end end
gem '#{@spec.name}', version gem '#{spec.name}', version
load Gem.bin_path('#{@spec.name}', '#{bin_file_name}', version) load Gem.bin_path('#{spec.name}', '#{bin_file_name}', version)
TEXT TEXT
end end
@ -469,14 +485,16 @@ TEXT
# return the stub script text used to launch the true ruby script # return the stub script text used to launch the true ruby script
def windows_stub_script(bindir, bin_file_name) def windows_stub_script(bindir, bin_file_name)
<<-TEXT ruby = File.basename(Gem.ruby).chomp('"')
return <<-TEXT
@ECHO OFF @ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT 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 GOTO :EOF
:WinNT :WinNT
@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %* @"#{ruby}" "%~dpn0" %*
TEXT TEXT
end end
## ##
@ -484,12 +502,12 @@ TEXT
# configure scripts and rakefiles or mkrf_conf files. # configure scripts and rakefiles or mkrf_conf files.
def build_extensions def build_extensions
return if @spec.extensions.empty? return if spec.extensions.empty?
say "Building native extensions. This could take a while..." 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 ran_rake = false # only run rake once
@spec.extensions.each do |extension| spec.extensions.each do |extension|
break if ran_rake break if ran_rake
results = [] results = []
@ -508,15 +526,15 @@ TEXT
extension_dir = begin extension_dir = begin
File.join @gem_dir, File.dirname(extension) File.join gem_dir, File.dirname(extension)
rescue TypeError # extension == nil rescue TypeError # extension == nil
@gem_dir gem_dir
end end
begin begin
Dir.chdir extension_dir do 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 say results.join("\n") if Gem.configuration.really_verbose
end end
@ -532,7 +550,7 @@ ERROR: Failed to build gem native extension.
#{results} #{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} Results logged to #{gem_make_out}
EOF EOF
@ -547,35 +565,27 @@ EOF
# Ensures that files can't be installed outside the gem directory. # Ensures that files can't be installed outside the gem directory.
def extract_files def extract_files
@gem_dir = File.expand_path @gem_dir
raise ArgumentError, "format required to extract from" if @format.nil? raise ArgumentError, "format required to extract from" if @format.nil?
dirs = []
@format.file_entries.each do |entry, file_data| @format.file_entries.each do |entry, file_data|
path = entry['path'].untaint path = entry['path'].untaint
if path =~ /\A\// then # for extra sanity if path.start_with? "/" then # for extra sanity
raise Gem::InstallError, raise Gem::InstallError, "attempt to install file into #{entry['path']}"
"attempt to install file into #{entry['path'].inspect}"
end 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 unless path.start_with? gem_dir then
msg = "attempt to install file into %p under %p" % msg = "attempt to install file into %p under %s" %
[entry['path'], @gem_dir] [entry['path'], gem_dir]
raise Gem::InstallError, msg raise Gem::InstallError, msg
end end
FileUtils.rm_rf(path) if File.exists?(path) FileUtils.rm_rf(path) if File.exist? path
dir = File.dirname(path) dir = File.dirname path
if !dirs.include?(dir) FileUtils.mkdir_p dir unless File.exist? dir
dirs << dir
FileUtils.mkdir_p dir
end
File.open(path, "wb") do |out| File.open(path, "wb") do |out|
out.write file_data out.write file_data
@ -598,5 +608,14 @@ EOF
end end
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 end

View file

@ -12,7 +12,7 @@ class Gem::Installer
## ##
# Available through requiring rubygems/installer_test_case # Available through requiring rubygems/installer_test_case
attr_accessor :gem_dir attr_writer :gem_dir
## ##
# Available through requiring rubygems/installer_test_case # Available through requiring rubygems/installer_test_case
@ -63,29 +63,38 @@ class Gem::InstallerTestCase < Gem::TestCase
def setup def setup
super super
@installer_tmp = File.join @tempdir, 'installer'
FileUtils.mkdir_p @installer_tmp
Gem.use_paths @installer_tmp
Gem.ensure_gem_subdirectories @installer_tmp
@spec = quick_gem 'a' @spec = quick_gem 'a'
util_make_exec @spec util_make_exec @spec
util_build_gem @spec
@gem = File.join @tempdir, @spec.file_name @gem = @spec.cache_file
@installer = util_installer @spec, @gem, @gemhome
@user_spec = quick_gem 'b' @user_spec = quick_gem 'b'
util_make_exec @user_spec util_make_exec @user_spec
util_build_gem @user_spec
@user_gem = @user_spec.cache_file
@user_gem = File.join @tempdir, @user_spec.file_name Gem.use_paths @gemhome
@user_installer = util_installer @user_spec, @user_gem, Gem.user_dir @installer = util_installer @spec, @gemhome
@user_installer.gem_dir = File.join(Gem.user_dir, 'gems', @user_installer = util_installer @user_spec, Gem.user_dir, :user
@user_spec.full_name)
Gem.use_paths @gemhome
end end
def util_gem_bindir spec = @spec def util_gem_bindir spec = @spec
File.join util_gem_dir(spec), "bin" # TODO: deprecate
spec.bin_dir
end end
def util_gem_dir spec = @spec def util_gem_dir spec = @spec
File.join @gemhome, "gems", spec.full_name # TODO: deprecate
spec.gem_dir
end end
def util_inst_bindir def util_inst_bindir
@ -96,16 +105,13 @@ class Gem::InstallerTestCase < Gem::TestCase
spec.executables = %w[executable] spec.executables = %w[executable]
spec.files << 'bin/executable' spec.files << 'bin/executable'
bindir = util_gem_bindir spec exec_path = spec.bin_file "executable"
FileUtils.mkdir_p bindir write_file exec_path do |io|
exec_path = File.join bindir, 'executable'
open exec_path, 'w' do |io|
io.puts shebang io.puts shebang
end end
temp_bin = File.join(@tempdir, 'bin') bin_path = File.join @tempdir, "bin", "executable"
FileUtils.mkdir_p temp_bin write_file bin_path do |io|
open File.join(temp_bin, 'executable'), 'w' do |io|
io.puts shebang io.puts shebang
end end
end end
@ -128,23 +134,15 @@ class Gem::InstallerTestCase < Gem::TestCase
use_ui ui do use_ui ui do
FileUtils.rm @gem FileUtils.rm @gem
Gem::Builder.new(@spec).build
@gem = Gem::Builder.new(@spec).build
end end
end end
@installer = Gem::Installer.new @gem @installer = Gem::Installer.new @gem
end end
def util_installer(spec, gem_path, gem_home) def util_installer(spec, gem_home, user=false)
util_build_gem spec Gem::Installer.new spec.cache_file, :user_install => user
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
end end
end end

View file

@ -82,7 +82,7 @@ module Gem::LocalRemoteOptions
add_option(:"Local/Remote", '--clear-sources', add_option(:"Local/Remote", '--clear-sources',
'Clear the gem sources') do |value, options| 'Clear the gem sources') do |value, options|
Gem.sources.clear Gem.sources = nil
options[:sources_cleared] = true options[:sources_cleared] = true
end end
end end
@ -123,7 +123,7 @@ module Gem::LocalRemoteOptions
# Add the --update-sources option # Add the --update-sources option
def add_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| 'Update local source cache') do |value, options|
Gem.configuration.update_sources = value Gem.configuration.update_sources = value
end end

View file

@ -12,7 +12,15 @@ require 'rubygems/user_interaction'
# retrieval during tests. # retrieval during tests.
class Gem::MockGemUi < Gem::StreamUI 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 module TTY
@ -61,8 +69,8 @@ class Gem::MockGemUi < Gem::StreamUI
def terminate_interaction(status=0) def terminate_interaction(status=0)
@terminated = true @terminated = true
raise TermError unless status == 0 raise TermError, status if status != 0
raise Gem::SystemExitException, status raise SystemExitException
end end
end end

View file

@ -12,32 +12,6 @@
require 'rubygems/specification' 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 module Gem::Package
class Error < StandardError; end class Error < StandardError; end
@ -63,6 +37,8 @@ module Gem::Package
class TarInvalidError < Error; end 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) def self.open(io, mode = "r", signer = nil, &block)
tar_type = case mode tar_type = case mode
when 'r' then TarInput when 'r' then TarInput

View file

@ -55,6 +55,7 @@ class Gem::Package::TarInput
sio.rewind sio.rewind
end end
# TODO use Gem.gunzip
gzis = Zlib::GzipReader.new(sio || entry) gzis = Zlib::GzipReader.new(sio || entry)
# YAML wants an instance of IO # YAML wants an instance of IO
@metadata = load_gemspec(gzis) @metadata = load_gemspec(gzis)
@ -115,7 +116,6 @@ class Gem::Package::TarInput
end end
@tarreader.rewind @tarreader.rewind
@fileops = Gem::FileOperations.new
unless has_meta then unless has_meta then
path = io.path if io.respond_to? :path path = io.path if io.respond_to? :path
@ -151,9 +151,9 @@ class Gem::Package::TarInput
dest = File.join destdir, entry.full_name dest = File.join destdir, entry.full_name
if File.directory? dest then if File.directory? dest then
@fileops.chmod entry.header.mode, dest, :verbose => false FileUtils.chmod entry.header.mode, dest, :verbose => false
else else
@fileops.mkdir_p dest, :mode => entry.header.mode, :verbose => false FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
end end
fsync_dir dest fsync_dir dest
@ -165,9 +165,9 @@ class Gem::Package::TarInput
# it's a file # it's a file
md5 = Digest::MD5.new if expected_md5sum md5 = Digest::MD5.new if expected_md5sum
destdir = File.join destdir, File.dirname(entry.full_name) 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) 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| open destfile, "wb", entry.header.mode do |os|
loop do loop do
@ -181,7 +181,7 @@ class Gem::Package::TarInput
os.fsync os.fsync
end 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.dirname(destfile)
fsync_dir File.join(File.dirname(destfile), "..") fsync_dir File.join(File.dirname(destfile), "..")

View file

@ -236,7 +236,7 @@ class Gem::Package::TarWriter
name = newname name = newname
if name.size > 100 or prefix.size > 155 then if name.size > 100 or prefix.size > 155 then
raise Gem::Package::TooLongFileName raise Gem::Package::TooLongFileName
end end
end end

View file

@ -106,7 +106,7 @@ class Gem::PackageTask < Rake::PackageTask
task :package => [:gem] 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_path = File.join package_dir, gem_file
gem_dir = File.join package_dir, gem_spec.full_name gem_dir = File.join package_dir, gem_spec.full_name

View file

@ -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

View file

@ -4,6 +4,8 @@
# File a patch instead and assign it to Ryan Davis or Eric Hodel. # File a patch instead and assign it to Ryan Davis or Eric Hodel.
###################################################################### ######################################################################
require "rubygems/deprecate"
## ##
# Available list of platforms for targeting Gem installations. # Available list of platforms for targeting Gem installations.
@ -121,8 +123,13 @@ class Gem::Platform
# the same CPU, OS and version. # the same CPU, OS and version.
def ==(other) def ==(other)
self.class === other and self.class === other and to_a == other.to_a
@cpu == other.cpu and @os == other.os and @version == other.version end
alias :eql? :==
def hash # :nodoc:
to_a.hash
end end
## ##
@ -185,5 +192,8 @@ class Gem::Platform
CURRENT = 'current' CURRENT = 'current'
extend Deprecate
deprecate :empty?, :none, 2011, 11
end end

View file

@ -75,6 +75,7 @@ class Gem::RemoteFetcher
when URI::HTTP then proxy when URI::HTTP then proxy
else URI.parse(proxy) else URI.parse(proxy)
end end
@user_agent = user_agent
end end
## ##
@ -85,7 +86,8 @@ class Gem::RemoteFetcher
# larger, more emcompassing effort. -erikh # larger, more emcompassing effort. -erikh
def download_to_cache dependency 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? return if found.empty?
@ -103,12 +105,12 @@ class Gem::RemoteFetcher
Gem.ensure_gem_subdirectories(install_dir) rescue nil Gem.ensure_gem_subdirectories(install_dir) rescue nil
if File.writable?(install_dir) if File.writable?(install_dir)
cache_dir = Gem.cache_dir(install_dir) cache_dir = File.join install_dir, "cache"
else else
cache_dir = Gem.cache_dir(Gem.user_dir) cache_dir = File.join Gem.user_dir, "cache"
end 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 local_gem_path = File.join cache_dir, gem_file_name
FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir 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 # Always escape URI's to deal with potential spaces and such
unless URI::Generic === source_uri unless URI::Generic === source_uri
source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ? source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ?
URI::DEFAULT_PARSER.escape(source_uri) : URI::DEFAULT_PARSER.escape(source_uri.to_s) :
URI.escape(source_uri)) URI.escape(source_uri.to_s))
end end
scheme = source_uri.scheme scheme = source_uri.scheme
@ -192,19 +194,55 @@ class Gem::RemoteFetcher
local_gem_path local_gem_path
end 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. # Downloads +uri+ and returns it as a String.
def fetch_path(uri, mtime = nil, head = false) 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 = Gem.gunzip data if data and not head and uri.to_s =~ /gz$/
data data
rescue FetchError rescue FetchError
raise raise
rescue Timeout::Error rescue Timeout::Error
raise FetchError.new('timed out', uri) raise FetchError.new('timed out', uri.to_s)
rescue IOError, SocketError, SystemCallError => e rescue IOError, SocketError, SystemCallError => e
raise FetchError.new("#{e.class}: #{e}", uri) raise FetchError.new("#{e.class}: #{e}", uri.to_s)
end end
## ##
@ -306,36 +344,8 @@ class Gem::RemoteFetcher
# read from the filesystem instead. # read from the filesystem instead.
def open_uri_or_path(uri, last_modified = nil, head = false, depth = 0) def open_uri_or_path(uri, last_modified = nil, head = false, depth = 0)
raise "block is dead" if block_given? raise "NO: Use fetch_path instead"
# TODO: deprecate for fetch_path
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
end end
## ##
@ -350,12 +360,7 @@ class Gem::RemoteFetcher
request.basic_auth uri.user, uri.password request.basic_auth uri.user, uri.password
end end
ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}" request.add_field 'User-Agent', @user_agent
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 'Connection', 'keep-alive' request.add_field 'Connection', 'keep-alive'
request.add_field 'Keep-Alive', '30' request.add_field 'Keep-Alive', '30'
@ -447,5 +452,24 @@ class Gem::RemoteFetcher
connection.start connection.start
end 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 end

View file

@ -141,6 +141,18 @@ class Gem::Requirement
requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv } requirements.all? { |op, rv| (OPS[op] || OPS["="]).call version, rv }
end 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: def to_s # :nodoc:
as_list.join ", " as_list.join ", "
end end

View file

@ -393,7 +393,7 @@ module Gem::Security
:munge_re => Regexp.new(/[^a-z0-9_.-]+/), :munge_re => Regexp.new(/[^a-z0-9_.-]+/),
# output directory for trusted certificate checksums # 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 # default permissions for trust directory and certs
:perms => { :perms => {

View file

@ -81,47 +81,47 @@ class Gem::Server
<dl> <dl>
<% values["specs"].each do |spec| %> <% values["specs"].each do |spec| %>
<dt> <dt>
<% if spec["first_name_entry"] then %> <% if spec["first_name_entry"] then %>
<a name="<%=spec["name"]%>"></a> <a name="<%=spec["name"]%>"></a>
<% end %> <% end %>
<b><%=spec["name"]%> <%=spec["version"]%></b> <b><%=spec["name"]%> <%=spec["version"]%></b>
<% if spec["rdoc_installed"] then %> <% if spec["rdoc_installed"] then %>
<a href="<%=spec["doc_path"]%>">[rdoc]</a> <a href="<%=spec["doc_path"]%>">[rdoc]</a>
<% else %> <% else %>
<span title="rdoc not installed">[rdoc]</span> <span title="rdoc not installed">[rdoc]</span>
<% end %> <% end %>
<% if spec["homepage"] then %> <% if spec["homepage"] then %>
<a href="<%=spec["homepage"]%>" title="<%=spec["homepage"]%>">[www]</a> <a href="<%=spec["homepage"]%>" title="<%=spec["homepage"]%>">[www]</a>
<% else %> <% else %>
<span title="no homepage available">[www]</span> <span title="no homepage available">[www]</span>
<% end %> <% end %>
<% if spec["has_deps"] then %> <% if spec["has_deps"] then %>
- depends on - depends on
<%= spec["dependencies"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>. <%= spec["dependencies"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
<% end %> <% end %>
</dt> </dt>
<dd> <dd>
<%=spec["summary"]%> <%=spec["summary"]%>
<% if spec["executables"] then %> <% if spec["executables"] then %>
<br/> <br/>
<% if spec["only_one_executable"] then %> <% if spec["only_one_executable"] then %>
Executable is Executable is
<% else %> <% else %>
Executables are Executables are
<%end%> <%end%>
<%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>. <%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>.
<%end%> <%end%>
<br/> <br/>
<br/> <br/>
</dd> </dd>
<% end %> <% end %>
</dl> </dl>
@ -460,15 +460,15 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
spec_dir spec_dir
end end
@source_index = Gem::SourceIndex.from_gems_in(*@spec_dirs) Gem::Specification.dirs = @gem_dirs
end end
def Marshal(req, res) def Marshal(req, res)
@source_index.refresh! Gem::Specification.reset
add_date res add_date res
index = Marshal.dump @source_index index = Deprecate.skip_during { Marshal.dump Gem.source_index }
if req.request_method == 'HEAD' then if req.request_method == 'HEAD' then
res['content-length'] = index.length res['content-length'] = index.length
@ -492,15 +492,16 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end end
def latest_specs(req, res) def latest_specs(req, res)
@source_index.refresh! Gem::Specification.reset
res['content-type'] = 'application/x-gzip' res['content-type'] = 'application/x-gzip'
add_date res add_date res
specs = @source_index.latest_specs.sort.map do |spec| latest_specs = Gem::Specification.latest_specs
platform = spec.original_platform
platform = Gem::Platform::RUBY if platform.nil? specs = latest_specs.sort.map do |spec|
platform = spec.original_platform || Gem::Platform::RUBY
[spec.name, spec.version, platform] [spec.name, spec.version, platform]
end end
@ -552,21 +553,20 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end end
def quick(req, res) def quick(req, res)
@source_index.refresh! Gem::Specification.reset
res['content-type'] = 'text/plain' res['content-type'] = 'text/plain'
add_date res add_date res
case req.request_uri.path case req.request_uri.path
when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+)(-.*?)?\.gemspec\.rz$| then when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+)(-.*?)?\.gemspec\.rz$| then
dep = Gem::Dependency.new $2, $3 marshal_format, name, version, platform = $1, $2, $3, $4
specs = @source_index.search dep specs = Gem::Specification.find_all_by_name name, version
marshal_format = $1
selector = [$2, $3, $4].map { |s| s.inspect }.join ' ' selector = [name, version, platform].map(&:inspect).join ' '
platform = if $4 then platform = if platform then
Gem::Platform.new $4.sub(/^-/, '') Gem::Platform.new platform.sub(/^-/, '')
else else
Gem::Platform::RUBY Gem::Platform::RUBY
end end
@ -589,7 +589,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end end
def root(req, res) def root(req, res)
@source_index.refresh! Gem::Specification.reset
add_date res add_date res
raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." unless raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." unless
@ -598,13 +598,15 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
specs = [] specs = []
total_file_count = 0 total_file_count = 0
@source_index.each do |path, spec| Gem::Specification.each do |spec|
total_file_count += spec.files.size total_file_count += spec.files.size
deps = spec.dependencies.map do |dep| deps = spec.dependencies.map { |dep|
{ "name" => dep.name, {
"name" => dep.name,
"type" => dep.type, "type" => dep.type,
"version" => dep.requirement.to_s, } "version" => dep.requirement.to_s,
end }
}
deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] } deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] }
deps.last["is_last"] = true unless deps.empty? deps.last["is_last"] = true unless deps.empty?
@ -798,13 +800,12 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end end
def specs(req, res) def specs(req, res)
@source_index.refresh! Gem::Specification.reset
add_date res add_date res
specs = @source_index.sort.map do |_, spec| specs = Gem::Specification.sort_by(&:sort_obj).map do |spec|
platform = spec.original_platform platform = spec.original_platform || Gem::Platform::RUBY
platform = Gem::Platform::RUBY if platform.nil?
[spec.name, spec.version, platform] [spec.name, spec.version, platform]
end end
@ -827,12 +828,11 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
def launch def launch
listeners = @server.listeners.map{|l| l.addr[2] } 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 host = listeners.any?{|l| l == '0.0.0.0'} ? 'localhost' : listeners.first
say "Launching browser to http://#{host}:#{@port}" say "Launching browser to http://#{host}:#{@port}"
system("#{@launch} http://#{host}:#{@port}") system("#{@launch} http://#{host}:#{@port}")
end end
end end

View file

@ -11,6 +11,7 @@
#++ #++
require 'rubygems/specification' require 'rubygems/specification'
require 'rubygems/deprecate'
## ##
# The SourceIndex object indexes all the gems available from a # The SourceIndex object indexes all the gems available from a
@ -34,79 +35,86 @@ class Gem::SourceIndex
attr_accessor :spec_dirs attr_accessor :spec_dirs
class << self ##
## # Factory method to construct a source index instance for a given
# Factory method to construct a source index instance for a given # path.
# path. #
# # deprecated::
# deprecated:: # If supplied, from_installed_gems will act just like
# If supplied, from_installed_gems will act just like # +from_gems_in+. This argument is deprecated and is provided
# +from_gems_in+. This argument is deprecated and is provided # just for backwards compatibility, and should not generally
# just for backwards compatibility, and should not generally # be used.
# be used. #
# # return::
# return:: # SourceIndex instance
# SourceIndex instance
def from_installed_gems(*deprecated) def self.from_installed_gems(*deprecated)
if deprecated.empty? if deprecated.empty?
from_gems_in(*installed_spec_directories) from_gems_in(*installed_spec_directories)
else else
from_gems_in(*deprecated) # HACK warn warn "NOTE: from_installed_gems(arg) is deprecated. From #{caller.first}"
end from_gems_in(*deprecated) # HACK warn
end 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 def self.installed_spec_directories
Gem.path.collect { |dir| File.join(dir, "specifications") } # 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+.
def self.from_gems_in(*spec_dirs)
new spec_dirs
end
##
# Loads a ruby-format specification from +file_name+ and returns the
# loaded spec.
def self.load_specification(file_name)
Deprecate.skip_during do
Gem::Specification.load Gem::Path.new(file_name)
end end
##
# 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
##
# Loads a ruby-format specification from +file_name+ and returns the
# loaded spec.
def load_specification(file_name)
Gem::Specification.load file_name
end
end end
## ##
# Constructs a source index instance from the provided specifications, which # Constructs a source index instance from the provided specifications, which
# is a Hash of gem full names and Gem::Specifications. # 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 = {} @gems = {}
specifications.each{ |full_name, spec| add_spec spec }
@spec_dirs = nil @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 end
# TODO: remove method
def all_gems def all_gems
@gems gems
end end
def prerelease_gems def prerelease_gems
@gems.reject{ |name, gem| !gem.version.prerelease? } @gems.reject { |name, gem| !gem.version.prerelease? }
end end
def released_gems def released_gems
@gems.reject{ |name, gem| gem.version.prerelease? } @gems.reject { |name, gem| gem.version.prerelease? }
end end
## ##
@ -116,10 +124,12 @@ class Gem::SourceIndex
@gems.clear @gems.clear
spec_dirs.reverse_each do |spec_dir| 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| 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 add_spec gemspec if gemspec
end end
end end
@ -159,8 +169,6 @@ class Gem::SourceIndex
result[name] << spec result[name] << spec
end end
# TODO: why is this a hash while @gems is an array? Seems like
# structural similarity would be good.
result.values.flatten result.values.flatten
end end
@ -246,7 +254,10 @@ class Gem::SourceIndex
def find_name(gem_name, requirement = Gem::Requirement.default) def find_name(gem_name, requirement = Gem::Requirement.default)
dep = Gem::Dependency.new gem_name, requirement dep = Gem::Dependency.new gem_name, requirement
search dep
Deprecate.skip_during do
search dep
end
end end
## ##
@ -258,9 +269,9 @@ class Gem::SourceIndex
# +gem_pattern+, and a Gem::Requirement for +platform_only+. This # +gem_pattern+, and a Gem::Requirement for +platform_only+. This
# behavior is deprecated and will be removed. # behavior is deprecated and will be removed.
def search(gem_pattern, platform_only = false) def search(gem_pattern, platform_or_requirement = false)
requirement = nil requirement = nil
only_platform = false only_platform = false # FIX: WTF is this?!?
# TODO - Remove support and warning for legacy arguments after 2008/11 # TODO - Remove support and warning for legacy arguments after 2008/11
unless Gem::Dependency === gem_pattern unless Gem::Dependency === gem_pattern
@ -269,9 +280,9 @@ class Gem::SourceIndex
case gem_pattern case gem_pattern
when Regexp then when Regexp then
requirement = platform_only || Gem::Requirement.default requirement = platform_or_requirement || Gem::Requirement.default
when Gem::Dependency then when Gem::Dependency then
only_platform = platform_only only_platform = platform_or_requirement
requirement = gem_pattern.requirement requirement = gem_pattern.requirement
gem_pattern = if Regexp === gem_pattern.name then gem_pattern = if Regexp === gem_pattern.name then
@ -282,7 +293,7 @@ class Gem::SourceIndex
/^#{Regexp.escape gem_pattern.name}$/ /^#{Regexp.escape gem_pattern.name}$/
end end
else else
requirement = platform_only || Gem::Requirement.default requirement = platform_or_requirement || Gem::Requirement.default
gem_pattern = /#{gem_pattern}/i gem_pattern = /#{gem_pattern}/i
end end
@ -290,7 +301,7 @@ class Gem::SourceIndex
requirement = Gem::Requirement.create requirement requirement = Gem::Requirement.create requirement
end end
specs = all_gems.values.select do |spec| specs = @gems.values.select do |spec|
spec.name =~ gem_pattern and spec.name =~ gem_pattern and
requirement.satisfied_by? spec.version requirement.satisfied_by? spec.version
end end
@ -343,7 +354,6 @@ class Gem::SourceIndex
def dump def dump
Marshal.dump(self) Marshal.dump(self)
end end
end end
# :stopdoc: # :stopdoc:
@ -356,5 +366,45 @@ module Gem
Cache = SourceIndex Cache = SourceIndex
end 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:

View file

@ -91,6 +91,7 @@ class Gem::SpecFetcher
all = false, all = false,
matching_platform = true, matching_platform = true,
prerelease = false) prerelease = false)
specs_and_sources, errors = find_matching_with_errors(dependency, specs_and_sources, errors = find_matching_with_errors(dependency,
all, all,
matching_platform, matching_platform,
@ -144,7 +145,10 @@ class Gem::SpecFetcher
# matching released versions are returned. If +matching_platform+ # matching released versions are returned. If +matching_platform+
# is false, gems for all platforms are returned. # 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 = {} found = {}
rejected_specs = {} rejected_specs = {}
@ -257,13 +261,12 @@ class Gem::SpecFetcher
loaded = false loaded = false
if File.exist? local_file then 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 loaded = true if spec_dump
spec_dump = Gem.read_binary local_file
else spec_dump ||= Gem.read_binary local_file
loaded = true
end
else else
spec_dump = @fetcher.fetch_path spec_path spec_dump = @fetcher.fetch_path spec_path
loaded = true loaded = true

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@ begin
rescue Gem::LoadError rescue Gem::LoadError
end end
require "rubygems/deprecate"
require 'minitest/autorun' require 'minitest/autorun'
require 'fileutils' require 'fileutils'
require 'tmpdir' require 'tmpdir'
@ -25,6 +26,7 @@ require 'rubygems/package'
require 'rubygems/test_utilities' require 'rubygems/test_utilities'
require 'pp' require 'pp'
require 'zlib' require 'zlib'
require 'pathname'
Gem.load_yaml Gem.load_yaml
require 'rubygems/mock_gem_ui' require 'rubygems/mock_gem_ui'
@ -44,6 +46,8 @@ module Gem
# requiring 'rubygems/test_case' # requiring 'rubygems/test_case'
def self.source_index=(si) def self.source_index=(si)
raise "This method is not supported"
Gem::Specification.reset if si # HACK
@@source_index = si @@source_index = si
end end
@ -82,12 +86,24 @@ end
class Gem::TestCase < MiniTest::Unit::TestCase 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 include Gem::DefaultUserInteraction
undef_method :default_test if instance_methods.include? 'default_test' or undef_method :default_test if instance_methods.include? 'default_test' or
instance_methods.include? :default_test 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 # #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_home = ENV['GEM_HOME']
@orig_gem_path = ENV['GEM_PATH'] @orig_gem_path = ENV['GEM_PATH']
@current_dir = Dir.pwd
@ui = Gem::MockGemUi.new @ui = Gem::MockGemUi.new
tmpdir = nil tmpdir = nil
Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
if ENV['KEEP_FILES'] then 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 else
@tempdir = File.join tmpdir, "test_rubygems_#{$$}" @tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
end end
@tempdir.untaint @tempdir.untaint
@gemhome = File.join @tempdir, 'gemhome' @gemhome = File.join @tempdir, 'gemhome'
@ -126,6 +143,9 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem.ensure_gem_subdirectories @gemhome Gem.ensure_gem_subdirectories @gemhome
@orig_LOAD_PATH = $LOAD_PATH.dup
$LOAD_PATH.map! { |s| File.expand_path s }
Dir.chdir @tempdir Dir.chdir @tempdir
@orig_ENV_HOME = ENV['HOME'] @orig_ENV_HOME = ENV['HOME']
@ -136,6 +156,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
FileUtils.mkdir_p @userhome FileUtils.mkdir_p @userhome
Gem.use_paths(@gemhome) Gem.use_paths(@gemhome)
Gem.loaded_specs.clear Gem.loaded_specs.clear
Gem.unresolved_deps.clear Gem.unresolved_deps.clear
@ -191,8 +212,6 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem.pre_uninstall do |uninstaller| Gem.pre_uninstall do |uninstaller|
@pre_uninstall_hook_arg = uninstaller @pre_uninstall_hook_arg = uninstaller
end end
@orig_LOAD_PATH = $LOAD_PATH.dup
end end
## ##
@ -209,15 +228,13 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem::RemoteFetcher.fetcher = nil Gem::RemoteFetcher.fetcher = nil
end end
Dir.chdir @current_dir Dir.chdir @@project_dir
FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES'] FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES']
ENV['GEM_HOME'] = @orig_gem_home ENV['GEM_HOME'] = @orig_gem_home
ENV['GEM_PATH'] = @orig_gem_path ENV['GEM_PATH'] = @orig_gem_path
Gem.clear_paths
_ = @orig_ruby _ = @orig_ruby
Gem.class_eval { @ruby = _ } if _ Gem.class_eval { @ruby = _ } if _
@ -240,7 +257,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
end end
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 Gem::Installer.new(gem, :wrappers => true).install
end end
@ -250,9 +267,19 @@ class Gem::TestCase < MiniTest::Unit::TestCase
def uninstall_gem spec def uninstall_gem spec
require 'rubygems/uninstaller' require 'rubygems/uninstaller'
uninstaller = Gem::Uninstaller.new spec.name, :executables => true, Gem::Uninstaller.new(spec.name,
:user_install => true :executables => true, :user_install => true).uninstall
uninstaller.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 end
## ##
@ -285,7 +312,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# Writes a binary file to +path+ which is relative to +@gemhome+ # Writes a binary file to +path+ which is relative to +@gemhome+
def write_file(path) def write_file(path)
path = File.join @gemhome, path path = File.join @gemhome, path unless Pathname.new(path).absolute?
dir = File.dirname path dir = File.dirname path
FileUtils.mkdir_p dir FileUtils.mkdir_p dir
@ -296,6 +323,10 @@ class Gem::TestCase < MiniTest::Unit::TestCase
path path
end end
def all_spec_names
Gem::Specification.map(&:full_name)
end
## ##
# Creates a Gem::Specification with a minimum of extra work. +name+ and # Creates a Gem::Specification with a minimum of extra work. +name+ and
# +version+ are the gem's name and version, platform, author, email, # +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.author = 'A User'
s.email = 'example@example.com' s.email = 'example@example.com'
s.homepage = 'http://example.com' s.homepage = 'http://example.com'
s.has_rdoc = true
s.summary = "this is a summary" s.summary = "this is a summary"
s.description = "This is a test description" s.description = "This is a test description"
yield(s) if block_given? yield(s) if block_given?
end end
path = File.join "specifications", spec.spec_name Gem::Specification.map # HACK: force specs to (re-)load before we write
written_path = write_file path do |io|
io.write(spec.to_ruby) written_path = write_file spec.spec_file do |io|
io.write spec.to_ruby_for_cache
end 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 return spec
end end
def quick_spec name, version = '2' def quick_spec name, version = '2'
# TODO: deprecate
require 'rubygems/specification' require 'rubygems/specification'
spec = Gem::Specification.new do |s| spec = Gem::Specification.new do |s|
@ -346,16 +378,15 @@ class Gem::TestCase < MiniTest::Unit::TestCase
s.author = 'A User' s.author = 'A User'
s.email = 'example@example.com' s.email = 'example@example.com'
s.homepage = 'http://example.com' s.homepage = 'http://example.com'
s.has_rdoc = true
s.summary = "this is a summary" s.summary = "this is a summary"
s.description = "This is a test description" s.description = "This is a test description"
yield(s) if block_given? yield(s) if block_given?
end end
spec.loaded_from = @gemhome spec.loaded_from = spec.spec_file
Gem.source_index.add_spec spec Gem::Specification.add_spec spec
return spec return spec
end end
@ -365,7 +396,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# 'cache'</tt>. Automatically creates files based on +spec.files+ # 'cache'</tt>. Automatically creates files based on +spec.files+
def util_build_gem(spec) def util_build_gem(spec)
dir = File.join(@gemhome, 'gems', spec.full_name) dir = spec.gem_dir
FileUtils.mkdir_p dir FileUtils.mkdir_p dir
Dir.chdir dir do Dir.chdir dir do
@ -379,8 +410,8 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem::Builder.new(spec).build Gem::Builder.new(spec).build
end end
FileUtils.mv spec.file_name, cache = spec.cache_file
Gem.cache_gem("#{spec.original_name}.gem") FileUtils.mv File.basename(cache), cache
end end
end end
@ -388,19 +419,16 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# Removes all installed gems from +@gemhome+. # Removes all installed gems from +@gemhome+.
def util_clear_gems def util_clear_gems
FileUtils.rm_rf File.join(@gemhome, 'gems') FileUtils.rm_rf File.join(@gemhome, "gems") # TODO: use Gem::Dirs
FileUtils.rm_rf File.join(@gemhome, 'specifications') FileUtils.rm_rf File.join(@gemhome, "specifications")
Gem.source_index.refresh! Gem::Specification.reset
end end
## ##
# Install the provided specs # Install the provided specs
def install_specs(*specs) def install_specs(*specs)
specs.each do |spec| Gem::Specification.add_specs(*specs)
# TODO: inverted responsibility
Gem.source_index.add_spec spec
end
Gem.searcher = nil Gem.searcher = nil
end end
@ -409,19 +437,42 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# up properly. Use this instead of util_spec and util_gem. # up properly. Use this instead of util_spec and util_gem.
def new_spec name, version, deps = nil, *files def new_spec name, version, deps = nil, *files
# TODO: unfactor and deprecate util_gem and util_spec require 'rubygems/specification'
spec, = unless files.empty? then
util_gem name, version do |s| spec = Gem::Specification.new do |s|
Array(deps).each do |n,v| s.platform = Gem::Platform::RUBY
s.add_dependency n, v s.name = name
end s.version = version
s.files.push(*files) s.author = 'A User'
end s.email = 'example@example.com'
else s.homepage = 'http://example.com'
util_spec name, version, deps s.summary = "this is a summary"
end s.description = "This is a test description"
spec.loaded_from = File.join @gemhome, 'specifications', spec.spec_name
spec.loaded = false 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 spec
end end
@ -429,6 +480,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# Creates a spec with +name+, +version+ and +deps+. # Creates a spec with +name+, +version+ and +deps+.
def util_spec(name, version, deps = nil, &block) def util_spec(name, version, deps = nil, &block)
# TODO: deprecate
raise "deps or block, not both" if deps and block raise "deps or block, not both" if deps and block
if deps then if deps then
@ -449,6 +501,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
# location are returned. # location are returned.
def util_gem(name, version, deps = nil, &block) def util_gem(name, version, deps = nil, &block)
# TODO: deprecate
raise "deps or block, not both" if deps and block raise "deps or block, not both" if deps and block
if deps then if deps then
@ -465,11 +518,10 @@ class Gem::TestCase < MiniTest::Unit::TestCase
cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
FileUtils.mkdir_p File.dirname cache_file FileUtils.mkdir_p File.dirname cache_file
FileUtils.mv Gem.cache_gem("#{spec.original_name}.gem"), cache_file FileUtils.mv spec.cache_file, cache_file
FileUtils.rm File.join(@gemhome, 'specifications', spec.spec_name) FileUtils.rm spec.spec_file
spec.loaded_from = nil spec.loaded_from = nil
spec.loaded = false
[spec, cache_file] [spec, cache_file]
end 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. 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: Also, a list:
* An entry that's actually kind of sort * 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 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 DESC
end end
@ -557,9 +609,7 @@ Also, a list:
util_build_gem spec util_build_gem spec
end end
FileUtils.rm_r File.join(@gemhome, 'gems', @pl1.original_name) FileUtils.rm_r File.join(@gemhome, "gems", @pl1.original_name)
Gem.source_index = nil
end end
## ##
@ -589,6 +639,7 @@ Also, a list:
@fetcher = Gem::FakeFetcher.new @fetcher = Gem::FakeFetcher.new
util_make_gems(prerelease) util_make_gems(prerelease)
Gem::Specification.reset
@all_gems = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2].sort @all_gems = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2].sort
@all_gem_names = @all_gems.map { |gem| gem.full_name } @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 = [@a1.full_name, @a2.full_name, @a3a.full_name, @b2.full_name]
@gem_names = gem_names.sort.join("\n") @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 Gem::RemoteFetcher.fetcher = @fetcher
end end
@ -612,37 +655,42 @@ Also, a list:
# Best used with +@all_gems+ from #util_setup_fake_fetcher. # Best used with +@all_gems+ from #util_setup_fake_fetcher.
def util_setup_spec_fetcher(*specs) def util_setup_spec_fetcher(*specs)
specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten] specs -= Gem::Specification._all
si = Gem::SourceIndex.new specs Gem::Specification.add_specs(*specs)
spec_fetcher = Gem::SpecFetcher.fetcher spec_fetcher = Gem::SpecFetcher.fetcher
prerelease, _ = Gem::Specification.partition { |spec|
spec.version.prerelease?
}
spec_fetcher.specs[@uri] = [] 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_tuple = [spec.name, spec.version, spec.original_platform]
spec_fetcher.specs[@uri] << spec_tuple spec_fetcher.specs[@uri] << spec_tuple
end end
spec_fetcher.latest_specs[@uri] = [] 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_tuple = [spec.name, spec.version, spec.original_platform]
spec_fetcher.latest_specs[@uri] << spec_tuple spec_fetcher.latest_specs[@uri] << spec_tuple
end end
spec_fetcher.prerelease_specs[@uri] = [] 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_tuple = [spec.name, spec.version, spec.original_platform]
spec_fetcher.prerelease_specs[@uri] << spec_tuple spec_fetcher.prerelease_specs[@uri] << spec_tuple
end end
(si.gems.merge si.prerelease_gems).sort_by { |_,spec| spec }.each do |_, spec| v = Gem.marshal_version
path = "#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{spec.original_name}.gemspec.rz" Gem::Specification.each do |spec|
path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz"
data = Marshal.dump spec data = Marshal.dump spec
data_deflate = Zlib::Deflate.deflate data data_deflate = Zlib::Deflate.deflate data
@fetcher.data[path] = data_deflate @fetcher.data[path] = data_deflate
end end
si nil # force errors
end end
## ##

View file

@ -103,8 +103,8 @@ class Gem::FakeFetcher
end end
def download spec, source_uri, install_dir = Gem.dir def download spec, source_uri, install_dir = Gem.dir
name = spec.file_name name = File.basename spec.cache_file
path = Gem.cache_gem(name, install_dir) path = File.join install_dir, "cache", name
Gem.ensure_gem_subdirectories install_dir Gem.ensure_gem_subdirectories install_dir
@ -120,7 +120,8 @@ class Gem::FakeFetcher
end end
def download_to_cache dependency 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? return if found.empty?

View file

@ -21,7 +21,7 @@ module Gem::Text
while work.length > wrap do while work.length > wrap do
if work =~ /^(.{0,#{wrap}})[ \n]/ then if work =~ /^(.{0,#{wrap}})[ \n]/ then
result << $1 result << $1.rstrip
work.slice!(0, $&.length) work.slice!(0, $&.length)
else else
result << work.slice!(0, wrap) result << work.slice!(0, wrap)

View file

@ -48,26 +48,23 @@ class Gem::Uninstaller
# Constructs an uninstaller that will uninstall +gem+ # Constructs an uninstaller that will uninstall +gem+
def initialize(gem, options = {}) def initialize(gem, options = {})
@gem = gem @gem = gem
@version = options[:version] || Gem::Requirement.default @version = options[:version] || Gem::Requirement.default
gem_home = options[:install_dir] || Gem.dir @gem_home = File.expand_path(options[:install_dir] || Gem.dir)
@gem_home = File.expand_path gem_home
@force_executables = options[:executables] @force_executables = options[:executables]
@force_all = options[:all] @force_all = options[:all]
@force_ignore = options[:ignore] @force_ignore = options[:ignore]
@bin_dir = options[:bin_dir] @bin_dir = options[:bin_dir]
@format_executable = options[:format_executable] @format_executable = options[:format_executable]
# only add user directory if install_dir is not set # only add user directory if install_dir is not set
@user_install = false @user_install = false
@user_install = options[:user_install] unless options[:install_dir] @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 if @user_install then
user_dir = File.join Gem.user_dir, 'specifications' Gem.use_paths Gem.user_dir, @gem_home
@user_index = Gem::SourceIndex.from_gems_in user_dir else
Gem.use_paths @gem_home
end end
end end
@ -76,14 +73,13 @@ class Gem::Uninstaller
# directory, and the cached .gem file. # directory, and the cached .gem file.
def uninstall def uninstall
list = @source_index.find_name @gem, @version list = Gem::Specification.find_all_by_name(@gem, @version)
list += @user_index.find_name @gem, @version if @user_install
if list.empty? then if list.empty? then
raise Gem::InstallError, "cannot uninstall, check `gem list -d #{@gem}`" raise Gem::InstallError, "cannot uninstall, check `gem list -d #{@gem}`"
elsif list.size > 1 and @force_all then elsif list.size > 1 and @force_all then
remove_all list.dup remove_all list
elsif list.size > 1 then elsif list.size > 1 then
gem_names = list.collect {|gem| gem.full_name} + ["All versions"] 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 _, index = choose_from_list "Select gem to uninstall:", gem_names
if index == list.size then if index == list.size then
remove_all list.dup remove_all list
elsif index >= 0 && index < list.size then elsif index >= 0 && index < list.size then
uninstall_gem list[index], list.dup uninstall_gem list[index]
else else
say "Error: must enter a number [1-#{list.size+1}]" say "Error: must enter a number [1-#{list.size+1}]"
end end
else else
uninstall_gem list.first, list.dup uninstall_gem list.first
end end
end end
## ##
# Uninstalls gem +spec+ # Uninstalls gem +spec+
def uninstall_gem(spec, specs) def uninstall_gem(spec)
@spec = spec @spec = spec
unless dependencies_ok? spec unless dependencies_ok? spec
@ -121,7 +117,7 @@ class Gem::Uninstaller
end end
remove_executables @spec remove_executables @spec
remove @spec, specs remove @spec
Gem.post_uninstall_hooks.each do |hook| Gem.post_uninstall_hooks.each do |hook|
hook.call self hook.call self
@ -137,10 +133,8 @@ class Gem::Uninstaller
def remove_executables(spec) def remove_executables(spec)
return if spec.nil? or spec.executables.empty? return if spec.nil? or spec.executables.empty?
bindir = @bin_dir ? @bin_dir : Gem.bindir(spec.installation_path) list = Gem::Specification.find_all { |s|
s.name == spec.name && s.version != spec.version
list = @source_index.find_name(spec.name).delete_if { |s|
s.version == spec.version
} }
executables = spec.executables.clone executables = spec.executables.clone
@ -165,6 +159,8 @@ class Gem::Uninstaller
unless remove then unless remove then
say "Executables and scripts will remain installed." say "Executables and scripts will remain installed."
else else
bindir = @bin_dir || Gem.bindir(spec.base_dir)
raise Gem::FilePermissionError, bindir unless File.writable? bindir raise Gem::FilePermissionError, bindir unless File.writable? bindir
spec.executables.each do |exe_name| spec.executables.each do |exe_name|
@ -181,7 +177,7 @@ class Gem::Uninstaller
# NOTE: removes uninstalled gems from +list+. # NOTE: removes uninstalled gems from +list+.
def remove_all(list) def remove_all(list)
list.dup.each { |spec| uninstall_gem spec, list } list.each { |spec| uninstall_gem spec }
end end
## ##
@ -191,7 +187,7 @@ class Gem::Uninstaller
# Warning: this method modifies the +list+ parameter. Once it has # Warning: this method modifies the +list+ parameter. Once it has
# uninstalled a gem, it is removed from that list. # uninstalled a gem, it is removed from that list.
def remove(spec, list) def remove(spec)
unless path_ok?(@gem_home, spec) or unless path_ok?(@gem_home, spec) or
(@user_install and path_ok?(Gem.user_dir, spec)) then (@user_install and path_ok?(Gem.user_dir, spec)) then
e = Gem::GemNotInHomeException.new \ e = Gem::GemNotInHomeException.new \
@ -201,28 +197,27 @@ class Gem::Uninstaller
raise e raise e
end end
raise Gem::FilePermissionError, spec.installation_path unless raise Gem::FilePermissionError, spec.base_dir unless
File.writable?(spec.installation_path) File.writable?(spec.base_dir)
FileUtils.rm_rf spec.full_gem_path FileUtils.rm_rf spec.full_gem_path
original_platform_name = [ # TODO: should this be moved to spec?... I vote eww (also exists in docmgr)
spec.name, spec.version, spec.original_platform].join '-' old_platform_name = [spec.name,
spec.version,
spec.original_platform].join '-'
spec_dir = File.join spec.installation_path, 'specifications' gemspec = spec.spec_file
gemspec = File.join spec_dir, spec.spec_name
unless File.exist? gemspec then 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 end
FileUtils.rm_rf gemspec FileUtils.rm_rf gemspec
gem = Gem.cache_gem(spec.file_name, spec.installation_path) gem = spec.cache_file
gem = File.join(spec.cache_dir, "#{old_platform_name}.gem") unless
unless File.exist? gem then File.exist? gem
gem = Gem.cache_gem("#{original_platform_name}.gem", spec.installation_path)
end
FileUtils.rm_rf gem FileUtils.rm_rf gem
@ -230,14 +225,14 @@ class Gem::Uninstaller
say "Successfully uninstalled #{spec.full_name}" say "Successfully uninstalled #{spec.full_name}"
list.delete spec Gem::Specification.remove_spec spec
end end
## ##
# Is +spec+ in +gem_dir+? # Is +spec+ in +gem_dir+?
def path_ok?(gem_dir, spec) 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 original_path = File.join gem_dir, 'gems', spec.original_name
full_path == spec.full_gem_path || original_path == spec.full_gem_path full_path == spec.full_gem_path || original_path == spec.full_gem_path
@ -246,8 +241,7 @@ class Gem::Uninstaller
def dependencies_ok?(spec) def dependencies_ok?(spec)
return true if @force_ignore return true if @force_ignore
deplist = Gem::DependencyList.from_source_index @source_index deplist = Gem::DependencyList.from_specs
deplist.add(*@user_index.gems.values) if @user_install
deplist.ok_to_remove?(spec.full_name) deplist.ok_to_remove?(spec.full_name)
end end
@ -255,11 +249,13 @@ class Gem::Uninstaller
msg = [''] msg = ['']
msg << 'You have requested to uninstall the gem:' msg << 'You have requested to uninstall the gem:'
msg << "\t#{spec.full_name}" msg << "\t#{spec.full_name}"
spec.dependent_gems.each do |gem,dep,satlist|
spec.dependent_gems.each do |dep_spec, dep, satlist|
msg << msg <<
("#{gem.name}-#{gem.version} depends on " + ("#{dep_spec.name}-#{dep_spec.version} depends on " +
"[#{dep.name} (#{dep.requirement})]") "[#{dep.name} (#{dep.requirement})]")
end end
msg << 'If you remove this gems, one or more dependencies will not be met.' msg << 'If you remove this gems, one or more dependencies will not be met.'
msg << 'Continue with Uninstall?' msg << 'Continue with Uninstall?'
return ask_yes_no(msg.join("\n"), true) return ask_yes_no(msg.join("\n"), true)
@ -272,7 +268,4 @@ class Gem::Uninstaller
filename filename
end end
end end
end end

View file

@ -90,44 +90,40 @@ module Gem::UserInteraction
include Gem::DefaultUserInteraction include Gem::DefaultUserInteraction
## def alert(*args)
# :method: alert ui.alert(*args)
end
## def alert_error(*args)
# :method: alert_error ui.alert_error(*args)
end
## def alert_warning(*args)
# :method: alert_warning ui.alert_warning(*args)
end
## def ask(*args)
# :method: ask ui.ask(*args)
end
## def ask_for_password(*args)
# :method: ask_yes_no ui.ask_for_password(*args)
end
## def ask_yes_no(*args)
# :method: choose_from_list ui.ask_yes_no(*args)
end
## def choose_from_list(*args)
# :method: say ui.choose_from_list(*args)
end
## def say(*args)
# :method: terminate_interaction ui.say(*args)
end
[:alert, def terminate_interaction(*args)
:alert_error, ui.terminate_interaction(*args)
: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__
end end
end end

View file

@ -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

View file

@ -29,12 +29,12 @@ class TestGem < Gem::TestCase
def assert_activate expected, *specs def assert_activate expected, *specs
specs.each do |spec| specs.each do |spec|
case spec case spec
when Array when String then
Gem.activate(*spec) Gem::Specification.find_by_name(spec).activate
when String when Gem::Specification then
Gem.activate spec spec.activate
else else
Gem.activate spec.name flunk spec.inspect
end end
end end
@ -57,17 +57,21 @@ class TestGem < Gem::TestCase
Gem.unresolved_deps.values.map(&:to_s).sort Gem.unresolved_deps.values.map(&:to_s).sort
end end
# TODO: move these to specification
def test_self_activate_via_require def test_self_activate_via_require
new_spec "a", "1", "b" => "= 1" a1 = new_spec "a", "1", "b" => "= 1"
new_spec "b", "1", nil, "lib/b/c.rb" b1 = new_spec "b", "1", nil, "lib/b/c.rb"
new_spec "b", "2", nil, "lib/b/c.rb" b2 = new_spec "b", "2", nil, "lib/b/c.rb"
Gem.activate "a", "= 1" install_specs a1, b1, b2
a1.activate
require "b/c" require "b/c"
assert_equal %w(a-1 b-1), loaded_spec_names assert_equal %w(a-1 b-1), loaded_spec_names
end end
# TODO: move these to specification
def test_self_activate_deep_unambiguous def test_self_activate_deep_unambiguous
a1 = new_spec "a", "1", "b" => "= 1" a1 = new_spec "a", "1", "b" => "= 1"
b1 = new_spec "b", "1", "c" => "= 1" b1 = new_spec "b", "1", "c" => "= 1"
@ -77,7 +81,7 @@ class TestGem < Gem::TestCase
install_specs a1, b1, b2, c1, c2 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 assert_equal %w(a-1 b-1 c-1), loaded_spec_names
end end
@ -88,6 +92,7 @@ class TestGem < Gem::TestCase
$LOADED_FEATURES.replace old_loaded_features $LOADED_FEATURES.replace old_loaded_features
end end
# TODO: move these to specification
def test_self_activate_ambiguous_direct def test_self_activate_ambiguous_direct
save_loaded_features do save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0" a1 = new_spec "a", "1", "b" => "> 0"
@ -96,9 +101,10 @@ class TestGem < Gem::TestCase
c1 = new_spec "c", "1" c1 = new_spec "c", "1"
c2 = new_spec "c", "2" c2 = new_spec "c", "2"
Gem::Specification.reset
install_specs a1, b1, b2, c1, c2 install_specs a1, b1, b2, c1, c2
Gem.activate "a", "= 1" a1.activate
assert_equal %w(a-1), loaded_spec_names assert_equal %w(a-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names assert_equal ["b (> 0)"], unresolved_names
@ -109,6 +115,7 @@ class TestGem < Gem::TestCase
end end
end end
# TODO: move these to specification
def test_self_activate_ambiguous_indirect def test_self_activate_ambiguous_indirect
save_loaded_features do save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0" a1 = new_spec "a", "1", "b" => "> 0"
@ -119,7 +126,7 @@ class TestGem < Gem::TestCase
install_specs a1, b1, b2, c1, c2 install_specs a1, b1, b2, c1, c2
Gem.activate "a", "= 1" a1.activate
assert_equal %w(a-1), loaded_spec_names assert_equal %w(a-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names assert_equal ["b (> 0)"], unresolved_names
@ -130,6 +137,7 @@ class TestGem < Gem::TestCase
end end
end end
# TODO: move these to specification
def test_self_activate_ambiguous_unrelated def test_self_activate_ambiguous_unrelated
save_loaded_features do save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0" a1 = new_spec "a", "1", "b" => "> 0"
@ -141,7 +149,7 @@ class TestGem < Gem::TestCase
install_specs a1, b1, b2, c1, c2, d1 install_specs a1, b1, b2, c1, c2, d1
Gem.activate "a", "= 1" a1.activate
assert_equal %w(a-1), loaded_spec_names assert_equal %w(a-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names assert_equal ["b (> 0)"], unresolved_names
@ -152,6 +160,7 @@ class TestGem < Gem::TestCase
end end
end end
# TODO: move these to specification
def test_self_activate_ambiguous_indirect_conflict def test_self_activate_ambiguous_indirect_conflict
save_loaded_features do save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0" a1 = new_spec "a", "1", "b" => "> 0"
@ -163,7 +172,7 @@ class TestGem < Gem::TestCase
install_specs a1, a2, b1, b2, c1, c2 install_specs a1, a2, b1, b2, c1, c2
Gem.activate "a", "= 2" a2.activate
assert_equal %w(a-2), loaded_spec_names assert_equal %w(a-2), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names assert_equal ["b (> 0)"], unresolved_names
@ -174,13 +183,14 @@ class TestGem < Gem::TestCase
end end
end end
# TODO: move these to specification
def test_require_already_activated def test_require_already_activated
save_loaded_features do save_loaded_features do
a1 = new_spec "a", "1", nil, "lib/d.rb" a1 = new_spec "a", "1", nil, "lib/d.rb"
install_specs a1 # , a2, b1, b2, c1, c2 install_specs a1 # , a2, b1, b2, c1, c2
Gem.activate "a", "= 1" a1.activate
assert_equal %w(a-1), loaded_spec_names assert_equal %w(a-1), loaded_spec_names
assert_equal [], unresolved_names assert_equal [], unresolved_names
@ -191,6 +201,7 @@ class TestGem < Gem::TestCase
end end
end end
# TODO: move these to specification
def test_require_already_activated_indirect_conflict def test_require_already_activated_indirect_conflict
save_loaded_features do save_loaded_features do
a1 = new_spec "a", "1", "b" => "> 0" a1 = new_spec "a", "1", "b" => "> 0"
@ -202,8 +213,8 @@ class TestGem < Gem::TestCase
install_specs a1, a2, b1, b2, c1, c2 install_specs a1, a2, b1, b2, c1, c2
Gem.activate "a", "= 1" a1.activate
Gem.activate "c", "= 1" c1.activate
assert_equal %w(a-1 c-1), loaded_spec_names assert_equal %w(a-1 c-1), loaded_spec_names
assert_equal ["b (> 0)"], unresolved_names assert_equal ["b (> 0)"], unresolved_names
@ -222,11 +233,26 @@ class TestGem < Gem::TestCase
end end
end end
def test_self_activate_loaded def test_require_does_not_glob
util_spec 'foo', '1' save_loaded_features do
a1 = new_spec "a", "1", nil, "lib/a1.rb"
assert Gem.activate 'foo' install_specs a1
refute Gem.activate 'foo'
assert_raises ::LoadError do
require "a*"
end
assert_equal [], loaded_spec_names
end
end
# TODO: move these to specification
def test_self_activate_loaded
foo = util_spec 'foo', '1'
assert foo.activate
refute foo.activate
end end
## ##
@ -249,15 +275,16 @@ class TestGem < Gem::TestCase
# [B] ~> 1.0 # [B] ~> 1.0
# #
# and should resolve using b-1.0 # and should resolve using b-1.0
# TODO: move these to specification
def test_self_activate_over 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.0'
util_spec 'b', '1.1' util_spec 'b', '1.1'
util_spec 'b', '2.0' util_spec 'b', '2.0'
util_spec 'c', '1.0', 'b' => '~> 1.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 %w[a-1.0 c-1.0], loaded_spec_names
assert_equal ["b (>= 1.0, ~> 1.0)"], unresolved_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" assert_activate %w[d-1 e-1], e1, "d"
end end
def test_self_all_load_paths
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
end
def test_self_available? def test_self_available?
util_make_gems util_make_gems
assert(Gem.available?("a")) Deprecate.skip_during do
assert(Gem.available?("a", "1")) assert(Gem.available?("a"))
assert(Gem.available?("a", ">1")) assert(Gem.available?("a", "1"))
assert(!Gem.available?("monkeys")) assert(Gem.available?("a", ">1"))
assert(!Gem.available?("monkeys"))
end
end
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 end
def test_self_bin_path_bin_name 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') assert_equal @abin_path, Gem.bin_path('a', 'abin', '4')
end 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 def test_self_bin_path_nonexistent_binfile
quick_spec 'a', '2' do |s| quick_spec 'a', '2' do |s|
s.executables = ['exec'] s.executables = ['exec']
@ -467,14 +478,14 @@ class TestGem < Gem::TestCase
def test_self_bin_path_no_bin_file def test_self_bin_path_no_bin_file
quick_spec 'a', '1' quick_spec 'a', '1'
assert_raises(Gem::Exception) do assert_raises(ArgumentError) do
Gem.bin_path('a', nil, '1') Gem.bin_path('a', nil, '1')
end end
end end
def test_self_bin_path_not_found def test_self_bin_path_not_found
assert_raises(Gem::GemNotFoundException) do assert_raises(Gem::GemNotFoundException) do
Gem.bin_path('non-existent') Gem.bin_path('non-existent', 'blah')
end end
end end
@ -482,7 +493,6 @@ class TestGem < Gem::TestCase
util_exec_gem util_exec_gem
quick_spec 'a', '10' do |s| quick_spec 'a', '10' do |s|
s.executables = [] s.executables = []
s.default_executable = nil
end end
# Should not find a-10's non-abin (bug) # Should not find a-10's non-abin (bug)
assert_equal @abin_path, Gem.bin_path('a', 'abin') assert_equal @abin_path, Gem.bin_path('a', 'abin')
@ -507,17 +517,12 @@ class TestGem < Gem::TestCase
end end
def test_self_clear_paths def test_self_clear_paths
Gem.dir assert_match(/gemhome$/, Gem.dir)
Gem.path assert_match(/gemhome$/, Gem.path.first)
searcher = Gem.searcher
source_index = Gem.source_index
Gem.clear_paths Gem.clear_paths
assert_equal nil, Gem.instance_variable_get(:@gem_home) assert_nil Gem::Specification.send(:class_variable_get, :@@all)
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
end end
def test_self_configuration def test_self_configuration
@ -540,8 +545,6 @@ class TestGem < Gem::TestCase
install_gem foo install_gem foo
end end
Gem.source_index = nil
gem 'foo' gem 'foo'
expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo' expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo'
@ -598,7 +601,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories @gemhome Gem.ensure_gem_subdirectories @gemhome
assert File.directory?(Gem.cache_dir(@gemhome)) assert File.directory? File.join(@gemhome, "cache")
end end
def test_self_ensure_gem_directories_missing_parents def test_self_ensure_gem_directories_missing_parents
@ -610,7 +613,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories gemdir Gem.ensure_gem_subdirectories gemdir
assert File.directory?(Gem.cache_dir(gemdir)) assert File.directory?(util_cache_dir)
end end
unless win_platform? then # only for FS that support write protection unless win_platform? then # only for FS that support write protection
@ -624,7 +627,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories gemdir Gem.ensure_gem_subdirectories gemdir
refute File.exist?(Gem.cache_dir(gemdir)) refute File.exist?(util_cache_dir)
ensure ensure
FileUtils.chmod 0600, gemdir FileUtils.chmod 0600, gemdir
end end
@ -641,7 +644,7 @@ class TestGem < Gem::TestCase
Gem.ensure_gem_subdirectories gemdir Gem.ensure_gem_subdirectories gemdir
refute File.exist?(Gem.cache_dir(gemdir)) refute File.exist? File.join(gemdir, "gems")
ensure ensure
FileUtils.chmod 0600, parent FileUtils.chmod 0600, parent
end end
@ -661,30 +664,26 @@ class TestGem < Gem::TestCase
end end
def test_self_find_files def test_self_find_files
discover_path = File.join 'lib', 'sff', 'discover.rb'
cwd = File.expand_path("test/rubygems", @@project_dir) cwd = File.expand_path("test/rubygems", @@project_dir)
$LOAD_PATH.unshift cwd $LOAD_PATH.unshift cwd
foo1 = quick_gem 'sff', '1' do |s| discover_path = File.join 'lib', 'sff', 'discover.rb'
s.files << discover_path
end
foo2 = quick_gem 'sff', '2' do |s| foo1, foo2 = %w(1 2).map { |version|
s.files << discover_path spec = quick_gem 'sff', version do |s|
end s.files << discover_path
end
path = File.join 'gems', foo1.full_name, discover_path write_file(File.join 'gems', spec.full_name, discover_path) do |fp|
write_file(path) { |fp| fp.puts "# #{path}" } fp.puts "# #{spec.full_name}"
end
path = File.join 'gems', foo2.full_name, discover_path spec
write_file(path) { |fp| fp.puts "# #{path}" } }
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
Gem.source_index = util_setup_spec_fetcher foo1, foo2
# HACK should be Gem.refresh
Gem.searcher = nil Gem.searcher = nil
Gem::Specification.reset
expected = [ expected = [
File.expand_path('test/rubygems/sff/discover.rb', @@project_dir), File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
@ -698,26 +697,11 @@ class TestGem < Gem::TestCase
assert_equal cwd, $LOAD_PATH.shift assert_equal cwd, $LOAD_PATH.shift
end 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 def test_self_loaded_specs
foo = quick_spec 'foo' foo = quick_spec 'foo'
install_gem foo install_gem foo
Gem.source_index = nil
Gem.activate 'foo' foo.activate
assert_equal true, Gem.loaded_specs.keys.include?('foo') assert_equal true, Gem.loaded_specs.keys.include?('foo')
end end
@ -738,9 +722,10 @@ class TestGem < Gem::TestCase
orig_APPLE_GEM_HOME = APPLE_GEM_HOME orig_APPLE_GEM_HOME = APPLE_GEM_HOME
Object.send :remove_const, :APPLE_GEM_HOME Object.send :remove_const, :APPLE_GEM_HOME
end 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 ensure
Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME
end end
@ -771,7 +756,6 @@ class TestGem < Gem::TestCase
end end
def test_self_path_ENV_PATH def test_self_path_ENV_PATH
Gem.send :set_paths, nil
path_count = Gem.path.size path_count = Gem.path.size
Gem.clear_paths Gem.clear_paths
@ -840,29 +824,20 @@ class TestGem < Gem::TestCase
def test_self_refresh def test_self_refresh
util_make_gems util_make_gems
a1_spec = File.join @gemhome, "specifications", @a1.spec_name a1_spec = @a1.spec_file
moved_path = File.join @tempdir, File.basename(a1_spec)
FileUtils.mv a1_spec, @tempdir FileUtils.mv a1_spec, moved_path
refute Gem.source_index.gems.include?(@a1.full_name)
FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
Gem.refresh Gem.refresh
assert_includes Gem.source_index.gems, @a1.full_name refute_includes Gem::Specification.all_names, @a1.full_name
assert_equal nil, Gem.instance_variable_get(:@searcher)
end
def test_self_required_location FileUtils.mv moved_path, a1_spec
util_make_gems
assert_equal File.join(@tempdir, *%w[gemhome gems c-1.2 lib code.rb]), Gem.refresh
Gem.required_location("c", "code.rb")
assert_equal File.join(@tempdir, *%w[gemhome gems a-1 lib code.rb]), assert_includes Gem::Specification.all_names, @a1.full_name
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")
end end
def test_self_ruby_escaping_spaces_in_path def test_self_ruby_escaping_spaces_in_path
@ -927,19 +902,20 @@ class TestGem < Gem::TestCase
util_restore_RUBY_VERSION util_restore_RUBY_VERSION
end end
def test_self_searcher def test_self_paths_eq
assert_kind_of Gem::GemPathSearcher, Gem.searcher
end
def test_self_set_paths
other = File.join @tempdir, 'other' other = File.join @tempdir, 'other'
path = [@userhome, other].join File::PATH_SEPARATOR 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 assert_equal [@userhome, other, @gemhome], Gem.path
end end
def test_self_set_paths_nonexistent_home def test_self_paths_eq_nonexistent_home
ENV['GEM_HOME'] = @gemhome ENV['GEM_HOME'] = @gemhome
Gem.clear_paths Gem.clear_paths
@ -947,19 +923,37 @@ class TestGem < Gem::TestCase
ENV['HOME'] = other ENV['HOME'] = other
Gem.send :set_paths, other Gem.paths = { "GEM_PATH" => other }
assert_equal [other, @gemhome], Gem.path assert_equal [other, @gemhome], Gem.path
end end
def test_self_source_index 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 end
def test_self_sources def test_self_sources
assert_equal %w[http://gems.example.com/], Gem.sources assert_equal %w[http://gems.example.com/], Gem.sources
end 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 def test_ssl_available_eh
orig_Gem_ssl_available = Gem.ssl_available? orig_Gem_ssl_available = Gem.ssl_available?
@ -994,20 +988,6 @@ class TestGem < Gem::TestCase
end end
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 if Gem.win_platform? then
def test_self_user_home_userprofile def test_self_user_home_userprofile
skip 'Ruby 1.9 properly handles ~ path expansion' unless '1.9' > RUBY_VERSION skip 'Ruby 1.9 properly handles ~ path expansion' unless '1.9' > RUBY_VERSION
@ -1069,8 +1049,8 @@ class TestGem < Gem::TestCase
install_gem foo install_gem foo
end end
Gem.source_index = nil
Gem.searcher = nil Gem.searcher = nil
Gem::Specification.reset
gem 'foo' gem 'foo'
@ -1114,6 +1094,10 @@ class TestGem < Gem::TestCase
def util_ensure_gem_dirs def util_ensure_gem_dirs
Gem.ensure_gem_subdirectories @gemhome Gem.ensure_gem_subdirectories @gemhome
#
# FIXME what does this solve precisely? -ebh
#
@additional.each do |dir| @additional.each do |dir|
Gem.ensure_gem_subdirectories @gemhome Gem.ensure_gem_subdirectories @gemhome
end end
@ -1121,7 +1105,6 @@ class TestGem < Gem::TestCase
def util_exec_gem def util_exec_gem
spec, _ = quick_spec 'a', '4' do |s| spec, _ = quick_spec 'a', '4' do |s|
s.default_executable = 'exec'
s.executables = ['exec', 'abin'] s.executables = ['exec', 'abin']
end end
@ -1164,5 +1147,9 @@ class TestGem < Gem::TestCase
Gem::Commands.send :remove_const, :InterruptCommand if Gem::Commands.send :remove_const, :InterruptCommand if
Gem::Commands.const_defined? :InterruptCommand Gem::Commands.const_defined? :InterruptCommand
end end
def util_cache_dir
File.join Gem.dir, "cache"
end
end end

View file

@ -6,6 +6,7 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/builder' require 'rubygems/builder'
require 'rubygems/package'
class TestGemBuilder < Gem::TestCase class TestGemBuilder < Gem::TestCase
@ -29,5 +30,21 @@ class TestGemBuilder < Gem::TestCase
end end
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

View file

@ -29,6 +29,7 @@ class TestGemCommandManager < Gem::TestCase
end end
ensure ensure
$:.replace old_load_path $:.replace old_load_path
Gem::CommandManager.reset
end end
def test_run_crash_command def test_run_crash_command
@ -46,6 +47,7 @@ class TestGemCommandManager < Gem::TestCase
end end
ensure ensure
$:.replace old_load_path $:.replace old_load_path
@command_manager.unregister_command :crash
end end
def test_process_args_bad_arg def test_process_args_bad_arg

View file

@ -40,10 +40,38 @@ class TestGemCommandsBuildCommand < Gem::TestCase
util_test_build_gem @gem, gemspec_file util_test_build_gem @gem, gemspec_file
end 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] @cmd.options[:args] = %w[some_gem]
use_ui @ui do use_ui @ui do
@cmd.execute assert_raises Gem::MockGemUi::TermError do
@cmd.execute
end
end end
assert_equal '', @ui.output assert_equal '', @ui.output
@ -67,7 +95,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
assert_equal [], output assert_equal [], output
assert_equal '', @ui.error 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) assert File.exist?(gem_file)
spec = Gem::Format.from_file_by_path(gem_file).spec spec = Gem::Format.from_file_by_path(gem_file).spec

View file

@ -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

View file

@ -15,11 +15,18 @@ class TestGemCommandsContentsCommand < Gem::TestCase
@cmd = Gem::Commands::ContentsCommand.new @cmd = Gem::Commands::ContentsCommand.new
end 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 def test_execute
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
quick_gem 'foo' do |gem|
gem.files = %w[lib/foo.rb Rakefile] gem 'foo'
end
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
@ -33,13 +40,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase
def test_execute_all def test_execute_all
@cmd.options[:all] = true @cmd.options[:all] = true
quick_gem 'foo' do |gem| gem 'foo'
gem.files = %w[lib/foo.rb Rakefile] gem 'bar'
end
quick_gem 'bar' do |gem|
gem.files = %w[lib/bar.rb Rakefile]
end
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
@ -67,13 +69,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase
def test_execute_exact_match def test_execute_exact_match
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
quick_gem 'foo' do |gem| gem 'foo'
gem.files = %w[lib/foo.rb Rakefile] gem 'bar'
end
quick_gem 'foo_bar' do |gem|
gem.files = %w[lib/foo_bar.rb Rakefile]
end
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
@ -88,9 +85,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@cmd.options[:lib_only] = true @cmd.options[:lib_only] = true
quick_gem 'foo' do |gem| gem 'foo'
gem.files = %w[lib/foo.rb Rakefile]
end
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
@ -104,13 +99,9 @@ class TestGemCommandsContentsCommand < Gem::TestCase
def test_execute_multiple def test_execute_multiple
@cmd.options[:args] = %w[foo bar] @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 'foo'
gem.files = %w[lib/bar.rb Rakefile] gem 'bar'
end
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
@ -126,17 +117,15 @@ class TestGemCommandsContentsCommand < Gem::TestCase
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@cmd.options[:prefix] = false @cmd.options[:prefix] = false
quick_gem 'foo' do |gem| gem 'foo'
gem.files = %w[lib/foo.rb Rakefile]
end
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
end end
expected = <<-EOF expected = <<-EOF
lib/foo.rb
Rakefile Rakefile
lib/foo.rb
EOF EOF
assert_equal expected, @ui.output assert_equal expected, @ui.output

View file

@ -24,8 +24,6 @@ class TestGemCommandsDependencyCommand < Gem::TestCase
gem.add_dependency 'baz', '> 1' gem.add_dependency 'baz', '> 1'
end end
Gem.source_index = nil
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
use_ui @ui do use_ui @ui do
@ -38,8 +36,6 @@ class TestGemCommandsDependencyCommand < Gem::TestCase
end end
def test_execute_no_args def test_execute_no_args
Gem.source_index = nil
@cmd.options[:args] = [] @cmd.options[:args] = []
use_ui @ui do use_ui @ui do
@ -99,8 +95,6 @@ Gem pl-1-x86-linux
end end
def test_execute_regexp def test_execute_regexp
Gem.source_index = nil
@cmd.options[:args] = %w[/[ab]/] @cmd.options[:args] = %w[/[ab]/]
use_ui @ui do use_ui @ui do
@ -136,8 +130,6 @@ Gem b-2
gem.add_dependency 'foo' gem.add_dependency 'foo'
end end
Gem.source_index = nil
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@cmd.options[:reverse_dependencies] = true @cmd.options[:reverse_dependencies] = true
@ -199,14 +191,31 @@ ERROR: Only reverse dependencies for local gems are supported.
assert_equal '', @ui.error assert_equal '', @ui.error
end 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 def test_execute_prerelease
@fetcher = Gem::FakeFetcher.new @fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher Gem::RemoteFetcher.fetcher = @fetcher
util_clear_gems
util_setup_spec_fetcher @a2_pre util_setup_spec_fetcher @a2_pre
FileUtils.rm File.join(@gemhome, 'specifications', @a2_pre.spec_name)
@cmd.options[:args] = %w[a] @cmd.options[:args] = %w[a]
@cmd.options[:domain] = :remote @cmd.options[:domain] = :remote
@cmd.options[:prerelease] = true @cmd.options[:prerelease] = true

View file

@ -22,7 +22,7 @@ class TestGemCommandsFetchCommand < Gem::TestCase
util_setup_spec_fetcher @a2 util_setup_spec_fetcher @a2
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = @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] @cmd.options[:args] = [@a2.name]
@ -38,12 +38,13 @@ class TestGemCommandsFetchCommand < Gem::TestCase
def test_execute_prerelease def test_execute_prerelease
util_setup_fake_fetcher true util_setup_fake_fetcher true
util_clear_gems
util_setup_spec_fetcher @a2, @a2_pre util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = @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}"] = @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[:args] = [@a2.name]
@cmd.options[:prerelease] = true @cmd.options[:prerelease] = true
@ -63,7 +64,7 @@ class TestGemCommandsFetchCommand < Gem::TestCase
util_setup_spec_fetcher @a1, @a2 util_setup_spec_fetcher @a1, @a2
@fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = @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[:args] = [@a2.name]
@cmd.options[:version] = Gem::Requirement.new '1' @cmd.options[:version] = Gem::Requirement.new '1'

View file

@ -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

View file

@ -24,13 +24,13 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end end
def test_execute_exclude_prerelease def test_execute_exclude_prerelease
util_setup_fake_fetcher(:prerelease) util_setup_fake_fetcher :prerelease
util_setup_spec_fetcher @a2, @a2_pre util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = @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}"] = @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] @cmd.options[:args] = [@a2.name]
@ -46,13 +46,13 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end end
def test_execute_explicit_version_includes_prerelease def test_execute_explicit_version_includes_prerelease
util_setup_fake_fetcher(:prerelease) util_setup_fake_fetcher :prerelease
util_setup_spec_fetcher @a2, @a2_pre util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = @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}"] = @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, @cmd.handle_options [@a2_pre.name, '--version', @a2_pre.version.to_s,
"--no-ri", "--no-rdoc"] "--no-ri", "--no-rdoc"]
@ -92,7 +92,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
util_setup_fake_fetcher util_setup_fake_fetcher
@cmd.options[:domain] = :local @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] @cmd.options[:args] = [@a2.name]
@ -121,15 +121,15 @@ class TestGemCommandsInstallCommand < Gem::TestCase
util_setup_fake_fetcher util_setup_fake_fetcher
@cmd.options[:user_install] = false @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] @cmd.options[:args] = [@a2.name]
use_ui @ui do use_ui @ui do
orig_dir = Dir.pwd orig_dir = Dir.pwd
begin begin
File.chmod 0755, @userhome FileUtils.chmod 0755, @userhome
File.chmod 0555, @gemhome FileUtils.chmod 0555, @gemhome
Dir.chdir @tempdir Dir.chdir @tempdir
assert_raises Gem::FilePermissionError do assert_raises Gem::FilePermissionError do
@ -137,7 +137,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end end
ensure ensure
Dir.chdir orig_dir Dir.chdir orig_dir
File.chmod 0755, @gemhome FileUtils.chmod 0755, @gemhome
end end
end end
end end
@ -208,13 +208,14 @@ ERROR: Possible alternatives: non_existent_with_hint
end end
def test_execute_prerelease def test_execute_prerelease
util_setup_fake_fetcher(:prerelease) util_setup_fake_fetcher :prerelease
util_clear_gems
util_setup_spec_fetcher @a2, @a2_pre util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = @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}"] = @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[:prerelease] = true
@cmd.options[:args] = [@a2_pre.name] @cmd.options[:args] = [@a2_pre.name]
@ -235,10 +236,10 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.options[:generate_ri] = true @cmd.options[:generate_ri] = true
util_setup_fake_fetcher util_setup_fake_fetcher
util_setup_spec_fetcher @a2 util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = @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] @cmd.options[:args] = [@a2.name]
@ -265,9 +266,9 @@ ERROR: Possible alternatives: non_existent_with_hint
util_setup_fake_fetcher util_setup_fake_fetcher
@cmd.options[:domain] = :local @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] @cmd.options[:args] = [@a2.name, @b2.name]
@ -293,10 +294,10 @@ ERROR: Possible alternatives: non_existent_with_hint
def test_execute_conservative def test_execute_conservative
util_setup_fake_fetcher util_setup_fake_fetcher
util_setup_spec_fetcher @b2 util_setup_spec_fetcher
@fetcher.data["#{@gem_repo}gems/#{@b2.file_name}"] = @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) uninstall_gem(@b2)
@ -308,16 +309,16 @@ ERROR: Possible alternatives: non_existent_with_hint
orig_dir = Dir.pwd orig_dir = Dir.pwd
begin begin
Dir.chdir @tempdir Dir.chdir @tempdir
e = assert_raises Gem::SystemExitException do assert_raises Gem::SystemExitException do
@cmd.execute @cmd.execute
end end
assert_equal 0, e.exit_code
ensure ensure
Dir.chdir orig_dir Dir.chdir orig_dir
end end
end end
out = @ui.output.split "\n" out = @ui.output.split "\n"
assert_equal "", @ui.error
assert_equal "Successfully installed #{@b2.full_name}", out.shift assert_equal "Successfully installed #{@b2.full_name}", out.shift
assert_equal "1 gem installed", out.shift assert_equal "1 gem installed", out.shift
assert out.empty?, out.inspect assert out.empty?, out.inspect

View file

@ -26,16 +26,13 @@ class TestGemCommandsListCommand < Gem::TestCase
def test_execute_installed def test_execute_installed
@cmd.handle_options %w[c --installed] @cmd.handle_options %w[c --installed]
e = assert_raises Gem::SystemExitException do assert_raises Gem::MockGemUi::SystemExitException do
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
end end
end end
assert_equal 0, e.exit_code
assert_equal "true\n", @ui.output assert_equal "true\n", @ui.output
assert_equal '', @ui.error assert_equal '', @ui.error
end end

View file

@ -20,24 +20,25 @@ class TestGemCommandsOutdatedCommand < Gem::TestCase
end end
def test_execute def test_execute
quick_gem 'foo', '0.1'
quick_gem 'foo', '0.2'
remote_10 = quick_spec 'foo', '1.0' remote_10 = quick_spec 'foo', '1.0'
remote_20 = quick_spec 'foo', '2.0' remote_20 = quick_spec 'foo', '2.0'
remote_spec_file = File.join @gemhome, 'specifications', remote_10.spec_name Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
remote_spec_file = File.join @gemhome, 'specifications', remote_20.spec_name
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
util_clear_gems
util_setup_spec_fetcher remote_10, remote_20 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 "foo (0.2 < 2.0)\n", @ui.output
assert_equal "", @ui.error assert_equal "", @ui.error
end end
end end

View file

@ -16,8 +16,8 @@ class TestGemCommandsPristineCommand < Gem::TestCase
def test_execute def test_execute
a = quick_spec 'a' do |s| s.executables = %w[foo] end 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" fp.puts "#!/usr/bin/ruby"
end end
@ -25,7 +25,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
foo_path = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo' 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!' io.puts 'I changed it!'
end end
@ -39,15 +39,14 @@ class TestGemCommandsPristineCommand < Gem::TestCase
out = @ui.output.split "\n" 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_equal "Restored #{a.full_name}", out.shift
assert_empty out, out.inspect assert_empty out, out.inspect
end end
def test_execute_all def test_execute_all
a = quick_spec 'a' do |s| s.executables = %w[foo] end a = quick_spec 'a' do |s| s.executables = %w[foo] end
FileUtils.mkdir_p File.join(@tempdir, 'bin') write_file File.join(@tempdir, 'bin', 'foo') do |fp|
File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp|
fp.puts "#!/usr/bin/ruby" fp.puts "#!/usr/bin/ruby"
end end
@ -67,35 +66,106 @@ class TestGemCommandsPristineCommand < Gem::TestCase
out = @ui.output.split "\n" 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_equal "Restored #{a.full_name}", out.shift
assert_empty out, out.inspect assert_empty out, out.inspect
end end
def test_execute_missing_cache_gem def test_execute_no_exetension
a = quick_spec 'a' do |s| a = quick_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end
s.executables = %w[foo]
ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb'
write_file ext_path do |io|
io.write '# extconf.rb'
end end
FileUtils.mkdir_p File.join(@tempdir, 'bin') util_build_gem a
File.open File.join(@tempdir, 'bin', 'foo'), 'w' do |fp| @cmd.options[:args] = %w[a]
fp.puts "#!/usr/bin/ruby" @cmd.options[:extensions] = false
use_ui @ui do
@cmd.execute
end 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 a
install_gem b
a_data = nil @cmd.options[:args] = %w[a b]
open File.join(@gemhome, 'cache', a.file_name), 'rb' do |fp|
a_data = fp.read 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
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 end
util_setup_fake_fetcher 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] @cmd.options[:args] = %w[a]
@ -106,11 +176,12 @@ class TestGemCommandsPristineCommand < Gem::TestCase
out = @ui.output.split "\n" out = @ui.output.split "\n"
[ [
"Restoring gem\(s\) to pristine condition...", "Restoring gems to pristine condition...",
"Restored a-1", "Restored a-1",
"Cached gem for a-2 not found, attempting to fetch...", "Cached gem for a-2 not found, attempting to fetch...",
"Restored a-2", "Restored a-2",
"Restored a-3.a" "Restored a-3.a",
"Restored a-3",
].each do |line| ].each do |line|
assert_equal line, out.shift assert_equal line, out.shift
end end
@ -127,7 +198,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
end end
end end
assert_match %r|specify a gem name|, e.message assert_match %r|at least one gem name|, e.message
end end
end end

View file

@ -21,7 +21,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
super super
@gems_dir = File.join @tempdir, 'gems' @gems_dir = File.join @tempdir, 'gems'
@cache_dir = Gem.cache_dir @gemhome @cache_dir = File.join @gemhome, "cache"
FileUtils.mkdir @gems_dir FileUtils.mkdir @gems_dir

View file

@ -15,8 +15,8 @@ class TestGemCommandsQueryCommand < Gem::TestCase
@cmd = Gem::Commands::QueryCommand.new @cmd = Gem::Commands::QueryCommand.new
util_setup_fake_fetcher util_setup_fake_fetcher
util_clear_gems
@si = util_setup_spec_fetcher @a1, @a2, @pl1, @a3a util_setup_spec_fetcher @a1, @a2, @pl1, @a3a
@fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
raise Gem::RemoteFetcher::FetchError raise Gem::RemoteFetcher::FetchError
@ -48,7 +48,8 @@ pl (1 i386-linux)
@a1.platform = 'x86-linux' @a1.platform = 'x86-linux'
@a2.platform = 'universal-darwin' @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] @cmd.handle_options %w[-r -a]
@ -113,7 +114,8 @@ pl (1 i386-linux)
@a2.homepage = 'http://a.example.com/' @a2.homepage = 'http://a.example.com/'
@a2.rubyforge_project = 'rubygems' @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] @cmd.handle_options %w[-r -d]
@ -154,7 +156,8 @@ pl (1)
@a2.rubyforge_project = 'rubygems' @a2.rubyforge_project = 'rubygems'
@a2.platform = 'universal-darwin' @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] @cmd.handle_options %w[-r -d]
@ -190,25 +193,22 @@ pl (1)
end end
def test_execute_installed 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 use_ui @ui do
@cmd.execute @cmd.execute
end end
end end
assert_equal 0, e.exit_code
assert_equal "true\n", @ui.output assert_equal "true\n", @ui.output
assert_equal '', @ui.error assert_equal '', @ui.error
end end
def test_execute_installed_no_name def test_execute_installed_no_name
@cmd.handle_options %w[--installed] @cmd.handle_options %w[--installed]
e = assert_raises Gem::SystemExitException do e = assert_raises Gem::MockGemUi::TermError do
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
end end
@ -223,7 +223,7 @@ pl (1)
def test_execute_installed_not_installed def test_execute_installed_not_installed
@cmd.handle_options %w[-n not_installed --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 use_ui @ui do
@cmd.execute @cmd.execute
end end
@ -236,9 +236,9 @@ pl (1)
end end
def test_execute_installed_version 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 use_ui @ui do
@cmd.execute @cmd.execute
end end
@ -246,14 +246,12 @@ pl (1)
assert_equal "true\n", @ui.output assert_equal "true\n", @ui.output
assert_equal '', @ui.error assert_equal '', @ui.error
assert_equal 0, e.exit_code
end end
def test_execute_installed_version_not_installed def test_execute_installed_version_not_installed
@cmd.handle_options %w[-n c --installed --version 2] @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 use_ui @ui do
@cmd.execute @cmd.execute
end end
@ -265,65 +263,6 @@ pl (1)
assert_equal 1, e.exit_code assert_equal 1, e.exit_code
end 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 def test_execute_local_notty
@cmd.handle_options %w[] @cmd.handle_options %w[]
@ -335,9 +274,6 @@ pl (1)
expected = <<-EOF expected = <<-EOF
a (3.a, 2, 1) a (3.a, 2, 1)
a_evil (9)
b (2)
c (1.2)
pl (1 i386-linux) pl (1 i386-linux)
EOF EOF
@ -412,9 +348,6 @@ a (3.a)
*** LOCAL GEMS *** *** LOCAL GEMS ***
a (3.a, 2, 1) a (3.a, 2, 1)
a_evil (9)
b (2)
c (1.2)
pl (1 i386-linux) pl (1 i386-linux)
EOF EOF

View file

@ -42,12 +42,11 @@ class TestGemCommandsSourcesCommand < Gem::TestCase
def test_execute_add def test_execute_add
util_setup_fake_fetcher util_setup_fake_fetcher
si = Gem::SourceIndex.new install_specs @a1
si.add_spec @a1
specs = si.map do |_, spec| specs = Gem::Specification.map { |spec|
[spec.name, spec.version, spec.original_platform] [spec.name, spec.version, spec.original_platform]
end }
specs_dump_gz = StringIO.new specs_dump_gz = StringIO.new
Zlib::GzipWriter.wrap specs_dump_gz do |io| 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] @cmd.handle_options %w[--update]
util_setup_fake_fetcher 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] [spec.name, spec.version, spec.original_platform]
end }
@fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] = @fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] =
util_gzip Marshal.dump(specs) 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] [spec.name, spec.version, spec.original_platform]
end }
@fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
util_gzip Marshal.dump(latest_specs) util_gzip Marshal.dump(latest_specs)

View file

@ -17,7 +17,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
def test_execute def test_execute
foo = quick_spec 'foo' foo = quick_spec 'foo'
Gem.source_index.add_spec foo
install_specs foo
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@ -77,8 +78,9 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end end
def test_execute_field def test_execute_field
foo = quick_spec 'foo' foo = new_spec 'foo', '2'
Gem.source_index.add_spec foo
install_specs foo
@cmd.options[:args] = %w[foo name] @cmd.options[:args] = %w[foo name]
@ -90,8 +92,9 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end end
def test_execute_marshal def test_execute_marshal
foo = quick_spec 'foo' foo = new_spec 'foo', '2'
Gem.source_index.add_spec foo
install_specs foo
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@cmd.options[:format] = :marshal @cmd.options[:format] = :marshal
@ -127,7 +130,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
def test_execute_ruby def test_execute_ruby
foo = quick_spec 'foo' foo = quick_spec 'foo'
Gem.source_index.add_spec foo
install_specs foo
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@cmd.options[:format] = :ruby @cmd.options[:format] = :ruby

View file

@ -25,12 +25,12 @@ class TestGemCommandsStaleCommand < Gem::TestCase
end end
files.each do |file| files.each do |file|
filename = bar_baz.full_gem_path + "/#{file}" filename = File.join(bar_baz.full_gem_path, file)
FileUtils.mkdir_p(File.dirname(filename)) FileUtils.mkdir_p File.dirname filename
FileUtils.touch(filename, :mtime => Time.now) FileUtils.touch(filename, :mtime => Time.now)
filename = foo_bar.full_gem_path + "/#{file}" filename = File.join(foo_bar.full_gem_path, file)
FileUtils.mkdir_p(File.dirname(filename)) FileUtils.mkdir_p File.dirname filename
FileUtils.touch(filename, :mtime => Time.now - 86400) FileUtils.touch(filename, :mtime => Time.now - 86400)
end end

View file

@ -21,20 +21,20 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
util_make_gems util_make_gems
assert_equal( assert_equal(
@cmd.find_in_cache(@a1.file_name), @cmd.find_in_cache(File.basename @a1.cache_file),
Gem.cache_gem(@a1.file_name, @gemhome), @a1.cache_file,
'found a-1.gem in the cache' 'found a-1.gem in the cache'
) )
end end
def test_get_path def test_get_path
util_make_gems
util_setup_fake_fetcher util_setup_fake_fetcher
util_clear_gems
util_setup_spec_fetcher @a1 util_setup_spec_fetcher @a1
a1_data = nil 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 a1_data = fp.read
end end
@ -44,15 +44,15 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
dep = Gem::Dependency.new(@a1.name, @a1.version) dep = Gem::Dependency.new(@a1.name, @a1.version)
assert_equal( assert_equal(
@cmd.get_path(dep), @cmd.get_path(dep),
Gem.cache_gem(@a1.file_name, @gemhome), @a1.cache_file,
'fetches a-1 and returns the cache path' 'fetches a-1 and returns the cache path'
) )
FileUtils.rm Gem.cache_gem(@a1.file_name, @gemhome) FileUtils.rm @a1.cache_file
assert_equal( assert_equal(
@cmd.get_path(dep), @cmd.get_path(dep),
Gem.cache_gem(@a1.file_name, @gemhome), @a1.cache_file,
'when removed from cache, refetches a-1' 'when removed from cache, refetches a-1'
) )
end end
@ -73,16 +73,14 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
end end
def test_execute_gem_path def test_execute_gem_path
util_make_gems
util_setup_spec_fetcher
util_setup_fake_fetcher util_setup_fake_fetcher
util_setup_spec_fetcher
Gem.clear_paths Gem.clear_paths
gemhome2 = File.join @tempdir, 'gemhome2' gemhome2 = File.join @tempdir, 'gemhome2'
Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR) Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
Gem.send :set_home, gemhome2
@cmd.options[:args] = %w[a] @cmd.options[:args] = %w[a]
@ -96,15 +94,14 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
end end
def test_execute_gem_path_missing def test_execute_gem_path_missing
util_make_gems util_setup_fake_fetcher
util_setup_spec_fetcher util_setup_spec_fetcher
Gem.clear_paths Gem.clear_paths
gemhome2 = File.join @tempdir, 'gemhome2' gemhome2 = File.join @tempdir, 'gemhome2'
Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR) Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
Gem.send :set_home, gemhome2
@cmd.options[:args] = %w[z] @cmd.options[:args] = %w[z]
@ -123,7 +120,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
util_clear_gems util_clear_gems
a2_data = nil 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 a2_data = fp.read
end end
@ -142,10 +139,28 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
assert File.exist?(File.join(@tempdir, 'a-2')), 'a should be unpacked' assert File.exist?(File.join(@tempdir, 'a-2')), 'a should be unpacked'
end end
def test_execute_sudo def test_execute_spec
util_make_gems util_make_gems
File.chmod 0555, @gemhome @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
FileUtils.chmod 0555, @gemhome
@cmd.options[:args] = %w[b] @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' assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked'
ensure ensure
File.chmod 0755, @gemhome FileUtils.chmod 0755, @gemhome
end end
def test_execute_with_target_option def test_execute_with_target_option
@ -203,5 +218,13 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
assert File.exist?(File.join(@tempdir, foo_spec.full_name)) assert File.exist?(File.join(@tempdir, foo_spec.full_name))
end end
def test_handle_options_metadata
refute @cmd.options[:spec]
@cmd.send :handle_options, %w[--spec a]
assert @cmd.options[:spec]
end
end end

View file

@ -24,15 +24,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@cmd.options[:generate_ri] = false @cmd.options[:generate_ri] = false
util_setup_fake_fetcher util_setup_fake_fetcher
util_clear_gems
@a1_path = Gem.cache_gem(@a1.file_name, @gemhome)
@a2_path = Gem.cache_gem(@a2.file_name, @gemhome)
util_setup_spec_fetcher @a1, @a2 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 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 read_binary @a2_path
end end
@ -81,18 +81,19 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
def util_add_to_fetcher *specs def util_add_to_fetcher *specs
specs.each do |spec| 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 Gem.read_binary gem_file
end end
end end
def test_execute_system def test_execute_system
util_clear_gems
util_setup_rubygem9 util_setup_rubygem9
util_setup_spec_fetcher @rubygem9 util_setup_spec_fetcher @rubygem9
util_add_to_fetcher @rubygem9 util_add_to_fetcher @rubygem9
util_clear_gems
@cmd.options[:args] = [] @cmd.options[:args] = []
@cmd.options[:system] = true @cmd.options[:system] = true
@ -113,17 +114,17 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end end
def test_execute_system_at_latest def test_execute_system_at_latest
util_clear_gems
util_setup_rubygem_current util_setup_rubygem_current
util_setup_spec_fetcher @rubygem_current util_setup_spec_fetcher @rubygem_current
util_add_to_fetcher @rubygem_current util_add_to_fetcher @rubygem_current
util_clear_gems
@cmd.options[:args] = [] @cmd.options[:args] = []
@cmd.options[:system] = true @cmd.options[:system] = true
@cmd.options[:generate_rdoc] = false @cmd.options[:generate_rdoc] = false
@cmd.options[:generate_ri] = false @cmd.options[:generate_ri] = false
assert_raises Gem::SystemExitException do assert_raises Gem::MockGemUi::SystemExitException do
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
end end
@ -135,11 +136,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end end
def test_execute_system_multiple def test_execute_system_multiple
util_clear_gems
util_setup_rubygem9 util_setup_rubygem9
util_setup_rubygem8 util_setup_rubygem8
util_setup_spec_fetcher @rubygem8, @rubygem9 util_setup_spec_fetcher @rubygem8, @rubygem9
util_add_to_fetcher @rubygem8, @rubygem9 util_add_to_fetcher @rubygem8, @rubygem9
util_clear_gems
@cmd.options[:args] = [] @cmd.options[:args] = []
@cmd.options[:system] = true @cmd.options[:system] = true
@ -184,6 +185,31 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty out assert_empty out
end 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 def test_execute_system_with_gems
@cmd.options[:args] = %w[gem] @cmd.options[:args] = %w[gem]
@cmd.options[:system] = true @cmd.options[:system] = true
@ -218,16 +244,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@a2.add_dependency 'c', '2' @a2.add_dependency 'c', '2'
@a2.add_dependency 'b', '2' @a2.add_dependency 'b', '2'
@b2_path = Gem.cache_gem(@b2.file_name, @gemhome) @b2_path = @b2.cache_file
@c1_2_path = Gem.cache_gem(@c1_2.file_name, @gemhome) @c1_2_path = @c1_2.cache_file
@c2_path = Gem.cache_gem(@c2.file_name, @gemhome) @c2_path = @c2.cache_file
@source_index = Gem::SourceIndex.new install_specs @a1, @a2, @b2, @c1_2, @c2
@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
util_build_gem @a1 util_build_gem @a1
util_build_gem @a2 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/#{@a1.file_name}"] = read_binary @a1_path
@fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = read_binary @a2_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/#{@b2.file_name}"] = read_binary @b2_path
@fetcher.data["#{@gem_repo}gems/#{@c1_2.file_name}"] = @fetcher.data["#{@gem_repo}gems/#{@c1_2.file_name}"] = read_binary @c1_2_path
read_binary @c1_2_path
@fetcher.data["#{@gem_repo}gems/#{@c2.file_name}"] = read_binary @c2_path @fetcher.data["#{@gem_repo}gems/#{@c2.file_name}"] = read_binary @c2_path
util_setup_spec_fetcher @a1, @a2, @b2, @c1_2, @c2 util_setup_spec_fetcher @a1, @a2, @b2, @c1_2, @c2
util_clear_gems
Gem::Installer.new(@c1_2_path).install Gem::Installer.new(@c1_2_path).install
Gem::Installer.new(@a1_path).install Gem::Installer.new(@a1_path).install
Gem::Specification.reset
@cmd.options[:args] = [] @cmd.options[:args] = []
use_ui @ui do use_ui @ui do

View file

@ -11,6 +11,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
def setup def setup
super super
Gem::Specification.reset
@cmd = Gem::Commands::WhichCommand.new @cmd = Gem::Commands::WhichCommand.new
end end
@ -28,6 +29,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end end
def test_execute_one_missing def test_execute_one_missing
# TODO: this test fails in isolation
util_foo_bar util_foo_bar
@cmd.handle_options %w[foo_bar missing] @cmd.handle_options %w[foo_bar missing]
@ -37,7 +40,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output 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 @ui.error
end end
@ -51,7 +54,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end end
assert_equal '', @ui.output 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 @ui.error
end end
@ -62,8 +65,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end end
files.each do |file| files.each do |file|
filename = @foo_bar.full_gem_path + "/#{file}" filename = File.join(@foo_bar.full_gem_path, file)
FileUtils.mkdir_p File.dirname(filename) FileUtils.mkdir_p File.dirname filename
FileUtils.touch filename FileUtils.touch filename
end end
end end

View file

@ -67,16 +67,20 @@ class TestGemDependency < Gem::TestCase
assert_match d, d, "match self" assert_match d, d, "match self"
assert_match dep("a", ">= 0"), d, "match version exact" assert_match dep("a", ">= 0"), d, "match version exact"
assert_match dep("a", ">= 0"), dep("a", "1"), "match version" 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 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 end
def test_equals_tilde_escape def test_equals_tilde_escape
refute_match dep("a|b"), dep("a", "1") 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 end
def test_equals_tilde_object def test_equals_tilde_object
@ -90,9 +94,11 @@ class TestGemDependency < Gem::TestCase
def test_equals_tilde_spec def test_equals_tilde_spec
assert_match dep("a", ">= 0"), spec("a", "0") assert_match dep("a", ">= 0"), spec("a", "0")
assert_match dep("a", "1"), spec("a", "1") assert_match dep("a", "1"), spec("a", "1")
assert_match dep(/a/, ">= 0"), spec("a", "0") Deprecate.skip_during do
assert_match dep(/a|b/, ">= 0"), spec("b", "0") assert_match dep(/a/, ">= 0"), spec("a", "0")
refute_match dep(/a/, ">= 0"), spec("b", "0") assert_match dep(/a|b/, ">= 0"), spec("b", "0")
refute_match dep(/a/, ">= 0"), spec("b", "0")
end
end end
def test_hash def test_hash
@ -166,5 +172,12 @@ class TestGemDependency < Gem::TestCase
assert d.prerelease? assert d.prerelease?
end end
def test_specific
refute dep('a', '> 1').specific?
assert dep('a', '= 1').specific?
end
end end

View file

@ -14,10 +14,14 @@ class TestGemDependencyInstaller < Gem::TestCase
super super
@gems_dir = File.join @tempdir, 'gems' @gems_dir = File.join @tempdir, 'gems'
@cache_dir = Gem.cache_dir(@gemhome) @cache_dir = File.join @gemhome, 'cache'
FileUtils.mkdir @gems_dir 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, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end
@a1_pre, @a1_pre_gem = util_gem 'a', '1.a' @a1_pre, @a1_pre_gem = util_gem 'a', '1.a'
@b1, @b1_gem = util_gem 'b', '1' do |s| @b1, @b1_gem = util_gem 'b', '1' do |s|
@ -25,12 +29,13 @@ class TestGemDependencyInstaller < Gem::TestCase
s.add_development_dependency 'aa' s.add_development_dependency 'aa'
end end
Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new util_clear_gems
util_reset_gems util_reset_gems
end end
def test_install def test_install
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
inst = nil inst = nil
@ -39,13 +44,13 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install 'a' inst.install 'a'
end end
assert_equal Gem::SourceIndex.new(@a1.full_name => @a1), assert_equal %w[a-1], Gem::Specification.map(&:full_name)
Gem::SourceIndex.from_installed_gems
assert_equal [@a1], inst.installed_gems assert_equal [@a1], inst.installed_gems
end end
def test_install_all_dependencies def test_install_all_dependencies
util_setup_gems
_, e1_gem = util_gem 'e', '1' do |s| _, e1_gem = util_gem 'e', '1' do |s|
s.add_dependency 'b' s.add_dependency 'b'
end end
@ -71,6 +76,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_cache_dir def test_install_cache_dir
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
inst = nil 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_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
assert Gem.cache_gem(@a1.file_name, @gemhome) assert File.exist? File.join(@gemhome, "cache", @a1.file_name)
assert Gem.cache_gem(@b1.file_name, @gemhome) assert File.exist? File.join(@gemhome, "cache", @b1.file_name)
end end
def test_install_dependencies_satisfied def test_install_dependencies_satisfied
util_setup_gems
a2, a2_gem = util_gem 'a', '2' a2, a2_gem = util_gem 'a', '2'
FileUtils.rm_rf File.join(@gemhome, 'gems') FileUtils.rm_rf File.join(@gemhome, 'gems')
Gem.source_index.refresh!
Gem::Specification.reset
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
FileUtils.mv a2_gem, @tempdir # not in index FileUtils.mv a2_gem, @tempdir # not in index
@ -109,14 +119,13 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install 'b' inst.install 'b'
end end
installed = Gem::SourceIndex.from_installed_gems.map { |n,s| s.full_name } assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
assert_equal %w[a-2 b-1], installed.sort
assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
end end
def test_install_dependency def test_install_dependency
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
inst = nil inst = nil
@ -130,6 +139,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_dependency_development def test_install_dependency_development
util_setup_gems
@aa1, @aa1_gem = util_gem 'aa', '1' @aa1, @aa1_gem = util_gem 'aa', '1'
util_reset_gems util_reset_gems
@ -148,6 +159,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_dependency_existing def test_install_dependency_existing
util_setup_gems
Gem::Installer.new(@a1_gem).install Gem::Installer.new(@a1_gem).install
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
@ -180,6 +193,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_local def test_install_local
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
inst = nil inst = nil
@ -192,6 +207,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_local_dependency def test_install_local_dependency
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
@ -206,6 +223,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_local_dependency_installed def test_install_local_dependency_installed
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
@ -222,6 +241,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_local_subdir def test_install_local_subdir
util_setup_gems
inst = nil inst = nil
Dir.chdir @tempdir do Dir.chdir @tempdir do
@ -233,11 +254,13 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_env_shebang def test_install_env_shebang
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
inst = nil inst = nil
Dir.chdir @tempdir do 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' inst.install 'a'
end end
@ -248,6 +271,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_force def test_install_force
util_setup_gems
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
si = util_setup_spec_fetcher @b1 si = util_setup_spec_fetcher @b1
@fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
@ -262,6 +287,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_ignore_dependencies def test_install_ignore_dependencies
util_setup_gems
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
inst = nil inst = nil
@ -274,6 +301,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_install_dir def test_install_install_dir
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
gemhome2 = File.join @tempdir, 'gemhome2' gemhome2 = File.join @tempdir, 'gemhome2'
Dir.mkdir 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_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?(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 end
def test_install_domain_both def test_install_domain_both
util_setup_gems
a1_data = nil a1_data = nil
File.open @a1_gem, 'rb' do |fp| File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read 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 } assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
a1, b1 = inst.installed_gems a1, b1 = inst.installed_gems
a1_expected = File.join(@gemhome, 'specifications', a1.spec_name) assert_equal a1.spec_file, a1.loaded_from
b1_expected = File.join(@gemhome, 'specifications', b1.spec_name) assert_equal b1.spec_file, b1.loaded_from
assert_equal a1_expected, a1.loaded_from
assert_equal b1_expected, b1.loaded_from
end end
def test_install_domain_both_no_network def test_install_domain_both_no_network
util_setup_gems
@fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] = @fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] =
proc do proc do
raise Gem::RemoteFetcher::FetchError raise Gem::RemoteFetcher::FetchError
@ -335,12 +365,11 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_domain_local def test_install_domain_local
util_setup_gems
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
inst = nil inst = nil
Gem.source_index.remove_spec @a1.full_name
Gem.source_index.remove_spec @a1_pre.full_name
Dir.chdir @tempdir do Dir.chdir @tempdir do
e = assert_raises Gem::DependencyError do e = assert_raises Gem::DependencyError do
inst = Gem::DependencyInstaller.new :domain => :local inst = Gem::DependencyInstaller.new :domain => :local
@ -355,6 +384,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_domain_remote def test_install_domain_remote
util_setup_gems
a1_data = nil a1_data = nil
File.open @a1_gem, 'rb' do |fp| File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read a1_data = fp.read
@ -369,6 +400,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_dual_repository def test_install_dual_repository
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir
inst = nil inst = nil
@ -393,6 +426,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_reinstall def test_install_reinstall
util_setup_gems
Gem::Installer.new(@a1_gem).install Gem::Installer.new(@a1_gem).install
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
inst = nil inst = nil
@ -402,13 +437,13 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install 'a' inst.install 'a'
end end
assert_equal Gem::SourceIndex.new(@a1.full_name => @a1), assert_equal %w[a-1], Gem::Specification.map(&:full_name)
Gem::SourceIndex.from_installed_gems assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
end end
def test_install_remote def test_install_remote
util_setup_gems
a1_data = nil a1_data = nil
File.open @a1_gem, 'rb' do |fp| File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read a1_data = fp.read
@ -426,6 +461,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_remote_dep def test_install_remote_dep
util_setup_gems
a1_data = nil a1_data = nil
File.open @a1_gem, 'rb' do |fp| File.open @a1_gem, 'rb' do |fp|
a1_data = fp.read a1_data = fp.read
@ -444,6 +481,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_install_remote_platform_newer def test_install_remote_platform_newer
util_setup_gems
a2_o, a2_o_gem = util_gem 'a', '2' do |s| a2_o, a2_o_gem = util_gem 'a', '2' do |s|
s.platform = Gem::Platform.new %w[cpu other_platform 1] s.platform = Gem::Platform.new %w[cpu other_platform 1]
end end
@ -473,6 +512,8 @@ class TestGemDependencyInstaller < Gem::TestCase
if defined? OpenSSL then if defined? OpenSSL then
def test_install_security_policy def test_install_security_policy
util_setup_gems
data = File.open(@a1_gem, 'rb') { |f| f.read } data = File.open(@a1_gem, 'rb') { |f| f.read }
@fetcher.data['http://gems.example.com/gems/a-1.gem'] = data @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 # Wrappers don't work on mswin
unless win_platform? then unless win_platform? then
def test_install_no_wrappers def test_install_no_wrappers
util_setup_gems
@fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem) @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' inst.install 'a'
refute_match(%r|This file was generated by RubyGems.|, refute_match(%r|This file was generated by RubyGems.|,
@ -537,14 +580,19 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_find_gems_gems_with_sources def test_find_gems_gems_with_sources
util_setup_gems
inst = Gem::DependencyInstaller.new inst = Gem::DependencyInstaller.new
dep = Gem::Dependency.new 'b', '>= 0' dep = Gem::Dependency.new 'b', '>= 0'
assert_equal [[@b1, @gem_repo]], Gem::Specification.reset
inst.find_gems_with_sources(dep)
assert_equal [[@b1, @gem_repo]], inst.find_gems_with_sources(dep)
end end
def test_find_gems_with_sources_local def test_find_gems_with_sources_local
util_setup_gems
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
inst = Gem::DependencyInstaller.new inst = Gem::DependencyInstaller.new
dep = Gem::Dependency.new 'a', '>= 0' dep = Gem::Dependency.new 'a', '>= 0'
@ -566,6 +614,8 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_find_gems_with_sources_prerelease def test_find_gems_with_sources_prerelease
util_setup_gems
installer = Gem::DependencyInstaller.new installer = Gem::DependencyInstaller.new
dependency = Gem::Dependency.new('a', Gem::Requirement.default) dependency = Gem::Dependency.new('a', Gem::Requirement.default)
@ -586,8 +636,8 @@ class TestGemDependencyInstaller < Gem::TestCase
def assert_resolve expected, *specs def assert_resolve expected, *specs
util_clear_gems util_clear_gems
util_setup_spec_fetcher(*specs) util_setup_spec_fetcher(*specs)
Gem::Specification.reset
inst = Gem::DependencyInstaller.new inst = Gem::DependencyInstaller.new
inst.find_spec_by_name_and_version specs.first.name inst.find_spec_by_name_and_version specs.first.name
@ -601,6 +651,7 @@ class TestGemDependencyInstaller < Gem::TestCase
util_clear_gems util_clear_gems
util_setup_spec_fetcher(*specs) util_setup_spec_fetcher(*specs)
Gem::Specification.reset
spec = specs.first spec = specs.first
@ -613,6 +664,9 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_gather_dependencies def test_gather_dependencies
util_setup_gems
util_reset_gems
inst = Gem::DependencyInstaller.new inst = Gem::DependencyInstaller.new
inst.find_spec_by_name_and_version 'b' inst.find_spec_by_name_and_version 'b'
inst.gather_dependencies inst.gather_dependencies
@ -725,6 +779,7 @@ class TestGemDependencyInstaller < Gem::TestCase
end end
def test_gather_dependencies_prerelease def test_gather_dependencies_prerelease
util_setup_gems
util_setup_c1_pre util_setup_c1_pre
assert_resolve_pre %w[a-1.a b-1 c-1.a], @c1_pre, @a1_pre, @b1 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 end
def util_reset_gems def util_reset_gems
@a1 ||= nil
@b1 ||= nil
@a1_pre ||= nil
@c1_pre ||= nil @c1_pre ||= nil
@d1 ||= nil @d1 ||= nil
@d2 ||= nil @d2 ||= nil

View file

@ -12,8 +12,11 @@ class TestGemDependencyList < Gem::TestCase
def setup def setup
super super
util_clear_gems
@deplist = Gem::DependencyList.new @deplist = Gem::DependencyList.new
# TODO: switch to new_spec
@a1 = quick_spec 'a', '1' @a1 = quick_spec 'a', '1'
@a2 = quick_spec 'a', '2' @a2 = quick_spec 'a', '2'
@a3 = quick_spec 'a', '3' @a3 = quick_spec 'a', '3'
@ -28,13 +31,10 @@ class TestGemDependencyList < Gem::TestCase
end end
def test_self_from_source_index def test_self_from_source_index
hash = { util_clear_gems
'a-1' => @a1, install_specs @a1, @b2
'b-2' => @b2,
}
si = Gem::SourceIndex.new hash deps = Deprecate.skip_during { Gem::DependencyList.from_source_index }
deps = Gem::DependencyList.from_source_index si
assert_equal %w[b-2 a-1], deps.dependency_order.map { |s| s.full_name } assert_equal %w[b-2 a-1], deps.dependency_order.map { |s| s.full_name }
end end

View file

@ -17,21 +17,21 @@ class TestGemDocManager < Gem::TestCase
end end
def test_uninstall_doc_unwritable def test_uninstall_doc_unwritable
path = @spec.installation_path path = @spec.base_dir
orig_mode = File.stat(path).mode orig_mode = File.stat(path).mode
# File.chmod has no effect on MS Windows directories (it needs ACL). # File.chmod has no effect on MS Windows directories (it needs ACL).
if win_platform? if win_platform?
skip("test_uninstall_doc_unwritable skipped on MS Windows") skip("test_uninstall_doc_unwritable skipped on MS Windows")
else else
File.chmod 0000, path FileUtils.chmod 0000, path
end end
assert_raises Gem::FilePermissionError do assert_raises Gem::FilePermissionError do
@manager.uninstall_doc @manager.uninstall_doc
end end
ensure ensure
File.chmod orig_mode, path FileUtils.chmod orig_mode, path
end end
end end

View file

@ -20,7 +20,7 @@ class TestGemFormat < Gem::Package::TarTestCase
def test_class_from_file_by_path def test_class_from_file_by_path
util_make_gems 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| names = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1].map do |spec|
spec.original_name spec.original_name

View file

@ -13,72 +13,88 @@ class Gem::GemPathSearcher
end end
class TestGemGemPathSearcher < Gem::TestCase class TestGemGemPathSearcher < Gem::TestCase
def setup def setup
super super
@foo1 = quick_gem 'foo', '0.1' do |s| @foo1 = new_spec 'foo', '0.1', nil, "lib/foo.rb"
s.require_paths << 'lib2' @foo1.require_paths << 'lib2'
s.files << 'lib/foo.rb'
end
path = File.join 'gems', @foo1.full_name, 'lib', 'foo.rb' path = File.join 'gems', @foo1.full_name, 'lib', 'foo.rb'
write_file(path) { |fp| fp.puts "# #{path}" } write_file(path) { |fp| fp.puts "# #{path}" }
@foo2 = quick_gem 'foo', '0.2' @foo2 = new_spec 'foo', '0.2'
@bar1 = quick_gem 'bar', '0.1' @bar1 = new_spec 'bar', '0.1'
@bar2 = quick_gem 'bar', '0.2' @bar2 = new_spec 'bar', '0.2'
@nrp = quick_gem 'nil_require_paths', '0.1' @nrp = new_spec 'nil_require_paths', '0.1' do |s|
@nrp.require_paths = nil s.require_paths = nil
end
util_setup_fake_fetcher
Gem::Specification.reset
util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2
@fetcher = Gem::FakeFetcher.new @fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher Gem::RemoteFetcher.fetcher = @fetcher
Gem.source_index = util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2 @gps = Deprecate.skip_during { Gem::GemPathSearcher.new }
@gps = Gem::GemPathSearcher.new
end end
def test_find def test_find
assert_equal @foo1, @gps.find('foo') Deprecate.skip_during do
assert_equal @foo1, @gps.find('foo')
end
end end
def test_find_all def test_find_all
assert_equal [@foo1], @gps.find_all('foo') Deprecate.skip_during do
assert_equal [@foo1], @gps.find_all('foo')
end
end end
def test_init_gemspecs 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 end
def test_lib_dirs_for def test_lib_dirs_for
lib_dirs = @gps.lib_dirs_for(@foo1) Deprecate.skip_during do
expected = File.join @gemhome, 'gems', @foo1.full_name, '{lib,lib2}' 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 end
def test_lib_dirs_for_nil_require_paths 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 end
def test_matching_file_eh def test_matching_file_eh
refute @gps.matching_file?(@foo1, 'bar') Deprecate.skip_during do
assert @gps.matching_file?(@foo1, 'foo') refute @gps.matching_file?(@foo1, 'bar')
assert @gps.matching_file?(@foo1, 'foo')
end
end end
def test_matching_files 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 end
def test_matching_files_nil_require_paths 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
end end

View file

@ -39,10 +39,7 @@ class TestGemGemRunner < Gem::TestCase
def test_build_args__are_handled def test_build_args__are_handled
Gem.clear_paths Gem.clear_paths
gr = Gem::GemRunner.new Gem::GemRunner.new.run(%W[help -- --build_arg1 --build_arg2])
assert_raises(Gem::SystemExitException) do
gr.run(%W[--help -- --build_arg1 --build_arg2])
end
assert_equal %w[--build_arg1 --build_arg2], Gem::Command.build_args assert_equal %w[--build_arg1 --build_arg2], Gem::Command.build_args
end end

View file

@ -16,6 +16,7 @@ class TestGemIndexer < Gem::TestCase
def setup def setup
super super
util_clear_gems
util_make_gems util_make_gems
@d2_0 = quick_spec 'd', '2.0' do |s| @d2_0 = quick_spec 'd', '2.0' do |s|
@ -33,11 +34,12 @@ class TestGemIndexer < Gem::TestCase
gems = File.join(@tempdir, 'gems') gems = File.join(@tempdir, 'gems')
FileUtils.mkdir_p 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', @indexer = Gem::Indexer.new(@tempdir,
:rss_host => 'example.com', :rss_title => 'ExampleForge gems',
:rss_gems_host => 'gems.example.com' :rss_host => 'example.com',
:rss_gems_host => 'gems.example.com')
end end
def test_initialize def test_initialize
@ -61,36 +63,37 @@ class TestGemIndexer < Gem::TestCase
end end
def test_build_indicies def test_build_indicies
spec = quick_spec 'd', '2.0'
spec.instance_variable_set :@original_platform, ''
@indexer.make_temp_directories @indexer.make_temp_directories
index = Gem::SourceIndex.new
index.add_spec spec
use_ui @ui do use_ui @ui do
@indexer.build_indicies index @indexer.build_indicies
end end
specs_path = File.join @indexer.directory, "specs.#{@marshal_version}" specs_path = File.join @indexer.directory, "specs.#{@marshal_version}"
specs_dump = Gem.read_binary specs_path specs_dump = Gem.read_binary specs_path
specs = Marshal.load specs_dump specs = Marshal.load specs_dump
expected = [ expected = [["a", Gem::Version.new("1"), "ruby"],
['d', Gem::Version.new('2.0'), '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_path = File.join(@indexer.directory,
"latest_specs.#{@marshal_version}" "latest_specs.#{@marshal_version}")
latest_specs_dump = Gem.read_binary latest_specs_path latest_specs_dump = Gem.read_binary latest_specs_path
latest_specs = Marshal.load latest_specs_dump latest_specs = Marshal.load latest_specs_dump
expected = [ expected = [["a", Gem::Version.new("2"), "ruby"],
['d', Gem::Version.new('2.0'), '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' assert_equal expected, latest_specs, 'latest_specs'
end end
@ -109,10 +112,10 @@ class TestGemIndexer < Gem::TestCase
assert File.directory?(quickdir) assert File.directory?(quickdir)
assert File.directory?(marshal_quickdir) assert File.directory?(marshal_quickdir)
assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
assert_indexed marshal_quickdir, "#{@a2.spec_name}.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}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -230,12 +233,12 @@ class TestGemIndexer < Gem::TestCase
<description> <description>
&lt;pre&gt;This line is really, really long. So long, in fact, that it is more than &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 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. Without the wrapping, the text might not look good in the RSS feed.
Also, a list: Also, a list:
* An entry that's actually kind of sort * 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 That's ok, somebody wasn't thinking straight when they made it more than
eighty characters.&lt;/pre&gt; eighty characters.&lt;/pre&gt;
</description> </description>
@ -272,10 +275,10 @@ eighty characters.&lt;/pre&gt;
assert File.directory?(quickdir) assert File.directory?(quickdir)
assert File.directory?(marshal_quickdir) assert File.directory?(marshal_quickdir)
assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
assert_indexed marshal_quickdir, "#{@a2.spec_name}.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}"
refute_indexed @tempdir, "specs.#{@marshal_version}.gz" refute_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -308,8 +311,8 @@ eighty characters.&lt;/pre&gt;
assert File.directory?(marshal_quickdir) assert File.directory?(marshal_quickdir)
assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" 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"
refute_indexed quickdir, "latest_index.rz" refute_indexed quickdir, "latest_index.rz"
refute_indexed quickdir, "#{@a1.spec_name}.rz" refute_indexed quickdir, "#{File.basename(@a1.spec_file)}.rz"
refute_indexed quickdir, "#{@a2.spec_name}.rz" refute_indexed quickdir, "#{File.basename(@a2.spec_file)}.rz"
refute_indexed quickdir, "#{@b2.spec_name}.rz" refute_indexed quickdir, "#{File.basename(@b2.spec_file)}.rz"
refute_indexed quickdir, "#{@c1_2.spec_name}.rz" refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}.rz"
refute_indexed quickdir, "#{@pl1.original_name}.gemspec.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, "#{File.basename(@a1.spec_file)}.rz"
assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
refute_indexed quickdir, "#{@c1_2.spec_name}" refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}"
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}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -389,8 +392,8 @@ eighty characters.&lt;/pre&gt;
assert File.directory?(quickdir) assert File.directory?(quickdir)
assert File.directory?(marshal_quickdir) assert File.directory?(marshal_quickdir)
assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz" assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz" assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -404,10 +407,7 @@ eighty characters.&lt;/pre&gt;
@indexer.generate_index @indexer.generate_index
end end
assert_match %r%^Loading 10 gems from #{Regexp.escape @tempdir}$%,
@ui.output
assert_match %r%^\.\.\.\.\.\.\.\.\.\.$%, @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$%, assert_match %r%^Generating Marshal quick index gemspecs for 10 gems$%,
@ui.output @ui.output
assert_match %r%^Complete$%, @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] @d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform]
gems = File.join @tempdir, 'gems' 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 use_ui @ui do
@indexer.update_index @indexer.update_index
end 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) specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index)

View file

@ -46,9 +46,8 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
@installer = Gem::Installer.new @gem, @cmd.options @installer = Gem::Installer.new @gem, @cmd.options
@installer.install @installer.install
assert File.exist?(File.join(Gem.user_dir, 'gems')) assert_path_exists File.join(Gem.user_dir, 'gems')
assert File.exist?(File.join(Gem.user_dir, 'gems', assert_path_exists File.join(Gem.user_dir, 'gems', @spec.full_name)
@spec.full_name))
end end
def test_user_install_disabled_read_only def test_user_install_disabled_read_only
@ -59,11 +58,13 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
refute @cmd.options[:user_install] refute @cmd.options[:user_install]
File.chmod 0755, @userhome FileUtils.chmod 0755, @userhome
FileUtils.chmod 0000, @gemhome FileUtils.chmod 0000, @gemhome
Gem.use_paths @gemhome, @userhome
assert_raises(Gem::FilePermissionError) do assert_raises(Gem::FilePermissionError) do
@installer = Gem::Installer.new @gem, @cmd.options Gem::Installer.new(@gem, @cmd.options).install
end end
end end
ensure ensure

View file

@ -8,6 +8,25 @@ require 'rubygems/installer_test_case'
class TestGemInstaller < Gem::InstallerTestCase 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 def test_app_script_text
@spec.version = 2 @spec.version = 2
util_make_exec @spec, '' util_make_exec @spec, ''
@ -108,7 +127,7 @@ load Gem.bin_path('a', 'executable', version)
def test_extract_files def test_extract_files
format = Object.new format = Object.new
def format.file_entries def format.file_entries
[[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'thefile']] [[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'content']]
end end
@installer.format = format @installer.format = format
@ -116,7 +135,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.extract_files @installer.extract_files
thefile_path = File.join(util_gem_dir, 'thefile') 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 unless Gem.win_platform? then
assert_equal 0400, File.stat(thefile_path).mode & 0777 assert_equal 0400, File.stat(thefile_path).mode & 0777
@ -145,8 +164,9 @@ load Gem.bin_path('a', 'executable', version)
@installer.extract_files @installer.extract_files
end end
assert_equal "attempt to install file into \"../thefile\" under #{util_gem_dir.inspect}", dir = util_gem_dir
e.message expected = "attempt to install file into \"../thefile\" under #{dir}"
assert_equal expected, e.message
assert_equal false, File.file?(File.join(@tempdir, '../thefile')), assert_equal false, File.file?(File.join(@tempdir, '../thefile')),
"You may need to remove this file if you broke the test once" "You may need to remove this file if you broke the test once"
end end
@ -163,7 +183,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.extract_files @installer.extract_files
end 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')), assert_equal false, File.file?(File.join('/thefile')),
"You may need to remove this file if you broke the test once" "You may need to remove this file if you broke the test once"
end end
@ -241,7 +261,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.wrappers = true @installer.wrappers = true
@spec.executables = %w[executable] @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' gem_bindir = File.join gem_dir, 'bin'
FileUtils.mkdir_p gem_bindir FileUtils.mkdir_p gem_bindir
File.open File.join(gem_bindir, 'executable'), 'w' do |f| File.open File.join(gem_bindir, 'executable'), 'w' do |f|
@ -253,7 +273,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.generate_bin @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 true, File.exist?(installed_exec)
assert_equal mask, File.stat(installed_exec).mode unless win_platform? 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? if win_platform?
skip('test_generate_bin_script_no_perms skipped on MS Windows') skip('test_generate_bin_script_no_perms skipped on MS Windows')
else else
File.chmod 0000, util_inst_bindir FileUtils.chmod 0000, util_inst_bindir
assert_raises Gem::FilePermissionError do assert_raises Gem::FilePermissionError do
@installer.generate_bin @installer.generate_bin
end end
end end
ensure ensure
File.chmod 0700, util_inst_bindir unless $DEBUG FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
end end
def test_generate_bin_script_no_shebang def test_generate_bin_script_no_shebang
@ -346,7 +366,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.generate_bin @installer.generate_bin
assert_equal true, File.directory?(util_inst_bindir) 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 true, File.symlink?(installed_exec)
assert_equal(File.join(util_gem_dir, 'bin', 'executable'), assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
File.readlink(installed_exec)) File.readlink(installed_exec))
@ -371,14 +391,14 @@ load Gem.bin_path('a', 'executable', version)
if win_platform? if win_platform?
skip('test_generate_bin_symlink_no_perms skipped on MS Windows') skip('test_generate_bin_symlink_no_perms skipped on MS Windows')
else else
File.chmod 0000, util_inst_bindir FileUtils.chmod 0000, util_inst_bindir
assert_raises Gem::FilePermissionError do assert_raises Gem::FilePermissionError do
@installer.generate_bin @installer.generate_bin
end end
end end
ensure ensure
File.chmod 0700, util_inst_bindir unless $DEBUG FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
end end
def test_generate_bin_symlink_update_newer def test_generate_bin_symlink_update_newer
@ -404,10 +424,10 @@ load Gem.bin_path('a', 'executable', version)
@spec.version = 3 @spec.version = 3
util_make_exec util_make_exec
@installer.gem_dir = File.join util_gem_dir @spec @installer.gem_dir = util_gem_dir @spec
@installer.generate_bin @installer.generate_bin
installed_exec = File.join(util_inst_bindir, 'executable') 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), File.readlink(installed_exec),
"Ensure symlink moved to latest version") "Ensure symlink moved to latest version")
end end
@ -441,8 +461,9 @@ load Gem.bin_path('a', 'executable', version)
@installer.generate_bin @installer.generate_bin
installed_exec = File.join(util_inst_bindir, 'executable') installed_exec = File.join util_inst_bindir, 'executable'
assert_equal(File.join(util_gem_dir, 'bin', 'executable'), expected = File.join util_gem_dir, 'bin', 'executable'
assert_equal(expected,
File.readlink(installed_exec), File.readlink(installed_exec),
"Ensure symlink not moved") "Ensure symlink not moved")
end end
@ -455,7 +476,7 @@ load Gem.bin_path('a', 'executable', version)
@installer.gem_dir = util_gem_dir @installer.gem_dir = util_gem_dir
@installer.generate_bin @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) assert_equal true, File.exist?(installed_exec)
@spec = Gem::Specification.new do |s| @spec = Gem::Specification.new do |s|
@ -522,7 +543,7 @@ load Gem.bin_path('a', 'executable', version)
Dir.mkdir util_inst_bindir Dir.mkdir util_inst_bindir
util_build_gem spec 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 installer = Gem::Installer.new gem
@ -535,7 +556,7 @@ load Gem.bin_path('a', 'executable', version)
util_clear_gems util_clear_gems
gemdir = File.join @gemhome, 'gems', @spec.full_name 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' stub_exe = File.join @gemhome, 'bin', 'executable'
rakefile = File.join gemdir, 'ext', 'a', 'Rakefile' 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' assert File.exist?(cache_file), 'cache file must exist'
end end
@newspec = nil
build_rake_in do build_rake_in do
use_ui @ui do use_ui @ui do
assert_equal @spec, @installer.install @newspec = @installer.install
end end
end end
assert_equal @spec, @newspec
assert File.exist? gemdir assert File.exist? gemdir
assert File.exist?(stub_exe), 'gem executable must exist' 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) 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 File.exist?(spec_file)
assert_same @installer, @post_build_hook_arg assert_same @installer, @post_build_hook_arg
@ -656,17 +679,17 @@ load Gem.bin_path('a', 'executable', version)
gemhome2 = "#{@gemhome}2" gemhome2 = "#{@gemhome}2"
@spec.add_dependency 'b' @spec.add_dependency 'b'
b2 = quick_spec 'b', 2 quick_gem 'b', 2
FileUtils.mv @gemhome, gemhome2 FileUtils.mv @gemhome, gemhome2
Gem.source_index.gems.delete b2.full_name
source_index = Gem::SourceIndex.from_gems_in File.join(gemhome2, Gem::Specification.dirs = [gemhome2] # TODO: switch all dirs= to use_paths
'specifications')
util_setup_gem util_setup_gem
@installer = Gem::Installer.new @gem, :install_dir => gemhome2, @installer = Gem::Installer.new @gem, :install_dir => gemhome2
:source_index => source_index
gem_home = Gem.dir
build_rake_in do build_rake_in do
use_ui @ui do use_ui @ui do
@ -675,6 +698,7 @@ load Gem.bin_path('a', 'executable', version)
end end
assert File.exist?(File.join(gemhome2, 'gems', @spec.full_name)) assert File.exist?(File.join(gemhome2, 'gems', @spec.full_name))
assert_equal gem_home, Gem.dir
end end
def test_install_force def test_install_force
@ -712,7 +736,7 @@ load Gem.bin_path('a', 'executable', version)
end end
def test_install_missing_dirs 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, 'docs')
FileUtils.rm_f File.join(Gem.dir, 'specifications') FileUtils.rm_f File.join(Gem.dir, 'specifications')
@ -722,11 +746,11 @@ load Gem.bin_path('a', 'executable', version)
@installer.install @installer.install
end 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, 'docs')
File.directory? File.join(Gem.dir, 'specifications') 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)) assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
end end
@ -812,8 +836,9 @@ load Gem.bin_path('a', 'executable', version)
@spec.post_install_message = 'I am a shiny gem!' @spec.post_install_message = 'I am a shiny gem!'
use_ui @ui do 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 @installer.install
end end
@ -838,7 +863,7 @@ load Gem.bin_path('a', 'executable', version)
util_build_gem spec util_build_gem spec
gem = Gem.cache_gem(spec.file_name, @gemhome) gem = File.join(@gemhome, 'cache', spec.file_name)
use_ui @ui do use_ui @ui do
@installer = Gem::Installer.new gem @installer = Gem::Installer.new gem
@ -1002,6 +1027,10 @@ load Gem.bin_path('a', 'executable', version)
assert_equal @spec, eval(File.read(spec_file)) assert_equal @spec, eval(File.read(spec_file))
end end
def test_dir
assert_match @installer.dir, %r!/installer/gems/a-2$!
end
def old_ruby_required def old_ruby_required
spec = quick_spec 'old_ruby_required', '1' do |s| spec = quick_spec 'old_ruby_required', '1' do |s|
s.required_ruby_version = '= 1.4.6' s.required_ruby_version = '= 1.4.6'
@ -1009,20 +1038,17 @@ load Gem.bin_path('a', 'executable', version)
util_build_gem spec util_build_gem spec
Gem.cache_gem(spec.file_name, @gemhome) spec.cache_file
end end
def util_execless def util_execless
@spec = quick_spec 'z' @spec = quick_spec 'z'
util_build_gem @spec
gem = File.join @tempdir, @spec.file_name @installer = util_installer @spec, @gemhome
@installer = util_installer @spec, gem, @gemhome
end end
def mask def mask
0100755 & (~File.umask) 0100755 & (~File.umask)
end end
end end

View file

@ -6,6 +6,7 @@
require 'rubygems/package/tar_test_case' require 'rubygems/package/tar_test_case'
require 'rubygems/package/tar_output' require 'rubygems/package/tar_output'
require 'rubygems/security'
class TestGemPackageTarOutput < Gem::Package::TarTestCase class TestGemPackageTarOutput < Gem::Package::TarTestCase

View file

@ -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

View file

@ -144,7 +144,7 @@ class TestGemPlatform < Gem::TestCase
def test_empty def test_empty
platform = Gem::Platform.new 'cpu-other_platform1' platform = Gem::Platform.new 'cpu-other_platform1'
assert_respond_to platform, :empty? assert_respond_to platform, :empty?
assert_equal false, platform.empty? assert_equal false, Deprecate.skip_during { platform.empty? }
end end
def test_to_s def test_to_s

View file

@ -99,7 +99,7 @@ gems:
# REFACTOR: copied from test_gem_dependency_installer.rb # REFACTOR: copied from test_gem_dependency_installer.rb
@gems_dir = File.join @tempdir, 'gems' @gems_dir = File.join @tempdir, 'gems'
@cache_dir = Gem.cache_dir(@gemhome) @cache_dir = File.join @gemhome, "cache"
FileUtils.mkdir @gems_dir FileUtils.mkdir @gems_dir
# TODO: why does the remote fetcher need it written to disk? # TODO: why does the remote fetcher need it written to disk?
@ -152,7 +152,7 @@ gems:
fetcher.fetch_size 'gems.example.com/yaml' fetcher.fetch_size 'gems.example.com/yaml'
end end
assert_equal 'uri scheme is invalid', e.message assert_equal 'uri scheme is invalid: nil', e.message
end end
def test_fetch_size_socket_error def test_fetch_size_socket_error
@ -209,7 +209,7 @@ gems:
fetcher = util_fuck_with_fetcher a1_data 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 a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com')
assert_equal("http://gems.example.com/gems/a-1.gem", assert_equal("http://gems.example.com/gems/a-1.gem",
fetcher.instance_variable_get(:@test_arg).to_s) fetcher.instance_variable_get(:@test_arg).to_s)
@ -221,8 +221,7 @@ gems:
inst = Gem::RemoteFetcher.fetcher inst = Gem::RemoteFetcher.fetcher
assert_equal Gem.cache_gem(@a1.file_name, @gemhome), assert_equal @a1.cache_file, inst.download(@a1, 'http://gems.example.com')
inst.download(@a1, 'http://gems.example.com')
end end
def test_download_local def test_download_local
@ -234,8 +233,7 @@ gems:
inst = Gem::RemoteFetcher.fetcher inst = Gem::RemoteFetcher.fetcher
end end
assert_equal Gem.cache_gem(@a1.file_name, @gemhome), assert_equal @a1.cache_file, inst.download(@a1, local_path)
inst.download(@a1, local_path)
end end
def test_download_local_space def test_download_local_space
@ -249,21 +247,19 @@ gems:
inst = Gem::RemoteFetcher.fetcher inst = Gem::RemoteFetcher.fetcher
end end
assert_equal Gem.cache_gem(@a1.file_name, @gemhome), assert_equal @a1.cache_file, inst.download(@a1, local_path)
inst.download(@a1, local_path)
end end
def test_download_install_dir def test_download_install_dir
a1_data = nil a1_data = File.open @a1_gem, 'rb' do |fp|
File.open @a1_gem, 'rb' do |fp| fp.read
a1_data = fp.read
end end
fetcher = util_fuck_with_fetcher a1_data fetcher = util_fuck_with_fetcher a1_data
install_dir = File.join @tempdir, 'more_gems' 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)) FileUtils.mkdir_p(File.dirname(a1_cache_gem))
actual = fetcher.download(@a1, 'http://gems.example.com', install_dir) actual = fetcher.download(@a1, 'http://gems.example.com', install_dir)
@ -279,7 +275,7 @@ gems:
FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a1_gem, @tempdir
local_path = File.join @tempdir, @a1.file_name local_path = File.join @tempdir, @a1.file_name
inst = nil inst = nil
File.chmod 0555, Gem.cache_dir(@gemhome) FileUtils.chmod 0555, @a1.cache_dir
Dir.chdir @tempdir do Dir.chdir @tempdir do
inst = Gem::RemoteFetcher.fetcher inst = Gem::RemoteFetcher.fetcher
@ -288,19 +284,20 @@ gems:
assert_equal File.join(@tempdir, @a1.file_name), assert_equal File.join(@tempdir, @a1.file_name),
inst.download(@a1, local_path) inst.download(@a1, local_path)
ensure ensure
File.chmod 0755, Gem.cache_dir(@gemhome) FileUtils.chmod 0755, @a1.cache_dir
end end
def test_download_read_only def test_download_read_only
File.chmod 0555, Gem.cache_dir(@gemhome) FileUtils.chmod 0555, @a1.cache_dir
File.chmod 0555, File.join(@gemhome) FileUtils.chmod 0555, @gemhome
fetcher = util_fuck_with_fetcher File.read(@a1_gem) fetcher = util_fuck_with_fetcher File.read(@a1_gem)
fetcher.download(@a1, 'http://gems.example.com') 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 ensure
File.chmod 0755, @gemhome FileUtils.chmod 0755, @gemhome
File.chmod 0755, Gem.cache_dir(@gemhome) FileUtils.chmod 0755, @a1.cache_dir
end end
end end
@ -319,7 +316,7 @@ gems:
fetcher = util_fuck_with_fetcher e1_data, :blow_chunks 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') assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com')
@ -337,7 +334,7 @@ gems:
inst = Gem::RemoteFetcher.fetcher inst = Gem::RemoteFetcher.fetcher
end end
cache_path = Gem.cache_gem(@a1.file_name, @gemhome) cache_path = @a1.cache_file
FileUtils.mv local_path, cache_path FileUtils.mv local_path, cache_path
gem = Gem::Format.from_file_by_path cache_path gem = Gem::Format.from_file_by_path cache_path
@ -422,7 +419,7 @@ gems:
def test_fetch_path_gzip def test_fetch_path_gzip
fetcher = Gem::RemoteFetcher.new nil 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' Gem.gzip 'foo'
end end
@ -432,7 +429,7 @@ gems:
def test_fetch_path_gzip_unmodified def test_fetch_path_gzip_unmodified
fetcher = Gem::RemoteFetcher.new nil fetcher = Gem::RemoteFetcher.new nil
def fetcher.open_uri_or_path(uri, mtime, head = nil) def fetcher.fetch_http(uri, mtime, head = nil)
nil nil
end end
@ -442,53 +439,59 @@ gems:
def test_fetch_path_io_error def test_fetch_path_io_error
fetcher = Gem::RemoteFetcher.new nil fetcher = Gem::RemoteFetcher.new nil
def fetcher.open_uri_or_path(uri, mtime, head = nil) def fetcher.fetch_http(*)
raise EOFError raise EOFError
end end
url = 'http://example.com/uri'
e = assert_raises Gem::RemoteFetcher::FetchError do e = assert_raises Gem::RemoteFetcher::FetchError do
fetcher.fetch_path 'uri' fetcher.fetch_path url
end end
assert_equal 'EOFError: EOFError (uri)', e.message assert_equal "EOFError: EOFError (#{url})", e.message
assert_equal 'uri', e.uri assert_equal url, e.uri
end end
def test_fetch_path_socket_error def test_fetch_path_socket_error
fetcher = Gem::RemoteFetcher.new nil 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 raise SocketError
end end
url = 'http://example.com/uri'
e = assert_raises Gem::RemoteFetcher::FetchError do e = assert_raises Gem::RemoteFetcher::FetchError do
fetcher.fetch_path 'uri' fetcher.fetch_path url
end end
assert_equal 'SocketError: SocketError (uri)', e.message assert_equal "SocketError: SocketError (#{url})", e.message
assert_equal 'uri', e.uri assert_equal url, e.uri
end end
def test_fetch_path_system_call_error def test_fetch_path_system_call_error
fetcher = Gem::RemoteFetcher.new nil 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)' raise Errno::ECONNREFUSED, 'connect(2)'
end end
url = 'http://example.com/uri'
e = assert_raises Gem::RemoteFetcher::FetchError do e = assert_raises Gem::RemoteFetcher::FetchError do
fetcher.fetch_path 'uri' fetcher.fetch_path url
end end
assert_match %r|ECONNREFUSED:.*connect\(2\) \(uri\)\z|, assert_match %r|ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z|,
e.message e.message
assert_equal 'uri', e.uri assert_equal url, e.uri
end end
def test_fetch_path_unmodified def test_fetch_path_unmodified
fetcher = Gem::RemoteFetcher.new nil fetcher = Gem::RemoteFetcher.new nil
def fetcher.open_uri_or_path(uri, mtime, head = nil) def fetcher.fetch_http(uri, mtime, head = nil)
nil nil
end end
@ -551,16 +554,18 @@ gems:
end end
end end
def test_open_uri_or_path def test_fetch_http
fetcher = Gem::RemoteFetcher.new nil fetcher = Gem::RemoteFetcher.new nil
url = 'http://gems.example.com/redirect'
conn = Object.new conn = Object.new
def conn.started?() true end def conn.started?() true end
def conn.request(req) def conn.request(req)
url = 'http://gems.example.com/redirect'
unless defined? @requested then unless defined? @requested then
@requested = true @requested = true
res = Net::HTTPMovedPermanently.new nil, 301, nil res = Net::HTTPMovedPermanently.new nil, 301, nil
res.add_field 'Location', 'http://gems.example.com/real_path' res.add_field 'Location', url
res res
else else
res = Net::HTTPOK.new nil, 200, nil res = Net::HTTPOK.new nil, 200, nil
@ -572,19 +577,21 @@ gems:
conn = { "#{Thread.current.object_id}:gems.example.com:80" => conn } conn = { "#{Thread.current.object_id}:gems.example.com:80" => conn }
fetcher.instance_variable_set :@connections, 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 assert_equal 'real_path', data
end end
def test_open_uri_or_path_limited_redirects def test_fetch_http_redirects
fetcher = Gem::RemoteFetcher.new nil fetcher = Gem::RemoteFetcher.new nil
url = 'http://gems.example.com/redirect'
conn = Object.new conn = Object.new
def conn.started?() true end def conn.started?() true end
def conn.request(req) def conn.request(req)
url = 'http://gems.example.com/redirect'
res = Net::HTTPMovedPermanently.new nil, 301, nil res = Net::HTTPMovedPermanently.new nil, 301, nil
res.add_field 'Location', 'http://gems.example.com/redirect' res.add_field 'Location', url
res res
end end
@ -592,11 +599,10 @@ gems:
fetcher.instance_variable_set :@connections, conn fetcher.instance_variable_set :@connections, conn
e = assert_raises Gem::RemoteFetcher::FetchError do e = assert_raises Gem::RemoteFetcher::FetchError do
fetcher.open_uri_or_path 'http://gems.example.com/redirect' fetcher.fetch_http URI.parse(url)
end end
assert_equal 'too many redirects (http://gems.example.com/redirect)', assert_equal "too many redirects (#{url})", e.message
e.message
end end
def test_request def test_request
@ -631,6 +637,85 @@ gems:
assert_equal t.rfc2822, conn.payload['if-modified-since'] assert_equal t.rfc2822, conn.payload['if-modified-since']
end 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 def test_yaml_error_on_size
use_ui @ui do use_ui @ui do
self.class.enable_yaml = false self.class.enable_yaml = false
@ -753,5 +838,24 @@ gems:
assert_equal "/home/skillet", @fetcher.correct_for_windows_path(path) assert_equal "/home/skillet", @fetcher.correct_for_windows_path(path)
end 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 end

View file

@ -256,6 +256,19 @@ class TestGemRequirement < Gem::TestCase
refute_satisfied_by "2.0", "~> 1.4.4" refute_satisfied_by "2.0", "~> 1.4.4"
end 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 def test_bad
refute_satisfied_by "", "> 0.1" refute_satisfied_by "", "> 0.1"
refute_satisfied_by "1.2.3", "!= 1.2.3" refute_satisfied_by "1.2.3", "!= 1.2.3"

View file

@ -9,12 +9,10 @@ require 'rubygems/server'
require 'stringio' require 'stringio'
class Gem::Server class Gem::Server
attr_accessor :source_index
attr_reader :server attr_reader :server
end end
class TestGemServer < Gem::TestCase class TestGemServer < Gem::TestCase
def setup def setup
super super
@ -41,52 +39,64 @@ class TestGemServer < Gem::TestCase
data = StringIO.new "GET /Marshal.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" data = StringIO.new "GET /Marshal.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
@req.parse data @req.parse data
@server.Marshal @req, @res Deprecate.skip_during do
@server.Marshal @req, @res
end
assert_equal 200, @res.status, @res.body assert_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date'] assert_match %r| \d\d:\d\d:\d\d |, @res['date']
assert_equal 'application/octet-stream', @res['content-type'] assert_equal 'application/octet-stream', @res['content-type']
si = Gem::SourceIndex.new Deprecate.skip_during do
si.add_specs @a1, @a2 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 end
def test_Marshal_Z def test_Marshal_Z
data = StringIO.new "GET /Marshal.#{Gem.marshal_version}.Z HTTP/1.0\r\n\r\n" data = StringIO.new "GET /Marshal.#{Gem.marshal_version}.Z HTTP/1.0\r\n\r\n"
@req.parse data @req.parse data
@server.Marshal @req, @res Deprecate.skip_during do
@server.Marshal @req, @res
end
assert_equal 200, @res.status, @res.body assert_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date'] assert_match %r| \d\d:\d\d:\d\d |, @res['date']
assert_equal 'application/x-deflate', @res['content-type'] assert_equal 'application/x-deflate', @res['content-type']
si = Gem::SourceIndex.new Deprecate.skip_during do
si.add_specs @a1, @a2 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 end
def test_latest_specs def test_latest_specs
data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
@req.parse data @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_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date'] assert_match %r| \d\d:\d\d:\d\d |, @res['date']
assert_equal 'application/octet-stream', @res['content-type'] assert_equal 'application/octet-stream', @res['content-type']
assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]], assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]],
Marshal.load(@res.body) Marshal.load(@res.body)
end end
def test_latest_specs_gz def test_latest_specs_gz
data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n"
@req.parse data @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_equal 200, @res.status, @res.body
assert_match %r| \d\d:\d\d:\d\d |, @res['date'] 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 @server.instance_variable_set :@server, webrick
end end
end end

View file

@ -55,7 +55,7 @@ class TestGemSilentUI < Gem::TestCase
assert_empty out, 'No output' assert_empty out, 'No output'
assert_empty err, 'No output' assert_empty err, 'No output'
out, err = capture_io do out, err = capture_io do
use_ui @sui do use_ui @sui do
value = @sui.ask_yes_no 'Problem?', true value = @sui.ask_yes_no 'Problem?', true
@ -66,7 +66,7 @@ class TestGemSilentUI < Gem::TestCase
assert_empty err, 'No output' assert_empty err, 'No output'
assert value, 'Value is true' assert value, 'Value is true'
out, err = capture_io do out, err = capture_io do
use_ui @sui do use_ui @sui do
value = @sui.ask_yes_no 'Problem?', false value = @sui.ask_yes_no 'Problem?', false

View file

@ -7,397 +7,250 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/source_index' require 'rubygems/source_index'
require 'rubygems/config_file' require 'rubygems/config_file'
require 'rubygems/deprecate'
class TestGemSourceIndex < Gem::TestCase class TestGemSourceIndex < Gem::TestCase
def setup def setup
super super
util_setup_fake_fetcher util_setup_fake_fetcher
end
def test_self_from_gems_in @source_index = Deprecate.skip_during { Gem.source_index }
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
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"
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}
if s.respond_to? :specification_version then
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 2
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
else
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)
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)
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)
end
end
assert_equal '', @ui.output
assert_equal '', @ui.error
end
def test_create_from_directory
# TODO
end end
def test_find_name def test_find_name
assert_equal [@a1, @a2, @a3a], @source_index.find_name('a') Deprecate.skip_during do
assert_equal [@a2], @source_index.find_name('a', '= 2') assert_equal [@a1, @a2, @a3a], @source_index.find_name('a')
assert_equal [], @source_index.find_name('bogusstring') assert_equal [@a2], @source_index.find_name('a', '= 2')
assert_equal [], @source_index.find_name('a', '= 3') assert_equal [], @source_index.find_name('bogusstring')
assert_equal [], @source_index.find_name('a', '= 3')
source_index = Gem::SourceIndex.new source_index = Gem::SourceIndex.new
source_index.add_spec @a1 source_index.add_spec @a1
source_index.add_spec @a2 source_index.add_spec @a2
assert_equal [@a1], source_index.find_name(@a1.name, '= 1') assert_equal [@a1], source_index.find_name(@a1.name, '= 1')
r1 = Gem::Requirement.create '= 1' r1 = Gem::Requirement.create '= 1'
assert_equal [@a1], source_index.find_name(@a1.name, r1) assert_equal [@a1], source_index.find_name(@a1.name, r1)
end
end end
def test_find_name_empty_cache def test_find_name_empty_cache
empty_source_index = Gem::SourceIndex.new({}) Deprecate.skip_during do
assert_equal [], empty_source_index.find_name("foo") empty_source_index = Gem::SourceIndex.new
assert_equal [], empty_source_index.find_name("foo")
end
end end
# HACK: deprecated impl is failing tests, but I may want to port it over
def test_latest_specs def test_latest_specs
p1_ruby = quick_spec 'p', '1' Deprecate.skip_during do
p1_platform = quick_spec 'p', '1' do |spec| p1_ruby = quick_spec 'p', '1'
spec.platform = Gem::Platform::CURRENT 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_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
@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 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_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
@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 end
def test_load_gems_in def test_load_gems_in
spec_dir1 = File.join @gemhome, 'specifications' Deprecate.skip_during do
spec_dir2 = File.join @tempdir, 'gemhome2', 'specifications' 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_dir1
FileUtils.mkdir_p spec_dir2 FileUtils.mkdir_p spec_dir2
a1 = quick_spec 'a', '1' do |spec| spec.author = 'author 1' 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 a2 = quick_spec 'a', '1' do |spec| spec.author = 'author 2' end
File.open File.join(spec_dir1, a1.spec_name), 'w' do |fp| path1 = File.join(spec_dir1, a1.spec_name)
fp.write a1.to_ruby path2 = File.join(spec_dir2, a2.spec_name)
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 File.dirname(path1), File.dirname(path2)
assert_equal a1.author, @source_index.specification(a1.full_name).author
end end
File.open File.join(spec_dir2, a2.spec_name), 'w' do |fp|
fp.write a2.to_ruby
end
@source_index.load_gems_in spec_dir1, spec_dir2
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 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) updated = quick_spec @a2.name, (@a2.version.bump)
util_setup_spec_fetcher updated 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| updated_platform = quick_spec @a2.name, (updated.version.bump) do |s|
s.platform = Gem::Platform.new 'x86-other_platform1' s.platform = Gem::Platform.new 'x86-other_platform1'
end
util_setup_spec_fetcher updated, updated_platform
assert_equal [updated_platform.name], @source_index.outdated
end end
util_setup_spec_fetcher updated, updated_platform
assert_equal [updated_platform.name], @source_index.outdated
end end
def test_prerelease_specs_kept_in_right_place def test_prerelease_specs_kept_in_right_place
gem_a1_alpha = quick_spec 'abba', '1.a' Deprecate.skip_during do
@source_index.add_spec gem_a1_alpha gem_a1_alpha = quick_spec 'abba', '1.a'
@source_index.add_spec gem_a1_alpha
refute @source_index.latest_specs.include?(gem_a1_alpha) refute_includes @source_index.latest_specs, gem_a1_alpha
assert @source_index.latest_specs(true).include?(gem_a1_alpha) assert_includes @source_index.latest_specs(true), gem_a1_alpha
assert @source_index.find_name(gem_a1_alpha.full_name).empty? assert_empty @source_index.find_name gem_a1_alpha.full_name
assert @source_index.prerelease_specs.include?(gem_a1_alpha) assert_includes @source_index.prerelease_specs, gem_a1_alpha
end
end end
def test_refresh_bang def test_refresh_bang
a1_spec = File.join @gemhome, "specifications", @a1.spec_name Deprecate.skip_during do
a1_spec = File.join @gemhome, "specifications", @a1.spec_name
FileUtils.mv a1_spec, @tempdir FileUtils.mv a1_spec, @tempdir
source_index = Gem::SourceIndex.from_installed_gems Gem::Specification.reset
Gem.send :class_variable_set, :@@source_index, nil
source_index = Gem.source_index
refute source_index.gems.include?(@a1.full_name) refute_includes source_index.gems.keys.sort, @a1.full_name
FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
source_index.refresh!
assert source_index.gems.include?(@a1.full_name)
end
def test_refresh_bang_not_from_dir
source_index = Gem::SourceIndex.new
e = assert_raises RuntimeError do
source_index.refresh! source_index.refresh!
end
assert_equal 'source index not created from disk', e.message assert source_index.gems.include?(@a1.full_name)
end
end end
def test_remove_spec 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], expected = si.gems.keys.sort
@source_index.all_gems.values.map { |s| s.full_name }.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], assert_equal expected, si.gems.keys.sort
@source_index.all_gems.values.map { |s| s.full_name }.sort
expected.delete "a-3.a"
@source_index.remove_spec 'a-3.a'
assert_equal expected, si.gems.keys.sort
end
end end
def test_search def test_search
requirement = Gem::Requirement.create '= 9' Deprecate.skip_during do
with_version = Gem::Dependency.new(/^a/, requirement) requirement = Gem::Requirement.create '= 9'
assert_equal [@a_evil9], @source_index.search(with_version) 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) with_default = Gem::Dependency.new(/^a/, Gem::Requirement.default)
assert_equal [@a1, @a2, @a3a, @a_evil9], @source_index.search(with_default) assert_equal [@a1, @a2, @a3a, @a_evil9], @source_index.search(with_default)
c1_1_dep = Gem::Dependency.new 'c', '~> 1.1' c1_1_dep = Gem::Dependency.new 'c', '~> 1.1'
assert_equal [@c1_2], @source_index.search(c1_1_dep) assert_equal [@c1_2], @source_index.search(c1_1_dep)
end
end end
def test_search_platform 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 = quick_spec 'a', '1'
a1_mine = quick_spec 'a', '1' do |s| a1_mine = quick_spec 'a', '1' do |s|
s.platform = Gem::Platform.new 'x86-my_platform1' 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
si.add_specs a1, a1_mine, a1_other
dep = Gem::Dependency.new 'a', Gem::Requirement.new('1')
gems = si.search dep, true
assert_equal [a1, a1_mine], gems.sort
end 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)
dep = Gem::Dependency.new 'a', Gem::Requirement.new('1')
gems = si.search dep, true
assert_equal [a1, a1_mine], gems.sort
end end
def test_signature def test_signature
sig = @source_index.gem_signature('foo-1.2.3') Deprecate.skip_during do
assert_equal 64, sig.length sig = @source_index.gem_signature('foo-1.2.3')
assert_match(/^[a-f0-9]{64}$/, sig) assert_equal 64, sig.length
assert_match(/^[a-f0-9]{64}$/, sig)
end
end end
def test_specification 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 end
def test_index_signature def test_index_signature
sig = @source_index.index_signature Deprecate.skip_during do
assert_match(/^[a-f0-9]{64}$/, sig) sig = @source_index.index_signature
assert_match(/^[a-f0-9]{64}$/, sig)
end
end end
end end

View file

@ -16,43 +16,43 @@ class TestGemSpecFetcher < Gem::TestCase
util_setup_fake_fetcher util_setup_fake_fetcher
@a_pre = quick_spec 'a', '1.a' @a_pre = new_spec 'a', '1.a'
@source_index.add_spec @pl1
@source_index.add_spec @a_pre
@specs = @source_index.gems.sort.map do |name, spec| install_specs @a_pre
Gem::Specification.remove_spec @b2
@specs = Gem::Specification.map { |spec|
[spec.name, spec.version, spec.original_platform] [spec.name, spec.version, spec.original_platform]
end.sort }.sort
@latest_specs = @source_index.latest_specs.sort.map do |spec| # 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] [spec.name, spec.version, spec.original_platform]
end }
@prerelease_specs = @source_index.prerelease_gems.sort.map do |name, spec| prerelease = Gem::Specification.find_all { |s| s.version.prerelease? }
@prerelease_specs = prerelease.map { |spec|
[spec.name, spec.version, spec.original_platform] [spec.name, spec.version, spec.original_platform]
end.sort }.sort
@fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] = v = Gem.marshal_version
util_gzip(Marshal.dump(@specs)) s_zip = util_gzip(Marshal.dump(@specs))
l_zip = util_gzip(Marshal.dump(@latest_specs))
@fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = p_zip = util_gzip(Marshal.dump(@prerelease_specs))
util_gzip(Marshal.dump(@latest_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.#{Gem.marshal_version}.gz"] = @fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip
util_gzip(Marshal.dump(@prerelease_specs))
@sf = Gem::SpecFetcher.new @sf = Gem::SpecFetcher.new
end end
def test_fetch_all def test_fetch_all
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}"
util_zip(Marshal.dump(@a1)) @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1))
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] = @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2))
util_zip(Marshal.dump(@a2)) @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre))
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] = @fetcher.data["#{d}#{@a3a.spec_name}.rz"] = util_zip(Marshal.dump(@a3a))
util_zip(Marshal.dump(@a_pre))
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a3a.spec_name}.rz"] =
util_zip(Marshal.dump(@a3a))
dep = Gem::Dependency.new 'a', 1 dep = Gem::Dependency.new 'a', 1
@ -70,12 +70,10 @@ class TestGemSpecFetcher < Gem::TestCase
end end
def test_fetch_latest def test_fetch_latest
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}"
util_zip(Marshal.dump(@a1)) @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1))
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] = @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2))
util_zip(Marshal.dump(@a2)) @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre))
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
util_zip(Marshal.dump(@a_pre))
dep = Gem::Dependency.new 'a', 1 dep = Gem::Dependency.new 'a', 1
specs_and_sources = @sf.fetch dep specs_and_sources = @sf.fetch dep
@ -88,15 +86,12 @@ class TestGemSpecFetcher < Gem::TestCase
end end
def test_fetch_prerelease def test_fetch_prerelease
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}"
util_zip(Marshal.dump(@a1)) @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1))
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a2.spec_name}.rz"] = @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2))
util_zip(Marshal.dump(@a2)) @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre))
@fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a_pre.spec_name}.rz"] =
util_zip(Marshal.dump(@a_pre))
dep = Gem::Dependency.new 'a', '1.a' specs_and_sources = @sf.fetch dep('a', '1.a'), false, true, true
specs_and_sources = @sf.fetch dep, false, true, true
spec_names = specs_and_sources.map do |spec, source_uri| spec_names = specs_and_sources.map do |spec, source_uri|
[spec.full_name, source_uri] [spec.full_name, source_uri]
@ -293,11 +288,11 @@ class TestGemSpecFetcher < Gem::TestCase
assert_equal [@uri], specs.keys assert_equal [@uri], specs.keys
assert_equal([["a", Gem::Version.new("1"), "ruby"], assert_equal([["a", Gem::Version.new("1"), "ruby"],
["a", Gem::Version.new("2"), "ruby"], ["a", Gem::Version.new("2"), "ruby"],
["a_evil", Gem::Version.new("9"), "ruby"], ["a_evil", Gem::Version.new("9"), "ruby"],
["c", Gem::Version.new("1.2"), "ruby"], ["c", Gem::Version.new("1.2"), "ruby"],
["pl", Gem::Version.new("1"), "i386-linux"]], ["pl", Gem::Version.new("1"), "i386-linux"]],
specs[@uri].sort) specs[@uri].sort)
end end
@ -347,19 +342,17 @@ class TestGemSpecFetcher < Gem::TestCase
end end
def test_load_specs def test_load_specs
specs = @sf.load_specs @uri, 'specs'
expected = [ 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(1), Gem::Platform::RUBY],
['a', Gem::Version.new(2), 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], ['a_evil', Gem::Version.new(9), Gem::Platform::RUBY],
['c', Gem::Version.new('1.2'), Gem::Platform::RUBY], ['c', Gem::Version.new('1.2'), Gem::Platform::RUBY],
['pl', Gem::Version.new(1), 'i386-linux'], ['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' cache_dir = File.join Gem.user_home, '.gem', 'specs', 'gems.example.com%80'
assert File.exist?(cache_dir), "#{cache_dir} does not exist" assert File.exist?(cache_dir), "#{cache_dir} does not exist"

View file

@ -35,8 +35,8 @@ Gem::Specification.new do |s|
s.version = %q{0.4.0} s.version = %q{0.4.0}
s.has_rdoc = true s.has_rdoc = true
s.summary = %q{A Hash which automatically computes keys.} s.summary = %q{A Hash which automatically computes keys.}
s.files = ["lib/keyedlist.rb"] s.files = [%q{lib/keyedlist.rb}]
s.require_paths = ["lib"] s.require_paths = [%q{lib}]
s.autorequire = %q{keyedlist} s.autorequire = %q{keyedlist}
s.author = %q{Florian Gross} s.author = %q{Florian Gross}
s.email = %q{flgr@ccan.de} s.email = %q{flgr@ccan.de}
@ -46,11 +46,9 @@ end
def setup def setup
super super
# TODO: there is no reason why the spec tests need to write to disk @a1 = quick_spec 'a', '1' do |s|
@a1 = quick_gem 'a', '1' do |s|
s.executable = 'exec' s.executable = 'exec'
s.extensions << 'ext/a/extconf.rb' s.extensions << 'ext/a/extconf.rb'
s.has_rdoc = 'true'
s.test_file = 'test/suite.rb' s.test_file = 'test/suite.rb'
s.requirements << 'A working computer' s.requirements << 'A working computer'
s.rubyforge_project = 'example' s.rubyforge_project = 'example'
@ -64,15 +62,10 @@ end
s.files = %w[lib/code.rb] s.files = %w[lib/code.rb]
end end
@a2 = quick_gem 'a', '2' do |s| @a2 = quick_spec 'a', '2' do |s|
s.files = %w[lib/code.rb] s.files = %w[lib/code.rb]
end 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 @current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
end end
@ -83,7 +76,6 @@ end
bindir bindir
cert_chain cert_chain
date date
default_executable
dependencies dependencies
description description
email email
@ -91,7 +83,6 @@ end
extensions extensions
extra_rdoc_files extra_rdoc_files
files files
has_rdoc
homepage homepage
licenses licenses
name name
@ -129,18 +120,39 @@ end
assert_equal @current_version, new_spec.specification_version assert_equal @current_version, new_spec.specification_version
end end
def test_self_load def test_self_from_yaml_syck_bug
spec = File.join @gemhome, 'specifications', @a2.spec_name # This is equivalent to (and totally valid) psych 1.0 output and
gs = Gem::Specification.load spec # causes parse errors on syck.
yaml = @a1.to_yaml
yaml.sub!(/^date:.*/, "date: 2011-04-26 00:00:00.000000000Z")
assert_equal @a2, gs 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
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, spec
end end
def test_self_load_legacy_ruby 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 'keyedlist', spec.name
assert_equal '0.4.0', spec.version.to_s assert_equal '0.4.0', spec.version.to_s
assert_equal true, spec.has_rdoc?
assert_equal Gem::Specification::TODAY, spec.date assert_equal Gem::Specification::TODAY, spec.date
assert spec.required_ruby_version.satisfied_by?(Gem::Version.new('1')) assert spec.required_ruby_version.satisfied_by?(Gem::Version.new('1'))
assert_equal false, spec.has_unit_tests? assert_equal false, spec.has_unit_tests?
@ -195,8 +207,6 @@ end
assert_equal [], spec.requirements assert_equal [], spec.requirements
assert_equal [], spec.dependencies assert_equal [], spec.dependencies
assert_equal 'bin', spec.bindir 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_ruby_version.to_s
assert_equal '>= 0', spec.required_rubygems_version.to_s assert_equal '>= 0', spec.required_rubygems_version.to_s
end end
@ -279,9 +289,6 @@ end
assert_equal 'bin', spec.bindir assert_equal 'bin', spec.bindir
assert_same spec.bindir, new_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_equal '>= 0', spec.required_ruby_version.to_s
assert_same spec.required_ruby_version, new_spec.required_ruby_version assert_same spec.required_ruby_version, new_spec.required_ruby_version
@ -290,6 +297,23 @@ end
new_spec.required_rubygems_version new_spec.required_rubygems_version
end 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 def test__dump
@a2.platform = Gem::Platform.local @a2.platform = Gem::Platform.local
@a2.instance_variable_set :@original_platform, 'old_platform' @a2.instance_variable_set :@original_platform, 'old_platform'
@ -338,37 +362,33 @@ end
def test_date_equals_date def test_date_equals_date
@a1.date = Date.new(2003, 9, 17) @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 end
def test_date_equals_string def test_date_equals_string
@a1.date = '2003-09-17' @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 end
def test_date_equals_time def test_date_equals_time
@a1.date = Time.local(2003, 9, 17, 0,0,0) @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 end
def test_date_equals_time_local def test_date_equals_time_local
# HACK PDT @a1.date = Time.local(2003, 9, 17, 19,50,0) # may not pass in utc >= +4
@a1.date = Time.local(2003, 9, 17, 19,50,0) assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date
assert_equal Time.local(2003, 9, 17, 0,0,0), @a1.date
end end
def test_date_equals_time_utc def test_date_equals_time_utc
# HACK PDT @a1.date = Time.utc(2003, 9, 17, 19,50,0)
@a1.date = Time.local(2003, 9, 17, 19,50,0) assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date
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
end end
def test_dependencies def test_dependencies
@ -391,60 +411,20 @@ end
end end
def test_eql_eh def test_eql_eh
g1 = quick_spec 'gem' g1 = new_spec 'gem', 1
g2 = quick_spec 'gem' g2 = new_spec 'gem', 1
assert_equal g1, g2 assert_equal g1, g2
assert_equal g1.hash, g2.hash assert_equal g1.hash, g2.hash
assert_equal true, g1.eql?(g2) assert_equal true, g1.eql?(g2)
end end
def test_equals2 def test_eql_eh_extensions
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
spec = @a1.dup spec = @a1.dup
spec.extensions = 'xx' spec.extensions = 'xx'
refute_equal @a1, spec refute_operator @a1, :eql?, spec
refute_equal spec, @a1 refute_operator spec, :eql?, @a1
end end
def test_executables def test_executables
@ -542,9 +522,26 @@ end
assert_kind_of Integer, @a1.hash assert_kind_of Integer, @a1.hash
end 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 def test_full_gem_path
assert_equal File.join(@gemhome, 'gems', @a1.full_name), assert_equal File.join(@gemhome, 'gems', @a1.full_name), @a1.full_gem_path
@a1.full_gem_path
@a1.original_platform = 'mswin32' @a1.original_platform = 'mswin32'
@ -553,11 +550,11 @@ end
end end
def test_full_gem_path_double_slash def test_full_gem_path_double_slash
gemhome = @gemhome.sub(/\w\//, '\&/') gemhome = @gemhome.to_s.sub(/\w\//, '\&/')
@a1.loaded_from = File.join gemhome, 'specifications', @a1.spec_name @a1.loaded_from = File.join gemhome, "specifications", @a1.spec_name
assert_equal File.join(@gemhome, 'gems', @a1.full_name), expected = File.join @gemhome, "gems", @a1.full_name
@a1.full_gem_path assert_equal expected, @a1.full_gem_path
end end
def test_full_name def test_full_name
@ -589,21 +586,6 @@ end
end 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 def test_hash
assert_equal @a1.hash, @a1.hash assert_equal @a1.hash, @a1.hash
assert_equal @a1.hash, @a1.dup.hash assert_equal @a1.hash, @a1.dup.hash
@ -611,15 +593,14 @@ end
end end
def test_installation_path 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 assert_nil @a1.installation_path
@a1.installation_path
end end
assert_equal 'spec a-1 is not from an installed gem', e.message
end end
def test_lib_files def test_lib_files
@ -717,8 +698,8 @@ end
end end
def test_spaceship_name def test_spaceship_name
s1 = quick_spec 'a', '1' s1 = new_spec 'a', '1'
s2 = quick_spec 'b', '1' s2 = new_spec 'b', '1'
assert_equal(-1, (s1 <=> s2)) assert_equal(-1, (s1 <=> s2))
assert_equal( 0, (s1 <=> s1)) assert_equal( 0, (s1 <=> s1))
@ -726,8 +707,8 @@ end
end end
def test_spaceship_platform def test_spaceship_platform
s1 = quick_spec 'a', '1' s1 = new_spec 'a', '1'
s2 = quick_spec 'a', '1' do |s| s2 = new_spec 'a', '1' do |s|
s.platform = Gem::Platform.new 'x86-my_platform1' s.platform = Gem::Platform.new 'x86-my_platform1'
end end
@ -737,8 +718,8 @@ end
end end
def test_spaceship_version def test_spaceship_version
s1 = quick_spec 'a', '1' s1 = new_spec 'a', '1'
s2 = quick_spec 'a', '2' s2 = new_spec 'a', '2'
assert_equal( -1, (s1 <=> s2)) assert_equal( -1, (s1 <=> s2))
assert_equal( 0, (s1 <=> s1)) assert_equal( 0, (s1 <=> s1))
@ -773,13 +754,13 @@ Gem::Specification.new do |s|
s.version = \"2\" s.version = \"2\"
s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version= 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.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
s.description = %q{This is a test description} s.description = %q{This is a test description}
s.email = %q{example@example.com} s.email = %q{example@example.com}
s.files = [\"lib/code.rb\"] s.files = [%q{lib/code.rb}]
s.homepage = %q{http://example.com} s.homepage = %q{http://example.com}
s.require_paths = [\"lib\"] s.require_paths = [%q{lib}]
s.rubygems_version = %q{#{Gem::VERSION}} s.rubygems_version = %q{#{Gem::VERSION}}
s.summary = %q{this is a summary} s.summary = %q{this is a summary}
@ -820,12 +801,12 @@ Gem::Specification.new do |s|
s.version = \"2\" s.version = \"2\"
s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version= 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.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
s.description = %q{This is a test description} s.description = %q{This is a test description}
s.email = %q{example@example.com} s.email = %q{example@example.com}
s.homepage = %q{http://example.com} s.homepage = %q{http://example.com}
s.require_paths = [\"lib\"] s.require_paths = [%q{lib}]
s.rubygems_version = %q{#{Gem::VERSION}} s.rubygems_version = %q{#{Gem::VERSION}}
s.summary = %q{this is a summary} s.summary = %q{this is a summary}
@ -868,22 +849,21 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform.new(#{expected_platform}) s.platform = Gem::Platform.new(#{expected_platform})
s.required_rubygems_version = Gem::Requirement.new(\">= 0\") if s.respond_to? :required_rubygems_version= 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.date = %q{#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}}
s.default_executable = %q{exec}
s.description = %q{This is a test description} s.description = %q{This is a test description}
s.email = %q{example@example.com} s.email = %q{example@example.com}
s.executables = [\"exec\"] s.executables = [%q{exec}]
s.extensions = [\"ext/a/extconf.rb\"] s.extensions = [%q{ext/a/extconf.rb}]
s.files = [\"lib/code.rb\", \"test/suite.rb\", \"bin/exec\", \"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.homepage = %q{http://example.com}
s.licenses = [\"MIT\"] s.licenses = [%q{MIT}]
s.require_paths = [\"lib\"] s.require_paths = [%q{lib}]
s.requirements = [\"A working computer\"] s.requirements = [%q{A working computer}]
s.rubyforge_project = %q{example} s.rubyforge_project = %q{example}
s.rubygems_version = %q{#{Gem::VERSION}} s.rubygems_version = %q{#{Gem::VERSION}}
s.summary = %q{this is a summary} 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 if s.respond_to? :specification_version then
s.specification_version = 3 s.specification_version = 3
@ -913,7 +893,9 @@ end
end end
def test_to_ruby_legacy 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 ruby_code = gemspec1.to_ruby
gemspec2 = eval ruby_code gemspec2 = eval ruby_code
@ -936,7 +918,7 @@ end
refute_match '!!null', yaml_str refute_match '!!null', yaml_str
same_spec = YAML.load(yaml_str) same_spec = Gem::Specification.from_yaml(yaml_str)
assert_equal @a1, same_spec assert_equal @a1, same_spec
end end
@ -945,7 +927,7 @@ end
@a1.platform = Gem::Platform.local @a1.platform = Gem::Platform.local
yaml_str = @a1.to_yaml 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 assert_equal Gem::Platform.local, same_spec.platform
@ -984,41 +966,48 @@ end
end 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 def test_validate_authors
util_setup_validate util_setup_validate
Dir.chdir @tempdir do Dir.chdir @tempdir do
@a1.authors = [] @a1.authors = [""]
use_ui @ui do use_ui @ui do
@a1.validate @a1.validate
end 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] @a1.authors = [Object.new]
e = assert_raises Gem::InvalidSpecificationException do assert_equal [], @a1.authors
@a1.validate
end
assert_equal 'authors must be Array of Strings', e.message
@a1.authors = ['FIXME (who is writing this software)']
e = assert_raises Gem::InvalidSpecificationException do e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end end
assert_equal '"FIXME" or "TODO" is not an author', e.message assert_equal "authors may not be empty", e.message
@a1.authors = ['TODO (who is writing this software)'] @a1.authors = ["#{f} (who is writing this software)"]
e = assert_raises Gem::InvalidSpecificationException do e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end 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 = ["#{t} (who is writing this software)"]
e = assert_raises Gem::InvalidSpecificationException do
@a1.validate
end
assert_equal %{"#{f}" or "#{t}" is not an author}, e.message
end end
end end
@ -1032,7 +1021,7 @@ end
@a1.validate @a1.validate
end end
assert_equal "WARNING: deprecated autorequire specified\n", assert_equal "#{w}: deprecated autorequire specified\n",
@ui.error, 'error' @ui.error, 'error'
end end
end end
@ -1047,34 +1036,34 @@ end
@a1.validate @a1.validate
end 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 @ui = Gem::MockGemUi.new
@a1.summary = 'this is my summary' @a1.summary = "this is my summary"
@a1.description = @a1.summary @a1.description = @a1.summary
use_ui @ui do use_ui @ui do
@a1.validate @a1.validate
end end
assert_equal "WARNING: description and summary are identical\n", assert_equal "#{w}: description and summary are identical\n",
@ui.error, 'error' @ui.error, "error"
@a1.description = 'FIXME (describe your package)' @a1.description = "#{f} (describe your package)"
e = assert_raises Gem::InvalidSpecificationException do e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end 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 e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end 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
end end
@ -1082,35 +1071,33 @@ end
util_setup_validate util_setup_validate
Dir.chdir @tempdir do Dir.chdir @tempdir do
@a1.email = '' @a1.email = ""
use_ui @ui do use_ui @ui do
@a1.validate @a1.validate
end 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 e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end 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 e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end 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
end end
def test_validate_empty def test_validate_empty
util_setup_validate
e = assert_raises Gem::InvalidSpecificationException do e = assert_raises Gem::InvalidSpecificationException do
Gem::Specification.new.validate Gem::Specification.new.validate
end end
@ -1134,7 +1121,7 @@ end
assert_equal %w[exec], @a1.executables assert_equal %w[exec], @a1.executables
assert_equal '', @ui.output, 'output' 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 end
def test_validate_empty_require_paths def test_validate_empty_require_paths
@ -1183,7 +1170,7 @@ end
@a1.validate @a1.validate
end 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 @ui = Gem::MockGemUi.new
@ -1193,7 +1180,7 @@ end
@a1.validate @a1.validate
end 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' @a1.homepage = 'over at my cool site'
@ -1216,6 +1203,26 @@ end
assert_equal 'invalid value for attribute name: ":json"', e.message assert_equal 'invalid value for attribute name: ":json"', e.message
end 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 def test_validate_platform_legacy
util_setup_validate util_setup_validate
@ -1270,23 +1277,23 @@ end
@a1.validate @a1.validate
end 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 e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end 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 e = assert_raises Gem::InvalidSpecificationException do
@a1.validate @a1.validate
end 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
end end
@ -1310,6 +1317,67 @@ end
specfile.delete specfile.delete
end 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 def util_setup_deps
@gem = quick_spec "awesome", "1.0" do |awesome| @gem = quick_spec "awesome", "1.0" do |awesome|
awesome.add_runtime_dependency "bonobo", [] awesome.add_runtime_dependency "bonobo", []
@ -1322,13 +1390,36 @@ end
def util_setup_validate def util_setup_validate
Dir.chdir @tempdir do Dir.chdir @tempdir do
FileUtils.mkdir_p File.join('ext', 'a') FileUtils.mkdir_p File.join("ext", "a")
FileUtils.mkdir_p 'lib' FileUtils.mkdir_p "lib"
FileUtils.mkdir_p 'test' FileUtils.mkdir_p "test"
FileUtils.mkdir_p "bin"
FileUtils.touch File.join('ext', 'a', 'extconf.rb') FileUtils.touch File.join("ext", "a", "extconf.rb")
FileUtils.touch File.join('lib', 'code.rb') FileUtils.touch File.join("lib", "code.rb")
FileUtils.touch File.join('test', 'suite.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 end
end end

Some files were not shown because too many files have changed in this diff Show more