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

Import rubygems 1.5.0 (release candidate)

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30599 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ryan 2011-01-19 00:08:49 +00:00
parent d26fb035ca
commit e798ccbacf
173 changed files with 2721 additions and 2455 deletions

View file

@ -1,3 +1,8 @@
Wed Jan 19 08:13:59 2011 Ryan Davis <ryand-ruby@zenspider.com>
* lib/rubygems*: Import rubygems 1.5.0 (release candidate)
* test/rubygems: Ditto
Tue Jan 18 23:31:01 2011 Yusuke Endoh <mame@tsg.ne.jp> Tue Jan 18 23:31:01 2011 Yusuke Endoh <mame@tsg.ne.jp>
* parse.y: avoid NULL reference. [ruby-dev:43067] * parse.y: avoid NULL reference. [ruby-dev:43067]

4
NEWS
View file

@ -102,6 +102,10 @@ with all sufficient information, see the ChangeLog file.
Output#encoding and Source#encoding) return an Encoding Output#encoding and Source#encoding) return an Encoding
object instead of an encoding name. object instead of an encoding name.
* Rubygems
* Rubygems has been upgraded to rubygems 1.5.0. For full release notes see
http://rubygems.rubyforge.org/rubygems-update/History_txt.html
* stringio * stringio
* extended method: * extended method:
* StringIO#set_encoding can get 2nd argument and optional hash. * StringIO#set_encoding can get 2nd argument and optional hash.

View file

@ -4,17 +4,10 @@
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
module RbConfig # N.B. This file is used by Config.datadir in rubygems.rb, and must not be
# removed before that require is removed. I require to avoid warning more than
## # once.
# Return the path to the data directory associated with the given package
# name. Normally this is just
# "#{RbConfig::CONFIG['datadir']}/#{package_name}", but may be modified by
# packages like RubyGems to handle versioned data directories.
def self.datadir(package_name)
File.join(CONFIG['datadir'], package_name)
end unless RbConfig.respond_to?(:datadir)
end
warn 'rbconfig/datadir.rb and {Rb}Config.datadir is being deprecated from '\
'RubyGems. It will be removed completely on or after June 2011. If you '\
'wish to rely on a datadir, please use Gem.datadir.'

View file

@ -5,9 +5,24 @@
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
# TODO: remove when 1.9.1 no longer supported
QUICKLOADER_SUCKAGE = RUBY_VERSION >= "1.9.1" and RUBY_VERSION < "1.9.2"
# TODO: remove when 1.9.2 no longer supported
GEM_PRELUDE_SUCKAGE = RUBY_VERSION >= "1.9.2" and RUBY_VERSION < "1.9.3"
gem_preluded = GEM_PRELUDE_SUCKAGE and defined? Gem
if GEM_PRELUDE_SUCKAGE and defined?(Gem::QuickLoader) then
Gem::QuickLoader.load_full_rubygems_library
class << Gem
remove_method :try_activate if Gem.respond_to?(:try_activate, true)
end
end
require 'rubygems/defaults' require 'rubygems/defaults'
require 'thread' require 'rbconfig'
require 'etc' require 'thread' # HACK: remove me for 1.5 - this is here just for rails
## ##
# RubyGems is the Ruby standard for publishing and managing third party # RubyGems is the Ruby standard for publishing and managing third party
@ -98,7 +113,7 @@ require 'etc'
# -The RubyGems Team # -The RubyGems Team
module Gem module Gem
RubyGemsVersion = VERSION = '1.3.7' RubyGemsVersion = VERSION = '1.5.0'
## ##
# 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
@ -110,40 +125,49 @@ module Gem
attr_accessor :name attr_accessor :name
# Version requirement of gem # Version requirement of gem
attr_accessor :version_requirement attr_accessor :requirement
def version_requirement
warn "#{Gem.location_of_caller.join ':'}:Warning: " \
"Gem::LoadError#version_requirement is deprecated " \
"and will be removed on or after January 2011. " \
"Use #requirement."
requirement
end end
def version_requirement= requirement
warn "#{Gem.location_of_caller.join ':'}:Warning: " \
"Gem::LoadError#version_requirement= is deprecated " \
"and will be removed on or after January 2011. " \
"Use #requirement."
self.requirement = requirement
end
end
RbConfigPriorities = %w[
EXEEXT RUBY_SO_NAME arch bindir datadir libdir ruby_install_name
ruby_version rubylibprefix sitedir sitelibdir vendordir vendorlibdir
]
unless defined?(ConfigMap)
## ##
# Configuration settings from ::RbConfig # Configuration settings from ::RbConfig
ConfigMap = Hash.new do |cm, key|
ConfigMap = {} unless defined?(ConfigMap) cm[key] = RbConfig::CONFIG[key.to_s]
end
require 'rbconfig' else
RbConfigPriorities.each do |key|
ConfigMap.merge!( ConfigMap[key.to_sym] = RbConfig::CONFIG[key]
:EXEEXT => RbConfig::CONFIG["EXEEXT"], end
:RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"], end
:arch => RbConfig::CONFIG["arch"],
:bindir => RbConfig::CONFIG["bindir"],
:datadir => RbConfig::CONFIG["datadir"],
:libdir => RbConfig::CONFIG["libdir"],
:ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
:ruby_version => RbConfig::CONFIG["ruby_version"],
:rubylibprefix => RbConfig::CONFIG["rubylibprefix"],
:sitedir => RbConfig::CONFIG["sitedir"],
:sitelibdir => RbConfig::CONFIG["sitelibdir"],
:vendordir => RbConfig::CONFIG["vendordir"] ,
:vendorlibdir => RbConfig::CONFIG["vendorlibdir"]
)
## ##
# Default directories in a gem repository # Default directories in a gem repository
DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES) DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
# :stopdoc:
MUTEX = Mutex.new
RubyGemsPackageVersion = VERSION RubyGemsPackageVersion = VERSION
# :startdoc: # :startdoc:
@ -174,9 +198,22 @@ module Gem
@pre_uninstall_hooks ||= [] @pre_uninstall_hooks ||= []
@pre_install_hooks ||= [] @pre_install_hooks ||= []
##
# Try to activate a gem containing +path+. Returns true if
# activation succeeded or wasn't needed because it was already
# activated. Returns false if it can't find the path in a gem.
def self.try_activate path
spec = Gem.searcher.find path
return false unless spec
Gem.activate spec.name, "= #{spec.version}"
return true
end
## ##
# Activates an installed gem matching +gem+. The gem must satisfy # Activates an installed gem matching +gem+. The gem must satisfy
# +version_requirements+. # +requirements+.
# #
# Returns true if the gem is activated, false if it is already # Returns true if the gem is activated, false if it is already
# loaded, or an exception otherwise. # loaded, or an exception otherwise.
@ -190,22 +227,22 @@ module Gem
# More information on version requirements can be found in the # More information on version requirements can be found in the
# Gem::Requirement and Gem::Version documentation. # Gem::Requirement and Gem::Version documentation.
def self.activate(gem, *version_requirements) def self.activate(gem, *requirements)
if version_requirements.last.is_a?(Hash) if requirements.last.is_a?(Hash)
options = version_requirements.pop options = requirements.pop
else else
options = {} options = {}
end end
sources = options[:sources] || [] sources = options[:sources] || []
if version_requirements.empty? then if requirements.empty? then
version_requirements = Gem::Requirement.default requirements = Gem::Requirement.default
end end
unless gem.respond_to?(:name) and unless gem.respond_to?(:name) and
gem.respond_to?(:requirement) then gem.respond_to?(:requirement) then
gem = Gem::Dependency.new(gem, version_requirements) gem = Gem::Dependency.new(gem, requirements)
end end
matches = Gem.source_index.find_name(gem.name, gem.requirement) matches = Gem.source_index.find_name(gem.name, gem.requirement)
@ -226,7 +263,7 @@ module Gem
e = Gem::LoadError.new msg e = Gem::LoadError.new msg
e.name = gem.name e.name = gem.name
e.version_requirement = gem.requirement e.requirement = gem.requirement
raise e raise e
end end
@ -247,9 +284,6 @@ module Gem
activate dep_gem, :sources => [spec, *sources] activate dep_gem, :sources => [spec, *sources]
end end
# bin directory must come before library directories
spec.require_paths.unshift spec.bindir if spec.bindir
require_paths = spec.require_paths.map do |path| require_paths = spec.require_paths.map do |path|
File.join spec.full_gem_path, path File.join spec.full_gem_path, path
end end
@ -310,26 +344,30 @@ module Gem
## ##
# Find the full path to the executable for gem +name+. If the +exec_name+ # Find the full path to the executable for gem +name+. If the +exec_name+
# is not given, the gem's default_executable is chosen, otherwise the # is not given, the gem's default_executable is chosen, otherwise the
# specified executable's path is returned. +version_requirements+ allows # specified executable's path is returned. +requirements+ allows
# you to specify specific gem versions. # you to specify specific gem versions.
def self.bin_path(name, exec_name = nil, *version_requirements) def self.bin_path(name, exec_name = nil, *requirements)
version_requirements = Gem::Requirement.default if requirements = Gem::Requirement.default if
version_requirements.empty? requirements.empty?
spec = Gem.source_index.find_name(name, version_requirements).last specs = Gem.source_index.find_name(name, requirements)
raise Gem::GemNotFoundException, raise Gem::GemNotFoundException,
"can't find gem #{name} (#{version_requirements})" unless spec "can't find gem #{name} (#{requirements})" if specs.empty?
specs = specs.find_all do |spec|
spec.executables.include?(exec_name)
end if exec_name
unless spec = specs.last
msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
raise Gem::GemNotFoundException, msg
end
exec_name ||= spec.default_executable exec_name ||= spec.default_executable
unless exec_name unless exec_name
msg = "no default executable for #{spec.full_name}" msg = "no default executable for #{spec.full_name} and none given"
raise Gem::Exception, msg
end
unless spec.executables.include? exec_name
msg = "can't find executable #{exec_name} for #{spec.full_name}"
raise Gem::Exception, msg raise Gem::Exception, msg
end end
@ -364,10 +402,8 @@ module Gem
@@source_index = nil @@source_index = nil
MUTEX.synchronize do
@searcher = nil @searcher = nil
end end
end
## ##
# The path to standard location of the user's .gemrc file. # The path to standard location of the user's .gemrc file.
@ -414,7 +450,7 @@ module Gem
def self.dir def self.dir
@gem_home ||= nil @gem_home ||= nil
set_home(ENV['GEM_HOME'] || Gem.configuration.home || default_dir) unless @gem_home set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
@gem_home @gem_home
end end
@ -455,41 +491,66 @@ module Gem
end end
## ##
# Returns a list of paths matching +file+ that can be used by a gem to pick # Returns a list of paths matching +glob+ that can be used by a gem to pick
# up features from other gems. For example: # up features from other gems. For example:
# #
# Gem.find_files('rdoc/discover').each do |path| load path end # Gem.find_files('rdoc/discover').each do |path| load path end
# #
# find_files search $LOAD_PATH for files as well as gems. # if +check_load_path+ is true (the default), then find_files also searches
# $LOAD_PATH for files as well as gems.
# #
# Note that find_files will return all files even if they are from different # Note that find_files will return all files even if they are from different
# versions of the same gem. # versions of the same gem.
def self.find_files(path) def self.find_files(glob, check_load_path=true)
load_path_files = suffixes.map do |sfx| files = []
base = path + sfx
$LOAD_PATH.map {|load_path|
Dir[File.expand_path(base, load_path)]
}
end.flatten.select {|f| File.file?(f.untaint)}
specs = searcher.find_all path if check_load_path
files = $LOAD_PATH.map { |load_path|
Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"]
}.flatten.select { |file| File.file? file.untaint }
end
specs_files = specs.map do |spec| specs = searcher.find_all glob
searcher.matching_files spec, path
end.flatten
(load_path_files + specs_files).flatten.uniq specs.each do |spec|
files.concat searcher.matching_files(spec, glob)
end
# $LOAD_PATH might contain duplicate entries or reference
# the spec dirs directly, so we prune.
files.uniq! if check_load_path
return files
end end
## ##
# Finds the user's home directory. # Finds the user's home directory.
#--
# Some comments from the ruby-talk list regarding finding the home
# directory:
#
# I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
# to be depending on HOME in those code samples. I propose that
# it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
# least on Win32).
def self.find_home def self.find_home
unless RUBY_VERSION > '1.9' then
['HOME', 'USERPROFILE'].each do |homekey|
return File.expand_path(ENV[homekey]) if ENV[homekey]
end
if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
return File.expand_path("#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}")
end
end
File.expand_path "~" File.expand_path "~"
rescue rescue
if File::ALT_SEPARATOR then if File::ALT_SEPARATOR then
"C:/" drive = ENV['HOMEDRIVE'] || ENV['SystemDrive']
File.join(drive.to_s, '/')
else else
"/" "/"
end end
@ -529,6 +590,20 @@ module Gem
Zlib::Inflate.inflate data Zlib::Inflate.inflate data
end end
##
# Get the default RubyGems API host. This is normally
# <tt>https://rubygems.org</tt>.
def self.host
@host ||= "https://rubygems.org"
end
## Set the default RubyGems API host.
def self.host= host
@host = host
end
## ##
# Return a list of all possible load paths for the latest version for all # Return a list of all possible load paths for the latest version for all
# gems in the Gem installation. # gems in the Gem installation.
@ -573,13 +648,29 @@ module Gem
# so you can override the gem_prelude.rb default $LOAD_PATH paths. # so you can override the gem_prelude.rb default $LOAD_PATH paths.
def self.load_path_insert_index def self.load_path_insert_index
$LOAD_PATH.index { |p| p.instance_variable_defined? :@gem_prelude_index } index = $LOAD_PATH.index ConfigMap[:sitelibdir]
if QUICKLOADER_SUCKAGE then
$LOAD_PATH.each_with_index do |path, i|
if path.instance_variables.include?(:@gem_prelude_index) or
path.instance_variables.include?('@gem_prelude_index') then
index = i
break
end
end
end end
def self.remove_prelude_paths index
# Gem::QuickLoader::GemLoadPaths.each do |path| end
# $LOAD_PATH.delete(path)
# end ##
# Loads YAML, preferring Psych
def self.load_yaml
require 'psych'
rescue ::LoadError
ensure
require 'yaml'
end end
## ##
@ -607,7 +698,7 @@ module Gem
@gem_path ||= nil @gem_path ||= nil
unless @gem_path then unless @gem_path then
paths = [ENV['GEM_PATH'] || Gem.configuration.path || default_path] paths = [ENV['GEM_PATH'] || default_path]
if defined?(APPLE_GEM_HOME) and not ENV['GEM_PATH'] then if defined?(APPLE_GEM_HOME) and not ENV['GEM_PATH'] then
paths << APPLE_GEM_HOME paths << APPLE_GEM_HOME
@ -720,10 +811,8 @@ module Gem
def self.refresh def self.refresh
source_index.refresh! source_index.refresh!
MUTEX.synchronize do
@searcher = nil @searcher = nil
end end
end
## ##
# Safely read a file in binary mode on all platforms. # Safely read a file in binary mode on all platforms.
@ -750,7 +839,7 @@ module Gem
end end
error.name = gem.name error.name = gem.name
error.version_requirement = gem.requirement error.requirement = gem.requirement
raise error raise error
end end
@ -812,10 +901,8 @@ module Gem
# The GemPathSearcher object used to search for matching installed gems. # The GemPathSearcher object used to search for matching installed gems.
def self.searcher def self.searcher
MUTEX.synchronize do
@searcher ||= Gem::GemPathSearcher.new @searcher ||= Gem::GemPathSearcher.new
end end
end
## ##
# Set the Gem home directory (as reported by Gem.dir). # Set the Gem home directory (as reported by Gem.dir).
@ -895,8 +982,14 @@ module Gem
# Suffixes for require-able paths. # Suffixes for require-able paths.
def self.suffixes def self.suffixes
['', '.rb', ".#{RbConfig::CONFIG["DLEXT"]}"] @suffixes ||= ['',
end unless defined?(suffixes) '.rb',
*%w(DLEXT DLEXT2).map { |key|
val = RbConfig::CONFIG[key]
".#{val}" unless val.empty?
}
].compact.uniq
end
## ##
# Prints the amount of time the supplied block takes to run using the debug # Prints the amount of time the supplied block takes to run using the debug
@ -952,11 +1045,9 @@ module Gem
end end
## ##
# Find all 'rubygems_plugin' files and load them # Load +plugins+ as ruby files
def self.load_plugins
plugins = Gem.find_files 'rubygems_plugin'
def self.load_plugin_files(plugins)
plugins.each do |plugin| plugins.each do |plugin|
# Skip older versions of the GemCutter plugin: Its commands are in # Skip older versions of the GemCutter plugin: Its commands are in
@ -973,6 +1064,31 @@ module Gem
end end
end end
##
# Find all 'rubygems_plugin' files in installed gems and load them
def self.load_plugins
load_plugin_files find_files('rubygems_plugin', false)
end
##
# Find all 'rubygems_plugin' files in $LOAD_PATH and load them
def self.load_env_plugins
path = "rubygems_plugin"
files = []
$LOAD_PATH.each do |load_path|
globbed = Dir["#{File.expand_path path, load_path}#{Gem.suffix_pattern}"]
globbed.each do |load_path_file|
files << load_path_file if File.file?(load_path_file.untaint)
end
end
load_plugin_files files
end
class << self class << self
## ##
@ -1014,21 +1130,27 @@ module Gem
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/" MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
## autoload :Version, 'rubygems/version'
# Location of legacy YAML quick gemspecs on remote repositories autoload :Requirement, 'rubygems/requirement'
autoload :Dependency, 'rubygems/dependency'
YAML_SPEC_DIR = 'quick/' autoload :GemPathSearcher, 'rubygems/gem_path_searcher'
autoload :SpecFetcher, 'rubygems/spec_fetcher'
autoload :Specification, 'rubygems/specification'
autoload :Cache, 'rubygems/source_index'
autoload :SourceIndex, 'rubygems/source_index'
autoload :Platform, 'rubygems/platform'
autoload :Builder, 'rubygems/builder'
autoload :ConfigFile, 'rubygems/config_file'
end end
module Kernel module Kernel
remove_method :gem if respond_to?(:gem, true) # defined in gem_prelude.rb on 1.9 remove_method :gem if respond_to? :gem # defined in gem_prelude.rb on 1.9
## ##
# Use Kernel#gem to activate a specific version of +gem_name+. # Use Kernel#gem to activate a specific version of +gem_name+.
# #
# +version_requirements+ is a list of version requirements that the # +requirements+ is a list of version requirements that the
# specified gem must match, most commonly "= example.version.number". See # specified gem must match, most commonly "= example.version.number". See
# Gem::Requirement for how to specify a version requirement. # Gem::Requirement for how to specify a version requirement.
# #
@ -1051,10 +1173,10 @@ module Kernel
# #
# GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb # GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
def gem(gem_name, *version_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, *version_requirements) Gem.activate(gem_name, *requirements)
end end
private :gem private :gem
@ -1068,19 +1190,14 @@ end
# "#{ConfigMap[:datadir]}/#{package_name}". # "#{ConfigMap[:datadir]}/#{package_name}".
def RbConfig.datadir(package_name) def RbConfig.datadir(package_name)
require 'rbconfig/datadir' # TODO Deprecate after June 2010.
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'
require 'rubygems/version'
require 'rubygems/requirement'
require 'rubygems/dependency'
require 'rubygems/gem_path_searcher' # Needed for Kernel#gem
require 'rubygems/source_index' # Needed for Kernel#gem
require 'rubygems/platform'
require 'rubygems/builder' # HACK: Needed for rake's package task.
unless gem_preluded then # TODO: remove guard after 1.9.2 dropped
begin begin
## ##
# Defaults the operating system (or packager) wants to provide for RubyGems. # Defaults the operating system (or packager) wants to provide for RubyGems.
@ -1098,24 +1215,15 @@ if defined?(RUBY_ENGINE) then
rescue LoadError rescue LoadError
end end
end end
require 'rubygems/config_file'
class << Gem
remove_method :try_activate if Gem.respond_to?(:try_activate, true)
def try_activate(path)
spec = Gem.searcher.find(path)
return false unless spec
Gem.activate(spec.name, "= #{spec.version}")
return true
end
end end
require 'rubygems/custom_require' ##
# Enables the require hook for RubyGems.
#
# Ruby 1.9 allows --disable-gems, so we require it when we didn't detect a Gem
# constant at rubygems.rb load time.
require 'rubygems/custom_require' unless RUBY_VERSION > '1.9'
Gem.clear_paths Gem.clear_paths
Gem.load_plugins

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -6,6 +12,16 @@
require 'rubygems/user_interaction' require 'rubygems/user_interaction'
begin
require 'psych'
rescue LoadError
end
Gem.load_yaml
require 'rubygems/package'
require 'rubygems/security'
## ##
# The Builder class processes RubyGem specification files # The Builder class processes RubyGem specification files
# to produce a .gem file. # to produce a .gem file.
@ -20,10 +36,6 @@ class Gem::Builder
# spec:: [Gem::Specification] The specification instance # spec:: [Gem::Specification] The specification instance
def initialize(spec) def initialize(spec)
require "yaml"
require "rubygems/package"
require "rubygems/security"
@spec = spec @spec = spec
end end
@ -72,7 +84,8 @@ EOM
def write_package def write_package
open @spec.file_name, 'wb' do |gem_io| open @spec.file_name, 'wb' do |gem_io|
Gem::Package.open gem_io, 'w', @signer do |pkg| Gem::Package.open gem_io, 'w', @signer do |pkg|
pkg.metadata = @spec.to_yaml yaml = @spec.to_yaml
pkg.metadata = yaml
@spec.files.each do |file| @spec.files.each do |file|
next if File.directory? file next if File.directory? file

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -146,15 +152,23 @@ class Gem::Command
end end
## ##
#
# Display to the user that a gem couldn't be found and reasons why # Display to the user that a gem couldn't be found and reasons why
def show_lookup_failure(gem_name, version, errors=nil)
def show_lookup_failure(gem_name, version, errors, domain)
if errors and !errors.empty? if errors and !errors.empty?
alert_error "Could not find a valid gem '#{gem_name}' (#{version}), here is why:" alert_error "Could not find a valid gem '#{gem_name}' (#{version}), here is why:"
errors.each { |x| say " #{x.wordy}" } errors.each { |x| say " #{x.wordy}" }
else else
alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository" alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository"
end end
unless domain == :local then # HACK
suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name gem_name
unless suggestions.empty?
alert_error "Possible alternatives: #{suggestions.join(", ")}"
end
end
end end
## ##

View file

@ -1,10 +1,15 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'timeout'
require 'rubygems/command' require 'rubygems/command'
require 'rubygems/user_interaction' require 'rubygems/user_interaction'
@ -42,6 +47,7 @@ class Gem::CommandManager
# Register all the subcommands supported by the gem command. # Register all the subcommands supported by the gem command.
def initialize def initialize
require 'timeout'
@commands = {} @commands = {}
register_command :build register_command :build
register_command :cert register_command :cert
@ -56,7 +62,6 @@ class Gem::CommandManager
register_command :install register_command :install
register_command :list register_command :list
register_command :lock register_command :lock
register_command :mirror
register_command :outdated register_command :outdated
register_command :owner register_command :owner
register_command :pristine register_command :pristine

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/builder' require 'rubygems/builder'

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/security' require 'rubygems/security'
@ -59,21 +65,21 @@ class Gem::Commands::CertCommand < Gem::Command
add_option('-C', '--certificate CERT', add_option('-C', '--certificate CERT',
'Certificate for --sign command.') do |value, options| 'Certificate for --sign command.') do |value, options|
cert = OpenSSL::X509::Certificate.new(File.read(value)) cert = OpenSSL::X509::Certificate.new(File.read(value))
Gem::Security::OPT[:issuer_cert] = cert options[:issuer_cert] = cert
end end
add_option('-K', '--private-key KEY', add_option('-K', '--private-key KEY',
'Private key for --sign command.') do |value, options| 'Private key for --sign command.') do |value, options|
key = OpenSSL::PKey::RSA.new(File.read(value)) key = OpenSSL::PKey::RSA.new(File.read(value))
Gem::Security::OPT[:issuer_key] = key options[:issuer_key] = key
end end
add_option('-s', '--sign NEWCERT', add_option('-s', '--sign NEWCERT',
'Sign a certificate with my key and', 'Sign a certificate with my key and',
'certificate.') do |value, options| 'certificate.') do |value, options|
cert = OpenSSL::X509::Certificate.new(File.read(value)) cert = OpenSSL::X509::Certificate.new(File.read(value))
my_cert = Gem::Security::OPT[:issuer_cert] my_cert = options[:issuer_cert]
my_key = Gem::Security::OPT[:issuer_key] my_key = options[:issuer_key]
cert = Gem::Security.sign_cert(cert, my_key, my_cert) cert = Gem::Security.sign_cert(cert, my_key, my_cert)
File.open(value, 'wb') { |file| file.write(cert.to_pem) } File.open(value, 'wb') { |file| file.write(cert.to_pem) }
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/version_option' require 'rubygems/version_option'
require 'rubygems/validator' require 'rubygems/validator'
@ -21,25 +27,10 @@ class Gem::Commands::CheckCommand < Gem::Command
options[:alien] = true options[:alien] = true
end end
add_option('-v', '--verbose', "Spew more words") do |value, options| add_version_option 'check'
options[:verbose] = true
end
add_option('-t', '--test', "Run unit tests for gem") do |value, options|
options[:test] = true
end
add_version_option 'run tests for'
end end
def execute def execute
if options[:test]
version = options[:version] || Gem::Requirement.default
dep = Gem::Dependency.new get_one_gem_name, version
gem_spec = Gem::SourceIndex.from_installed_gems.search(dep).first
Gem::Validator.new.unit_test(gem_spec)
end
if options[:alien] if options[:alien]
say "Performing the 'alien' operation" say "Performing the 'alien' operation"
say say
@ -52,7 +43,7 @@ class Gem::Commands::CheckCommand < Gem::Command
say " #{error_entry.problem}" say " #{error_entry.problem}"
end end
else else
say "#{key} is error-free" if options[:verbose] say "#{key} is error-free" if Gem.configuration.verbose
end end
say say
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/source_index' require 'rubygems/source_index'
require 'rubygems/dependency_list' require 'rubygems/dependency_list'
@ -8,7 +14,7 @@ class Gem::Commands::CleanupCommand < Gem::Command
def initialize def initialize
super 'cleanup', super 'cleanup',
'Clean up old versions of installed gems in the local repository', 'Clean up old versions of installed gems in the local repository',
:force => false, :test => false, :install_dir => Gem.dir :force => false, :install_dir => Gem.dir
add_option('-d', '--dryrun', "") do |value, options| add_option('-d', '--dryrun', "") do |value, options|
options[:dryrun] = true options[:dryrun] = true

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/version_option' require 'rubygems/version_option'

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/local_remote_options' require 'rubygems/local_remote_options'
require 'rubygems/version_option' require 'rubygems/version_option'
@ -76,7 +82,6 @@ class Gem::Commands::DependencyCommand < Gem::Command
if remote? and not options[:reverse_dependencies] then if remote? and not options[:reverse_dependencies] then
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
begin
specs_and_sources = fetcher.find_matching(dependency, false, true, specs_and_sources = fetcher.find_matching(dependency, false, true,
dependency.prerelease?) dependency.prerelease?)
@ -85,17 +90,6 @@ class Gem::Commands::DependencyCommand < Gem::Command
source_indexes[source_uri].add_spec spec source_indexes[source_uri].add_spec spec
end end
rescue Gem::RemoteFetcher::FetchError => e
raise unless fetcher.warn_legacy e do
require 'rubygems/source_info_cache'
specs = Gem::SourceInfoCache.search_with_source dependency, false
specs.each do |spec, source_uri|
source_indexes[source_uri].add_spec spec
end
end
end
end end
if source_indexes.empty? then if source_indexes.empty? then

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
class Gem::Commands::EnvironmentCommand < Gem::Command class Gem::Commands::EnvironmentCommand < Gem::Command
@ -13,6 +19,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
gempath display path used to search for gems gempath display path used to search for gems
version display the gem format version version display the gem format version
remotesources display the remote gem servers remotesources display the remote gem servers
platform display the supporte gem platforms
<omitted> display everything <omitted> display everything
EOF EOF
return args.gsub(/^\s+/, '') return args.gsub(/^\s+/, '')
@ -32,8 +39,6 @@ is a YAML file with the following YAML keys:
levels levels
:update_sources: Enable/disable automatic updating of repository metadata :update_sources: Enable/disable automatic updating of repository metadata
:backtrace: Print backtrace when RubyGems encounters an error :backtrace: Print backtrace when RubyGems encounters an error
:bulk_threshold: Switch to a bulk update when this many sources are out of
date (legacy setting)
:gempath: The paths in which to look for gems :gempath: The paths in which to look for gems
gem_command: A string containing arguments for the specified gem command gem_command: A string containing arguments for the specified gem command
@ -76,6 +81,8 @@ lib/rubygems/defaults/operating_system.rb
out << Gem.path.join(File::PATH_SEPARATOR) out << Gem.path.join(File::PATH_SEPARATOR)
when /^remotesources/ then when /^remotesources/ then
out << Gem.sources.join("\n") out << Gem.sources.join("\n")
when /^platform/ then
out << Gem.platforms.join(File::PATH_SEPARATOR)
when nil then when nil then
out = "RubyGems Environment:\n" out = "RubyGems Environment:\n"

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/local_remote_options' require 'rubygems/local_remote_options'
require 'rubygems/version_option' require 'rubygems/version_option'
@ -52,7 +58,7 @@ class Gem::Commands::FetchCommand < Gem::Command
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
show_lookup_failure gem_name, version, errors show_lookup_failure gem_name, version, errors, options[:domain]
next next
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/indexer' require 'rubygems/indexer'
@ -19,8 +25,7 @@ class Gem::Commands::GenerateIndexCommand < Gem::Command
end end
add_option '--[no-]legacy', add_option '--[no-]legacy',
'Generate indexes for RubyGems older than', 'Generate Marshal.4.8' do |value, options|
'1.2.0' do |value, options|
unless options[:build_modern] or value then unless options[:build_modern] or value then
raise OptionParser::InvalidOption, 'no indicies will be built' raise OptionParser::InvalidOption, 'no indicies will be built'
end end
@ -87,20 +92,12 @@ When done, it will generate a set of files like this:
quick/Marshal.<version>/<gemname>.gemspec.rz # Marshal quick index file quick/Marshal.<version>/<gemname>.gemspec.rz # Marshal quick index file
# these files support legacy RubyGems # these files support legacy RubyGems
quick/index
quick/index.rz # quick index manifest
quick/<gemname>.gemspec.rz # legacy YAML quick index
# file
Marshal.<version> Marshal.<version>
Marshal.<version>.Z # Marshal full index Marshal.<version>.Z # Marshal full index
yaml
yaml.Z # legacy YAML full index
The .Z and .rz extension files are compressed with the inflate algorithm. The .Z and .rz extension files are compressed with the inflate algorithm.
The Marshal version number comes from ruby's Marshal::MAJOR_VERSION and The Marshal version number comes from ruby's Marshal::MAJOR_VERSION and
Marshal::MINOR_VERSION constants. It is used to ensure compatibility. Marshal::MINOR_VERSION constants. It is used to ensure compatibility.
The yaml indexes exist for legacy RubyGems clients and fallback in case of
Marshal version changes.
If --rss-host and --rss-gem-host are given an RSS feed will be generated at If --rss-host and --rss-gem-host are given an RSS feed will be generated at
index.rss containing gems released in the last two days. index.rss containing gems released in the last two days.

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
class Gem::Commands::HelpCommand < Gem::Command class Gem::Commands::HelpCommand < Gem::Command
@ -14,11 +20,6 @@ Some examples of 'gem' usage.
gem install rake --remote gem install rake --remote
* Install 'rake' from remote server, and run unit tests,
and generate RDocs:
gem install --remote rake --test --rdoc --ri
* Install 'rake', but only version 0.3.1, even if dependencies * Install 'rake', but only version 0.3.1, even if dependencies
are not met, and into a user-specific directory: are not met, and into a user-specific directory:

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/doc_manager' require 'rubygems/doc_manager'
require 'rubygems/install_update_options' require 'rubygems/install_update_options'
@ -22,7 +28,6 @@ class Gem::Commands::InstallCommand < Gem::Command
:generate_rdoc => true, :generate_rdoc => true,
:generate_ri => true, :generate_ri => true,
:format_executable => false, :format_executable => false,
:test => false,
:version => Gem::Requirement.default, :version => Gem::Requirement.default,
}) })
@ -41,7 +46,7 @@ class Gem::Commands::InstallCommand < Gem::Command
def defaults_str # :nodoc: def defaults_str # :nodoc:
"--both --version '#{Gem::Requirement.default}' --rdoc --ri --no-force\n" \ "--both --version '#{Gem::Requirement.default}' --rdoc --ri --no-force\n" \
"--no-test --install-dir #{Gem.dir}" "--install-dir #{Gem.dir}"
end end
def description # :nodoc: def description # :nodoc:
@ -115,6 +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])
inst = Gem::DependencyInstaller.new options inst = Gem::DependencyInstaller.new options
inst.install gem_name, options[:version] inst.install gem_name, options[:version]
@ -127,7 +134,7 @@ to write the specification by hand. For example:
alert_error "Error installing #{gem_name}:\n\t#{e.message}" alert_error "Error installing #{gem_name}:\n\t#{e.message}"
exit_code |= 1 exit_code |= 1
rescue Gem::GemNotFoundException => e rescue Gem::GemNotFoundException => e
show_lookup_failure e.name, e.version, e.errors show_lookup_failure e.name, e.version, e.errors, options[:domain]
exit_code |= 2 exit_code |= 2
end end
@ -154,19 +161,6 @@ to write the specification by hand. For example:
Gem::DocManager.new(gem, options[:rdoc_args]).generate_rdoc Gem::DocManager.new(gem, options[:rdoc_args]).generate_rdoc
end end
end end
if options[:test] then
installed_gems.each do |spec|
gem_spec = Gem::SourceIndex.from_installed_gems.find_name(spec.name, spec.version.version).first
result = Gem::Validator.new.unit_test(gem_spec)
if result and not result.passed?
unless ask_yes_no("...keep Gem?", true)
require 'rubygems/uninstaller'
Gem::Uninstaller.new(spec.name, :version => spec.version.version).uninstall
end
end
end
end
end end
raise Gem::SystemExitException, exit_code raise Gem::SystemExitException, exit_code

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/commands/query_command' require 'rubygems/commands/query_command'

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
class Gem::Commands::LockCommand < Gem::Command class Gem::Commands::LockCommand < Gem::Command
@ -75,7 +81,7 @@ lock it down to the exact version.
until pending.empty? do until pending.empty? do
full_name = pending.shift full_name = pending.shift
spec = Gem::SourceIndex.load_specification spec_path(full_name) spec = Gem::Specification.load spec_path(full_name)
if spec.nil? then if spec.nil? then
complain "Could not find gem #{full_name}, try using the full name" complain "Could not find gem #{full_name}, try using the full name"

View file

@ -1,111 +0,0 @@
require 'yaml'
require 'zlib'
require 'rubygems/command'
require 'open-uri'
class Gem::Commands::MirrorCommand < Gem::Command
def initialize
super 'mirror', 'Mirror a gem repository'
end
def description # :nodoc:
<<-EOF
The mirror command uses the ~/.gemmirrorrc config file to mirror remote gem
repositories to a local path. The config file is a YAML document that looks
like this:
---
- from: http://gems.example.com # source repository URI
to: /path/to/mirror # destination directory
Multiple sources and destinations may be specified.
EOF
end
def execute
config_file = File.join Gem.user_home, '.gemmirrorrc'
raise "Config file #{config_file} not found" unless File.exist? config_file
mirrors = YAML.load_file config_file
raise "Invalid config file #{config_file}" unless mirrors.respond_to? :each
mirrors.each do |mir|
raise "mirror missing 'from' field" unless mir.has_key? 'from'
raise "mirror missing 'to' field" unless mir.has_key? 'to'
get_from = mir['from']
save_to = File.expand_path mir['to']
raise "Directory not found: #{save_to}" unless File.exist? save_to
raise "Not a directory: #{save_to}" unless File.directory? save_to
gems_dir = File.join save_to, "gems"
if File.exist? gems_dir then
raise "Not a directory: #{gems_dir}" unless File.directory? gems_dir
else
Dir.mkdir gems_dir
end
source_index_data = ''
say "fetching: #{get_from}/Marshal.#{Gem.marshal_version}.Z"
get_from = URI.parse get_from
if get_from.scheme.nil? then
get_from = get_from.to_s
elsif get_from.scheme == 'file' then
# check if specified URI contains a drive letter (file:/D:/Temp)
get_from = get_from.to_s
get_from = if get_from =~ /^file:.*[a-z]:/i then
get_from[6..-1]
else
get_from[5..-1]
end
end
open File.join(get_from.to_s, "Marshal.#{Gem.marshal_version}.Z"), "rb" do |y|
source_index_data = Zlib::Inflate.inflate y.read
open File.join(save_to, "Marshal.#{Gem.marshal_version}"), "wb" do |out|
out.write source_index_data
end
end
source_index = Marshal.load source_index_data
progress = ui.progress_reporter source_index.size,
"Fetching #{source_index.size} gems"
source_index.each do |fullname, gem|
gem_file = gem.file_name
gem_dest = File.join gems_dir, gem_file
unless File.exist? gem_dest then
begin
open "#{get_from}/gems/#{gem_file}", "rb" do |g|
contents = g.read
open gem_dest, "wb" do |out|
out.write contents
end
end
rescue
old_gf = gem_file
gem_file = gem_file.downcase
retry if old_gf != gem_file
alert_error $!
end
end
progress.updated gem_file
end
progress.done
end
end
end

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/local_remote_options' require 'rubygems/local_remote_options'
require 'rubygems/spec_fetcher' require 'rubygems/spec_fetcher'

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/local_remote_options' require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities' require 'rubygems/gemcutter_utilities'

View file

@ -1,4 +1,9 @@
require 'fileutils' ######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/format' require 'rubygems/format'
require 'rubygems/installer' require 'rubygems/installer'

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/local_remote_options' require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities' require 'rubygems/gemcutter_utilities'
@ -21,6 +27,13 @@ class Gem::Commands::PushCommand < Gem::Command
def initialize def initialize
super 'push', description super 'push', description
add_proxy_option add_proxy_option
add_option(
'--host HOST',
'Push to another gemcutter-compatible host'
) do |value, options|
options[:host] = value
end
end end
def execute def execute
@ -29,9 +42,13 @@ class Gem::Commands::PushCommand < Gem::Command
end end
def send_gem name def send_gem name
say "Pushing gem to RubyGems.org..." say "Pushing gem to #{options[:host] || Gem.host}..."
response = rubygems_api_request :post, "api/v1/gems" do |request| args = [:post, "api/v1/gems"]
args << options[:host] if options[:host]
response = rubygems_api_request(*args) do |request|
request.body = Gem.read_binary name request.body = Gem.read_binary name
request.add_field "Content-Length", request.body.size request.add_field "Content-Length", request.body.size
request.add_field "Content-Type", "application/octet-stream" request.add_field "Content-Type", "application/octet-stream"

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/local_remote_options' require 'rubygems/local_remote_options'
require 'rubygems/spec_fetcher' require 'rubygems/spec_fetcher'
@ -108,31 +114,11 @@ class Gem::Commands::QueryCommand < Gem::Command
all = options[:all] all = options[:all]
begin
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
spec_tuples = fetcher.find_matching dep, all, false, prerelease spec_tuples = fetcher.find_matching dep, all, false, prerelease
spec_tuples += fetcher.find_matching dep, false, false, true if spec_tuples += fetcher.find_matching dep, false, false, true if
prerelease and all prerelease and all
rescue Gem::RemoteFetcher::FetchError => e
if prerelease then
raise Gem::OperationNotSupportedError,
"Prereleases not supported on legacy repositories"
end
raise unless fetcher.warn_legacy e do
require 'rubygems/source_info_cache'
dep.name = '' if dep.name == //
specs = Gem::SourceInfoCache.search_with_source dep, false, all
spec_tuples = specs.map do |spec, source_uri|
[[spec.name, spec.version, spec.original_platform, spec],
source_uri]
end
end
end
output_query_results spec_tuples output_query_results spec_tuples
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/version_option' require 'rubygems/version_option'
require 'rubygems/doc_manager' require 'rubygems/doc_manager'

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/commands/query_command' require 'rubygems/commands/query_command'

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/server' require 'rubygems/server'
@ -43,6 +49,14 @@ class Gem::Commands::ServerCommand < Gem::Command
options[:addresses] ||= [] options[:addresses] ||= []
options[:addresses].push(*address) options[:addresses].push(*address)
end end
add_option '-l', '--launch[=COMMAND]',
'launches a browser window',
"COMMAND defaults to 'start' on Windows",
"and 'open' on all other platforms" do |launch, options|
launch ||= Gem.win_platform? ? 'start' : 'open'
options[:launch] = launch
end
end end
def defaults_str # :nodoc: def defaults_str # :nodoc:

View file

@ -1,7 +1,10 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'fileutils'
require 'rbconfig'
require 'tmpdir'
## ##
# Installs RubyGems itself. This command is ordinarily only available from a # Installs RubyGems itself. This command is ordinarily only available from a
@ -10,6 +13,8 @@ require 'tmpdir'
class Gem::Commands::SetupCommand < Gem::Command class Gem::Commands::SetupCommand < Gem::Command
def initialize def initialize
require 'tmpdir'
super 'setup', 'Install RubyGems', super 'setup', 'Install RubyGems',
:format_executable => true, :rdoc => true, :ri => true, :format_executable => true, :rdoc => true, :ri => true,
:site_or_vendor => :sitelibdir, :site_or_vendor => :sitelibdir,
@ -98,6 +103,7 @@ By default, this RubyGems will install gem as:
check_ruby_version check_ruby_version
require 'fileutils'
if Gem.configuration.really_verbose then if Gem.configuration.really_verbose then
extend FileUtils::Verbose extend FileUtils::Verbose
else else

View file

@ -1,4 +1,9 @@
require 'fileutils' ######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/remote_fetcher' require 'rubygems/remote_fetcher'
require 'rubygems/source_info_cache' require 'rubygems/source_info_cache'
@ -10,6 +15,8 @@ class Gem::Commands::SourcesCommand < Gem::Command
include Gem::LocalRemoteOptions include Gem::LocalRemoteOptions
def initialize def initialize
require 'fileutils'
super 'sources', super 'sources',
'Manage the sources and cache file RubyGems uses to search for gems' 'Manage the sources and cache file RubyGems uses to search for gems'
@ -79,25 +86,9 @@ class Gem::Commands::SourcesCommand < Gem::Command
rescue URI::Error, ArgumentError rescue URI::Error, ArgumentError
say "#{source_uri} is not a URI" say "#{source_uri} is not a URI"
rescue Gem::RemoteFetcher::FetchError => e rescue Gem::RemoteFetcher::FetchError => e
yaml_uri = uri + 'yaml'
gem_repo = Gem::RemoteFetcher.fetcher.fetch_size yaml_uri rescue false
if e.uri =~ /specs\.#{Regexp.escape Gem.marshal_version}\.gz$/ and
gem_repo then
alert_warning <<-EOF
RubyGems 1.2+ index not found for:
\t#{source_uri}
Will cause RubyGems to revert to legacy indexes, degrading performance.
EOF
say "#{source_uri} added to sources"
else
say "Error fetching #{source_uri}:\n\t#{e.message}" say "Error fetching #{source_uri}:\n\t#{e.message}"
end end
end end
end
if options[:remove] then if options[:remove] then
source_uri = options[:remove] source_uri = options[:remove]
@ -115,16 +106,11 @@ Will cause RubyGems to revert to legacy indexes, degrading performance.
if options[:update] then if options[:update] then
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
if fetcher.legacy_repos.empty? then
Gem.sources.each do |update_uri| Gem.sources.each do |update_uri|
update_uri = URI.parse update_uri update_uri = URI.parse update_uri
fetcher.load_specs update_uri, 'specs' fetcher.load_specs update_uri, 'specs'
fetcher.load_specs update_uri, 'latest_specs' fetcher.load_specs update_uri, 'latest_specs'
end end
else
Gem::SourceInfoCache.cache true
Gem::SourceInfoCache.cache.flush
end
say "source cache successfully updated" say "source cache successfully updated"
end end

View file

@ -1,4 +1,9 @@
require 'yaml' ######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/local_remote_options' require 'rubygems/local_remote_options'
require 'rubygems/version_option' require 'rubygems/version_option'
@ -11,6 +16,8 @@ class Gem::Commands::SpecificationCommand < Gem::Command
include Gem::VersionOption include Gem::VersionOption
def initialize def initialize
Gem.load_yaml
super 'specification', 'Display gem specification (in yaml)', super 'specification', 'Display gem specification (in yaml)',
:domain => :local, :version => Gem::Requirement.default, :domain => :local, :version => Gem::Requirement.default,
:format => :yaml :format => :yaml

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
class Gem::Commands::StaleCommand < Gem::Command class Gem::Commands::StaleCommand < Gem::Command

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/version_option' require 'rubygems/version_option'
require 'rubygems/uninstaller' require 'rubygems/uninstaller'

View file

@ -1,4 +1,9 @@
require 'fileutils' ######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/installer' require 'rubygems/installer'
require 'rubygems/version_option' require 'rubygems/version_option'
@ -8,6 +13,8 @@ class Gem::Commands::UnpackCommand < Gem::Command
include Gem::VersionOption include Gem::VersionOption
def initialize def initialize
require 'fileutils'
super 'unpack', 'Unpack an installed gem to the current directory', super 'unpack', 'Unpack an installed gem to the current directory',
:version => Gem::Requirement.default, :version => Gem::Requirement.default,
:target => Dir.pwd :target => Dir.pwd

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/command_manager' require 'rubygems/command_manager'
require 'rubygems/install_update_options' require 'rubygems/install_update_options'
@ -17,8 +23,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
'Update the named gems (or all installed gems) in the local repository', 'Update the named gems (or all installed gems) in the local repository',
:generate_rdoc => true, :generate_rdoc => true,
:generate_ri => true, :generate_ri => true,
:force => false, :force => false
:test => false
add_install_update_options add_install_update_options
@ -37,7 +42,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
end end
def defaults_str # :nodoc: def defaults_str # :nodoc:
"--rdoc --ri --no-force --no-test --install-dir #{Gem.dir}" "--rdoc --ri --no-force --install-dir #{Gem.dir}"
end end
def usage # :nodoc: def usage # :nodoc:
@ -60,6 +65,19 @@ class Gem::Commands::UpdateCommand < Gem::Command
hig['rubygems-update'] = rubygems_update hig['rubygems-update'] = rubygems_update
options[:user_install] = false options[:user_install] = false
Gem.source_index.refresh!
update_gems = Gem.source_index.find_name 'rubygems-update'
latest_update_gem = update_gems.sort_by { |s| s.version }.last
say "Updating RubyGems to #{latest_update_gem.version}"
installed = do_rubygems_update latest_update_gem.version
say "RubyGems system software updated" if installed
return
else else
say "Updating installed gems" say "Updating installed gems"
@ -97,18 +115,6 @@ class Gem::Commands::UpdateCommand < Gem::Command
end end
end end
if gems_to_update.include? "rubygems-update" then
Gem.source_index.refresh!
update_gems = Gem.source_index.find_name 'rubygems-update'
latest_update_gem = update_gems.sort_by { |s| s.version }.last
say "Updating RubyGems to #{latest_update_gem.version}"
installed = do_rubygems_update latest_update_gem.version
say "RubyGems system software updated" if installed
else
if updated.empty? then if updated.empty? then
say "Nothing to update" say "Nothing to update"
else else
@ -129,7 +135,6 @@ class Gem::Commands::UpdateCommand < Gem::Command
end end
end end
end end
end
## ##
# Update the RubyGems software to +version+. # Update the RubyGems software to +version+.
@ -164,22 +169,8 @@ class Gem::Commands::UpdateCommand < Gem::Command
dependency = Gem::Dependency.new l_spec.name, "> #{l_spec.version}" dependency = Gem::Dependency.new l_spec.name, "> #{l_spec.version}"
begin
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
spec_tuples = fetcher.find_matching dependency spec_tuples = fetcher.find_matching dependency
rescue Gem::RemoteFetcher::FetchError => e
raise unless fetcher.warn_legacy e do
require 'rubygems/source_info_cache'
dependency.name = '' if dependency.name == //
specs = Gem::SourceInfoCache.search_with_source dependency
spec_tuples = specs.map do |spec, source_uri|
[[spec.name, spec.version, spec.original_platform], source_uri]
end
end
end
matching_gems = spec_tuples.select do |(name, _, platform),| matching_gems = spec_tuples.select do |(name, _, platform),|
name == l_name and Gem::Platform.match platform name == l_name and Gem::Platform.match platform

View file

@ -1,3 +1,9 @@
######################################################################
# 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/command' require 'rubygems/command'
require 'rubygems/gem_path_searcher' require 'rubygems/gem_path_searcher'
@ -33,6 +39,7 @@ class Gem::Commands::WhichCommand < Gem::Command
found = false found = false
options[:args].each do |arg| options[:args].each do |arg|
arg = arg.sub(/#{Regexp.union(*EXT)}$/, '')
dirs = $LOAD_PATH dirs = $LOAD_PATH
spec = searcher.find arg spec = searcher.find arg

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -47,10 +53,29 @@ class Gem::ConfigFile
system_config_path = system_config_path =
begin begin
require 'etc.so' require "etc"
Etc.sysconfdir Etc.sysconfdir
rescue LoadError, NoMethodError
begin
# TODO: remove after we drop 1.8.7 and 1.9.1
require 'Win32API'
CSIDL_COMMON_APPDATA = 0x0023
path = 0.chr * 260
if RUBY_VERSION > '1.9' then
SHGetFolderPath = Win32API.new 'shell32', 'SHGetFolderPath', 'PLPLP',
'L', :stdcall
SHGetFolderPath.call nil, CSIDL_COMMON_APPDATA, nil, 1, path
else
SHGetFolderPath = Win32API.new 'shell32', 'SHGetFolderPath', 'LLLLP',
'L'
SHGetFolderPath.call 0, CSIDL_COMMON_APPDATA, 0, 1, path
end
path.strip
rescue LoadError rescue LoadError
'/etc' "/etc"
end
end end
SYSTEM_WIDE_CONFIG_FILE = File.join system_config_path, 'gemrc' SYSTEM_WIDE_CONFIG_FILE = File.join system_config_path, 'gemrc'
@ -192,7 +217,7 @@ class Gem::ConfigFile
dirname = File.dirname(credentials_path) dirname = File.dirname(credentials_path)
Dir.mkdir(dirname) unless File.exists?(dirname) Dir.mkdir(dirname) unless File.exists?(dirname)
require 'yaml' Gem.load_yaml
File.open(credentials_path, 'w') do |f| File.open(credentials_path, 'w') do |f|
f.write config.to_yaml f.write config.to_yaml
@ -202,9 +227,10 @@ class Gem::ConfigFile
end end
def load_file(filename) def load_file(filename)
Gem.load_yaml
return {} unless filename and File.exists?(filename) return {} unless filename and File.exists?(filename)
begin begin
require 'yaml'
YAML.load(File.read(filename)) YAML.load(File.read(filename))
rescue ArgumentError rescue ArgumentError
warn "Failed to load #{config_file_name}" warn "Failed to load #{config_file_name}"
@ -299,7 +325,6 @@ class Gem::ConfigFile
# Writes out this config file, replacing its source. # Writes out this config file, replacing its source.
def write def write
require 'yaml'
open config_file_name, 'w' do |io| open config_file_name, 'w' do |io|
io.write to_yaml io.write to_yaml
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -28,11 +34,9 @@ module Kernel
def require(path) # :doc: def require(path) # :doc:
gem_original_require path gem_original_require path
rescue LoadError => load_error rescue LoadError => load_error
if load_error.message.end_with?(path) if load_error.message.end_with?(path) and Gem.try_activate(path) then
if Gem.try_activate(path)
return gem_original_require(path) return gem_original_require(path)
end end
end
raise load_error raise load_error
end end
@ -40,5 +44,5 @@ module Kernel
private :require private :require
private :gem_original_require private :gem_original_require
end unless Kernel.private_method_defined?(:gem_original_require) end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
module Gem module Gem
@post_install_hooks ||= [] @post_install_hooks ||= []

View file

@ -1,3 +1,9 @@
######################################################################
# 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/requirement" require "rubygems/requirement"
## ##
@ -5,18 +11,6 @@ require "rubygems/requirement"
class Gem::Dependency class Gem::Dependency
# :stopdoc:
@warned_version_requirement = false
def self.warned_version_requirement
@warned_version_requirement
end
def self.warned_version_requirement= value
@warned_version_requirement = value
end
# :startdoc:
## ##
# Valid dependency types. # Valid dependency types.
#-- #--
@ -54,7 +48,7 @@ class Gem::Dependency
unless TYPES.include? type unless TYPES.include? type
raise ArgumentError, "Valid types are #{TYPES.inspect}, " raise ArgumentError, "Valid types are #{TYPES.inspect}, "
+ "not #{@type.inspect}" + "not #{type.inspect}"
end end
@name = name @name = name
@ -88,7 +82,7 @@ class Gem::Dependency
@prerelease || requirement.prerelease? @prerelease || requirement.prerelease?
end end
def pretty_print(q) # :nodoc: def pretty_print q # :nodoc:
q.group 1, 'Gem::Dependency.new(', ')' do q.group 1, 'Gem::Dependency.new(', ')' do
q.pp name q.pp name
q.text ',' q.text ','
@ -133,12 +127,6 @@ class Gem::Dependency
@requirement = @version_requirements if defined?(@version_requirements) @requirement = @version_requirements if defined?(@version_requirements)
end end
##
# Rails subclasses Gem::Dependency and uses this method, so we'll hack
# around it.
alias __requirement requirement # :nodoc:
def requirements_list def requirements_list
requirement.as_list requirement.as_list
end end
@ -147,30 +135,6 @@ class Gem::Dependency
"#{name} (#{requirement}, #{type})" "#{name} (#{requirement}, #{type})"
end end
def version_requirements # :nodoc:
unless Gem::Dependency.warned_version_requirement then
warn "#{Gem.location_of_caller.join ':'}:Warning: " \
"Gem::Dependency#version_requirements is deprecated " \
"and will be removed on or after August 2010. " \
"Use #requirement"
Gem::Dependency.warned_version_requirement = true
end
__requirement
end
alias version_requirement version_requirements # :nodoc:
def version_requirements= requirements # :nodoc:
warn "#{Gem.location_of_caller.join ':'}:Warning: " \
"Gem::Dependency#version_requirements= is deprecated " \
"and will be removed on or after August 2010. " \
"Use Gem::Dependency.new."
@requirement = Gem::Requirement.create requirements
end
def == other # :nodoc: def == other # :nodoc:
Gem::Dependency === other && Gem::Dependency === other &&
self.name == other.name && self.name == other.name &&
@ -182,7 +146,7 @@ class Gem::Dependency
# Dependencies are ordered by name. # Dependencies are ordered by name.
def <=> other def <=> other
[@name] <=> [other.name] @name <=> other.name
end end
## ##
@ -193,16 +157,11 @@ class Gem::Dependency
def =~ other def =~ other
unless Gem::Dependency === other unless Gem::Dependency === other
other = Gem::Dependency.new other.name, other.version rescue return false return unless other.respond_to?(:name) && other.respond_to?(:version)
other = Gem::Dependency.new other.name, other.version
end end
pattern = name return false unless name === other.name
if Regexp === pattern then
return false unless pattern =~ other.name
else
return false unless pattern == other.name
end
reqs = other.requirement.requirements reqs = other.requirement.requirements
@ -214,18 +173,18 @@ class Gem::Dependency
requirement.satisfied_by? version requirement.satisfied_by? version
end end
def match?(spec_name, spec_version) def match? name, version
pattern = name return false unless self.name === name
if Regexp === pattern
return false unless pattern =~ spec_name
else
return false unless pattern == spec_name
end
return true if requirement.none? return true if requirement.none?
requirement.satisfied_by? Gem::Version.new(spec_version) requirement.satisfied_by? Gem::Version.new(version)
end
def matches_spec? spec
return false unless name === spec.name
return true if requirement.none?
requirement.satisfied_by?(spec.version)
end end
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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'
require 'rubygems/dependency_list' require 'rubygems/dependency_list'
require 'rubygems/installer' require 'rubygems/installer'
@ -132,9 +138,14 @@ class Gem::DependencyInstaller
dependency_list = Gem::DependencyList.new @development dependency_list = Gem::DependencyList.new @development
dependency_list.add(*specs) dependency_list.add(*specs)
unless @ignore_dependencies then
to_do = specs.dup to_do = specs.dup
add_found_dependencies to_do, dependency_list unless @ignore_dependencies
@gems_to_install = dependency_list.dependency_order.reverse
end
def add_found_dependencies to_do, dependency_list
seen = {} seen = {}
until to_do.empty? do until to_do.empty? do
@ -148,9 +159,12 @@ class Gem::DependencyInstaller
deps.each do |dep| deps.each do |dep|
results = find_gems_with_sources(dep).reverse results = find_gems_with_sources(dep).reverse
# FIX: throw in everything that satisfies, and let
# FIX: dependencylist reduce to the chosen few
results.reject! do |dep_spec,| results.reject! do |dep_spec,|
to_do.push dep_spec to_do.push dep_spec
# already locally installed
@source_index.any? do |_, installed_spec| @source_index.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
@ -160,15 +174,14 @@ class Gem::DependencyInstaller
results.each do |dep_spec, source_uri| results.each do |dep_spec, source_uri|
next if seen[dep_spec.name] next if seen[dep_spec.name]
@specs_and_sources << [dep_spec, source_uri] @specs_and_sources << [dep_spec, source_uri]
# FIX: this is the bug
dependency_list.add dep_spec dependency_list.add dep_spec
end end
end end
end end
end end
@gems_to_install = dependency_list.dependency_order.reverse
end
## ##
# Finds a spec and the source_uri it came from for gem +gem_name+ and # Finds a spec and the source_uri it came from for gem +gem_name+ and
# +version+. Returns an Array of specs and sources required for # +version+. Returns an Array of specs and sources required for

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -187,6 +193,7 @@ class Gem::DependencyList
begin begin
yield spec yield spec
rescue TSort::Cyclic rescue TSort::Cyclic
# do nothing
end end
break break
end end
@ -201,13 +208,7 @@ class Gem::DependencyList
# +ignored+. # +ignored+.
def active_count(specs, ignored) def active_count(specs, ignored)
result = 0 specs.count { |spec| ignored[spec.full_name].nil? }
specs.each do |spec|
result += 1 unless ignored[spec.full_name]
end
result
end end
end end

View file

@ -1,10 +1,15 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'fileutils'
require 'rubygems' require 'rubygems'
## ##
@ -85,6 +90,7 @@ class Gem::DocManager
# RDoc (template etc.) as a String. # RDoc (template etc.) as a String.
def initialize(spec, rdoc_args="") def initialize(spec, rdoc_args="")
require 'fileutils'
@spec = spec @spec = spec
@doc_dir = File.join(spec.installation_path, "doc", spec.full_name) @doc_dir = File.join(spec.installation_path, "doc", spec.full_name)
@rdoc_args = rdoc_args.nil? ? [] : rdoc_args.split @rdoc_args = rdoc_args.nil? ? [] : rdoc_args.split

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
class Gem::ErrorReason; end class Gem::ErrorReason; end
# Generated when trying to lookup a gem to indicate that the gem # Generated when trying to lookup a gem to indicate that the gem

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
## ##
# Base exception class for RubyGems. All exception raised by RubyGems are a # Base exception class for RubyGems. All exception raised by RubyGems are a
# subclass of this one. # subclass of this one.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -22,7 +28,9 @@ class Gem::Ext::Builder
File.open('Makefile', 'wb') {|f| f.print mf} File.open('Makefile', 'wb') {|f| f.print mf}
make_program = ENV['make'] # try to find make program from Ruby configue arguments first
RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
make_program = $1 || ENV['make']
unless make_program then unless make_program then
make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make' make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -19,7 +25,7 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
# 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 + '"' if dest_path.include?(' ')
cmd = ENV['rake'] || "#{Gem.ruby} -rubygems #{Gem.bin_path('rake')}" rescue Gem.default_exec_format % 'rake' cmd = ENV['rake'] || "\"#{Gem.ruby}\" -rubygems #{Gem.bin_path('rake')}" rescue Gem.default_exec_format % 'rake'
cmd += " RUBYARCHDIR=#{dest_path} RUBYLIBDIR=#{dest_path}" # ENV is frozen cmd += " RUBYARCHDIR=#{dest_path} RUBYLIBDIR=#{dest_path}" # ENV is frozen
run cmd, results run cmd, results

View file

@ -1,11 +1,15 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'fileutils'
require 'rubygems/package' require 'rubygems/package'
## ##

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -42,9 +48,7 @@ begin
# Reference a constant defined in the .rb portion of ssl (just to # Reference a constant defined in the .rb portion of ssl (just to
# make sure that part is loaded too). # make sure that part is loaded too).
OpenSSL::Digest::SHA1 Gem.ssl_available = !!OpenSSL::Digest::SHA1
Gem.ssl_available = true
class OpenSSL::X509::Certificate # :nodoc: class OpenSSL::X509::Certificate # :nodoc:
# Check the validity of this certificate. # Check the validity of this certificate.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
## ##
# 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.
@ -22,7 +28,7 @@ class Gem::GemPathSearcher
end end
## ##
# Look in all the installed gems until a matching _path_ is found. # Look in all the installed gems until a matching +glob+ is found.
# Return the _gemspec_ of the gem where it was found. If no match # Return the _gemspec_ of the gem where it was found. If no match
# is found, return nil. # is found, return nil.
# #
@ -41,16 +47,18 @@ class Gem::GemPathSearcher
# This method doesn't care about the full filename that matches; # This method doesn't care about the full filename that matches;
# only that there is a match. # only that there is a match.
def find(path) def find(glob)
@gemspecs.find do |spec| matching_file? spec, path end @gemspecs.find do |spec|
matching_file? spec, glob
end
end end
## ##
# Works like #find, but finds all gemspecs matching +path+. # Works like #find, but finds all gemspecs matching +glob+.
def find_all(path) def find_all(glob)
@gemspecs.select do |spec| @gemspecs.select do |spec|
matching_file? spec, path matching_file? spec, glob
end end
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -8,6 +14,11 @@ require 'rubygems/command_manager'
require 'rubygems/config_file' require 'rubygems/config_file'
require 'rubygems/doc_manager' require 'rubygems/doc_manager'
##
# Load additional plugins from $LOAD_PATH
Gem.load_env_plugins rescue nil
## ##
# Run an instance of the gem program. # Run an instance of the gem program.
# #
@ -76,3 +87,4 @@ class Gem::GemRunner
end end
Gem.load_plugins

View file

@ -1,4 +1,9 @@
require 'net/http' ######################################################################
# 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/remote_fetcher' require 'rubygems/remote_fetcher'
module Gem::GemcutterUtilities module Gem::GemcutterUtilities
@ -23,8 +28,9 @@ module Gem::GemcutterUtilities
end end
end end
def rubygems_api_request(method, path, &block) def rubygems_api_request(method, path, host = Gem.host, &block)
host = ENV['RUBYGEMS_HOST'] || 'https://rubygems.org' require 'net/http'
host = ENV['RUBYGEMS_HOST'] if ENV['RUBYGEMS_HOST']
uri = URI.parse "#{host}/#{path}" uri = URI.parse "#{host}/#{path}"
request_method = Net::HTTP.const_get method.to_s.capitalize request_method = Net::HTTP.const_get method.to_s.capitalize

View file

@ -1,6 +1,8 @@
require 'fileutils' ######################################################################
require 'tmpdir' # This file is imported from the rubygems project.
require 'zlib' # 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'
require 'rubygems/format' require 'rubygems/format'
@ -57,6 +59,10 @@ class Gem::Indexer
# Create an indexer that will index the gems in +directory+. # Create an indexer that will index the gems in +directory+.
def initialize(directory, options = {}) def initialize(directory, options = {})
require 'fileutils'
require 'tmpdir'
require 'zlib'
unless ''.respond_to? :to_xs then unless ''.respond_to? :to_xs then
raise "Gem::Indexer requires that the XML Builder library be installed:" \ raise "Gem::Indexer requires that the XML Builder library be installed:" \
"\n\tgem install builder" "\n\tgem install builder"
@ -136,42 +142,6 @@ 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)
progress = ui.progress_reporter index.size,
"Generating YAML quick index gemspecs for #{index.size} gems",
"Complete"
Gem.time 'Generated YAML quick index gemspecs' do
index.released_gems.each do |original_name, spec|
spec_file_name = "#{original_name}.gemspec.rz"
yaml_name = File.join @quick_dir, spec_file_name
yaml_zipped = Gem.deflate spec.to_yaml
open yaml_name, 'wb' do |io| io.write yaml_zipped end
progress.updated original_name
end
progress.done
end
say "Generating quick index"
Gem.time 'Generated quick index' do
open @quick_index, 'wb' do |io|
io.puts index.sort.map { |_, spec| spec.original_name }
end
end
say "Generating latest index"
Gem.time 'Generated latest index' do
open @latest_index, 'wb' do |io|
io.puts index.latest_specs.sort.map { |spec| spec.original_name }
end
end
# Don't need prerelease legacy index
say "Generating Marshal master index" say "Generating Marshal master index"
Gem.time 'Generated Marshal master index' do Gem.time 'Generated Marshal master index' do
@ -180,32 +150,6 @@ class Gem::Indexer
end end
end end
progress = ui.progress_reporter index.size,
"Generating YAML master index for #{index.size} gems (this may take a while)",
"Complete"
Gem.time 'Generated YAML master index' do
open @master_index, 'wb' do |io|
io.puts "--- !ruby/object:#{index.class}"
io.puts "gems:"
gems = index.sort_by { |name, gemspec| gemspec.sort_obj }
gems.each do |original_name, gemspec|
yaml = gemspec.to_yaml.gsub(/^/, ' ')
yaml = yaml.sub(/\A ---/, '') # there's a needed extra ' ' here
io.print " #{original_name}:"
io.puts yaml
progress.updated original_name
end
end
progress.done
end
@files << @quick_dir
@files << @master_index
@files << "#{@master_index}.Z"
@files << @marshal_index @files << @marshal_index
@files << "#{@marshal_index}.Z" @files << "#{@marshal_index}.Z"
end end
@ -462,17 +406,8 @@ class Gem::Indexer
Gem.time 'Compressed indicies' do Gem.time 'Compressed indicies' do
if @build_legacy then if @build_legacy then
compress @quick_index, 'rz'
paranoid @quick_index, 'rz'
compress @latest_index, 'rz'
paranoid @latest_index, 'rz'
compress @marshal_index, 'Z' compress @marshal_index, 'Z'
paranoid @marshal_index, 'Z' paranoid @marshal_index, 'Z'
compress @master_index, 'Z'
paranoid @master_index, 'Z'
end end
if @build_modern then if @build_modern then

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -58,10 +64,6 @@ module Gem::InstallUpdateOptions
options[:force] = value options[:force] = value
end end
add_option(:"Install/Update", '-t', '--[no-]test',
'Ignored; just for compatiblity') do |value, options|
end
add_option(:"Install/Update", '-w', '--[no-]wrappers', add_option(:"Install/Update", '-w', '--[no-]wrappers',
'Use bin wrappers for executables', 'Use bin wrappers for executables',
'Not available on dosish platforms') do |value, options| 'Not available on dosish platforms') do |value, options|
@ -103,6 +105,12 @@ module Gem::InstallUpdateOptions
"dependencies") do |value, options| "dependencies") do |value, options|
options[:development] = true options[:development] = true
end end
add_option(:"Install/Update", "--conservative",
"Don't attempt to upgrade gems already",
"meeting version requirement") do |value, options|
options[:conservative] = true
end
end end
## ##

View file

@ -1,13 +1,17 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'fileutils'
require 'rbconfig'
require 'rubygems/format' require 'rubygems/format'
require 'rubygems/exceptions'
require 'rubygems/ext' require 'rubygems/ext'
require 'rubygems/require_paths_builder' require 'rubygems/require_paths_builder'
@ -40,7 +44,7 @@ class Gem::Installer
include Gem::UserInteraction include Gem::UserInteraction
include Gem::RequirePathsBuilder include Gem::RequirePathsBuilder if QUICKLOADER_SUCKAGE
## ##
# The directory a gem's executables will be installed into # The directory a gem's executables will be installed into
@ -91,6 +95,8 @@ class Gem::Installer
# :wrappers:: Install wrappers if true, symlinks if false. # :wrappers:: Install wrappers if true, symlinks if false.
def initialize(gem, options={}) def initialize(gem, options={})
require 'fileutils'
@gem = gem @gem = gem
options = { options = {
@ -198,7 +204,7 @@ class Gem::Installer
build_extensions build_extensions
write_spec write_spec
write_require_paths_file_if_needed write_require_paths_file_if_needed if QUICKLOADER_SUCKAGE
# HACK remove? Isn't this done in multiple places? # HACK remove? Isn't this done in multiple places?
cached_gem = File.join @gem_home, "cache", @gem.split(/\//).pop cached_gem = File.join @gem_home, "cache", @gem.split(/\//).pop
@ -318,10 +324,6 @@ class Gem::Installer
def generate_bin_script(filename, bindir) def generate_bin_script(filename, bindir)
bin_script_path = File.join bindir, formatted_program_filename(filename) bin_script_path = File.join bindir, formatted_program_filename(filename)
File.join @gem_dir, @spec.bindir, filename
# HACK some gems don't have #! in their executables, restore 2008/06
#if File.read(exec_path, 2) == '#!' then
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
File.open bin_script_path, 'w', 0755 do |file| File.open bin_script_path, 'w', 0755 do |file|
@ -331,11 +333,6 @@ class Gem::Installer
say bin_script_path if Gem.configuration.really_verbose say bin_script_path if Gem.configuration.really_verbose
generate_windows_script filename, bindir generate_windows_script filename, bindir
#else
# FileUtils.rm_f bin_script_path
# FileUtils.cp exec_path, bin_script_path,
# :verbose => Gem.configuration.really_verbose
#end
end end
## ##
@ -497,6 +494,8 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
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
@ -514,7 +513,12 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
end end
FileUtils.rm_rf(path) if File.exists?(path) FileUtils.rm_rf(path) if File.exists?(path)
FileUtils.mkdir_p File.dirname(path)
dir = File.dirname(path)
if !dirs.include?(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

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -51,6 +57,7 @@ module Gem::LocalRemoteOptions
end end
add_bulk_threshold_option add_bulk_threshold_option
add_clear_sources_option
add_source_option add_source_option
add_proxy_option add_proxy_option
add_update_sources_option add_update_sources_option
@ -68,6 +75,18 @@ module Gem::LocalRemoteOptions
end end
end end
##
# Add the --clear-sources option
def add_clear_sources_option
add_option(:"Local/Remote", '--clear-sources',
'Clear the gem sources') do |value, options|
Gem.sources.clear
options[:sources_cleared] = true
end
end
## ##
# Add the --http-proxy option # Add the --http-proxy option
@ -88,14 +107,14 @@ module Gem::LocalRemoteOptions
accept_uri_http accept_uri_http
add_option(:"Local/Remote", '--source URL', URI::HTTP, add_option(:"Local/Remote", '--source URL', URI::HTTP,
'Use URL as the remote source for gems') do |source, options| 'Add URL as a remote source for gems') do |source, options|
source << '/' if source !~ /\/\z/ source << '/' if source !~ /\/\z/
if options[:added_source] then if options.delete :sources_cleared then
Gem.sources << source unless Gem.sources.include?(source) Gem.sources = [source]
else else
options[:added_source] = true Gem.sources << source unless Gem.sources.include?(source)
Gem.sources.replace [source]
end end
end end
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -5,9 +11,6 @@
#++ #++
require 'rubygems' require 'rubygems'
require 'fileutils'
require 'yaml'
require 'zlib'
## ##
# The format class knows the guts of the RubyGem .gem file format and provides # The format class knows the guts of the RubyGem .gem file format and provides
@ -24,6 +27,10 @@ class Gem::OldFormat
# gem:: [String] The file name of the gem # gem:: [String] The file name of the gem
def initialize(gem_path) def initialize(gem_path)
require 'fileutils'
require 'zlib'
Gem.load_yaml
@gem_path = gem_path @gem_path = gem_path
end end

View file

@ -1,15 +1,15 @@
######################################################################
# 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.
######################################################################
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#-- #--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.
#++ #++
require 'fileutils'
require 'find'
require 'stringio'
require 'yaml'
require 'zlib'
require 'rubygems/security' require 'rubygems/security'
require 'rubygems/specification' require 'rubygems/specification'
@ -20,6 +20,7 @@ require 'rubygems/specification'
class Gem::FileOperations class Gem::FileOperations
def initialize(logger = nil) def initialize(logger = nil)
require 'fileutils'
@logger = logger @logger = logger
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#-- #--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#-- #--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier

View file

@ -1,9 +1,18 @@
######################################################################
# 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.
######################################################################
# -*- coding: iso-8859-1 -*- # -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.
#-- #--
require 'zlib'
Gem.load_yaml
class Gem::Package::TarInput class Gem::Package::TarInput
include Gem::Package::FSyncDir include Gem::Package::FSyncDir

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#-- #--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#-- #--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#-- #--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
# Copyright (c) 2003, 2004 Jim Weirich, 2009 Eric Hodel # Copyright (c) 2003, 2004 Jim Weirich, 2009 Eric Hodel
# #
# Permission is hereby granted, free of charge, to any person obtaining # Permission is hereby granted, free of charge, to any person obtaining
@ -111,14 +117,14 @@ class Gem::PackageTask < Rake::PackageTask
Gem.configuration.verbose = trace Gem.configuration.verbose = trace
file gem_path => [package_dir, gem_dir] + @gem_spec.files do file gem_path => [package_dir, gem_dir] + @gem_spec.files do
chdir(gem_dir) do
when_writing "Creating #{gem_spec.file_name}" do when_writing "Creating #{gem_spec.file_name}" do
Gem::Builder.new(gem_spec).build Gem::Builder.new(gem_spec).build
verbose trace do verbose(true) {
mv gem_file, gem_path mv gem_file, ".."
}
end end
end end
end end
end end
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
## ##
# Available list of platforms for targeting Gem installations. # Available list of platforms for targeting Gem installations.

View file

@ -1,9 +1,12 @@
require 'net/http' ######################################################################
require 'stringio' # This file is imported from the rubygems project.
require 'time' # DO NOT make modifications in this repo. They _will_ be reverted!
require 'uri' # File a patch instead and assign it to Ryan Davis or Eric Hodel.
######################################################################
require 'rubygems' require 'rubygems'
require 'rubygems/user_interaction'
require 'uri'
## ##
# RemoteFetcher handles the details of fetching gems and gem information from # RemoteFetcher handles the details of fetching gems and gem information from
@ -56,6 +59,11 @@ class Gem::RemoteFetcher
# * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy # * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy
def initialize(proxy = nil) def initialize(proxy = nil)
require 'net/http'
require 'stringio'
require 'time'
require 'uri'
Socket.do_not_reverse_lookup = true Socket.do_not_reverse_lookup = true
@connections = {} @connections = {}
@ -75,6 +83,8 @@ class Gem::RemoteFetcher
# always replaced. # always replaced.
def download(spec, source_uri, install_dir = Gem.dir) def download(spec, source_uri, install_dir = Gem.dir)
Gem.ensure_gem_subdirectories(install_dir) rescue nil
if File.writable?(install_dir) if File.writable?(install_dir)
cache_dir = File.join install_dir, 'cache' cache_dir = File.join install_dir, 'cache'
else else
@ -147,7 +157,7 @@ class Gem::RemoteFetcher
source_uri.path source_uri.path
end end
source_path = URI.unescape source_path source_path = unescape source_path
begin begin
FileUtils.cp source_path, local_gem_path unless FileUtils.cp source_path, local_gem_path unless
@ -191,12 +201,20 @@ class Gem::RemoteFetcher
def escape(str) def escape(str)
return unless str return unless str
URI.escape(str) @uri_parser ||= uri_escaper
@uri_parser.escape str
end end
def unescape(str) def unescape(str)
return unless str return unless str
URI.unescape(str) @uri_parser ||= uri_escaper
@uri_parser.unescape str
end
def uri_escaper
URI::Parser.new
rescue NameError
URI
end end
## ##
@ -241,7 +259,7 @@ class Gem::RemoteFetcher
] ]
end end
connection_id = net_http_args.join ':' connection_id = [Thread.current.object_id, *net_http_args].join ':'
@connections[connection_id] ||= Net::HTTP.new(*net_http_args) @connections[connection_id] ||= Net::HTTP.new(*net_http_args)
connection = @connections[connection_id] connection = @connections[connection_id]
@ -339,7 +357,34 @@ class Gem::RemoteFetcher
say "#{request.method} #{uri}" if say "#{request.method} #{uri}" if
Gem.configuration.really_verbose Gem.configuration.really_verbose
file_name = File.basename(uri.path)
# perform download progress reporter only for gems
if request.response_body_permitted? && file_name =~ /\.gem$/
reporter = ui.download_reporter
response = connection.request(request) do |incomplete_response|
if Net::HTTPOK === incomplete_response
reporter.fetch(file_name, incomplete_response.content_length)
downloaded = 0
data = ''
incomplete_response.read_body do |segment|
data << segment
downloaded += segment.length
reporter.update(downloaded)
end
reporter.done
if incomplete_response.respond_to? :body=
incomplete_response.body = data
else
incomplete_response.instance_variable_set(:@body, data)
end
end
end
else
response = connection.request request response = connection.request request
end
say "#{response.code} #{response.message}" if say "#{response.code} #{response.message}" if
Gem.configuration.really_verbose Gem.configuration.really_verbose

View file

@ -1,13 +1,24 @@
######################################################################
# 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'
# TODO: remove after 1.9.1 dropped
module Gem::RequirePathsBuilder module Gem::RequirePathsBuilder
def write_require_paths_file_if_needed(spec = @spec, gem_home = @gem_home) def write_require_paths_file_if_needed(spec = @spec, gem_home = @gem_home)
require_paths = spec.require_paths return if spec.require_paths == ["lib"] &&
return if require_paths.size == 1 and require_paths.first == "lib" (spec.bindir.nil? || spec.bindir == "bin")
file_name = "#{gem_home}/gems/#{@spec.full_name}/.require_paths".untaint file_name = File.join(gem_home, 'gems', "#{@spec.full_name}", ".require_paths")
File.open(file_name, "wb") do |file| file_name.untaint
file.puts require_paths File.open(file_name, "w") do |file|
end spec.require_paths.each do |path|
file.puts path
end
file.puts spec.bindir if spec.bindir
end end
end end
end if QUICKLOADER_SUCKAGE

View file

@ -1,3 +1,9 @@
######################################################################
# 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/version" require "rubygems/version"
## ##
@ -14,7 +20,7 @@ class Gem::Requirement
"<" => lambda { |v, r| v < r }, "<" => lambda { |v, r| v < r },
">=" => lambda { |v, r| v >= r }, ">=" => lambda { |v, r| v >= r },
"<=" => lambda { |v, r| v <= r }, "<=" => lambda { |v, r| v <= r },
"~>" => lambda { |v, r| v = v.release; v >= r && v < r.bump } "~>" => lambda { |v, r| v >= r && v.release < r.bump }
} }
quoted = OPS.keys.map { |k| Regexp.quote k }.join "|" quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"

View file

@ -1,12 +1,19 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'rubygems' require 'rubygems/exceptions'
require 'rubygems/gem_openssl' require 'rubygems/gem_openssl'
#
# = Signed Gems README # = Signed Gems README
# #
# == Table of Contents # == Table of Contents
@ -265,6 +272,34 @@ require 'rubygems/gem_openssl'
# A more detailed description of each options is available in the walkthrough # A more detailed description of each options is available in the walkthrough
# above. # above.
# #
# == Manually verifying signatures
#
# In case you don't trust RubyGems you can verify gem signatures manually:
#
# 1. Fetch and unpack the gem
#
# gem fetch some_signed_gem
# tar -xf some_signed_gem-1.0.gem
#
# 2. Grab the public key from the gemspec
#
# gem spec some_signed_gem-1.0.gem cert_chain | \
# ruby -pe 'sub(/^ +/, "")' > public_key.crt
#
# 3. Generate a SHA1 hash of the data.tar.gz
#
# openssl dgst -sha1 < data.tar.gz > my.hash
#
# 4. Verify the signature
#
# openssl rsautl -verify -inkey public_key.crt -certin \
# -in data.tar.gz.sig > verified.hash
#
# 5. Compare your hash to the verified hash
#
# diff -s verified.hash my.hash
#
# 6. Repeat 5 and 6 with metadata.gz
# #
# == OpenSSL Reference # == OpenSSL Reference
# #
@ -319,11 +354,14 @@ require 'rubygems/gem_openssl'
module Gem::Security module Gem::Security
##
# Gem::Security default exception type
class Exception < Gem::Exception; end class Exception < Gem::Exception; end
# ##
# default options for most of the methods below # Default options for most of the methods below
#
OPT = { OPT = {
# private key options # private key options
:key_algo => Gem::SSL::PKEY_RSA, :key_algo => Gem::SSL::PKEY_RSA,
@ -365,11 +403,11 @@ module Gem::Security
}, },
} }
# ##
# A Gem::Security::Policy object encapsulates the settings for verifying # A Gem::Security::Policy object encapsulates the settings for verifying
# signed gem files. This is the base class. You can either declare an # signed gem files. This is the base class. You can either declare an
# instance of this or use one of the preset security policies below. # instance of this or use one of the preset security policies below.
#
class Policy class Policy
attr_accessor :verify_data, :verify_signer, :verify_chain, attr_accessor :verify_data, :verify_signer, :verify_chain,
:verify_root, :only_trusted, :only_signed :verify_root, :only_trusted, :only_signed
@ -509,9 +547,9 @@ module Gem::Security
end end
end end
# ##
# No security policy: all package signature checks are disabled. # No security policy: all package signature checks are disabled.
#
NoSecurity = Policy.new( NoSecurity = Policy.new(
:verify_data => false, :verify_data => false,
:verify_signer => false, :verify_signer => false,
@ -521,14 +559,14 @@ module Gem::Security
:only_signed => false :only_signed => false
) )
# ##
# AlmostNo security policy: only verify that the signing certificate is the # AlmostNo security policy: only verify that the signing certificate is the
# one that actually signed the data. Make no attempt to verify the signing # one that actually signed the data. Make no attempt to verify the signing
# certificate chain. # certificate chain.
# #
# This policy is basically useless. better than nothing, but can still be # This policy is basically useless. better than nothing, but can still be
# easily spoofed, and is not recommended. # easily spoofed, and is not recommended.
#
AlmostNoSecurity = Policy.new( AlmostNoSecurity = Policy.new(
:verify_data => true, :verify_data => true,
:verify_signer => false, :verify_signer => false,
@ -538,13 +576,13 @@ module Gem::Security
:only_signed => false :only_signed => false
) )
# ##
# Low security policy: only verify that the signing certificate is actually # Low security policy: only verify that the signing certificate is actually
# the gem signer, and that the signing certificate is valid. # the gem signer, and that the signing certificate is valid.
# #
# This policy is better than nothing, but can still be easily spoofed, and # This policy is better than nothing, but can still be easily spoofed, and
# is not recommended. # is not recommended.
#
LowSecurity = Policy.new( LowSecurity = Policy.new(
:verify_data => true, :verify_data => true,
:verify_signer => true, :verify_signer => true,
@ -554,7 +592,7 @@ module Gem::Security
:only_signed => false :only_signed => false
) )
# ##
# Medium security policy: verify the signing certificate, verify the signing # Medium security policy: verify the signing certificate, verify the signing
# certificate chain all the way to the root certificate, and only trust root # certificate chain all the way to the root certificate, and only trust root
# certificates that we have explicitly allowed trust for. # certificates that we have explicitly allowed trust for.
@ -562,7 +600,7 @@ module Gem::Security
# This security policy is reasonable, but it allows unsigned packages, so a # This security policy is reasonable, but it allows unsigned packages, so a
# malicious person could simply delete the package signature and pass the # malicious person could simply delete the package signature and pass the
# gem off as unsigned. # gem off as unsigned.
#
MediumSecurity = Policy.new( MediumSecurity = Policy.new(
:verify_data => true, :verify_data => true,
:verify_signer => true, :verify_signer => true,
@ -572,7 +610,7 @@ module Gem::Security
:only_signed => false :only_signed => false
) )
# ##
# High security policy: only allow signed gems to be installed, verify the # High security policy: only allow signed gems to be installed, verify the
# signing certificate, verify the signing certificate chain all the way to # signing certificate, verify the signing certificate chain all the way to
# the root certificate, and only trust root certificates that we have # the root certificate, and only trust root certificates that we have
@ -580,7 +618,7 @@ module Gem::Security
# #
# This security policy is significantly more difficult to bypass, and offers # This security policy is significantly more difficult to bypass, and offers
# a reasonable guarantee that the contents of the gem have not been altered. # a reasonable guarantee that the contents of the gem have not been altered.
#
HighSecurity = Policy.new( HighSecurity = Policy.new(
:verify_data => true, :verify_data => true,
:verify_signer => true, :verify_signer => true,
@ -590,9 +628,9 @@ module Gem::Security
:only_signed => true :only_signed => true
) )
# ##
# Hash of configured security policies # Hash of configured security policies
#
Policies = { Policies = {
'NoSecurity' => NoSecurity, 'NoSecurity' => NoSecurity,
'AlmostNoSecurity' => AlmostNoSecurity, 'AlmostNoSecurity' => AlmostNoSecurity,
@ -601,25 +639,24 @@ module Gem::Security
'HighSecurity' => HighSecurity, 'HighSecurity' => HighSecurity,
} }
# ##
# Sign the cert cert with @signing_key and @signing_cert, using the digest # Sign the cert cert with @signing_key and @signing_cert, using the digest
# algorithm opt[:dgst_algo]. Returns the newly signed certificate. # algorithm opt[:dgst_algo]. Returns the newly signed certificate.
#
def self.sign_cert(cert, signing_key, signing_cert, opt = {}) def self.sign_cert(cert, signing_key, signing_cert, opt = {})
opt = OPT.merge(opt) opt = OPT.merge(opt)
# set up issuer information
cert.issuer = signing_cert.subject cert.issuer = signing_cert.subject
cert.sign(signing_key, opt[:dgst_algo].new) cert.sign signing_key, opt[:dgst_algo].new
cert cert
end end
# ##
# Make sure the trust directory exists. If it does exist, make sure it's # Make sure the trust directory exists. If it does exist, make sure it's
# actually a directory. If not, then create it with the appropriate # actually a directory. If not, then create it with the appropriate
# permissions. # permissions.
#
def self.verify_trust_dir(path, perms) def self.verify_trust_dir(path, perms)
# if the directory exists, then make sure it is in fact a directory. if # if the directory exists, then make sure it is in fact a directory. if
# it doesn't exist, then create it with the appropriate permissions # it doesn't exist, then create it with the appropriate permissions
@ -636,94 +673,99 @@ module Gem::Security
end end
end end
# ##
# Build a certificate from the given DN and private key. # Build a certificate from the given DN and private key.
#
def self.build_cert(name, key, opt = {}) def self.build_cert(name, key, opt = {})
Gem.ensure_ssl_available Gem.ensure_ssl_available
opt = OPT.merge(opt) opt = OPT.merge opt
# create new cert cert = OpenSSL::X509::Certificate.new
ret = OpenSSL::X509::Certificate.new
# populate cert attributes cert.not_after = Time.now + opt[:cert_age]
ret.version = 2 cert.not_before = Time.now
ret.serial = 0 cert.public_key = key.public_key
ret.public_key = key.public_key cert.serial = 0
ret.not_before = Time.now cert.subject = name
ret.not_after = Time.now + opt[:cert_age] cert.version = 2
ret.subject = name
# add certificate extensions ef = OpenSSL::X509::ExtensionFactory.new nil, cert
ef = OpenSSL::X509::ExtensionFactory.new(nil, ret)
ret.extensions = opt[:cert_exts].map { |k, v| ef.create_extension(k, v) }
# sign cert cert.extensions = opt[:cert_exts].map do |ext_name, value|
i_key, i_cert = opt[:issuer_key] || key, opt[:issuer_cert] || ret ef.create_extension ext_name, value
ret = sign_cert(ret, i_key, i_cert, opt)
# return cert
ret
end end
# i_key = opt[:issuer_key] || key
i_cert = opt[:issuer_cert] || cert
cert = sign_cert cert, i_key, i_cert, opt
cert
end
##
# Build a self-signed certificate for the given email address. # Build a self-signed certificate for the given email address.
#
def self.build_self_signed_cert(email_addr, opt = {}) def self.build_self_signed_cert(email_addr, opt = {})
Gem.ensure_ssl_available Gem.ensure_ssl_available
opt = OPT.merge(opt) opt = OPT.merge(opt)
path = { :key => nil, :cert => nil } path = { :key => nil, :cert => nil }
# split email address up name = email_to_name email_addr, opt[:munge_re]
cn, dcs = email_addr.split('@')
dcs = dcs.split('.')
# munge email CN and DCs key = opt[:key_algo].new opt[:key_size]
cn = cn.gsub(opt[:munge_re], '_')
dcs = dcs.map { |dc| dc.gsub(opt[:munge_re], '_') }
# create DN verify_trust_dir opt[:trust_dir], opt[:perms][:trust_dir]
name = "CN=#{cn}/" << dcs.map { |dc| "DC=#{dc}" }.join('/')
name = OpenSSL::X509::Name::parse(name)
# build private key if opt[:save_key] then
key = opt[:key_algo].new(opt[:key_size])
# method name pretty much says it all :)
verify_trust_dir(opt[:trust_dir], opt[:perms][:trust_dir])
# if we're saving the key, then write it out
if opt[:save_key]
path[:key] = opt[:save_key_path] || (opt[:output_fmt] % 'private_key') path[:key] = opt[:save_key_path] || (opt[:output_fmt] % 'private_key')
File.open(path[:key], 'wb') do |file|
file.chmod(opt[:perms][:signing_key]) open path[:key], 'wb' do |io|
file.write(key.to_pem) io.chmod opt[:perms][:signing_key]
io.write key.to_pem
end end
end end
# build self-signed public cert from key cert = build_cert name, key, opt
cert = build_cert(name, key, opt)
# if we're saving the cert, then write it out if opt[:save_cert] then
if opt[:save_cert]
path[:cert] = opt[:save_cert_path] || (opt[:output_fmt] % 'public_cert') path[:cert] = opt[:save_cert_path] || (opt[:output_fmt] % 'public_cert')
File.open(path[:cert], 'wb') do |file|
file.chmod(opt[:perms][:signing_cert]) open path[:cert], 'wb' do |file|
file.write(cert.to_pem) file.chmod opt[:perms][:signing_cert]
file.write cert.to_pem
end end
end end
# return key, cert, and paths (if applicable)
{ :key => key, :cert => cert, { :key => key, :cert => cert,
:key_path => path[:key], :cert_path => path[:cert] } :key_path => path[:key], :cert_path => path[:cert] }
end end
# ##
# Turns +email_address+ into an OpenSSL::X509::Name
def self.email_to_name email_address, munge_re
cn, dcs = email_address.split '@'
dcs = dcs.split '.'
cn = cn.gsub munge_re, '_'
dcs = dcs.map do |dc|
dc.gsub munge_re, '_'
end
name = "CN=#{cn}/" << dcs.map { |dc| "DC=#{dc}" }.join('/')
OpenSSL::X509::Name.parse name
end
##
# Add certificate to trusted cert list. # Add certificate to trusted cert list.
# #
# Note: At the moment these are stored in OPT[:trust_dir], although that # Note: At the moment these are stored in OPT[:trust_dir], although that
# directory may change in the future. # directory may change in the future.
#
def self.add_trusted_cert(cert, opt = {}) def self.add_trusted_cert(cert, opt = {})
opt = OPT.merge(opt) opt = OPT.merge(opt)
@ -743,11 +785,13 @@ module Gem::Security
nil nil
end end
# ##
# Basic OpenSSL-based package signing class. # Basic OpenSSL-based package signing class.
#
class Signer class Signer
attr_accessor :key, :cert_chain
attr_accessor :cert_chain
attr_accessor :key
def initialize(key, cert_chain) def initialize(key, cert_chain)
Gem.ensure_ssl_available Gem.ensure_ssl_available
@ -774,13 +818,14 @@ module Gem::Security
end end
end end
# ##
# Sign data with given digest algorithm # Sign data with given digest algorithm
#
def sign(data) def sign(data)
@key.sign(@algo.new, data) @key.sign(@algo.new, data)
end end
end end
end end

View file

@ -1,5 +1,10 @@
######################################################################
# 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 'webrick' require 'webrick'
require 'yaml'
require 'zlib' require 'zlib'
require 'erb' require 'erb'
@ -21,7 +26,6 @@ require 'rubygems/doc_manager'
# * legacy indexes: # * legacy indexes:
# * "/Marshal.#{Gem.marshal_version}" - Full SourceIndex dump of metadata # * "/Marshal.#{Gem.marshal_version}" - Full SourceIndex dump of metadata
# for installed gems # for installed gems
# * "/yaml" - YAML dump of metadata for installed gems - deprecated
# #
# == Usage # == Usage
# #
@ -429,18 +433,19 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
def self.run(options) def self.run(options)
new(options[:gemdir], options[:port], options[:daemon], new(options[:gemdir], options[:port], options[:daemon],
options[:addresses]).run options[:launch], options[:addresses]).run
end end
## ##
# Only the first directory in gem_dirs is used for serving gems # Only the first directory in gem_dirs is used for serving gems
def initialize(gem_dirs, port, daemon, addresses = nil) def initialize(gem_dirs, port, daemon, launch = nil, addresses = nil)
Socket.do_not_reverse_lookup = true Socket.do_not_reverse_lookup = true
@gem_dirs = Array gem_dirs @gem_dirs = Array gem_dirs
@port = port @port = port
@daemon = daemon @daemon = daemon
@launch = launch
@addresses = addresses @addresses = addresses
logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL
@server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger @server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger
@ -553,19 +558,6 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
add_date res add_date res
case req.request_uri.path case req.request_uri.path
when '/quick/index' then
res.body << @source_index.map { |name,| name }.sort.join("\n")
when '/quick/index.rz' then
index = @source_index.map { |name,| name }.sort.join("\n")
res['content-type'] = 'application/x-deflate'
res.body << Gem.deflate(index)
when '/quick/latest_index' then
index = @source_index.latest_specs.map { |spec| spec.full_name }
res.body << index.sort.join("\n")
when '/quick/latest_index.rz' then
index = @source_index.latest_specs.map { |spec| spec.full_name }
res['content-type'] = 'application/x-deflate'
res.body << Gem.deflate(index.sort.join("\n"))
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 dep = Gem::Dependency.new $2, $3
specs = @source_index.search dep specs = @source_index.search dep
@ -590,9 +582,6 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
elsif marshal_format then elsif marshal_format then
res['content-type'] = 'application/x-deflate' res['content-type'] = 'application/x-deflate'
res.body << Gem.deflate(Marshal.dump(specs.first)) res.body << Gem.deflate(Marshal.dump(specs.first))
else # deprecated YAML format
res['content-type'] = 'application/x-deflate'
res.body << Gem.deflate(specs.first.to_yaml)
end end
else else
raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
@ -675,6 +664,9 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
values = { "gem_count" => specs.size.to_s, "specs" => specs, values = { "gem_count" => specs.size.to_s, "specs" => specs,
"total_file_count" => total_file_count.to_s } "total_file_count" => total_file_count.to_s }
# suppress 1.9.3dev warning about unused variable
values = values
result = template.result binding result = template.result binding
res.body = result res.body = result
end end
@ -768,9 +760,6 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
WEBrick::Daemon.start if @daemon WEBrick::Daemon.start if @daemon
@server.mount_proc "/yaml", method(:yaml)
@server.mount_proc "/yaml.Z", method(:yaml)
@server.mount_proc "/Marshal.#{Gem.marshal_version}", method(:Marshal) @server.mount_proc "/Marshal.#{Gem.marshal_version}", method(:Marshal)
@server.mount_proc "/Marshal.#{Gem.marshal_version}.Z", method(:Marshal) @server.mount_proc "/Marshal.#{Gem.marshal_version}.Z", method(:Marshal)
@ -803,6 +792,8 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
trap("INT") { @server.shutdown; exit! } trap("INT") { @server.shutdown; exit! }
trap("TERM") { @server.shutdown; exit! } trap("TERM") { @server.shutdown; exit! }
launch if @launch
@server.start @server.start
end end
@ -833,26 +824,14 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end end
end end
def yaml(req, res) def launch
@source_index.refresh! listeners = @server.listeners.map{|l| l.addr[2] }
add_date res host = listeners.any?{|l| l == '0.0.0.0'} ? 'localhost' : listeners.first
index = @source_index.to_yaml say "Launching browser to http://#{host}:#{@port}"
if req.path =~ /Z$/ then system("#{@launch} http://#{host}:#{@port}")
res['content-type'] = 'application/x-deflate'
index = Gem.deflate index
else
res['content-type'] = 'text/plain'
end
if req.request_method == 'HEAD' then
res['content-length'] = index.length
return
end
res.body << index
end end
end end

View file

@ -1,18 +1,17 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'rubygems/user_interaction'
require 'rubygems/specification' require 'rubygems/specification'
# :stopdoc:
module Gem
autoload :SpecFetcher, 'rubygems/spec_fetcher'
end
# :startdoc:
## ##
# The SourceIndex object indexes all the gems available from a # The SourceIndex object indexes all the gems available from a
# particular source (e.g. a list of gem directories, or a remote # particular source (e.g. a list of gem directories, or a remote
@ -28,8 +27,6 @@ class Gem::SourceIndex
include Enumerable include Enumerable
include Gem::UserInteraction
attr_reader :gems # :nodoc: attr_reader :gems # :nodoc:
## ##
@ -38,8 +35,6 @@ class Gem::SourceIndex
attr_accessor :spec_dirs attr_accessor :spec_dirs
class << self class << self
include Gem::UserInteraction
## ##
# Factory method to construct a source index instance for a given # Factory method to construct a source index instance for a given
# path. # path.
@ -83,33 +78,7 @@ class Gem::SourceIndex
# loaded spec. # loaded spec.
def load_specification(file_name) def load_specification(file_name)
return nil unless file_name and File.exist? file_name Gem::Specification.load file_name
spec_code = if defined? Encoding then
File.read file_name, :encoding => 'UTF-8'
else
File.read file_name
end.untaint
begin
gemspec = eval spec_code, binding, file_name
if gemspec.is_a?(Gem::Specification)
gemspec.loaded_from = file_name
return gemspec
end
alert_warning "File '#{file_name}' does not evaluate to a gem specification"
rescue SignalException, SystemExit
raise
rescue SyntaxError => e
alert_warning e
alert_warning spec_code
rescue Exception => e
alert_warning "#{e.inspect}\n#{spec_code}"
alert_warning "Invalid .gemspec format in '#{file_name}'"
end
return nil
end end
end end
@ -150,7 +119,7 @@ class Gem::SourceIndex
spec_files = Dir.glob File.join(spec_dir, '*.gemspec') spec_files = Dir.glob File.join(spec_dir, '*.gemspec')
spec_files.each do |spec_file| spec_files.each do |spec_file|
gemspec = self.class.load_specification spec_file.untaint gemspec = Gem::Specification.load spec_file
add_spec gemspec if gemspec add_spec gemspec if gemspec
end end
end end
@ -275,8 +244,8 @@ class Gem::SourceIndex
## ##
# Find a gem by an exact match on the short name. # Find a gem by an exact match on the short name.
def find_name(gem_name, version_requirement = Gem::Requirement.default) def find_name(gem_name, requirement = Gem::Requirement.default)
dep = Gem::Dependency.new gem_name, version_requirement dep = Gem::Dependency.new gem_name, requirement
search dep search dep
end end
@ -290,7 +259,7 @@ class Gem::SourceIndex
# 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_only = false)
version_requirement = nil requirement = nil
only_platform = false only_platform = false
# TODO - Remove support and warning for legacy arguments after 2008/11 # TODO - Remove support and warning for legacy arguments after 2008/11
@ -300,10 +269,10 @@ class Gem::SourceIndex
case gem_pattern case gem_pattern
when Regexp then when Regexp then
version_requirement = platform_only || Gem::Requirement.default requirement = platform_only || Gem::Requirement.default
when Gem::Dependency then when Gem::Dependency then
only_platform = platform_only only_platform = platform_only
version_requirement = gem_pattern.requirement requirement = gem_pattern.requirement
gem_pattern = if Regexp === gem_pattern.name then gem_pattern = if Regexp === gem_pattern.name then
gem_pattern.name gem_pattern.name
elsif gem_pattern.name.empty? then elsif gem_pattern.name.empty? then
@ -312,17 +281,17 @@ class Gem::SourceIndex
/^#{Regexp.escape gem_pattern.name}$/ /^#{Regexp.escape gem_pattern.name}$/
end end
else else
version_requirement = platform_only || Gem::Requirement.default requirement = platform_only || Gem::Requirement.default
gem_pattern = /#{gem_pattern}/i gem_pattern = /#{gem_pattern}/i
end end
unless Gem::Requirement === version_requirement then unless Gem::Requirement === requirement then
version_requirement = Gem::Requirement.create version_requirement requirement = Gem::Requirement.create requirement
end end
specs = all_gems.values.select do |spec| specs = all_gems.values.select do |spec|
spec.name =~ gem_pattern and spec.name =~ gem_pattern and
version_requirement.satisfied_by? spec.version requirement.satisfied_by? spec.version
end end
if only_platform then if only_platform then
@ -354,19 +323,9 @@ class Gem::SourceIndex
latest_specs.each do |local| latest_specs.each do |local|
dependency = Gem::Dependency.new local.name, ">= #{local.version}" dependency = Gem::Dependency.new local.name, ">= #{local.version}"
begin
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
remotes = fetcher.find_matching dependency remotes = fetcher.find_matching dependency
remotes = remotes.map { |(_, version, _), _| version } remotes = remotes.map { |(_, version, _), _| version }
rescue Gem::RemoteFetcher::FetchError => e
raise unless fetcher.warn_legacy e do
require 'rubygems/source_info_cache'
specs = Gem::SourceInfoCache.search_with_source dependency, true
remotes = specs.map { |spec,| spec.version }
end
end
latest = remotes.sort.last latest = remotes.sort.last
@ -376,43 +335,6 @@ class Gem::SourceIndex
outdateds outdateds
end end
##
# Updates this SourceIndex from +source_uri+. If +all+ is false, only the
# latest gems are fetched.
def update(source_uri, all)
source_uri = URI.parse source_uri unless URI::Generic === source_uri
source_uri.path += '/' unless source_uri.path =~ /\/$/
use_incremental = false
begin
gem_names = fetch_quick_index source_uri, all
remove_extra gem_names
missing_gems = find_missing gem_names
return false if missing_gems.size.zero?
say "Missing metadata for #{missing_gems.size} gems" if
missing_gems.size > 0 and Gem.configuration.really_verbose
use_incremental = missing_gems.size <= Gem.configuration.bulk_threshold
rescue Gem::OperationNotSupportedError => ex
alert_error "Falling back to bulk fetch: #{ex.message}" if
Gem.configuration.really_verbose
use_incremental = false
end
if use_incremental then
update_with_missing(source_uri, missing_gems)
else
new_index = fetch_bulk_index(source_uri)
@gems.replace(new_index.gems)
end
true
end
def ==(other) # :nodoc: def ==(other) # :nodoc:
self.class === other and @gems == other.gems self.class === other and @gems == other.gems
end end
@ -421,166 +343,6 @@ class Gem::SourceIndex
Marshal.dump(self) Marshal.dump(self)
end end
private
def fetcher
require 'rubygems/remote_fetcher'
Gem::RemoteFetcher.fetcher
end
def fetch_index_from(source_uri)
@fetch_error = nil
indexes = %W[
Marshal.#{Gem.marshal_version}.Z
Marshal.#{Gem.marshal_version}
yaml.Z
yaml
]
indexes.each do |name|
spec_data = nil
index = source_uri + name
begin
spec_data = fetcher.fetch_path index
spec_data = unzip(spec_data) if name =~ /\.Z$/
if name =~ /Marshal/ then
return Marshal.load(spec_data)
else
return YAML.load(spec_data)
end
rescue => e
if Gem.configuration.really_verbose then
alert_error "Unable to fetch #{name}: #{e.message}"
end
@fetch_error = e
end
end
nil
end
def fetch_bulk_index(source_uri)
say "Bulk updating Gem source index for: #{source_uri}" if
Gem.configuration.verbose
index = fetch_index_from(source_uri)
if index.nil? then
raise Gem::RemoteSourceException,
"Error fetching remote gem cache: #{@fetch_error}"
end
@fetch_error = nil
index
end
##
# Get the quick index needed for incremental updates.
def fetch_quick_index(source_uri, all)
index = all ? 'index' : 'latest_index'
zipped_index = fetcher.fetch_path source_uri + "quick/#{index}.rz"
unzip(zipped_index).split("\n")
rescue ::Exception => e
unless all then
say "Latest index not found, using quick index" if
Gem.configuration.really_verbose
fetch_quick_index source_uri, true
else
raise Gem::OperationNotSupportedError,
"No quick index found: #{e.message}"
end
end
##
# Make a list of full names for all the missing gemspecs.
def find_missing(spec_names)
unless defined? @originals then
@originals = {}
each do |full_name, spec|
@originals[spec.original_name] = spec
end
end
spec_names.find_all { |full_name|
@originals[full_name].nil?
}
end
def remove_extra(spec_names)
dictionary = spec_names.inject({}) { |h, k| h[k] = true; h }
each do |name, spec|
remove_spec name unless dictionary.include? spec.original_name
end
end
##
# Unzip the given string.
def unzip(string)
require 'zlib'
Gem.inflate string
end
##
# Tries to fetch Marshal representation first, then YAML
def fetch_single_spec(source_uri, spec_name)
@fetch_error = nil
begin
marshal_uri = source_uri + "quick/Marshal.#{Gem.marshal_version}/#{spec_name}.gemspec.rz"
zipped = fetcher.fetch_path marshal_uri
return Marshal.load(unzip(zipped))
rescue => ex
@fetch_error = ex
if Gem.configuration.really_verbose then
say "unable to fetch marshal gemspec #{marshal_uri}: #{ex.class} - #{ex}"
end
end
begin
yaml_uri = source_uri + "quick/#{spec_name}.gemspec.rz"
zipped = fetcher.fetch_path yaml_uri
return YAML.load(unzip(zipped))
rescue => ex
@fetch_error = ex
if Gem.configuration.really_verbose then
say "unable to fetch YAML gemspec #{yaml_uri}: #{ex.class} - #{ex}"
end
end
nil
end
##
# Update the cached source index with the missing names.
def update_with_missing(source_uri, missing_names)
progress = ui.progress_reporter(missing_names.size,
"Updating metadata for #{missing_names.size} gems from #{source_uri}")
missing_names.each do |spec_name|
gemspec = fetch_single_spec(source_uri, spec_name)
if gemspec.nil? then
ui.say "Failed to download spec #{spec_name} from #{source_uri}:\n" \
"\t#{@fetch_error.message}"
else
add_spec gemspec
progress.updated spec_name
end
@fetch_error = nil
end
progress.done
progress.count
end
end end
# :stopdoc: # :stopdoc:

View file

@ -1,395 +0,0 @@
require 'fileutils'
require 'rubygems'
require 'rubygems/source_info_cache_entry'
require 'rubygems/user_interaction'
##
# SourceInfoCache stores a copy of the gem index for each gem source.
#
# There are two possible cache locations, the system cache and the user cache:
# * The system cache is preferred if it is writable or can be created.
# * The user cache is used otherwise
#
# Once a cache is selected, it will be used for all operations.
# SourceInfoCache will not switch between cache files dynamically.
#
# Cache data is a Hash mapping a source URI to a SourceInfoCacheEntry.
#
#--
# To keep things straight, this is how the cache objects all fit together:
#
# Gem::SourceInfoCache
# @cache_data = {
# source_uri => Gem::SourceInfoCacheEntry
# @size = source index size
# @source_index = Gem::SourceIndex
# ...
# }
class Gem::SourceInfoCache
include Gem::UserInteraction
##
# The singleton Gem::SourceInfoCache. If +all+ is true, a full refresh will
# be performed if the singleton instance is being initialized.
def self.cache(all = false)
return @cache if @cache
@cache = new
@cache.refresh all if Gem.configuration.update_sources
@cache
end
def self.cache_data
cache.cache_data
end
##
# The name of the system cache file.
def self.latest_system_cache_file
File.join File.dirname(system_cache_file),
"latest_#{File.basename system_cache_file}"
end
##
# The name of the latest user cache file.
def self.latest_user_cache_file
File.join File.dirname(user_cache_file),
"latest_#{File.basename user_cache_file}"
end
##
# Reset all singletons, discarding any changes.
def self.reset
@cache = nil
@system_cache_file = nil
@user_cache_file = nil
end
##
# Search all source indexes. See Gem::SourceInfoCache#search.
def self.search(*args)
cache.search(*args)
end
##
# Search all source indexes returning the source_uri. See
# Gem::SourceInfoCache#search_with_source.
def self.search_with_source(*args)
cache.search_with_source(*args)
end
##
# The name of the system cache file. (class method)
def self.system_cache_file
@system_cache_file ||= Gem.default_system_source_cache_dir
end
##
# The name of the user cache file.
def self.user_cache_file
@user_cache_file ||=
ENV['GEMCACHE'] || Gem.default_user_source_cache_dir
end
def initialize # :nodoc:
@cache_data = nil
@cache_file = nil
@dirty = false
@only_latest = true
end
##
# The most recent cache data.
def cache_data
return @cache_data if @cache_data
cache_file # HACK writable check
@only_latest = true
@cache_data = read_cache_data latest_cache_file
@cache_data
end
##
# The name of the cache file.
def cache_file
return @cache_file if @cache_file
@cache_file = (try_file(system_cache_file) or
try_file(user_cache_file) or
raise "unable to locate a writable cache file")
end
##
# Write the cache to a local file (if it is dirty).
def flush
write_cache if @dirty
@dirty = false
end
def latest_cache_data
latest_cache_data = {}
cache_data.each do |repo, sice|
latest = sice.source_index.latest_specs
new_si = Gem::SourceIndex.new
new_si.add_specs(*latest)
latest_sice = Gem::SourceInfoCacheEntry.new new_si, sice.size
latest_cache_data[repo] = latest_sice
end
latest_cache_data
end
##
# The name of the latest cache file.
def latest_cache_file
File.join File.dirname(cache_file), "latest_#{File.basename cache_file}"
end
##
# The name of the latest system cache file.
def latest_system_cache_file
self.class.latest_system_cache_file
end
##
# The name of the latest user cache file.
def latest_user_cache_file
self.class.latest_user_cache_file
end
##
# Merges the complete cache file into this Gem::SourceInfoCache.
def read_all_cache_data
if @only_latest then
@only_latest = false
all_data = read_cache_data cache_file
cache_data.update all_data do |source_uri, latest_sice, all_sice|
all_sice.source_index.gems.update latest_sice.source_index.gems
Gem::SourceInfoCacheEntry.new all_sice.source_index, latest_sice.size
end
begin
refresh true
rescue Gem::RemoteFetcher::FetchError
end
end
end
##
# Reads cached data from +file+.
def read_cache_data(file)
# Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small
data = open file, 'rb' do |fp| fp.read end
cache_data = Marshal.load data
cache_data.each do |url, sice|
next unless sice.is_a?(Hash)
update
cache = sice['cache']
size = sice['size']
if cache.is_a?(Gem::SourceIndex) and size.is_a?(Numeric) then
new_sice = Gem::SourceInfoCacheEntry.new cache, size
cache_data[url] = new_sice
else # irreperable, force refetch.
reset_cache_for url, cache_data
end
end
cache_data
rescue Errno::ENOENT
{}
rescue => e
if Gem.configuration.really_verbose then
say "Exception during cache_data handling: #{e.class} - #{e}"
say "Cache file was: #{file}"
say "\t#{e.backtrace.join "\n\t"}"
end
{}
end
##
# Refreshes each source in the cache from its repository. If +all+ is
# false, only latest gems are updated.
def refresh(all)
Gem.sources.each do |source_uri|
cache_entry = cache_data[source_uri]
if cache_entry.nil? then
cache_entry = Gem::SourceInfoCacheEntry.new nil, 0
cache_data[source_uri] = cache_entry
end
update if cache_entry.refresh source_uri, all
end
flush
end
def reset_cache_for(url, cache_data)
say "Reseting cache for #{url}" if Gem.configuration.really_verbose
sice = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0
sice.refresh url, false # HACK may be unnecessary, see ::cache and #refresh
cache_data[url] = sice
cache_data
end
def reset_cache_data
@cache_data = nil
@only_latest = true
end
##
# Force cache file to be reset, useful for integration testing of rubygems
def reset_cache_file
@cache_file = nil
end
##
# Searches all source indexes. See Gem::SourceIndex#search for details on
# +pattern+ and +platform_only+. If +all+ is set to true, the full index
# will be loaded before searching.
def search(pattern, platform_only = false, all = false)
read_all_cache_data if all
cache_data.map do |source_uri, sic_entry|
next unless Gem.sources.include? source_uri
# TODO - Remove this gunk after 2008/11
unless pattern.kind_of? Gem::Dependency then
pattern = Gem::Dependency.new pattern, Gem::Requirement.default
end
sic_entry.source_index.search pattern, platform_only
end.flatten.compact
end
##
# Searches all source indexes for +pattern+. If +only_platform+ is true,
# only gems matching Gem.platforms will be selected. Returns an Array of
# pairs containing the Gem::Specification found and the source_uri it was
# found at.
def search_with_source(pattern, only_platform = false, all = false)
read_all_cache_data if all
results = []
cache_data.map do |source_uri, sic_entry|
next unless Gem.sources.include? source_uri
# TODO - Remove this gunk after 2008/11
unless pattern.kind_of?(Gem::Dependency)
pattern = Gem::Dependency.new(pattern, Gem::Requirement.default)
end
sic_entry.source_index.search(pattern, only_platform).each do |spec|
results << [spec, source_uri]
end
end
results
end
##
# Set the source info cache data directly. This is mainly used for unit
# testing when we don't want to read a file system to grab the cached source
# index information. The +hash+ should map a source URL into a
# SourceInfoCacheEntry.
def set_cache_data(hash)
@cache_data = hash
update
end
##
# The name of the system cache file.
def system_cache_file
self.class.system_cache_file
end
##
# Determine if +path+ is a candidate for a cache file. Returns +path+ if
# it is, nil if not.
def try_file(path)
return path if File.writable? path
return nil if File.exist? path
dir = File.dirname path
unless File.exist? dir then
begin
FileUtils.mkdir_p dir
rescue RuntimeError, SystemCallError
return nil
end
end
return path if File.writable? dir
nil
end
##
# Mark the cache as updated (i.e. dirty).
def update
@dirty = true
end
##
# The name of the user cache file.
def user_cache_file
self.class.user_cache_file
end
##
# Write data to the proper cache files.
def write_cache
if not File.exist?(cache_file) or not @only_latest then
open cache_file, 'wb' do |io|
io.write Marshal.dump(cache_data)
end
end
open latest_cache_file, 'wb' do |io|
io.write Marshal.dump(latest_cache_data)
end
end
reset
end

View file

@ -1,56 +0,0 @@
require 'rubygems'
require 'rubygems/source_index'
require 'rubygems/remote_fetcher'
##
# Entries held by a SourceInfoCache.
class Gem::SourceInfoCacheEntry
##
# The source index for this cache entry.
attr_reader :source_index
##
# The size of the source entry. Used to determine if the source index has
# changed.
attr_reader :size
##
# Create a cache entry.
def initialize(si, size)
@source_index = si || Gem::SourceIndex.new({})
@size = size
@all = false
end
def refresh(source_uri, all)
begin
marshal_uri = URI.join source_uri.to_s, "Marshal.#{Gem.marshal_version}"
remote_size = Gem::RemoteFetcher.fetcher.fetch_size marshal_uri
rescue Gem::RemoteSourceException
yaml_uri = URI.join source_uri.to_s, 'yaml'
remote_size = Gem::RemoteFetcher.fetcher.fetch_size yaml_uri
end
# TODO Use index_signature instead of size?
return false if @size == remote_size and @all
updated = @source_index.update source_uri, all
@size = remote_size
@all = all
updated
end
def ==(other) # :nodoc:
self.class === other and
@size == other.size and
@source_index == other.source_index
end
end

View file

@ -1,9 +1,13 @@
require 'zlib' ######################################################################
require 'fileutils' # 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/remote_fetcher' require 'rubygems/remote_fetcher'
require 'rubygems/user_interaction' require 'rubygems/user_interaction'
require 'rubygems/errors' require 'rubygems/errors'
require 'rubygems/text'
## ##
# SpecFetcher handles metadata updates from remote gem repositories. # SpecFetcher handles metadata updates from remote gem repositories.
@ -11,6 +15,13 @@ require 'rubygems/errors'
class Gem::SpecFetcher class Gem::SpecFetcher
include Gem::UserInteraction include Gem::UserInteraction
include Gem::Text
FILES = {
:all => 'specs',
:latest => 'latest_specs',
:prerelease => 'prerelease_specs',
}
## ##
# The SpecFetcher cache dir. # The SpecFetcher cache dir.
@ -43,6 +54,8 @@ class Gem::SpecFetcher
end end
def initialize def initialize
require 'fileutils'
@dir = File.join Gem.user_home, '.gem', 'specs' @dir = File.join Gem.user_home, '.gem', 'specs'
@update_cache = File.stat(Gem.user_home).uid == Process.uid @update_cache = File.stat(Gem.user_home).uid == Process.uid
@ -50,6 +63,12 @@ class Gem::SpecFetcher
@latest_specs = {} @latest_specs = {}
@prerelease_specs = {} @prerelease_specs = {}
@caches = {
:latest => @latest_specs,
:prerelease => @prerelease_specs,
:all => @specs
}
@fetcher = Gem::RemoteFetcher.fetcher @fetcher = Gem::RemoteFetcher.fetcher
end end
@ -74,14 +93,6 @@ class Gem::SpecFetcher
end end
return [ss, errors] return [ss, errors]
rescue Gem::RemoteFetcher::FetchError => e
raise unless warn_legacy e do
require 'rubygems/source_info_cache'
return [Gem::SourceInfoCache.search_with_source(dependency,
matching_platform, all), nil]
end
end end
def fetch(*args) def fetch(*args)
@ -160,26 +171,31 @@ class Gem::SpecFetcher
end end
## ##
# Returns Array of gem repositories that were generated with RubyGems less # Suggests a gem based on the supplied +gem_name+. Returns a string
# than 1.2. # of the gem name if an approximate match can be found or nil
# otherwise. NOTE: for performance reasons only gems which exactly
# match the first character of +gem_name+ are considered.
def legacy_repos def suggest_gems_from_name gem_name
Gem.sources.reject do |source_uri| gem_name = gem_name.downcase
source_uri = URI.parse source_uri max = gem_name.size / 2
spec_path = source_uri + "specs.#{Gem.marshal_version}.gz" specs = list.values.flatten(1) # flatten(1) is 1.8.7 and up
begin matches = specs.map { |name, version, platform|
@fetcher.fetch_size spec_path next unless Gem::Platform.match platform
rescue Gem::RemoteFetcher::FetchError
begin distance = levenshtein_distance gem_name, name.downcase
@fetcher.fetch_size(source_uri + 'yaml') # re-raise if non-repo
rescue Gem::RemoteFetcher::FetchError next if distance >= max
alert_error "#{source_uri} does not appear to be a repository"
raise return [name] if distance == 0
end
false [name, distance]
end }.compact
end
matches = matches.uniq.sort_by { |name, dist| dist }
matches.first(5).map { |name, dist| name }
end end
## ##
@ -198,14 +214,8 @@ class Gem::SpecFetcher
end end
list = {} list = {}
file = FILES[type]
file = { :latest => 'latest_specs', cache = @caches[type]
:prerelease => 'prerelease_specs',
:all => 'specs' }[type]
cache = { :latest => @latest_specs,
:prerelease => @prerelease_specs,
:all => @specs }[type]
Gem.sources.each do |source_uri| Gem.sources.each do |source_uri|
source_uri = URI.parse source_uri source_uri = URI.parse source_uri
@ -273,28 +283,5 @@ class Gem::SpecFetcher
specs specs
end end
##
# Warn about legacy repositories if +exception+ indicates only legacy
# repositories are available, and yield to the block. Returns false if the
# exception indicates some other FetchError.
def warn_legacy(exception)
uri = exception.uri.to_s
if uri =~ /specs\.#{Regexp.escape Gem.marshal_version}\.gz$/ then
alert_warning <<-EOF
RubyGems 1.2+ index not found for:
\t#{legacy_repos.join "\n\t"}
RubyGems will revert to legacy indexes degrading performance.
EOF
yield
return true
end
false
end
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -498,17 +504,37 @@ class Gem::Specification
end end
## ##
# Loads ruby format gemspec from +filename+ # Loads Ruby format gemspec from +file+.
def self.load(filename) def self.load file
gemspec = nil return unless file && File.file?(file)
raise "NESTED Specification.load calls not allowed!" if @@gather
@@gather = proc { |gs| gemspec = gs } file = file.dup.untaint
data = File.read filename
eval data, nil, filename code = if defined? Encoding
gemspec File.read file, :encoding => "UTF-8"
ensure else
@@gather = nil File.read file
end
code.untaint
begin
spec = eval code, binding, file
if Gem::Specification === spec
spec.loaded_from = file
return spec
end
warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)."
rescue SignalException, SystemExit
raise
rescue SyntaxError, Exception => e
warn "Invalid gemspec in [#{file}]: #{e}"
end
nil
end end
## ##
@ -672,8 +698,7 @@ class Gem::Specification
def hash # :nodoc: def hash # :nodoc:
@@attributes.inject(0) { |hash_code, (name, _)| @@attributes.inject(0) { |hash_code, (name, _)|
n = self.send(name).hash hash_code ^ self.send(name).hash
hash_code + n
} }
end end
@ -765,7 +790,6 @@ class Gem::Specification
result << nil result << nil
result << " if s.respond_to? :specification_version then" result << " if s.respond_to? :specification_version then"
result << " current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION"
result << " s.specification_version = #{specification_version}" result << " s.specification_version = #{specification_version}"
result << nil result << nil
@ -909,7 +933,7 @@ class Gem::Specification
# Warnings # Warnings
%w[author description email homepage rubyforge_project summary].each do |attribute| %w[author description email homepage summary].each do |attribute|
value = self.send attribute value = self.send attribute
alert_warning "no #{attribute} specified" if value.nil? or value.empty? alert_warning "no #{attribute} specified" if value.nil? or value.empty?
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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 'tempfile' require 'tempfile'
require 'rubygems' require 'rubygems'
require 'rubygems/remote_fetcher' require 'rubygems/remote_fetcher'

View file

@ -1,3 +1,9 @@
######################################################################
# 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'
## ##
@ -26,5 +32,40 @@ module Gem::Text
result.join("\n").gsub(/^/, " " * indent) result.join("\n").gsub(/^/, " " * indent)
end end
# This code is based directly on the Text gem implementation
# Returns a value representing the "cost" of transforming str1 into str2
def levenshtein_distance str1, str2
s = str1
t = str2
n = s.length
m = t.length
max = n/2
return m if (0 == n)
return n if (0 == m)
return n if (n - m).abs > max
d = (0..m).to_a
x = nil
n.times do |i|
e = i+1
m.times do |j|
cost = (s[i] == t[j]) ? 0 : 1
x = [
d[j+1] + 1, # insertion
e + 1, # deletion
d[j] + cost # substitution
].min
d[j] = e
e = x
end
d[m] = x
end
return x
end
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
@ -218,6 +224,7 @@ class Gem::StreamUI
result result
end end
if RUBY_VERSION >= "1.9" then
## ##
# Ask for a password. Does not echo response to terminal. # Ask for a password. Does not echo response to terminal.
@ -233,6 +240,51 @@ class Gem::StreamUI
password.chomp! if password password.chomp! if password
password password
end end
else
##
# Ask for a password. Does not echo response to terminal.
def ask_for_password(question)
return nil if not @ins.tty?
@outs.print(question + " ")
@outs.flush
Gem.win_platform? ? ask_for_password_on_windows : ask_for_password_on_unix
end
##
# Asks for a password that works on windows. Ripped from the Heroku gem.
def ask_for_password_on_windows
require "Win32API"
char = nil
password = ''
while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
break if char == 10 || char == 13 # received carriage return or newline
if char == 127 || char == 8 # backspace and delete
password.slice!(-1, 1)
else
password << char.chr
end
end
puts
password
end
##
# Asks for a password that works on unix
def ask_for_password_on_unix
system "stty -echo"
password = @ins.gets
password.chomp! if password
system "stty echo"
password
end
end
## ##
# Display a statement. # Display a statement.
@ -384,6 +436,76 @@ class Gem::StreamUI
end end
end end
##
# Return a download reporter object chosen from the current verbosity
def download_reporter(*args)
case Gem.configuration.verbose
when nil, false
SilentDownloadReporter.new(@outs, *args)
else
VerboseDownloadReporter.new(@outs, *args)
end
end
##
# An absolutely silent download reporter.
class SilentDownloadReporter
def initialize(out_stream, *args)
end
def fetch(filename, filesize)
end
def update(current)
end
def done
end
end
##
# A progress reporter that prints out messages about the current progress.
class VerboseDownloadReporter
attr_reader :file_name, :total_bytes, :progress
def initialize(out_stream, *args)
@out = out_stream
@progress = 0
end
def fetch(file_name, total_bytes)
@file_name, @total_bytes = file_name, total_bytes
update_display(false)
end
def update(bytes)
new_progress = ((bytes.to_f * 100) / total_bytes.to_f).ceil
return if new_progress == @progress
@progress = new_progress
update_display
end
def done
@progress = 100
update_display(true, true)
end
private
def update_display(show_progress = true, new_line = false)
return unless @out.tty?
if show_progress
@out.print "\rFetching: %s (%3d%%)" % [@file_name, @progress]
else
@out.print "Fetching: %s" % @file_name
end
@out.puts if new_line
end
end
end end
## ##

View file

@ -1,21 +1,18 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'find'
require 'digest'
require 'rubygems/format' require 'rubygems/format'
require 'rubygems/installer' require 'rubygems/installer'
begin
gem 'test-unit'
rescue Gem::LoadError
# Ignore - use the test-unit library that's part of the standard library
end
## ##
# Validator performs various gem file and gem database validation # Validator performs various gem file and gem database validation
@ -23,6 +20,11 @@ class Gem::Validator
include Gem::UserInteraction include Gem::UserInteraction
def initialize
require 'find'
require 'digest'
end
## ##
# Given a gem file's contents, validates against its own MD5 checksum # Given a gem file's contents, validates against its own MD5 checksum
# gem_data:: [String] Contents of the gem file # gem_data:: [String] Contents of the gem file
@ -165,79 +167,6 @@ class Gem::Validator
errors errors
end end
=begin
if RUBY_VERSION < '1.9' then
class TestRunner
def initialize(suite, ui)
@suite = suite
@ui = ui
end
def self.run(suite, ui)
require 'test/unit/ui/testrunnermediator'
return new(suite, ui).start
end
def start
@mediator = Test::Unit::UI::TestRunnerMediator.new(@suite)
@mediator.add_listener(Test::Unit::TestResult::FAULT, &method(:add_fault))
return @mediator.run_suite
end
def add_fault(fault)
if Gem.configuration.verbose then
@ui.say fault.long_display
end
end
end
autoload :TestRunner, 'test/unit/ui/testrunnerutilities'
end
=end
##
# Runs unit tests for a given gem specification
def unit_test(gem_spec)
start_dir = Dir.pwd
Dir.chdir(gem_spec.full_gem_path)
$: << gem_spec.full_gem_path
# XXX: why do we need this gem_spec when we've already got 'spec'?
test_files = gem_spec.test_files
if test_files.empty? then
say "There are no unit tests to run for #{gem_spec.full_name}"
return nil
end
gem gem_spec.name, "= #{gem_spec.version.version}"
test_files.each do |f| require f end
=begin
if RUBY_VERSION < '1.9' then
suite = Test::Unit::TestSuite.new("#{gem_spec.name}-#{gem_spec.version}")
ObjectSpace.each_object(Class) do |klass|
suite << klass.suite if (klass < Test::Unit::TestCase)
end
result = TestRunner.run suite, ui
alert_error result.to_s unless result.passed?
else
result = MiniTest::Unit.new
result.run
end
=end
result = MiniTest::Unit.new
result.run
result
ensure
Dir.chdir(start_dir)
end
def remove_leading_dot_dir(path) def remove_leading_dot_dir(path)
path.sub(/^\.\//, "") path.sub(/^\.\//, "")
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
## ##
# The Version class processes string versions into comparable # The Version class processes string versions into comparable
# values. A version string should normally be a series of numbers # values. A version string should normally be a series of numbers
@ -8,15 +14,18 @@
# #
# If any part contains letters (currently only a-z are supported) then # If any part contains letters (currently only a-z are supported) then
# that version is considered prerelease. Versions with a prerelease # that version is considered prerelease. Versions with a prerelease
# part in the Nth part sort less than versions with N-1 parts. Prerelease # part in the Nth part sort less than versions with N-1
# parts are sorted alphabetically using the normal Ruby string sorting # parts. Prerelease parts are sorted alphabetically using the normal
# rules. # Ruby string sorting rules. If a prerelease part contains both
# letters and numbers, it will be broken into multiple parts to
# provide expected sort behavior (1.0.a10 becomes 1.0.a.10, and is
# greater than 1.0.a9).
# #
# Prereleases sort between real releases (newest to oldest): # Prereleases sort between real releases (newest to oldest):
# #
# 1. 1.0 # 1. 1.0
# 2. 1.0.b # 2. 1.0.b1
# 3. 1.0.a # 3. 1.0.a.2
# 4. 0.9 # 4. 0.9
# #
# == How Software Changes # == How Software Changes
@ -138,6 +147,8 @@
# "~> 3.5.0" 3.5.0 ... 3.6 # "~> 3.5.0" 3.5.0 ... 3.6
class Gem::Version class Gem::Version
autoload :Requirement, 'rubygems/requirement'
include Comparable include Comparable
VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc: VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc:
@ -184,15 +195,13 @@ class Gem::Version
@version = version.to_s @version = version.to_s
@version.strip! @version.strip!
segments # prime @segments
end end
## ##
# Return a new version object where the next to the last revision # Return a new version object where the next to the last revision
# number is one greater (e.g., 5.3.1 => 5.4). # number is one greater (e.g., 5.3.1 => 5.4).
# #
# Pre-release (alpha) parts, e.g, 5.3.1.b2 => 5.4, are ignored. # Pre-release (alpha) parts, e.g, 5.3.1.b.2 => 5.4, are ignored.
def bump def bump
segments = self.segments.dup segments = self.segments.dup
@ -208,7 +217,7 @@ class Gem::Version
# same precision. Version "1.0" is not the same as version "1". # same precision. Version "1.0" is not the same as version "1".
def eql? other def eql? other
self.class === other and segments == other.segments self.class === other and @version == other.version
end end
def hash # :nodoc: def hash # :nodoc:
@ -239,7 +248,7 @@ class Gem::Version
# A version is considered a prerelease if it contains a letter. # A version is considered a prerelease if it contains a letter.
def prerelease? def prerelease?
@prerelease ||= segments.any? { |s| String === s } @prerelease ||= @version =~ /[a-zA-Z]/
end end
def pretty_print q # :nodoc: def pretty_print q # :nodoc:
@ -260,12 +269,10 @@ class Gem::Version
def segments # :nodoc: def segments # :nodoc:
# @segments is lazy so it can pick up @version values that come # segments is lazy so it can pick up version values that come from
# from old marshaled versions, which don't go through # old marshaled versions, which don't go through marshal_load.
# marshal_load. +segments+ is called in +initialize+ to "prime
# the pump" in normal cases.
@segments ||= @version.scan(/[0-9a-z]+/i).map do |s| @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
/^\d+$/ =~ s ? s.to_i : s /^\d+$/ =~ s ? s.to_i : s
end end
end end
@ -284,23 +291,33 @@ class Gem::Version
end end
## ##
# Compares this version with +other+ returning -1, 0, or 1 if the other # Compares this version with +other+ returning -1, 0, or 1 if the
# version is larger, the same, or smaller than this one. # other version is larger, the same, or smaller than this
# one. Attempts to compare to something that's not a
# <tt>Gem::Version</tt> return +nil+.
def <=> other def <=> other
return 1 unless other # HACK: comparable with nil? why? return unless Gem::Version === other
return nil unless self.class === other return 0 if @version == other.version
lhsize = segments.size lhsegments = segments
rhsize = other.segments.size rhsegments = other.segments
lhsize = lhsegments.size
rhsize = rhsegments.size
limit = (lhsize > rhsize ? lhsize : rhsize) - 1 limit = (lhsize > rhsize ? lhsize : rhsize) - 1
0.upto(limit) do |i| i = 0
lhs, rhs = segments[i] || 0, other.segments[i] || 0
while i <= limit
lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
i += 1
next if lhs == rhs
return -1 if String === lhs && Numeric === rhs return -1 if String === lhs && Numeric === rhs
return 1 if Numeric === lhs && String === rhs return 1 if Numeric === lhs && String === rhs
return lhs <=> rhs if lhs != rhs
return lhs <=> rhs
end end
return 0 return 0

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.

View file

@ -1,3 +1,9 @@
######################################################################
# 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.
######################################################################
#-- #--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved. # All rights reserved.

View file

@ -0,0 +1,6 @@
######################################################################
# 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.
######################################################################

View file

@ -1,3 +1,9 @@
######################################################################
# 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'
require 'minitest/unit' require 'minitest/unit'
require 'test/insure_session' require 'test/insure_session'

View file

@ -1,4 +1,10 @@
require_relative 'gemutilities' ######################################################################
# 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 "test/rubygems/gemutilities"
require 'rubygems/installer' require 'rubygems/installer'
class Gem::Installer class Gem::Installer

View file

@ -1,4 +1,10 @@
require_relative 'gemutilities' ######################################################################
# 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 "test/rubygems/gemutilities"
require 'rubygems/package' require 'rubygems/package'
class TarTestCase < RubyGemTestCase class TarTestCase < RubyGemTestCase
@ -120,8 +126,10 @@ class TarTestCase < RubyGemTestCase
def util_entry(tar) def util_entry(tar)
io = TempIO.new tar io = TempIO.new tar
header = Gem::Package::TarHeader.from io header = Gem::Package::TarHeader.from io
entry = Gem::Package::TarReader::Entry.new header, io
Gem::Package::TarReader::Entry.new header, io
end end
def util_dir_entry def util_dir_entry

View file

@ -1,8 +1,18 @@
######################################################################
# 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.
######################################################################
at_exit { $SAFE = 1 } at_exit { $SAFE = 1 }
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) # $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
if defined? Gem::QuickLoader
Gem::QuickLoader.load_full_rubygems_library
else
require 'rubygems' require 'rubygems'
end
require 'fileutils' require 'fileutils'
require 'minitest/autorun' require 'minitest/autorun'
require 'tmpdir' require 'tmpdir'
@ -11,6 +21,8 @@ require 'rubygems/package'
require 'rubygems/test_utilities' require 'rubygems/test_utilities'
require 'pp' require 'pp'
require 'yaml' require 'yaml'
require 'zlib'
begin begin
YAML::ENGINE.yamler = 'psych' YAML::ENGINE.yamler = 'psych'
rescue LoadError rescue LoadError
@ -23,11 +35,11 @@ end
require 'rdoc/rdoc' require 'rdoc/rdoc'
require_relative 'mockgemui' require "test/rubygems/mockgemui"
module Gem module Gem
def self.searcher=(searcher) def self.searcher=(searcher)
MUTEX.synchronize do @searcher = searcher end @searcher = searcher
end end
def self.source_index=(si) def self.source_index=(si)
@ -38,6 +50,10 @@ module Gem
@@win_platform = val @@win_platform = val
end end
def self.ruby= ruby
@ruby = ruby
end
module DefaultUserInteraction module DefaultUserInteraction
@ui = MockGemUi.new @ui = MockGemUi.new
end end
@ -53,15 +69,19 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
def setup def setup
super super
@orig_gem_home = ENV['GEM_HOME']
@orig_gem_path = ENV['GEM_PATH']
@ui = MockGemUi.new @ui = 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
@tempdir = File.join tmpdir, "test_rubygems_#{$$}.#{Time.now.to_i}"
else
@tempdir = File.join tmpdir, "test_rubygems_#{$$}" @tempdir = File.join tmpdir, "test_rubygems_#{$$}"
end
@tempdir.untaint @tempdir.untaint
@gemhome = File.join @tempdir, "gemhome" @gemhome = File.join @tempdir, 'gemhome'
@gemcache = File.join(@gemhome, "source_cache")
@usrcache = File.join(@gemhome, ".gem", "user_cache")
@latest_usrcache = File.join(@gemhome, ".gem", "latest_user_cache")
@userhome = File.join @tempdir, 'userhome' @userhome = File.join @tempdir, 'userhome'
Gem.ensure_gem_subdirectories @gemhome Gem.ensure_gem_subdirectories @gemhome
@ -80,7 +100,6 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
FileUtils.mkdir_p @gemhome FileUtils.mkdir_p @gemhome
FileUtils.mkdir_p @userhome FileUtils.mkdir_p @userhome
ENV['GEMCACHE'] = @usrcache
Gem.use_paths(@gemhome) Gem.use_paths(@gemhome)
Gem.loaded_specs.clear Gem.loaded_specs.clear
@ -131,9 +150,13 @@ class RubyGemTestCase < 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
def teardown def teardown
$LOAD_PATH.replace @orig_LOAD_PATH
Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY
Gem::ConfigMap[:arch] = @orig_arch Gem::ConfigMap[:arch] = @orig_arch
@ -141,15 +164,15 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
Gem::RemoteFetcher.fetcher = nil Gem::RemoteFetcher.fetcher = nil
end end
FileUtils.rm_rf @tempdir FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES']
ENV.delete 'GEMCACHE' ENV['GEM_HOME'] = @orig_gem_home
ENV.delete 'GEM_HOME' ENV['GEM_PATH'] = @orig_gem_path
ENV.delete 'GEM_PATH'
Gem.clear_paths Gem.clear_paths
Gem.class_eval { @ruby = ruby } if ruby = @orig_ruby _ = @orig_ruby
Gem.class_eval { @ruby = _ } if _
if @orig_ENV_HOME then if @orig_ENV_HOME then
ENV['HOME'] = @orig_ENV_HOME ENV['HOME'] = @orig_ENV_HOME
@ -171,6 +194,14 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
Gem::Installer.new(gem, :wrappers => true).install Gem::Installer.new(gem, :wrappers => true).install
end end
def uninstall_gem gem
require 'rubygems/uninstaller'
uninstaller = Gem::Uninstaller.new gem.name, :executables => true,
:user_install => true
uninstaller.uninstall
end
def mu_pp(obj) def mu_pp(obj)
s = '' s = ''
s = PP.pp obj, s s = PP.pp obj, s
@ -283,7 +314,15 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
Gem.source_index.refresh! Gem.source_index.refresh!
end end
def util_gem(name, version, &block) def util_gem(name, version, deps = nil, &block)
if deps then # fuck you eric
block = proc do |s|
deps.each do |n, req|
s.add_dependency n, (req || '>= 0')
end
end
end
spec = quick_gem(name, version, &block) spec = quick_gem(name, version, &block)
util_build_gem spec util_build_gem spec
@ -500,13 +539,12 @@ Also, a list:
def build_rake_in def build_rake_in
gem_ruby = Gem.ruby gem_ruby = Gem.ruby
ruby = @@ruby Gem.ruby = @@ruby
Gem.module_eval {@ruby = ruby}
env_rake = ENV["rake"] env_rake = ENV["rake"]
ENV["rake"] = @@rake ENV["rake"] = @@rake
yield @@rake yield @@rake
ensure ensure
Gem.module_eval {@ruby = gem_ruby} Gem.ruby = gem_ruby
if env_rake if env_rake
ENV["rake"] = env_rake ENV["rake"] = env_rake
else else
@ -515,11 +553,11 @@ Also, a list:
end end
def self.rubybin def self.rubybin
if ruby = ENV["RUBY"] ruby = ENV["RUBY"]
return ruby return ruby if ruby
end
ruby = "ruby" ruby = "ruby"
rubyexe = ruby+".exe" rubyexe = "#{ruby}.exe"
3.times do 3.times do
if File.exist? ruby and File.executable? ruby and !File.directory? ruby if File.exist? ruby and File.executable? ruby and !File.directory? ruby
return File.expand_path(ruby) return File.expand_path(ruby)
@ -529,12 +567,12 @@ Also, a list:
end end
ruby = File.join("..", ruby) ruby = File.join("..", ruby)
end end
begin begin
require "rbconfig" require "rbconfig"
File.join( File.join(RbConfig::CONFIG["bindir"],
RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] +
RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"] RbConfig::CONFIG["EXEEXT"])
)
rescue LoadError rescue LoadError
"ruby" "ruby"
end end

View file

@ -1,3 +1,9 @@
######################################################################
# 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'
def install_session def install_session

View file

@ -1,3 +1,9 @@
######################################################################
# 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 'stringio' require 'stringio'
require 'rubygems/user_interaction' require 'rubygems/user_interaction'

View file

@ -1,2 +1,8 @@
######################################################################
# 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.
######################################################################
TestGem::TEST_PLUGIN_EXCEPTION = :loaded TestGem::TEST_PLUGIN_EXCEPTION = :loaded
raise Exception.new('boom') raise Exception.new('boom')

View file

@ -1 +1,7 @@
######################################################################
# 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.
######################################################################
TestGem::TEST_PLUGIN_LOAD = :loaded TestGem::TEST_PLUGIN_LOAD = :loaded

View file

@ -1,2 +1,8 @@
######################################################################
# 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.
######################################################################
TestGem::TEST_PLUGIN_STANDARDERROR = :loaded TestGem::TEST_PLUGIN_STANDARDERROR = :loaded
raise StandardError.new('boom') raise StandardError.new('boom')

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