mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* lib/rubygems: Update to RubyGems 2.4.1 master(713ab65)
Complete history at: https://github.com/rubygems/rubygems/blob/master/History.txt#L3-L216 * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47582 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									e548c09d42
								
							
						
					
					
						commit
						4de117a615
					
				
					 153 changed files with 5400 additions and 981 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,11 @@
 | 
			
		|||
Sun Sep 14 12:29:02 2014  SHIBATA Hiroshi  <shibata.hiroshi@gmail.com>
 | 
			
		||||
 | 
			
		||||
	* lib/rubygems:  Update to RubyGems 2.4.1 master(713ab65)
 | 
			
		||||
	  Complete history at:
 | 
			
		||||
	  https://github.com/rubygems/rubygems/blob/master/History.txt#L3-L216
 | 
			
		||||
 | 
			
		||||
	* test/rubygems:  ditto.
 | 
			
		||||
 | 
			
		||||
Sun Sep 14 11:03:24 2014  Aaron Patterson <aaron@tenderlovemaking.com>
 | 
			
		||||
 | 
			
		||||
	* ext/psych/lib/psych.rb: update version
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,9 +6,10 @@
 | 
			
		|||
#++
 | 
			
		||||
 | 
			
		||||
require 'rbconfig'
 | 
			
		||||
require 'thread'
 | 
			
		||||
 | 
			
		||||
module Gem
 | 
			
		||||
  VERSION = '2.2.2'
 | 
			
		||||
  VERSION = '2.4.1'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# Must be first since it unloads the prelude from 1.9.2
 | 
			
		||||
| 
						 | 
				
			
			@ -56,8 +57,8 @@ require 'rubygems/errors'
 | 
			
		|||
# RubyGems defaults are stored in rubygems/defaults.rb.  If you're packaging
 | 
			
		||||
# RubyGems or implementing Ruby you can change RubyGems' defaults.
 | 
			
		||||
#
 | 
			
		||||
# For RubyGems packagers, provide lib/rubygems/operating_system.rb and
 | 
			
		||||
# override any defaults from lib/rubygems/defaults.rb.
 | 
			
		||||
# For RubyGems packagers, provide lib/rubygems/defaults/operating_system.rb
 | 
			
		||||
# and override any defaults from lib/rubygems/defaults.rb.
 | 
			
		||||
#
 | 
			
		||||
# For Ruby implementers, provide lib/rubygems/defaults/#{RUBY_ENGINE}.rb and
 | 
			
		||||
# override any defaults from lib/rubygems/defaults.rb.
 | 
			
		||||
| 
						 | 
				
			
			@ -156,6 +157,7 @@ module Gem
 | 
			
		|||
 | 
			
		||||
  @configuration = nil
 | 
			
		||||
  @loaded_specs = {}
 | 
			
		||||
  LOADED_SPECS_MUTEX = Mutex.new
 | 
			
		||||
  @path_to_default_spec_map = {}
 | 
			
		||||
  @platforms = []
 | 
			
		||||
  @ruby = nil
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +300,7 @@ module Gem
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The path the the data directory specified by the gem name.  If the
 | 
			
		||||
  # The path to the data directory specified by the gem name.  If the
 | 
			
		||||
  # package is not available as a gem, return nil.
 | 
			
		||||
 | 
			
		||||
  def self.datadir(gem_name)
 | 
			
		||||
| 
						 | 
				
			
			@ -544,9 +546,9 @@ module Gem
 | 
			
		|||
  #   Fetching: minitest-3.0.1.gem (100%)
 | 
			
		||||
  #   => [#<Gem::Specification:0x1013b4528 @name="minitest", ...>]
 | 
			
		||||
 | 
			
		||||
  def self.install name, version = Gem::Requirement.default, **options
 | 
			
		||||
  def self.install name, version = Gem::Requirement.default, *options
 | 
			
		||||
    require "rubygems/dependency_installer"
 | 
			
		||||
    inst = Gem::DependencyInstaller.new(**options)
 | 
			
		||||
    inst = Gem::DependencyInstaller.new(*options)
 | 
			
		||||
    inst.install name, version
 | 
			
		||||
    inst.installed_gems
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -995,19 +997,31 @@ module Gem
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Looks for gem dependency files (gem.deps.rb, Gemfile, Isolate) from the
 | 
			
		||||
  # current directory up and activates the gems in the first file found.
 | 
			
		||||
  # Looks for a gem dependency file at +path+ and activates the gems in the
 | 
			
		||||
  # file if found.  If the file is not found an ArgumentError is raised.
 | 
			
		||||
  #
 | 
			
		||||
  # If +path+ is not given the RUBYGEMS_GEMDEPS environment variable is used,
 | 
			
		||||
  # but if no file is found no exception is raised.
 | 
			
		||||
  #
 | 
			
		||||
  # If '-' is given for +path+ RubyGems searches up from the current working
 | 
			
		||||
  # directory for gem dependency files (gem.deps.rb, Gemfile, Isolate) and
 | 
			
		||||
  # activates the gems in the first one found.
 | 
			
		||||
  #
 | 
			
		||||
  # You can run this automatically when rubygems starts.  To enable, set
 | 
			
		||||
  # the <code>RUBYGEMS_GEMDEPS</code> environment variable to either the path
 | 
			
		||||
  # of your Gemfile or "-" to auto-discover in parent directories.
 | 
			
		||||
  # of your gem dependencies file or "-" to auto-discover in parent
 | 
			
		||||
  # directories.
 | 
			
		||||
  #
 | 
			
		||||
  # NOTE: Enabling automatic discovery on multiuser systems can lead to
 | 
			
		||||
  # execution of arbitrary code when used from directories outside your
 | 
			
		||||
  # control.
 | 
			
		||||
 | 
			
		||||
  def self.use_gemdeps
 | 
			
		||||
    return unless path = ENV['RUBYGEMS_GEMDEPS']
 | 
			
		||||
  def self.use_gemdeps path = nil
 | 
			
		||||
    raise_exception = path
 | 
			
		||||
 | 
			
		||||
    path ||= ENV['RUBYGEMS_GEMDEPS']
 | 
			
		||||
    return unless path
 | 
			
		||||
 | 
			
		||||
    path = path.dup
 | 
			
		||||
 | 
			
		||||
    if path == "-" then
 | 
			
		||||
| 
						 | 
				
			
			@ -1025,7 +1039,11 @@ module Gem
 | 
			
		|||
 | 
			
		||||
    path.untaint
 | 
			
		||||
 | 
			
		||||
    return unless File.file? path
 | 
			
		||||
    unless File.file? path then
 | 
			
		||||
      return unless raise_exception
 | 
			
		||||
 | 
			
		||||
      raise ArgumentError, "Unable to find gem dependencies file at #{path}"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    rs = Gem::RequestSet.new
 | 
			
		||||
    rs.load_gemdeps path
 | 
			
		||||
| 
						 | 
				
			
			@ -1035,6 +1053,10 @@ module Gem
 | 
			
		|||
      sp.activate
 | 
			
		||||
      sp
 | 
			
		||||
    end
 | 
			
		||||
  rescue Gem::LoadError, Gem::UnsatisfiableDependencyError => e
 | 
			
		||||
    warn e.message
 | 
			
		||||
    warn "You may need to `gem install -g` to install missing gems"
 | 
			
		||||
    warn ""
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class << self
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,7 +126,7 @@ class Gem::AvailableSet
 | 
			
		|||
    dep = req.dependency
 | 
			
		||||
 | 
			
		||||
    match = @set.find_all do |t|
 | 
			
		||||
      dep.matches_spec? t.spec
 | 
			
		||||
      dep.match? t.spec
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    match.map do |t|
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,11 @@ class Gem::BasicSpecification
 | 
			
		|||
 | 
			
		||||
  attr_writer :extension_dir # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Is this specification ignored for activation purposes?
 | 
			
		||||
 | 
			
		||||
  attr_writer :ignored # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The path this gemspec was loaded from.  This attribute is not persisted.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +58,16 @@ class Gem::BasicSpecification
 | 
			
		|||
  # Return true if this spec can require +file+.
 | 
			
		||||
 | 
			
		||||
  def contains_requirable_file? file
 | 
			
		||||
    build_extensions
 | 
			
		||||
    if instance_variable_defined?(:@ignored) or
 | 
			
		||||
       instance_variable_defined?('@ignored') then
 | 
			
		||||
      return false
 | 
			
		||||
    elsif missing_extensions? then
 | 
			
		||||
      @ignored = true
 | 
			
		||||
 | 
			
		||||
      warn "Ignoring #{full_name} because its extensions are not built.  " +
 | 
			
		||||
           "Try: gem pristine #{full_name}"
 | 
			
		||||
      return false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    suffixes = Gem.suffixes
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -120,11 +134,11 @@ class Gem::BasicSpecification
 | 
			
		|||
  # activated.
 | 
			
		||||
 | 
			
		||||
  def full_require_paths
 | 
			
		||||
    full_paths = @require_paths.map do |path|
 | 
			
		||||
    full_paths = raw_require_paths.map do |path|
 | 
			
		||||
      File.join full_gem_path, path
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    full_paths.unshift extension_dir unless @extensions.empty?
 | 
			
		||||
    full_paths.unshift extension_dir unless @extensions.nil? || @extensions.empty?
 | 
			
		||||
 | 
			
		||||
    full_paths
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +190,7 @@ class Gem::BasicSpecification
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def raw_require_paths # :nodoc:
 | 
			
		||||
    @require_paths
 | 
			
		||||
    Array(@require_paths)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -197,13 +211,9 @@ class Gem::BasicSpecification
 | 
			
		|||
  #   spec.require_path = '.'
 | 
			
		||||
 | 
			
		||||
  def require_paths
 | 
			
		||||
    return @require_paths if @extensions.empty?
 | 
			
		||||
    return raw_require_paths if @extensions.nil? || @extensions.empty?
 | 
			
		||||
 | 
			
		||||
    relative_extension_dir =
 | 
			
		||||
      File.join '..', '..', 'extensions', Gem::Platform.local.to_s,
 | 
			
		||||
                Gem.extension_api_version, full_name
 | 
			
		||||
 | 
			
		||||
    [relative_extension_dir].concat @require_paths
 | 
			
		||||
    [extension_dir].concat raw_require_paths
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,6 +148,8 @@ class Gem::Command
 | 
			
		|||
 | 
			
		||||
  ##
 | 
			
		||||
  # Display to the user that a gem couldn't be found and reasons why
 | 
			
		||||
  #--
 | 
			
		||||
  # TODO: replace +domain+ with a parameter to suppress suggestions
 | 
			
		||||
 | 
			
		||||
  def show_lookup_failure(gem_name, version, errors, domain)
 | 
			
		||||
    if errors and !errors.empty?
 | 
			
		||||
| 
						 | 
				
			
			@ -557,7 +559,8 @@ basic help message containing pointers to more information.
 | 
			
		|||
  Further help:
 | 
			
		||||
    gem help commands            list all 'gem' commands
 | 
			
		||||
    gem help examples            show some examples of usage
 | 
			
		||||
    gem help platforms           show information about platforms
 | 
			
		||||
    gem help gem_dependencies    gem dependencies file guide
 | 
			
		||||
    gem help platforms           gem platforms guide
 | 
			
		||||
    gem help <COMMAND>           show help on COMMAND
 | 
			
		||||
                                   (e.g. 'gem help install')
 | 
			
		||||
    gem server                   present a web page at
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,7 @@ class Gem::CommandManager
 | 
			
		|||
    :list,
 | 
			
		||||
    :lock,
 | 
			
		||||
    :mirror,
 | 
			
		||||
    :open,
 | 
			
		||||
    :outdated,
 | 
			
		||||
    :owner,
 | 
			
		||||
    :pristine,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,9 +129,8 @@ class Gem::Commands::CertCommand < Gem::Command
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def build_key # :nodoc:
 | 
			
		||||
    if options[:key] then
 | 
			
		||||
      options[:key]
 | 
			
		||||
    else
 | 
			
		||||
    return options[:key] if options[:key]
 | 
			
		||||
 | 
			
		||||
    passphrase = ask_for_password 'Passphrase for your Private Key:'
 | 
			
		||||
    say "\n"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +145,6 @@ class Gem::Commands::CertCommand < Gem::Command
 | 
			
		|||
 | 
			
		||||
    return key, key_path
 | 
			
		||||
  end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def certificates_matching filter
 | 
			
		||||
    return enum_for __method__, filter unless block_given?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,10 +67,10 @@ If no gems are named all gems in GEM_HOME are cleaned.
 | 
			
		|||
 | 
			
		||||
    say "Clean Up Complete"
 | 
			
		||||
 | 
			
		||||
    if Gem.configuration.really_verbose then
 | 
			
		||||
    verbose do
 | 
			
		||||
      skipped = @default_gems.map { |spec| spec.full_name }
 | 
			
		||||
 | 
			
		||||
      say "Skipped default gems: #{skipped.join ', '}"
 | 
			
		||||
      "Skipped default gems: #{skipped.join ', '}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,8 @@ class Gem::Commands::ContentsCommand < Gem::Command
 | 
			
		|||
 | 
			
		||||
  def initialize
 | 
			
		||||
    super 'contents', 'Display the contents of the installed gems',
 | 
			
		||||
          :specdirs => [], :lib_only => false, :prefix => true
 | 
			
		||||
          :specdirs => [], :lib_only => false, :prefix => true,
 | 
			
		||||
          :show_install_dir => false
 | 
			
		||||
 | 
			
		||||
    add_version_option
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +33,11 @@ class Gem::Commands::ContentsCommand < Gem::Command
 | 
			
		|||
      options[:prefix] = prefix
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    add_option(      '--[no-]show-install-dir',
 | 
			
		||||
               'Show only the gem install dir') do |show, options|
 | 
			
		||||
      options[:show_install_dir] = show
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @path_kind = nil
 | 
			
		||||
    @spec_dirs = nil
 | 
			
		||||
    @version   = nil
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +71,12 @@ prefix or only the files that are requireable.
 | 
			
		|||
    names = gem_names
 | 
			
		||||
 | 
			
		||||
    names.each do |name|
 | 
			
		||||
      found = gem_contents name
 | 
			
		||||
      found =
 | 
			
		||||
        if options[:show_install_dir] then
 | 
			
		||||
          gem_install_dir name
 | 
			
		||||
        else
 | 
			
		||||
          gem_contents name
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
      terminate_interaction 1 unless found or names.length > 1
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +126,16 @@ prefix or only the files that are requireable.
 | 
			
		|||
    true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def gem_install_dir name
 | 
			
		||||
    spec = spec_for name
 | 
			
		||||
 | 
			
		||||
    return false unless spec
 | 
			
		||||
 | 
			
		||||
    say spec.gem_dir
 | 
			
		||||
 | 
			
		||||
    true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def gem_names # :nodoc:
 | 
			
		||||
    if options[:all] then
 | 
			
		||||
      Gem::Specification.map(&:name)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def arguments # :nodoc:
 | 
			
		||||
    "GEMNAME       name of gem to show dependencies for"
 | 
			
		||||
    "REGEXP        show dependencies for gems whose names start with REGEXP"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def defaults_str # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +50,7 @@ use with other commands.
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def usage # :nodoc:
 | 
			
		||||
    "#{program_name} GEMNAME"
 | 
			
		||||
    "#{program_name} REGEXP"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def fetch_remote_specs dependency # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,8 +28,9 @@ The RubyGems environment can be controlled through command line arguments,
 | 
			
		|||
gemrc files, environment variables and built-in defaults.
 | 
			
		||||
 | 
			
		||||
Command line argument defaults and some RubyGems defaults can be set in a
 | 
			
		||||
~/.gemrc file for individual users and a /etc/gemrc for all users. These
 | 
			
		||||
files are YAML files with the following YAML keys:
 | 
			
		||||
~/.gemrc file for individual users and a gemrc in the SYSTEM CONFIGURATION
 | 
			
		||||
DIRECTORY for all users. These files are YAML files with the following YAML
 | 
			
		||||
keys:
 | 
			
		||||
 | 
			
		||||
  :sources: A YAML array of remote gem repositories to install gems from
 | 
			
		||||
  :verbose: Verbosity of the gem command. false, true, and :really are the
 | 
			
		||||
| 
						 | 
				
			
			@ -120,6 +121,8 @@ lib/rubygems/defaults/operating_system.rb
 | 
			
		|||
 | 
			
		||||
    out << "  - SPEC CACHE DIRECTORY: #{Gem.spec_cache_dir}\n"
 | 
			
		||||
 | 
			
		||||
    out << "  - SYSTEM CONFIGURATION DIRECTORY: #{Gem::ConfigFile::SYSTEM_CONFIG_PATH}\n"
 | 
			
		||||
 | 
			
		||||
    out << "  - RUBYGEMS PLATFORMS:\n"
 | 
			
		||||
    Gem.platforms.each do |platform|
 | 
			
		||||
      out << "    - #{platform}\n"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,183 @@ Some examples of 'gem' usage.
 | 
			
		|||
    gem update --system
 | 
			
		||||
  EOF
 | 
			
		||||
 | 
			
		||||
  GEM_DEPENDENCIES = <<-EOF
 | 
			
		||||
A gem dependencies file allows installation of a consistent set of gems across
 | 
			
		||||
multiple environments.  The RubyGems implementation is designed to be
 | 
			
		||||
compatible with Bundler's Gemfile format.  You can see additional
 | 
			
		||||
documentation on the format at:
 | 
			
		||||
 | 
			
		||||
  http://bundler.io
 | 
			
		||||
 | 
			
		||||
RubyGems automatically looks for these gem dependencies files:
 | 
			
		||||
 | 
			
		||||
* gem.deps.rb
 | 
			
		||||
* Gemfile
 | 
			
		||||
* Isolate
 | 
			
		||||
 | 
			
		||||
These files are looked up automatically using `gem install -g`, or you can
 | 
			
		||||
specify a custom file.
 | 
			
		||||
 | 
			
		||||
When the RUBYGEMS_GEMDEPS environment variable is set to a gem dependencies
 | 
			
		||||
file the gems from that file will be activated at startup time.  Set it to a
 | 
			
		||||
specific filename or to "-" to have RubyGems automatically discover the gem
 | 
			
		||||
dependencies file by walking up from the current directory.
 | 
			
		||||
 | 
			
		||||
You can also activate gem dependencies at program startup using
 | 
			
		||||
Gem.use_gemdeps.
 | 
			
		||||
 | 
			
		||||
NOTE: Enabling automatic discovery on multiuser systems can lead to execution
 | 
			
		||||
of arbitrary code when used from directories outside your control.
 | 
			
		||||
 | 
			
		||||
Gem Dependencies
 | 
			
		||||
================
 | 
			
		||||
 | 
			
		||||
Use #gem to declare which gems you directly depend upon:
 | 
			
		||||
 | 
			
		||||
  gem 'rake'
 | 
			
		||||
 | 
			
		||||
To depend on a specific set of versions:
 | 
			
		||||
 | 
			
		||||
  gem 'rake', '~> 10.3', '>= 10.3.2'
 | 
			
		||||
 | 
			
		||||
RubyGems will require the gem name when activating the gem using
 | 
			
		||||
the RUBYGEMS_GEMDEPS environment variable or Gem::use_gemdeps.  Use the
 | 
			
		||||
require: option to override this behavior if the gem does not have a file of
 | 
			
		||||
that name or you don't want to require those files:
 | 
			
		||||
 | 
			
		||||
  gem 'my_gem', require: 'other_file'
 | 
			
		||||
 | 
			
		||||
To prevent RubyGems from requiring any files use:
 | 
			
		||||
 | 
			
		||||
  gem 'my_gem', require: false
 | 
			
		||||
 | 
			
		||||
To load dependencies from a .gemspec file:
 | 
			
		||||
 | 
			
		||||
  gemspec
 | 
			
		||||
 | 
			
		||||
RubyGems looks for the first .gemspec file in the current directory.  To
 | 
			
		||||
override this use the name: option:
 | 
			
		||||
 | 
			
		||||
  gemspec name: 'specific_gem'
 | 
			
		||||
 | 
			
		||||
To look in a different directory use the path: option:
 | 
			
		||||
 | 
			
		||||
  gemspec name: 'specific_gem', path: 'gemspecs'
 | 
			
		||||
 | 
			
		||||
To depend on a gem unpacked into a local directory:
 | 
			
		||||
 | 
			
		||||
  gem 'modified_gem', path: 'vendor/modified_gem'
 | 
			
		||||
 | 
			
		||||
To depend on a gem from git:
 | 
			
		||||
 | 
			
		||||
  gem 'private_gem', git: 'git@my.company.example:private_gem.git'
 | 
			
		||||
 | 
			
		||||
To depend on a gem from github:
 | 
			
		||||
 | 
			
		||||
  gem 'private_gem', github: 'my_company/private_gem'
 | 
			
		||||
 | 
			
		||||
To depend on a gem from a github gist:
 | 
			
		||||
 | 
			
		||||
  gem 'bang', gist: '1232884'
 | 
			
		||||
 | 
			
		||||
Git, github and gist support the ref:, branch: and tag: options to specify a
 | 
			
		||||
commit reference or hash, branch or tag respectively to use for the gem.
 | 
			
		||||
 | 
			
		||||
Setting the submodules: option to true for git, github and gist dependencies
 | 
			
		||||
causes fetching of submodules when fetching the repository.
 | 
			
		||||
 | 
			
		||||
You can depend on multiple gems from a single repository with the git method:
 | 
			
		||||
 | 
			
		||||
  git 'https://github.com/rails/rails.git' do
 | 
			
		||||
    gem 'activesupport'
 | 
			
		||||
    gem 'activerecord'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
Gem Sources
 | 
			
		||||
===========
 | 
			
		||||
 | 
			
		||||
RubyGems uses the default sources for regular `gem install` for gem
 | 
			
		||||
dependencies files.  Unlike bundler, you do need to specify a source.
 | 
			
		||||
 | 
			
		||||
You can override the sources used for downloading gems with:
 | 
			
		||||
 | 
			
		||||
  source 'https://gem_server.example'
 | 
			
		||||
 | 
			
		||||
You may specify multiple sources.  Unlike bundler the prepend: option is not
 | 
			
		||||
supported. Sources are used in-order, to prepend a source place it at the
 | 
			
		||||
front of the list.
 | 
			
		||||
 | 
			
		||||
Gem Platform
 | 
			
		||||
============
 | 
			
		||||
 | 
			
		||||
You can restrict gem dependencies to specific platforms with the #platform
 | 
			
		||||
and #platforms methods:
 | 
			
		||||
 | 
			
		||||
  platform :ruby_21 do
 | 
			
		||||
    gem 'debugger'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
See the bundler Gemfile manual page for a list of platforms supported in a gem
 | 
			
		||||
dependencies file.:
 | 
			
		||||
 | 
			
		||||
  http://bundler.io/v1.6/man/gemfile.5.html
 | 
			
		||||
 | 
			
		||||
Ruby Version and Engine Dependency
 | 
			
		||||
==================================
 | 
			
		||||
 | 
			
		||||
You can specifiy the version, engine and engine version of ruby to use with
 | 
			
		||||
your gem dependencies file.  If you are not running the specified version
 | 
			
		||||
RubyGems will raise an exception.
 | 
			
		||||
 | 
			
		||||
To depend on a specific version of ruby:
 | 
			
		||||
 | 
			
		||||
  ruby '2.1.2'
 | 
			
		||||
 | 
			
		||||
To depend on a specific ruby engine:
 | 
			
		||||
 | 
			
		||||
  ruby '1.9.3', engine: 'jruby'
 | 
			
		||||
 | 
			
		||||
To depend on a specific ruby engine version:
 | 
			
		||||
 | 
			
		||||
  ruby '1.9.3', engine: 'jruby', engine_version: '1.7.11'
 | 
			
		||||
 | 
			
		||||
Grouping Dependencies
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
Gem dependencies may be placed in groups that can be excluded from install.
 | 
			
		||||
Dependencies required for development or testing of your code may be excluded
 | 
			
		||||
when installed in a production environment.
 | 
			
		||||
 | 
			
		||||
A #gem dependency may be placed in a group using the group: option:
 | 
			
		||||
 | 
			
		||||
  gem 'minitest', group: :test
 | 
			
		||||
 | 
			
		||||
To install dependencies from a gemfile without specific groups use the
 | 
			
		||||
`--without` option for `gem install -g`:
 | 
			
		||||
 | 
			
		||||
  $ gem install -g --without test
 | 
			
		||||
 | 
			
		||||
The group: option also accepts multiple groups if the gem fits in multiple
 | 
			
		||||
categories.
 | 
			
		||||
 | 
			
		||||
Multiple groups may be excluded during install by comma-separating the groups for `--without` or by specifying `--without` multiple times.
 | 
			
		||||
 | 
			
		||||
The #group method can also be used to place gems in groups:
 | 
			
		||||
 | 
			
		||||
  group :test do
 | 
			
		||||
    gem 'minitest'
 | 
			
		||||
    gem 'minitest-emoji'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
The #group method allows multiple groups.
 | 
			
		||||
 | 
			
		||||
The #gemspec development dependencies are placed in the :development group by
 | 
			
		||||
default.  This may be overriden with the :development_group option:
 | 
			
		||||
 | 
			
		||||
  gemspec development_group: :other
 | 
			
		||||
 | 
			
		||||
  EOF
 | 
			
		||||
 | 
			
		||||
  PLATFORMS = <<-'EOF'
 | 
			
		||||
RubyGems platforms are composed of three parts, a CPU, an OS, and a
 | 
			
		||||
version.  These values are taken from values in rbconfig.rb.  You can view
 | 
			
		||||
| 
						 | 
				
			
			@ -90,6 +267,16 @@ When building platform gems, set the platform in the gem specification to
 | 
			
		|||
Gem::Platform::CURRENT.  This will correctly mark the gem with your ruby's
 | 
			
		||||
platform.
 | 
			
		||||
  EOF
 | 
			
		||||
 | 
			
		||||
  # NOTE when updating also update Gem::Command::HELP
 | 
			
		||||
 | 
			
		||||
  SUBCOMMANDS = [
 | 
			
		||||
    ["commands",         :show_commands],
 | 
			
		||||
    ["options",          Gem::Command::HELP],
 | 
			
		||||
    ["examples",         EXAMPLES],
 | 
			
		||||
    ["gem_dependencies", GEM_DEPENDENCIES],
 | 
			
		||||
    ["platforms",        PLATFORMS],
 | 
			
		||||
  ]
 | 
			
		||||
  # :startdoc:
 | 
			
		||||
 | 
			
		||||
  def initialize
 | 
			
		||||
| 
						 | 
				
			
			@ -98,15 +285,6 @@ platform.
 | 
			
		|||
    @command_manager = Gem::CommandManager.instance
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def arguments # :nodoc:
 | 
			
		||||
    args = <<-EOF
 | 
			
		||||
      commands      List all 'gem' commands
 | 
			
		||||
      examples      Show examples of 'gem' usage
 | 
			
		||||
      <command>     Show specific help for <command>
 | 
			
		||||
    EOF
 | 
			
		||||
    return args.gsub(/^\s+/, '')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def usage # :nodoc:
 | 
			
		||||
    "#{program_name} ARGUMENT"
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -114,19 +292,20 @@ platform.
 | 
			
		|||
  def execute
 | 
			
		||||
    arg = options[:args][0]
 | 
			
		||||
 | 
			
		||||
    if begins? "commands", arg then
 | 
			
		||||
      show_commands
 | 
			
		||||
    _, help = SUBCOMMANDS.find do |command,|
 | 
			
		||||
      begins? command, arg
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    elsif begins? "options", arg then
 | 
			
		||||
      say Gem::Command::HELP
 | 
			
		||||
    if help then
 | 
			
		||||
      if Symbol === help then
 | 
			
		||||
        send help
 | 
			
		||||
      else
 | 
			
		||||
        say help
 | 
			
		||||
      end
 | 
			
		||||
      return
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    elsif begins? "examples", arg then
 | 
			
		||||
      say EXAMPLES
 | 
			
		||||
 | 
			
		||||
    elsif begins? "platforms", arg then
 | 
			
		||||
      say PLATFORMS
 | 
			
		||||
 | 
			
		||||
    elsif options[:help] then
 | 
			
		||||
    if options[:help] then
 | 
			
		||||
      show_help
 | 
			
		||||
 | 
			
		||||
    elsif arg then
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,8 @@ class Gem::Commands::InstallCommand < Gem::Command
 | 
			
		|||
  def initialize
 | 
			
		||||
    defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({
 | 
			
		||||
      :format_executable => false,
 | 
			
		||||
      :lock              => true,
 | 
			
		||||
      :suggest_alternate => true,
 | 
			
		||||
      :version           => Gem::Requirement.default,
 | 
			
		||||
      :without_groups    => [],
 | 
			
		||||
    })
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +71,16 @@ class Gem::Commands::InstallCommand < Gem::Command
 | 
			
		|||
      o[:explain] = v
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    add_option(:"Install/Update", '--[no-]lock',
 | 
			
		||||
               'Create a lock file (when used with -g/--file)') do |v,o|
 | 
			
		||||
      o[:lock] = v
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    add_option(:"Install/Update", '--[no-]suggestions',
 | 
			
		||||
               'Suggest alternates when gems are not found') do |v,o|
 | 
			
		||||
      o[:suggest_alternate] = v
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @installed_specs = []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +90,7 @@ class Gem::Commands::InstallCommand < Gem::Command
 | 
			
		|||
 | 
			
		||||
  def defaults_str # :nodoc:
 | 
			
		||||
    "--both --version '#{Gem::Requirement.default}' --document --no-force\n" +
 | 
			
		||||
    "--install-dir #{Gem.dir}"
 | 
			
		||||
    "--install-dir #{Gem.dir} --lock"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def description # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +104,25 @@ The wrapper allows you to choose among alternate gem versions using _version_.
 | 
			
		|||
For example `rake _0.7.3_ --version` will run rake version 0.7.3 if a newer
 | 
			
		||||
version is also installed.
 | 
			
		||||
 | 
			
		||||
Gem Dependency Files
 | 
			
		||||
====================
 | 
			
		||||
 | 
			
		||||
RubyGems can install a consistent set of gems across multiple environments
 | 
			
		||||
using `gem install -g` when a gem dependencies file (gem.deps.rb, Gemfile or
 | 
			
		||||
Isolate) is present.  If no explicit file is given RubyGems attempts to find
 | 
			
		||||
one in the current directory.
 | 
			
		||||
 | 
			
		||||
When the RUBYGEMS_GEMDEPS environment variable is set to a gem dependencies
 | 
			
		||||
file the gems from that file will be activated at startup time.  Set it to a
 | 
			
		||||
specific filename or to "-" to have RubyGems automatically discover the gem
 | 
			
		||||
dependencies file by walking up from the current directory.
 | 
			
		||||
 | 
			
		||||
NOTE: Enabling automatic discovery on multiuser systems can lead to
 | 
			
		||||
execution of arbitrary code when used from directories outside your control.
 | 
			
		||||
 | 
			
		||||
Extension Install Failures
 | 
			
		||||
==========================
 | 
			
		||||
 | 
			
		||||
If an extension fails to compile during gem installation the gem
 | 
			
		||||
specification is not written out, but the gem remains unpacked in the
 | 
			
		||||
repository.  You may need to specify the path to the library's headers and
 | 
			
		||||
| 
						 | 
				
			
			@ -204,23 +235,20 @@ to write the specification by hand.  For example:
 | 
			
		|||
      install_gem_without_dependencies name, req
 | 
			
		||||
    else
 | 
			
		||||
      inst = Gem::DependencyInstaller.new options
 | 
			
		||||
 | 
			
		||||
      if options[:explain]
 | 
			
		||||
      request_set = inst.resolve_dependencies name, req
 | 
			
		||||
 | 
			
		||||
      if options[:explain]
 | 
			
		||||
        puts "Gems to install:"
 | 
			
		||||
 | 
			
		||||
        request_set.specs.map { |s| s.full_name }.sort.each do |s|
 | 
			
		||||
          puts "  #{s}"
 | 
			
		||||
        request_set.sorted_requests.each do |s|
 | 
			
		||||
          puts "  #{s.full_name}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        return
 | 
			
		||||
      else
 | 
			
		||||
        inst.install name, req
 | 
			
		||||
        @installed_specs.concat request_set.install options
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @installed_specs.push(*inst.installed_gems)
 | 
			
		||||
 | 
			
		||||
      show_install_errors inst.errors
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -250,6 +278,14 @@ to write the specification by hand.  For example:
 | 
			
		|||
    inst = Gem::Installer.new gem, options
 | 
			
		||||
    inst.install
 | 
			
		||||
 | 
			
		||||
    require 'rubygems/dependency_installer'
 | 
			
		||||
    dinst = Gem::DependencyInstaller.new options
 | 
			
		||||
    dinst.installed_gems.replace [inst.spec]
 | 
			
		||||
 | 
			
		||||
    Gem.done_installing_hooks.each do |hook|
 | 
			
		||||
      hook.call dinst, [inst.spec]
 | 
			
		||||
    end unless Gem.done_installing_hooks.empty?
 | 
			
		||||
 | 
			
		||||
    @installed_specs.push(inst.spec)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -264,8 +300,10 @@ to write the specification by hand.  For example:
 | 
			
		|||
      rescue Gem::InstallError => e
 | 
			
		||||
        alert_error "Error installing #{gem_name}:\n\t#{e.message}"
 | 
			
		||||
        exit_code |= 1
 | 
			
		||||
      rescue Gem::GemNotFoundException => e
 | 
			
		||||
        show_lookup_failure e.name, e.version, e.errors, options[:domain]
 | 
			
		||||
      rescue Gem::GemNotFoundException, Gem::UnsatisfiableDependencyError => e
 | 
			
		||||
        domain = options[:domain]
 | 
			
		||||
        domain = :local unless options[:suggest_alternate]
 | 
			
		||||
        show_lookup_failure e.name, e.version, e.errors, domain
 | 
			
		||||
 | 
			
		||||
        exit_code |= 2
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,13 +8,13 @@ require 'rubygems/commands/query_command'
 | 
			
		|||
class Gem::Commands::ListCommand < Gem::Commands::QueryCommand
 | 
			
		||||
 | 
			
		||||
  def initialize
 | 
			
		||||
    super 'list', 'Display local gems whose name starts with STRING'
 | 
			
		||||
    super 'list', 'Display local gems whose name matches REGEXP'
 | 
			
		||||
 | 
			
		||||
    remove_option('--name-matches')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def arguments # :nodoc:
 | 
			
		||||
    "STRING        start of gem name to look for"
 | 
			
		||||
    "REGEXP        regexp to look for in gem name"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def defaults_str # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										74
									
								
								lib/rubygems/commands/open_command.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								lib/rubygems/commands/open_command.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
require 'English'
 | 
			
		||||
require 'rubygems/command'
 | 
			
		||||
require 'rubygems/version_option'
 | 
			
		||||
require 'rubygems/util'
 | 
			
		||||
 | 
			
		||||
class Gem::Commands::OpenCommand < Gem::Command
 | 
			
		||||
 | 
			
		||||
  include Gem::VersionOption
 | 
			
		||||
 | 
			
		||||
  def initialize
 | 
			
		||||
    super 'open', 'Open gem sources in editor'
 | 
			
		||||
 | 
			
		||||
    add_option('-e', '--editor EDITOR', String,
 | 
			
		||||
               "Opens gem sources in EDITOR") do |editor, options|
 | 
			
		||||
      options[:editor] = editor || get_env_editor
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def arguments # :nodoc:
 | 
			
		||||
    "GEMNAME     name of gem to open in editor"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def defaults_str # :nodoc:
 | 
			
		||||
    "-e #{get_env_editor}"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def description # :nodoc:
 | 
			
		||||
    <<-EOF
 | 
			
		||||
        The open command opens gem in editor and changes current path
 | 
			
		||||
        to gem's source directory. Editor can be specified with -e option,
 | 
			
		||||
        otherwise rubygems will look for editor in $EDITOR, $VISUAL and
 | 
			
		||||
        $GEM_EDITOR variables.
 | 
			
		||||
    EOF
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def usage # :nodoc:
 | 
			
		||||
    "#{program_name} GEMNAME [-e EDITOR]"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get_env_editor
 | 
			
		||||
    ENV['GEM_EDITOR'] ||
 | 
			
		||||
      ENV['VISUAL'] ||
 | 
			
		||||
      ENV['EDITOR'] ||
 | 
			
		||||
      'vi'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def execute
 | 
			
		||||
    @version = options[:version] || Gem::Requirement.default
 | 
			
		||||
    @editor  = options[:editor] || get_env_editor
 | 
			
		||||
 | 
			
		||||
    found = open_gem(get_one_gem_name)
 | 
			
		||||
 | 
			
		||||
    terminate_interaction 1 unless found
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def open_gem name
 | 
			
		||||
    spec = spec_for name
 | 
			
		||||
    return false unless spec
 | 
			
		||||
 | 
			
		||||
    open_editor(spec.full_gem_path)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def open_editor path
 | 
			
		||||
    system(*@editor.split(/\s+/) + [path])
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def spec_for name
 | 
			
		||||
    spec = Gem::Specification.find_all_by_name(name, @version).last
 | 
			
		||||
 | 
			
		||||
    return spec if spec
 | 
			
		||||
 | 
			
		||||
    say "Unable to find gem '#{name}'"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +86,9 @@ permission to.
 | 
			
		|||
          request.add_field "Authorization", api_key
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        with_response response, "Removing #{owner}"
 | 
			
		||||
        action = method == :delete ? "Removing" : "Adding"
 | 
			
		||||
 | 
			
		||||
        with_response response, "#{action} #{owner}"
 | 
			
		||||
      rescue
 | 
			
		||||
        # ignore
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ require 'rubygems/commands/query_command'
 | 
			
		|||
class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand
 | 
			
		||||
 | 
			
		||||
  def initialize
 | 
			
		||||
    super 'search', 'Display remote gems whose name contains STRING'
 | 
			
		||||
    super 'search', 'Display remote gems whose name matches REGEXP'
 | 
			
		||||
 | 
			
		||||
    remove_option '--name-matches'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def arguments # :nodoc:
 | 
			
		||||
    "STRING        fragment of gem name to search for"
 | 
			
		||||
    "REGEXP        regexp to search for in gem name"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def defaults_str # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -21,8 +21,8 @@ class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand
 | 
			
		|||
 | 
			
		||||
  def description # :nodoc:
 | 
			
		||||
    <<-EOF
 | 
			
		||||
The search command displays remote gems whose name contains the given
 | 
			
		||||
string.
 | 
			
		||||
The search command displays remote gems whose name matches the given
 | 
			
		||||
regexp.
 | 
			
		||||
 | 
			
		||||
The --details option displays additional details from the gem but will
 | 
			
		||||
take a little longer to complete as it must download the information
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ To list local gems use the list command.
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def usage # :nodoc:
 | 
			
		||||
    "#{program_name} [STRING]"
 | 
			
		||||
    "#{program_name} [REGEXP]"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -446,7 +446,7 @@ abort "#{deprecation_message}"
 | 
			
		|||
        history.force_encoding Encoding::UTF_8 if
 | 
			
		||||
          Object.const_defined? :Encoding
 | 
			
		||||
 | 
			
		||||
        history = history.sub(/^# coding:.*?^=/m, '')
 | 
			
		||||
        history = history.sub(/^# coding:.*?(?=^=)/m, '')
 | 
			
		||||
 | 
			
		||||
        text = history.split(HISTORY_HEADER)
 | 
			
		||||
        text.shift # correct an off-by-one generated by split
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ class Gem::Commands::UninstallCommand < Gem::Command
 | 
			
		|||
  def initialize
 | 
			
		||||
    super 'uninstall', 'Uninstall gems from the local repository',
 | 
			
		||||
          :version => Gem::Requirement.default, :user_install => true,
 | 
			
		||||
          :check_dev => false
 | 
			
		||||
          :check_dev => false, :vendor => false
 | 
			
		||||
 | 
			
		||||
    add_option('-a', '--[no-]all',
 | 
			
		||||
      'Uninstall all matching versions'
 | 
			
		||||
| 
						 | 
				
			
			@ -76,6 +76,18 @@ class Gem::Commands::UninstallCommand < Gem::Command
 | 
			
		|||
 | 
			
		||||
    add_version_option
 | 
			
		||||
    add_platform_option
 | 
			
		||||
 | 
			
		||||
    add_option('--vendor',
 | 
			
		||||
               'Uninstall gem from the vendor directory.',
 | 
			
		||||
               'Only for use by gem repackagers.') do |value, options|
 | 
			
		||||
      unless Gem.vendor_dir then
 | 
			
		||||
        raise OptionParser::InvalidOption.new 'your platform is not supported'
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      alert_warning 'Use your OS package manager to uninstall vendor gems'
 | 
			
		||||
      options[:vendor] = true
 | 
			
		||||
      options[:install_dir] = Gem.vendor_dir
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def arguments # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,8 @@ class Gem::Commands::UpdateCommand < Gem::Command
 | 
			
		|||
 | 
			
		||||
  attr_reader :installer # :nodoc:
 | 
			
		||||
 | 
			
		||||
  attr_reader :updated # :nodoc:
 | 
			
		||||
 | 
			
		||||
  def initialize
 | 
			
		||||
    super 'update', 'Update installed gems to the latest version',
 | 
			
		||||
      :document => %w[rdoc ri],
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +47,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def arguments # :nodoc:
 | 
			
		||||
    "GEMNAME       name of gem to update"
 | 
			
		||||
    "REGEXP        regexp to search for in gem name"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def defaults_str # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -56,13 +58,13 @@ class Gem::Commands::UpdateCommand < Gem::Command
 | 
			
		|||
    <<-EOF
 | 
			
		||||
The update command will update your gems to the latest version.
 | 
			
		||||
 | 
			
		||||
The update comamnd does not remove the previous version.  Use the cleanup
 | 
			
		||||
The update command does not remove the previous version. Use the cleanup
 | 
			
		||||
command to remove old versions.
 | 
			
		||||
    EOF
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def usage # :nodoc:
 | 
			
		||||
    "#{program_name} GEMNAME [GEMNAME ...]"
 | 
			
		||||
    "#{program_name} REGEXP [REGEXP ...]"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def check_latest_rubygems version # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -97,10 +99,14 @@ command to remove old versions.
 | 
			
		|||
 | 
			
		||||
    updated = update_gems gems_to_update
 | 
			
		||||
 | 
			
		||||
    updated_names = updated.map { |spec| spec.name }
 | 
			
		||||
    not_updated_names = options[:args].uniq - updated_names
 | 
			
		||||
 | 
			
		||||
    if updated.empty? then
 | 
			
		||||
      say "Nothing to update"
 | 
			
		||||
    else
 | 
			
		||||
      say "Gems updated: #{updated.map { |spec| spec.name }.join ' '}"
 | 
			
		||||
      say "Gems updated: #{updated_names.join(' ')}"
 | 
			
		||||
      say "Gems already up-to-date: #{not_updated_names.join(' ')}" unless not_updated_names.empty?
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -199,15 +205,11 @@ command to remove old versions.
 | 
			
		|||
 | 
			
		||||
    @installer ||= Gem::DependencyInstaller.new options
 | 
			
		||||
 | 
			
		||||
    success = false
 | 
			
		||||
 | 
			
		||||
    say "Updating #{name}"
 | 
			
		||||
    begin
 | 
			
		||||
      @installer.install name, Gem::Requirement.new(version)
 | 
			
		||||
      success = true
 | 
			
		||||
    rescue Gem::InstallError => e
 | 
			
		||||
    rescue Gem::InstallError, Gem::DependencyError => e
 | 
			
		||||
      alert_error "Error installing #{name}:\n\t#{e.message}"
 | 
			
		||||
      success = false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @installer.installed_gems.each do |spec|
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +261,7 @@ command to remove old versions.
 | 
			
		|||
 | 
			
		||||
    highest_installed_gems.each do |l_name, l_spec|
 | 
			
		||||
      next if not gem_names.empty? and
 | 
			
		||||
              gem_names.all? { |name| /#{name}/ !~ l_spec.name }
 | 
			
		||||
              gem_names.none? { |name| name == l_spec.name }
 | 
			
		||||
 | 
			
		||||
      highest_remote_ver = highest_remote_version l_spec
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -272,4 +274,3 @@ command to remove old versions.
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,10 +44,7 @@ as the reason for the removal request.
 | 
			
		|||
      options[:undo] = true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    add_option('-k', '--key KEY_NAME',
 | 
			
		||||
               'Use API key from your gem credentials file') do |value, options|
 | 
			
		||||
      options[:key] = value
 | 
			
		||||
    end
 | 
			
		||||
    add_key_option
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def execute
 | 
			
		||||
| 
						 | 
				
			
			@ -55,14 +52,12 @@ as the reason for the removal request.
 | 
			
		|||
 | 
			
		||||
    version   = get_version_from_requirements(options[:version])
 | 
			
		||||
    platform  = get_platform_from_requirements(options)
 | 
			
		||||
    api_key   = Gem.configuration.rubygems_api_key
 | 
			
		||||
    api_key   = Gem.configuration.api_keys[options[:key].to_sym] if options[:key]
 | 
			
		||||
 | 
			
		||||
    if version then
 | 
			
		||||
      if options[:undo] then
 | 
			
		||||
        unyank_gem(version, platform, api_key)
 | 
			
		||||
        unyank_gem(version, platform)
 | 
			
		||||
      else
 | 
			
		||||
        yank_gem(version, platform, api_key)
 | 
			
		||||
        yank_gem(version, platform)
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      say "A version argument is required: #{usage}"
 | 
			
		||||
| 
						 | 
				
			
			@ -70,19 +65,19 @@ as the reason for the removal request.
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def yank_gem(version, platform, api_key)
 | 
			
		||||
  def yank_gem(version, platform)
 | 
			
		||||
    say "Yanking gem from #{self.host}..."
 | 
			
		||||
    yank_api_request(:delete, version, platform, "api/v1/gems/yank", api_key)
 | 
			
		||||
    yank_api_request(:delete, version, platform, "api/v1/gems/yank")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def unyank_gem(version, platform, api_key)
 | 
			
		||||
  def unyank_gem(version, platform)
 | 
			
		||||
    say "Unyanking gem from #{host}..."
 | 
			
		||||
    yank_api_request(:put, version, platform, "api/v1/gems/unyank", api_key)
 | 
			
		||||
    yank_api_request(:put, version, platform, "api/v1/gems/unyank")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def yank_api_request(method, version, platform, api, api_key)
 | 
			
		||||
  def yank_api_request(method, version, platform, api)
 | 
			
		||||
    name = get_one_gem_name
 | 
			
		||||
    response = rubygems_api_request(method, api) do |request|
 | 
			
		||||
      request.add_field("Authorization", api_key)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ class Gem::ConfigFile
 | 
			
		|||
 | 
			
		||||
  # :stopdoc:
 | 
			
		||||
 | 
			
		||||
  system_config_path =
 | 
			
		||||
  SYSTEM_CONFIG_PATH =
 | 
			
		||||
    begin
 | 
			
		||||
      require "etc"
 | 
			
		||||
      Etc.sysconfdir
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +86,7 @@ class Gem::ConfigFile
 | 
			
		|||
 | 
			
		||||
  # :startdoc:
 | 
			
		||||
 | 
			
		||||
  SYSTEM_WIDE_CONFIG_FILE = File.join system_config_path, 'gemrc'
 | 
			
		||||
  SYSTEM_WIDE_CONFIG_FILE = File.join SYSTEM_CONFIG_PATH, 'gemrc'
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # List of arguments supplied to the config file object.
 | 
			
		||||
| 
						 | 
				
			
			@ -383,6 +383,8 @@ if you believe they were disclosed to a third party.
 | 
			
		|||
        @backtrace = true
 | 
			
		||||
      when /^--debug$/ then
 | 
			
		||||
        $DEBUG = true
 | 
			
		||||
 | 
			
		||||
        warn 'NOTE:  Debugging mode prints all exceptions even when rescued'
 | 
			
		||||
      else
 | 
			
		||||
        @args << arg
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			@ -428,6 +430,15 @@ if you believe they were disclosed to a third party.
 | 
			
		|||
                            DEFAULT_VERBOSITY
 | 
			
		||||
                          end
 | 
			
		||||
 | 
			
		||||
    yaml_hash[:ssl_verify_mode] =
 | 
			
		||||
      @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
 | 
			
		||||
 | 
			
		||||
    yaml_hash[:ssl_ca_cert] =
 | 
			
		||||
      @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
 | 
			
		||||
 | 
			
		||||
    yaml_hash[:ssl_client_cert] =
 | 
			
		||||
      @hash[:ssl_client_cert] if @hash.key? :ssl_client_cert
 | 
			
		||||
 | 
			
		||||
    keys = yaml_hash.keys.map { |key| key.to_s }
 | 
			
		||||
    keys << 'debug'
 | 
			
		||||
    re = Regexp.union(*keys)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,11 @@ module Kernel
 | 
			
		|||
  # Kernel#gem should be called *before* any require statements (otherwise
 | 
			
		||||
  # RubyGems may load a conflicting library version).
 | 
			
		||||
  #
 | 
			
		||||
  # Kernel#gem only loads prerelease versions when prerelease +requirements+
 | 
			
		||||
  # are given:
 | 
			
		||||
  #
 | 
			
		||||
  #   gem 'rake', '>= 1.1.a', '< 2'
 | 
			
		||||
  #
 | 
			
		||||
  # In older RubyGems versions, the environment variable GEM_SKIP could be
 | 
			
		||||
  # used to skip activation of specified gems, for example to test out changes
 | 
			
		||||
  # that haven't been installed yet.  Now RubyGems defers to -I and the
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +56,9 @@ module Kernel
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    spec = Gem::Dependency.new(gem_name, *requirements).to_spec
 | 
			
		||||
    spec.activate if spec
 | 
			
		||||
    Gem::LOADED_SPECS_MUTEX.synchronize {
 | 
			
		||||
      spec.activate
 | 
			
		||||
    } if spec
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private :gem
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,12 +50,8 @@ module Kernel
 | 
			
		|||
    # normal require handle loading a gem from the rescue below.
 | 
			
		||||
 | 
			
		||||
    if Gem::Specification.unresolved_deps.empty? then
 | 
			
		||||
      begin
 | 
			
		||||
      RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
      return gem_original_require(path)
 | 
			
		||||
      ensure
 | 
			
		||||
        RUBYGEMS_ACTIVATION_MONITOR.enter
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # If +path+ is for a gem that has already been loaded, don't
 | 
			
		||||
| 
						 | 
				
			
			@ -71,8 +67,6 @@ module Kernel
 | 
			
		|||
    begin
 | 
			
		||||
      RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
      return gem_original_require(path)
 | 
			
		||||
    ensure
 | 
			
		||||
      RUBYGEMS_ACTIVATION_MONITOR.enter
 | 
			
		||||
    end if spec
 | 
			
		||||
 | 
			
		||||
    # Attempt to find +path+ in any unresolved gems...
 | 
			
		||||
| 
						 | 
				
			
			@ -105,6 +99,7 @@ module Kernel
 | 
			
		|||
      names = found_specs.map(&:name).uniq
 | 
			
		||||
 | 
			
		||||
      if names.size > 1 then
 | 
			
		||||
        RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
        raise Gem::LoadError, "#{path} found in multiple gems: #{names.join ', '}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -115,32 +110,27 @@ module Kernel
 | 
			
		|||
      unless valid then
 | 
			
		||||
        le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate"
 | 
			
		||||
        le.name = names.first
 | 
			
		||||
        RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
        raise le
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      valid.activate
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
    RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
    return gem_original_require(path)
 | 
			
		||||
    ensure
 | 
			
		||||
      RUBYGEMS_ACTIVATION_MONITOR.enter
 | 
			
		||||
    end
 | 
			
		||||
  rescue LoadError => load_error
 | 
			
		||||
    RUBYGEMS_ACTIVATION_MONITOR.enter
 | 
			
		||||
 | 
			
		||||
    if load_error.message.start_with?("Could not find") or
 | 
			
		||||
        (load_error.message.end_with?(path) and Gem.try_activate(path)) then
 | 
			
		||||
      begin
 | 
			
		||||
      RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
      return gem_original_require(path)
 | 
			
		||||
      ensure
 | 
			
		||||
        RUBYGEMS_ACTIVATION_MONITOR.enter
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    raise load_error
 | 
			
		||||
  ensure
 | 
			
		||||
    RUBYGEMS_ACTIVATION_MONITOR.exit
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private :require
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,11 +89,11 @@ module Gem
 | 
			
		|||
  # Default gem load path
 | 
			
		||||
 | 
			
		||||
  def self.default_path
 | 
			
		||||
    if Gem.user_home && File.exist?(Gem.user_home) then
 | 
			
		||||
      [user_dir, default_dir]
 | 
			
		||||
    else
 | 
			
		||||
      [default_dir]
 | 
			
		||||
    end
 | 
			
		||||
    path = []
 | 
			
		||||
    path << user_dir if user_home && File.exist?(user_home)
 | 
			
		||||
    path << default_dir
 | 
			
		||||
    path << vendor_dir if vendor_dir and File.directory? vendor_dir
 | 
			
		||||
    path
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -160,4 +160,18 @@ module Gem
 | 
			
		|||
    true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Directory where vendor gems are installed.
 | 
			
		||||
 | 
			
		||||
  def self.vendor_dir # :nodoc:
 | 
			
		||||
    if vendor_dir = ENV['GEM_VENDOR'] then
 | 
			
		||||
      return vendor_dir.dup
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return nil unless RbConfig::CONFIG.key? 'vendordir'
 | 
			
		||||
 | 
			
		||||
    File.join RbConfig::CONFIG['vendordir'], 'gems',
 | 
			
		||||
              RbConfig::CONFIG['ruby_version']
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ class Gem::Dependency
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def inspect # :nodoc:
 | 
			
		||||
    if @prerelease
 | 
			
		||||
    if prerelease? then
 | 
			
		||||
      "<%s type=%p name=%p requirements=%p prerelease=ok>" %
 | 
			
		||||
        [self.class, self.type, self.name, requirement.to_s]
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +145,6 @@ class Gem::Dependency
 | 
			
		|||
    @requirement = @version_requirements if defined?(@version_requirements)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: this method needs documentation or :nodoc''d
 | 
			
		||||
  def requirements_list
 | 
			
		||||
    requirement.as_list
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -205,9 +204,19 @@ class Gem::Dependency
 | 
			
		|||
 | 
			
		||||
  alias === =~
 | 
			
		||||
 | 
			
		||||
  # DOC: this method needs either documented or :nodoc'd
 | 
			
		||||
  ##
 | 
			
		||||
  # :call-seq:
 | 
			
		||||
  #   dep.match? name          => true or false
 | 
			
		||||
  #   dep.match? name, version => true or false
 | 
			
		||||
  #   dep.match? spec          => true or false
 | 
			
		||||
  #
 | 
			
		||||
  # Does this dependency match the specification described by +name+ and
 | 
			
		||||
  # +version+ or match +spec+?
 | 
			
		||||
  #
 | 
			
		||||
  # NOTE:  Unlike #matches_spec? this method does not return true when the
 | 
			
		||||
  # version is a prerelease version unless this is a prerelease dependency.
 | 
			
		||||
 | 
			
		||||
  def match? obj, version=nil
 | 
			
		||||
  def match? obj, version=nil, allow_prerelease=false
 | 
			
		||||
    if !version
 | 
			
		||||
      name = obj.name
 | 
			
		||||
      version = obj.version
 | 
			
		||||
| 
						 | 
				
			
			@ -216,12 +225,23 @@ class Gem::Dependency
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    return false unless self.name === name
 | 
			
		||||
    return true if requirement.none?
 | 
			
		||||
 | 
			
		||||
    requirement.satisfied_by? Gem::Version.new(version)
 | 
			
		||||
    version = Gem::Version.new version
 | 
			
		||||
 | 
			
		||||
    return true if requirement.none? and not version.prerelease?
 | 
			
		||||
    return false if version.prerelease? and
 | 
			
		||||
                    not allow_prerelease and
 | 
			
		||||
                    not prerelease?
 | 
			
		||||
 | 
			
		||||
    requirement.satisfied_by? version
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: this method needs either documented or :nodoc'd
 | 
			
		||||
  ##
 | 
			
		||||
  # Does this dependency match +spec+?
 | 
			
		||||
  #
 | 
			
		||||
  # NOTE:  This is not a convenience method.  Unlike #match? this method
 | 
			
		||||
  # returns true when +spec+ is a prerelease version even if this dependency
 | 
			
		||||
  # is not a prerelease dependency.
 | 
			
		||||
 | 
			
		||||
  def matches_spec? spec
 | 
			
		||||
    return false unless name === spec.name
 | 
			
		||||
| 
						 | 
				
			
			@ -249,8 +269,6 @@ class Gem::Dependency
 | 
			
		|||
    self.class.new name, self_req.as_list.concat(other_req.as_list)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: this method needs either documented or :nodoc'd
 | 
			
		||||
 | 
			
		||||
  def matching_specs platform_only = false
 | 
			
		||||
    matches = Gem::Specification.stubs.find_all { |spec|
 | 
			
		||||
      self.name === spec.name and # TODO: == instead of ===
 | 
			
		||||
| 
						 | 
				
			
			@ -273,8 +291,6 @@ class Gem::Dependency
 | 
			
		|||
    @requirement.specific?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: this method needs either documented or :nodoc'd
 | 
			
		||||
 | 
			
		||||
  def to_specs
 | 
			
		||||
    matches = matching_specs true
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -287,12 +303,13 @@ class Gem::Dependency
 | 
			
		|||
 | 
			
		||||
      if specs.empty?
 | 
			
		||||
        total = Gem::Specification.to_a.size
 | 
			
		||||
        error = Gem::LoadError.new \
 | 
			
		||||
          "Could not find '#{name}' (#{requirement}) among #{total} total gem(s)"
 | 
			
		||||
        msg   = "Could not find '#{name}' (#{requirement}) among #{total} total gem(s)\n"
 | 
			
		||||
      else
 | 
			
		||||
        error = Gem::LoadError.new \
 | 
			
		||||
          "Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]"
 | 
			
		||||
        msg   = "Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]\n"
 | 
			
		||||
      end
 | 
			
		||||
      msg << "Checked in 'GEM_PATH=#{Gem.path.join(File::PATH_SEPARATOR)}', execute `gem env` for more information"
 | 
			
		||||
 | 
			
		||||
      error = Gem::LoadError.new(msg)
 | 
			
		||||
      error.name        = self.name
 | 
			
		||||
      error.requirement = self.requirement
 | 
			
		||||
      raise error
 | 
			
		||||
| 
						 | 
				
			
			@ -303,11 +320,15 @@ class Gem::Dependency
 | 
			
		|||
    matches
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: this method needs either documented or :nodoc'd
 | 
			
		||||
 | 
			
		||||
  def to_spec
 | 
			
		||||
    matches = self.to_specs
 | 
			
		||||
 | 
			
		||||
    matches.find { |spec| spec.activated? } or matches.last
 | 
			
		||||
    active = matches.find { |spec| spec.activated? }
 | 
			
		||||
 | 
			
		||||
    return active if active
 | 
			
		||||
 | 
			
		||||
    matches.delete_if { |spec| spec.version.prerelease? } unless prerelease?
 | 
			
		||||
 | 
			
		||||
    matches.last
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,7 @@ class Gem::DependencyInstaller
 | 
			
		|||
  def initialize options = {}
 | 
			
		||||
    @only_install_dir = !!options[:install_dir]
 | 
			
		||||
    @install_dir = options[:install_dir] || Gem.dir
 | 
			
		||||
    @build_root = options[:build_root]
 | 
			
		||||
 | 
			
		||||
    options = DEFAULT_OPTIONS.merge options
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +103,7 @@ class Gem::DependencyInstaller
 | 
			
		|||
 | 
			
		||||
    @cache_dir = options[:cache_dir] || @install_dir
 | 
			
		||||
 | 
			
		||||
    @errors = nil
 | 
			
		||||
    @errors = []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -157,6 +158,7 @@ class Gem::DependencyInstaller
 | 
			
		|||
 | 
			
		||||
    dependency_list.remove_specs_unsatisfied_by dependencies
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Creates an AvailableSet to install from based on +dep_or_name+ and
 | 
			
		||||
  # +version+
 | 
			
		||||
| 
						 | 
				
			
			@ -243,9 +245,9 @@ class Gem::DependencyInstaller
 | 
			
		|||
        # FIX if there is a problem talking to the network, we either need to always tell
 | 
			
		||||
        # the user (no really_verbose) or fail hard, not silently tell them that we just
 | 
			
		||||
        # couldn't find their requested gem.
 | 
			
		||||
        if Gem.configuration.really_verbose then
 | 
			
		||||
          say "Error fetching remote data:\t\t#{e.message}"
 | 
			
		||||
          say "Falling back to local-only install"
 | 
			
		||||
        verbose do
 | 
			
		||||
          "Error fetching remote data:\t\t#{e.message}\n" \
 | 
			
		||||
            "Falling back to local-only install"
 | 
			
		||||
        end
 | 
			
		||||
        @domain = :local
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			@ -375,13 +377,16 @@ class Gem::DependencyInstaller
 | 
			
		|||
    options = {
 | 
			
		||||
      :bin_dir             => @bin_dir,
 | 
			
		||||
      :build_args          => @build_args,
 | 
			
		||||
      :document            => @document,
 | 
			
		||||
      :env_shebang         => @env_shebang,
 | 
			
		||||
      :force               => @force,
 | 
			
		||||
      :format_executable   => @format_executable,
 | 
			
		||||
      :ignore_dependencies => @ignore_dependencies,
 | 
			
		||||
      :prerelease          => @prerelease,
 | 
			
		||||
      :security_policy     => @security_policy,
 | 
			
		||||
      :user_install        => @user_install,
 | 
			
		||||
      :wrappers            => @wrappers,
 | 
			
		||||
      :build_root          => @build_root,
 | 
			
		||||
      :install_as_default  => @install_as_default
 | 
			
		||||
    }
 | 
			
		||||
    options[:install_dir] = @install_dir if @only_install_dir
 | 
			
		||||
| 
						 | 
				
			
			@ -415,25 +420,59 @@ class Gem::DependencyInstaller
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def resolve_dependencies dep_or_name, version # :nodoc:
 | 
			
		||||
    as = available_set_for dep_or_name, version
 | 
			
		||||
 | 
			
		||||
    request_set = as.to_request_set install_development_deps
 | 
			
		||||
    request_set = Gem::RequestSet.new
 | 
			
		||||
    request_set.development         = @development
 | 
			
		||||
    request_set.development_shallow = @dev_shallow
 | 
			
		||||
    request_set.soft_missing = @force
 | 
			
		||||
    request_set.prerelease = @prerelease
 | 
			
		||||
    request_set.remote = false unless consider_remote?
 | 
			
		||||
 | 
			
		||||
    installer_set = Gem::Resolver::InstallerSet.new @domain
 | 
			
		||||
    installer_set.always_install.concat request_set.always_install
 | 
			
		||||
    installer_set.ignore_installed = @only_install_dir
 | 
			
		||||
 | 
			
		||||
    if consider_local?
 | 
			
		||||
      if dep_or_name =~ /\.gem$/ and File.file? dep_or_name then
 | 
			
		||||
        src = Gem::Source::SpecificFile.new dep_or_name
 | 
			
		||||
        installer_set.add_local dep_or_name, src.spec, src
 | 
			
		||||
        version = src.spec.version if version == Gem::Requirement.default
 | 
			
		||||
      elsif dep_or_name =~ /\.gem$/ then
 | 
			
		||||
        Dir[dep_or_name].each do |name|
 | 
			
		||||
          begin
 | 
			
		||||
            src = Gem::Source::SpecificFile.new name
 | 
			
		||||
            installer_set.add_local dep_or_name, src.spec, src
 | 
			
		||||
          rescue Gem::Package::FormatError
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      # else This is a dependency. InstallerSet handles this case
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    dependency =
 | 
			
		||||
      if spec = installer_set.local?(dep_or_name) then
 | 
			
		||||
        Gem::Dependency.new spec.name, version
 | 
			
		||||
      elsif String === dep_or_name then
 | 
			
		||||
        Gem::Dependency.new dep_or_name, version
 | 
			
		||||
      else
 | 
			
		||||
        dep_or_name
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    dependency.prerelease = @prerelease
 | 
			
		||||
 | 
			
		||||
    request_set.import [dependency]
 | 
			
		||||
 | 
			
		||||
    installer_set.add_always_install dependency
 | 
			
		||||
 | 
			
		||||
    request_set.always_install = installer_set.always_install
 | 
			
		||||
 | 
			
		||||
    if @ignore_dependencies then
 | 
			
		||||
      installer_set.ignore_dependencies = true
 | 
			
		||||
      request_set.ignore_dependencies   = true
 | 
			
		||||
      request_set.soft_missing          = true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    composed_set = Gem::Resolver.compose_sets as, installer_set
 | 
			
		||||
    request_set.resolve installer_set
 | 
			
		||||
 | 
			
		||||
    request_set.resolve composed_set
 | 
			
		||||
    @errors.concat request_set.errors
 | 
			
		||||
 | 
			
		||||
    request_set
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,7 +105,7 @@ class Gem::Doctor
 | 
			
		|||
      next if ent == "." || ent == ".."
 | 
			
		||||
 | 
			
		||||
      child = File.join(directory, ent)
 | 
			
		||||
      next unless File.exists?(child)
 | 
			
		||||
      next unless File.exist?(child)
 | 
			
		||||
 | 
			
		||||
      basename = File.basename(child, extension)
 | 
			
		||||
      next if installed_specs.include? basename
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,36 @@ module Gem
 | 
			
		|||
    attr_accessor :requirement
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Raised when there are conflicting gem specs loaded
 | 
			
		||||
 | 
			
		||||
  class ConflictError < LoadError
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
    # A Hash mapping conflicting specifications to the dependencies that
 | 
			
		||||
    # caused the conflict
 | 
			
		||||
 | 
			
		||||
    attr_reader :conflicts
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
    # The specification that had the conflict
 | 
			
		||||
 | 
			
		||||
    attr_reader :target
 | 
			
		||||
 | 
			
		||||
    def initialize target, conflicts
 | 
			
		||||
      @target    = target
 | 
			
		||||
      @conflicts = conflicts
 | 
			
		||||
      @name      = target.name
 | 
			
		||||
 | 
			
		||||
      reason = conflicts.map { |act, dependencies|
 | 
			
		||||
        "#{act.full_name} conflicts with #{dependencies.join(", ")}"
 | 
			
		||||
      }.join ", "
 | 
			
		||||
 | 
			
		||||
      # TODO: improve message by saying who activated `con`
 | 
			
		||||
 | 
			
		||||
      super("Unable to activate #{target.full_name}, because #{reason}")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class ErrorReason; end
 | 
			
		||||
 | 
			
		||||
  # Generated when trying to lookup a gem to indicate that the gem
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ class Gem::DependencyRemovalException < Gem::Exception; end
 | 
			
		|||
# toplevel.  Indicates which dependencies were incompatible through #conflict
 | 
			
		||||
# and #conflicting_dependencies
 | 
			
		||||
 | 
			
		||||
class Gem::DependencyResolutionError < Gem::Exception
 | 
			
		||||
class Gem::DependencyResolutionError < Gem::DependencyError
 | 
			
		||||
 | 
			
		||||
  attr_reader :conflict
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -214,7 +214,7 @@ end
 | 
			
		|||
# Raised by Resolver when a dependency requests a gem for which
 | 
			
		||||
# there is no spec.
 | 
			
		||||
 | 
			
		||||
class Gem::UnsatisfiableDependencyError < Gem::Exception
 | 
			
		||||
class Gem::UnsatisfiableDependencyError < Gem::DependencyError
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The unsatisfiable dependency.  This is a
 | 
			
		||||
| 
						 | 
				
			
			@ -222,6 +222,11 @@ class Gem::UnsatisfiableDependencyError < Gem::Exception
 | 
			
		|||
 | 
			
		||||
  attr_reader :dependency
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Errors encountered which may have contributed to this exception
 | 
			
		||||
 | 
			
		||||
  attr_accessor :errors
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Creates a new UnsatisfiableDependencyError for the unsatisfiable
 | 
			
		||||
  # Gem::Resolver::DependencyRequest +dep+
 | 
			
		||||
| 
						 | 
				
			
			@ -239,6 +244,21 @@ class Gem::UnsatisfiableDependencyError < Gem::Exception
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    @dependency = dep
 | 
			
		||||
    @errors     = []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The name of the unresolved dependency
 | 
			
		||||
 | 
			
		||||
  def name
 | 
			
		||||
    @dependency.name
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The Requirement of the unresolved dependency (not Version).
 | 
			
		||||
 | 
			
		||||
  def version
 | 
			
		||||
    @dependency.requirement
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -161,7 +161,7 @@ EOF
 | 
			
		|||
          results = builder.build(extension, @gem_dir, dest_path,
 | 
			
		||||
                                  results, @build_args, lib_dir)
 | 
			
		||||
 | 
			
		||||
          say results.join("\n") if Gem.configuration.really_verbose
 | 
			
		||||
          verbose { results.join("\n") }
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,13 +11,15 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
 | 
			
		|||
  FileEntry = FileUtils::Entry_ # :nodoc:
 | 
			
		||||
 | 
			
		||||
  def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
 | 
			
		||||
    tmp_dest = Dir.mktmpdir(".gem.", ".")
 | 
			
		||||
    # relative path required as some versions of mktmpdir return an absolute
 | 
			
		||||
    # path which breaks make if it includes a space in the name
 | 
			
		||||
    tmp_dest = get_relative_path(Dir.mktmpdir(".gem.", "."))
 | 
			
		||||
 | 
			
		||||
    t = nil
 | 
			
		||||
    Tempfile.open %w"siteconf .rb", "." do |siteconf|
 | 
			
		||||
      t = siteconf
 | 
			
		||||
      siteconf.puts "require 'rbconfig'"
 | 
			
		||||
      siteconf.puts "dest_path = #{(tmp_dest || dest_path).dump}"
 | 
			
		||||
      siteconf.puts "dest_path = #{tmp_dest.dump}"
 | 
			
		||||
      %w[sitearchdir sitelibdir].each do |dir|
 | 
			
		||||
        siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
 | 
			
		||||
        siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
 | 
			
		||||
| 
						 | 
				
			
			@ -25,14 +27,10 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
 | 
			
		|||
 | 
			
		||||
      siteconf.flush
 | 
			
		||||
 | 
			
		||||
      siteconf_path = File.expand_path siteconf.path
 | 
			
		||||
 | 
			
		||||
      rubyopt = ENV["RUBYOPT"]
 | 
			
		||||
      destdir = ENV["DESTDIR"]
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
        ENV["RUBYOPT"] = ["-r#{siteconf_path}", rubyopt].compact.join(' ')
 | 
			
		||||
        cmd = [Gem.ruby, File.basename(extension), *args].join ' '
 | 
			
		||||
        cmd = [Gem.ruby, "-r", get_relative_path(siteconf.path), File.basename(extension), *args].join ' '
 | 
			
		||||
 | 
			
		||||
        begin
 | 
			
		||||
          run cmd, results
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +40,6 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        ENV["DESTDIR"] = nil
 | 
			
		||||
        ENV["RUBYOPT"] = rubyopt
 | 
			
		||||
 | 
			
		||||
        make dest_path, results
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,11 +54,10 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
 | 
			
		|||
 | 
			
		||||
          FileEntry.new(tmp_dest).traverse do |ent|
 | 
			
		||||
            destent = ent.class.new(dest_path, ent.rel)
 | 
			
		||||
            destent.exist? or File.rename(ent.path, destent.path)
 | 
			
		||||
            destent.exist? or FileUtils.mv(ent.path, destent.path)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      ensure
 | 
			
		||||
        ENV["RUBYOPT"] = rubyopt
 | 
			
		||||
        ENV["DESTDIR"] = destdir
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -72,5 +68,11 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
 | 
			
		|||
    FileUtils.rm_rf tmp_dest if tmp_dest
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
  def self.get_relative_path(path)
 | 
			
		||||
    path[0..Dir.pwd.length-1] = '.' if path.start_with?(Dir.pwd)
 | 
			
		||||
    path
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,7 +86,7 @@ module Gem::GemcutterUtilities
 | 
			
		|||
 | 
			
		||||
  def sign_in sign_in_host = nil
 | 
			
		||||
    sign_in_host ||= self.host
 | 
			
		||||
    return if Gem.configuration.rubygems_api_key
 | 
			
		||||
    return if api_key
 | 
			
		||||
 | 
			
		||||
    pretty_host = if Gem::DEFAULT_HOST == sign_in_host then
 | 
			
		||||
                    'RubyGems.org'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,23 @@ module Gem::InstallUpdateOptions
 | 
			
		|||
                           end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    add_option(:"Install/Update", '--build-root DIR',
 | 
			
		||||
               'Temporary installation root. Useful for building',
 | 
			
		||||
               'packages. Do not use this when installing remote gems.') do |value, options|
 | 
			
		||||
      options[:build_root] = File.expand_path(value)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    add_option(:"Install/Update", '--vendor',
 | 
			
		||||
               'Install gem into the vendor directory.',
 | 
			
		||||
               'Only for use by gem repackagers.') do |value, options|
 | 
			
		||||
      unless Gem.vendor_dir then
 | 
			
		||||
        raise OptionParser::InvalidOption.new 'your platform is not supported'
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      options[:vendor] = true
 | 
			
		||||
      options[:install_dir] = Gem.vendor_dir
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    add_option(:"Install/Update", '-N', '--no-document',
 | 
			
		||||
               'Disable documentation generation') do |value, options|
 | 
			
		||||
      options[:document] = []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,9 @@ class Gem::Installer
 | 
			
		|||
 | 
			
		||||
  include Gem::UserInteraction
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  ##
 | 
			
		||||
  # Filename of the gem being installed.
 | 
			
		||||
 | 
			
		||||
  attr_reader :gem
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +49,8 @@ class Gem::Installer
 | 
			
		|||
 | 
			
		||||
  attr_reader :bin_dir
 | 
			
		||||
 | 
			
		||||
  attr_reader :build_root # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The gem repository the gem will be installed into
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +68,8 @@ class Gem::Installer
 | 
			
		|||
 | 
			
		||||
  @path_warning = false
 | 
			
		||||
 | 
			
		||||
  @install_lock = Mutex.new
 | 
			
		||||
 | 
			
		||||
  class << self
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +77,19 @@ class Gem::Installer
 | 
			
		|||
 | 
			
		||||
    attr_accessor :path_warning
 | 
			
		||||
 | 
			
		||||
    # DOC: Missing docs or :nodoc:.
 | 
			
		||||
    ##
 | 
			
		||||
    # Certain aspects of the install process are not thread-safe. This lock is
 | 
			
		||||
    # used to allow multiple threads to install Gems at the same time.
 | 
			
		||||
 | 
			
		||||
    attr_reader :install_lock
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
    # Overrides the executable format.
 | 
			
		||||
    #
 | 
			
		||||
    # This is a sprintf format with a "%s" which will be replaced with the
 | 
			
		||||
    # executable name.  It is based off the ruby executable name's difference
 | 
			
		||||
    # from "ruby".
 | 
			
		||||
 | 
			
		||||
    attr_writer :exec_format
 | 
			
		||||
 | 
			
		||||
    # Defaults to use Ruby's program prefix and suffix.
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +258,7 @@ class Gem::Installer
 | 
			
		|||
 | 
			
		||||
    say spec.post_install_message unless spec.post_install_message.nil?
 | 
			
		||||
 | 
			
		||||
    Gem::Specification.add_spec spec unless Gem::Specification.include? spec
 | 
			
		||||
    Gem::Installer.install_lock.synchronize { Gem::Specification.add_spec spec }
 | 
			
		||||
 | 
			
		||||
    run_post_install_hooks
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -318,6 +336,7 @@ class Gem::Installer
 | 
			
		|||
  # True if the gems in the system satisfy +dependency+.
 | 
			
		||||
 | 
			
		||||
  def installation_satisfies_dependency?(dependency)
 | 
			
		||||
    return true if @options[:development] and dependency.type == :development
 | 
			
		||||
    return true if installed_specs.detect { |s| dependency.matches_spec? s }
 | 
			
		||||
    return false if @only_install_dir
 | 
			
		||||
    not dependency.matching_specs.empty?
 | 
			
		||||
| 
						 | 
				
			
			@ -382,12 +401,11 @@ class Gem::Installer
 | 
			
		|||
        file.puts windows_stub_script(bindir, filename)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      say script_path if Gem.configuration.really_verbose
 | 
			
		||||
      verbose script_path
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  def generate_bin
 | 
			
		||||
  def generate_bin # :nodoc:
 | 
			
		||||
    return if spec.executables.nil? or spec.executables.empty?
 | 
			
		||||
 | 
			
		||||
    Dir.mkdir @bin_dir unless File.exist? @bin_dir
 | 
			
		||||
| 
						 | 
				
			
			@ -433,7 +451,7 @@ class Gem::Installer
 | 
			
		|||
      file.print app_script_text(filename)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    say bin_script_path if Gem.configuration.really_verbose
 | 
			
		||||
    verbose bin_script_path
 | 
			
		||||
 | 
			
		||||
    generate_windows_script filename, bindir
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -536,8 +554,7 @@ class Gem::Installer
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  def ensure_required_ruby_version_met
 | 
			
		||||
  def ensure_required_ruby_version_met # :nodoc:
 | 
			
		||||
    if rrv = spec.required_ruby_version then
 | 
			
		||||
      unless rrv.satisfied_by? Gem.ruby_version then
 | 
			
		||||
        raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}."
 | 
			
		||||
| 
						 | 
				
			
			@ -545,8 +562,7 @@ class Gem::Installer
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  def ensure_required_rubygems_version_met
 | 
			
		||||
  def ensure_required_rubygems_version_met # :nodoc:
 | 
			
		||||
    if rrgv = spec.required_rubygems_version then
 | 
			
		||||
      unless rrgv.satisfied_by? Gem.rubygems_version then
 | 
			
		||||
        raise Gem::InstallError,
 | 
			
		||||
| 
						 | 
				
			
			@ -556,8 +572,7 @@ class Gem::Installer
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  def ensure_dependencies_met
 | 
			
		||||
  def ensure_dependencies_met # :nodoc:
 | 
			
		||||
    deps = spec.runtime_dependencies
 | 
			
		||||
    deps |= spec.development_dependencies if @development
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -566,8 +581,7 @@ class Gem::Installer
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  def process_options
 | 
			
		||||
  def process_options # :nodoc:
 | 
			
		||||
    @options = {
 | 
			
		||||
      :bin_dir      => nil,
 | 
			
		||||
      :env_shebang  => false,
 | 
			
		||||
| 
						 | 
				
			
			@ -590,12 +604,20 @@ class Gem::Installer
 | 
			
		|||
    # (or use) a new bin dir under the gem_home.
 | 
			
		||||
    @bin_dir             = options[:bin_dir] || Gem.bindir(gem_home)
 | 
			
		||||
    @development         = options[:development]
 | 
			
		||||
    @build_root          = options[:build_root]
 | 
			
		||||
 | 
			
		||||
    @build_args          = options[:build_args] || Gem::Command.build_args
 | 
			
		||||
 | 
			
		||||
    unless @build_root.nil?
 | 
			
		||||
      require 'pathname'
 | 
			
		||||
      @build_root = Pathname.new(@build_root).expand_path
 | 
			
		||||
      @bin_dir = File.join(@build_root, options[:bin_dir] || Gem.bindir(@gem_home))
 | 
			
		||||
      @gem_home = File.join(@build_root, @gem_home)
 | 
			
		||||
      alert_warning "You build with buildroot.\n  Build root: #{@build_root}\n  Bin dir: #{@bin_dir}\n  Gem home: #{@gem_home}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  def check_that_user_bin_dir_is_in_path
 | 
			
		||||
  def check_that_user_bin_dir_is_in_path # :nodoc:
 | 
			
		||||
    user_bin_dir = @bin_dir || Gem.bindir(gem_home)
 | 
			
		||||
    user_bin_dir = user_bin_dir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if
 | 
			
		||||
      File::ALT_SEPARATOR
 | 
			
		||||
| 
						 | 
				
			
			@ -606,16 +628,19 @@ class Gem::Installer
 | 
			
		|||
      user_bin_dir = user_bin_dir.downcase
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    unless path.split(File::PATH_SEPARATOR).include? user_bin_dir then
 | 
			
		||||
    path = path.split(File::PATH_SEPARATOR)
 | 
			
		||||
 | 
			
		||||
    unless path.include? user_bin_dir then
 | 
			
		||||
      unless !Gem.win_platform? && (path.include? user_bin_dir.sub(ENV['HOME'], '~'))
 | 
			
		||||
        unless self.class.path_warning then
 | 
			
		||||
          alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t  gem executables will not run."
 | 
			
		||||
          self.class.path_warning = true
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # DOC: Missing docs or :nodoc:.
 | 
			
		||||
  def verify_gem_home(unpack = false)
 | 
			
		||||
  def verify_gem_home(unpack = false) # :nodoc:
 | 
			
		||||
    FileUtils.mkdir_p gem_home
 | 
			
		||||
    raise Gem::FilePermissionError, gem_home unless
 | 
			
		||||
      unpack or File.writable?(gem_home)
 | 
			
		||||
| 
						 | 
				
			
			@ -660,10 +685,10 @@ TEXT
 | 
			
		|||
    return <<-TEXT
 | 
			
		||||
@ECHO OFF
 | 
			
		||||
IF NOT "%~f0" == "~f0" GOTO :WinNT
 | 
			
		||||
@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
 | 
			
		||||
@"#{bindir.tr(File::SEPARATOR, File::ALT_SEPARATOR)}\\#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
 | 
			
		||||
GOTO :EOF
 | 
			
		||||
:WinNT
 | 
			
		||||
@"#{ruby}" "%~dpn0" %*
 | 
			
		||||
@"%~dp0#{ruby}" "%~dpn0" %*
 | 
			
		||||
TEXT
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,6 +101,8 @@ class Gem::InstallerTestCase < Gem::TestCase
 | 
			
		|||
 | 
			
		||||
    @installer      = util_installer @spec, @gemhome
 | 
			
		||||
    @user_installer = util_installer @user_spec, Gem.user_dir, :user
 | 
			
		||||
 | 
			
		||||
    Gem::Installer.path_warning = false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def util_gem_bindir spec = @spec # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,8 +100,8 @@ module Gem::LocalRemoteOptions
 | 
			
		|||
  def add_source_option
 | 
			
		||||
    accept_uri_http
 | 
			
		||||
 | 
			
		||||
    add_option(:"Local/Remote", '--source URL', URI::HTTP,
 | 
			
		||||
               'Add URL as a remote source for gems') do |source, options|
 | 
			
		||||
    add_option(:"Local/Remote", '-s', '--source URL', URI::HTTP,
 | 
			
		||||
               'Append URL to list of remote gem sources') do |source, options|
 | 
			
		||||
 | 
			
		||||
      source << '/' if source !~ /\/\z/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ class Gem::NameTuple
 | 
			
		|||
      "#{@name}-#{@version}"
 | 
			
		||||
    else
 | 
			
		||||
      "#{@name}-#{@version}-#{@platform}"
 | 
			
		||||
    end
 | 
			
		||||
    end.untaint
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +90,9 @@ class Gem::NameTuple
 | 
			
		|||
  alias to_s inspect # :nodoc:
 | 
			
		||||
 | 
			
		||||
  def <=> other
 | 
			
		||||
    to_a <=> other.to_a
 | 
			
		||||
    [@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1] <=>
 | 
			
		||||
      [other.name, other.version,
 | 
			
		||||
       other.platform == Gem::Platform::RUBY ? -1 : 1]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  include Comparable
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,10 +54,12 @@ class Gem::Package
 | 
			
		|||
  class FormatError < Error
 | 
			
		||||
    attr_reader :path
 | 
			
		||||
 | 
			
		||||
    def initialize message, path = nil
 | 
			
		||||
      @path = path
 | 
			
		||||
    def initialize message, source = nil
 | 
			
		||||
      if source
 | 
			
		||||
        @path = source.path
 | 
			
		||||
 | 
			
		||||
        message << " in #{path}" if path
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      super message
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +82,7 @@ class Gem::Package
 | 
			
		|||
 | 
			
		||||
  class TarInvalidError < Error; end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  attr_accessor :build_time # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -114,19 +117,26 @@ class Gem::Package
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Creates a new Gem::Package for the file at +gem+.
 | 
			
		||||
  # Creates a new Gem::Package for the file at +gem+. +gem+ can also be
 | 
			
		||||
  # provided as an IO object.
 | 
			
		||||
  #
 | 
			
		||||
  # If +gem+ is an existing file in the old format a Gem::Package::Old will be
 | 
			
		||||
  # returned.
 | 
			
		||||
 | 
			
		||||
  def self.new gem
 | 
			
		||||
    return super unless Gem::Package == self
 | 
			
		||||
    return super unless File.exist? gem
 | 
			
		||||
    gem = if gem.is_a?(Gem::Package::Source)
 | 
			
		||||
            gem
 | 
			
		||||
          elsif gem.respond_to? :read
 | 
			
		||||
            Gem::Package::IOSource.new gem
 | 
			
		||||
          else
 | 
			
		||||
            Gem::Package::FileSource.new gem
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
    start = File.read gem, 20
 | 
			
		||||
    return super(gem) unless Gem::Package == self
 | 
			
		||||
    return super unless gem.present?
 | 
			
		||||
 | 
			
		||||
    return super unless start
 | 
			
		||||
    return super unless start.include? 'MD5SUM ='
 | 
			
		||||
    return super unless gem.start
 | 
			
		||||
    return super unless gem.start.include? 'MD5SUM ='
 | 
			
		||||
 | 
			
		||||
    Gem::Package::Old.new gem
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +237,7 @@ class Gem::Package
 | 
			
		|||
 | 
			
		||||
    setup_signer
 | 
			
		||||
 | 
			
		||||
    open @gem, 'wb' do |gem_io|
 | 
			
		||||
    @gem.with_write_io do |gem_io|
 | 
			
		||||
      Gem::Package::TarWriter.new gem_io do |gem|
 | 
			
		||||
        add_metadata gem
 | 
			
		||||
        add_contents gem
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +265,7 @@ EOM
 | 
			
		|||
 | 
			
		||||
    @contents = []
 | 
			
		||||
 | 
			
		||||
    open @gem, 'rb' do |io|
 | 
			
		||||
    @gem.with_read_io do |io|
 | 
			
		||||
      gem_tar = Gem::Package::TarReader.new io
 | 
			
		||||
 | 
			
		||||
      gem_tar.each do |entry|
 | 
			
		||||
| 
						 | 
				
			
			@ -312,7 +322,7 @@ EOM
 | 
			
		|||
 | 
			
		||||
    FileUtils.mkdir_p destination_dir
 | 
			
		||||
 | 
			
		||||
    open @gem, 'rb' do |io|
 | 
			
		||||
    @gem.with_read_io do |io|
 | 
			
		||||
      reader = Gem::Package::TarReader.new io
 | 
			
		||||
 | 
			
		||||
      reader.each do |entry|
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +370,7 @@ EOM
 | 
			
		|||
          out.write entry.read
 | 
			
		||||
        end if entry.file?
 | 
			
		||||
 | 
			
		||||
        say destination if Gem.configuration.really_verbose
 | 
			
		||||
        verbose destination
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -490,7 +500,7 @@ EOM
 | 
			
		|||
    @files     = []
 | 
			
		||||
    @spec      = nil
 | 
			
		||||
 | 
			
		||||
    open @gem, 'rb' do |io|
 | 
			
		||||
    @gem.with_read_io do |io|
 | 
			
		||||
      Gem::Package::TarReader.new io do |reader|
 | 
			
		||||
        read_checksums reader
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -592,6 +602,9 @@ EOM
 | 
			
		|||
end
 | 
			
		||||
 | 
			
		||||
require 'rubygems/package/digest_io'
 | 
			
		||||
require 'rubygems/package/source'
 | 
			
		||||
require 'rubygems/package/file_source'
 | 
			
		||||
require 'rubygems/package/io_source'
 | 
			
		||||
require 'rubygems/package/old'
 | 
			
		||||
require 'rubygems/package/tar_header'
 | 
			
		||||
require 'rubygems/package/tar_reader'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										33
									
								
								lib/rubygems/package/file_source.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								lib/rubygems/package/file_source.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
##
 | 
			
		||||
# The primary source of gems is a file on disk, including all usages
 | 
			
		||||
# internal to rubygems.
 | 
			
		||||
#
 | 
			
		||||
# This is a private class, do not depend on it directly. Instead, pass a path
 | 
			
		||||
# object to `Gem::Package.new`.
 | 
			
		||||
 | 
			
		||||
class Gem::Package::FileSource < Gem::Package::Source # :nodoc: all
 | 
			
		||||
 | 
			
		||||
  attr_reader :path
 | 
			
		||||
 | 
			
		||||
  def initialize path
 | 
			
		||||
    @path = path
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def start
 | 
			
		||||
    @start ||= File.read path, 20
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def present?
 | 
			
		||||
    File.exist? path
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def with_write_io &block
 | 
			
		||||
    open path, 'wb', &block
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def with_read_io &block
 | 
			
		||||
    open path, 'rb', &block
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										45
									
								
								lib/rubygems/package/io_source.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								lib/rubygems/package/io_source.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
##
 | 
			
		||||
# Supports reading and writing gems from/to a generic IO object.  This is
 | 
			
		||||
# useful for other applications built on top of rubygems, such as
 | 
			
		||||
# rubygems.org.
 | 
			
		||||
#
 | 
			
		||||
# This is a private class, do not depend on it directly. Instead, pass an IO
 | 
			
		||||
# object to `Gem::Package.new`.
 | 
			
		||||
 | 
			
		||||
class Gem::Package::IOSource < Gem::Package::Source # :nodoc: all
 | 
			
		||||
 | 
			
		||||
  attr_reader :io
 | 
			
		||||
 | 
			
		||||
  def initialize io
 | 
			
		||||
    @io = io
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def start
 | 
			
		||||
    @start ||= begin
 | 
			
		||||
      if io.pos > 0
 | 
			
		||||
        raise Gem::Package::Error, "Cannot read start unless IO is at start"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      value = io.read 20
 | 
			
		||||
      io.rewind
 | 
			
		||||
      value
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def present?
 | 
			
		||||
    true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def with_read_io
 | 
			
		||||
    yield io
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def with_write_io
 | 
			
		||||
    yield io
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def path
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +37,7 @@ class Gem::Package::Old < Gem::Package
 | 
			
		|||
 | 
			
		||||
    return @contents if @contents
 | 
			
		||||
 | 
			
		||||
    open @gem, 'rb' do |io|
 | 
			
		||||
    @gem.with_read_io do |io|
 | 
			
		||||
      read_until_dashes io # spec
 | 
			
		||||
      header = file_list io
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ class Gem::Package::Old < Gem::Package
 | 
			
		|||
 | 
			
		||||
    errstr = "Error reading files from gem"
 | 
			
		||||
 | 
			
		||||
    open @gem, 'rb' do |io|
 | 
			
		||||
    @gem.with_read_io do |io|
 | 
			
		||||
      read_until_dashes io # spec
 | 
			
		||||
      header = file_list io
 | 
			
		||||
      raise Gem::Exception, errstr unless header
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ class Gem::Package::Old < Gem::Package
 | 
			
		|||
          out.write file_data
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        say destination if Gem.configuration.really_verbose
 | 
			
		||||
        verbose destination
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  rescue Zlib::DataError
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ class Gem::Package::Old < Gem::Package
 | 
			
		|||
 | 
			
		||||
    yaml = ''
 | 
			
		||||
 | 
			
		||||
    open @gem, 'rb' do |io|
 | 
			
		||||
    @gem.with_read_io do |io|
 | 
			
		||||
      skip_ruby io
 | 
			
		||||
      read_until_dashes io do |line|
 | 
			
		||||
        yaml << line
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								lib/rubygems/package/source.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lib/rubygems/package/source.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
class Gem::Package::Source # :nodoc:
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,6 +129,8 @@ class Gem::Package::TarReader::Entry
 | 
			
		|||
    ret
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  alias readpartial read # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Rewinds to the beginning of the tar file entry
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ class Gem::Platform
 | 
			
		|||
 | 
			
		||||
  def self.local
 | 
			
		||||
    arch = RbConfig::CONFIG['arch']
 | 
			
		||||
    arch = "#{arch}_60" if arch =~ /mswin32$/
 | 
			
		||||
    arch = "#{arch}_60" if arch =~ /mswin(?:32|64)$/
 | 
			
		||||
    @local ||= new(arch)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -173,6 +173,7 @@ class Gem::Platform
 | 
			
		|||
              when /^dalvik(\d+)?$/       then [nil,         'dalvik',  $1    ]
 | 
			
		||||
              when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet',  $2    ]
 | 
			
		||||
              when /mswin32(\_(\d+))?/    then ['x86',       'mswin32', $2    ]
 | 
			
		||||
              when /mswin64(\_(\d+))?/    then ['x64',       'mswin64', $2    ]
 | 
			
		||||
              when 'powerpc-darwin'       then ['powerpc',   'darwin',  nil   ]
 | 
			
		||||
              when /powerpc-darwin(\d)/   then ['powerpc',   'darwin',  $1    ]
 | 
			
		||||
              when /sparc-solaris2.8/     then ['sparc',     'solaris', '2.8' ]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -263,7 +263,7 @@ class Gem::RDoc # :nodoc: all
 | 
			
		|||
      Gem::Requirement.new('>= 2.4.0') =~ self.class.rdoc_version
 | 
			
		||||
 | 
			
		||||
    r = new_rdoc
 | 
			
		||||
    say "rdoc #{args.join ' '}" if Gem.configuration.really_verbose
 | 
			
		||||
    verbose { "rdoc #{args.join ' '}" }
 | 
			
		||||
 | 
			
		||||
    Dir.chdir @spec.full_gem_path do
 | 
			
		||||
      begin
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +279,6 @@ class Gem::RDoc # :nodoc: all
 | 
			
		|||
        ui.errs.puts "... RDOC args: #{args.join(' ')}"
 | 
			
		||||
        ui.backtrace ex
 | 
			
		||||
        ui.errs.puts "(continuing with the rest of the installation)"
 | 
			
		||||
      ensure
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ require 'rubygems'
 | 
			
		|||
require 'rubygems/request'
 | 
			
		||||
require 'rubygems/uri_formatter'
 | 
			
		||||
require 'rubygems/user_interaction'
 | 
			
		||||
require 'rubygems/request/connection_pools'
 | 
			
		||||
require 'resolv'
 | 
			
		||||
 | 
			
		||||
##
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +74,9 @@ class Gem::RemoteFetcher
 | 
			
		|||
    Socket.do_not_reverse_lookup = true
 | 
			
		||||
 | 
			
		||||
    @proxy = proxy
 | 
			
		||||
    @pools = {}
 | 
			
		||||
    @pool_lock = Mutex.new
 | 
			
		||||
    @cert_files = Gem::Request.get_cert_files
 | 
			
		||||
 | 
			
		||||
    @dns = dns
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -154,11 +158,10 @@ class Gem::RemoteFetcher
 | 
			
		|||
    # REFACTOR: split this up and dispatch on scheme (eg download_http)
 | 
			
		||||
    # REFACTOR: be sure to clean up fake fetcher when you do this... cleaner
 | 
			
		||||
    case scheme
 | 
			
		||||
    when 'http', 'https' then
 | 
			
		||||
    when 'http', 'https', 's3' then
 | 
			
		||||
      unless File.exist? local_gem_path then
 | 
			
		||||
        begin
 | 
			
		||||
          say "Downloading gem #{gem_file_name}" if
 | 
			
		||||
            Gem.configuration.really_verbose
 | 
			
		||||
          verbose "Downloading gem #{gem_file_name}"
 | 
			
		||||
 | 
			
		||||
          remote_gem_path = source_uri + "gems/#{gem_file_name}"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -168,8 +171,7 @@ class Gem::RemoteFetcher
 | 
			
		|||
 | 
			
		||||
          alternate_name = "#{spec.original_name}.gem"
 | 
			
		||||
 | 
			
		||||
          say "Failed, downloading gem #{alternate_name}" if
 | 
			
		||||
            Gem.configuration.really_verbose
 | 
			
		||||
          verbose "Failed, downloading gem #{alternate_name}"
 | 
			
		||||
 | 
			
		||||
          remote_gem_path = source_uri + "gems/#{alternate_name}"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -188,8 +190,7 @@ class Gem::RemoteFetcher
 | 
			
		|||
        local_gem_path = source_uri.to_s
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      say "Using local gem #{local_gem_path}" if
 | 
			
		||||
        Gem.configuration.really_verbose
 | 
			
		||||
      verbose "Using local gem #{local_gem_path}"
 | 
			
		||||
    when nil then # TODO test for local overriding cache
 | 
			
		||||
      source_path = if Gem.win_platform? && source_uri.scheme &&
 | 
			
		||||
                       !source_uri.path.include?(':') then
 | 
			
		||||
| 
						 | 
				
			
			@ -207,8 +208,7 @@ class Gem::RemoteFetcher
 | 
			
		|||
        local_gem_path = source_uri.to_s
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      say "Using local gem #{local_gem_path}" if
 | 
			
		||||
        Gem.configuration.really_verbose
 | 
			
		||||
      verbose "Using local gem #{local_gem_path}"
 | 
			
		||||
    else
 | 
			
		||||
      raise ArgumentError, "unsupported URI scheme #{source_uri.scheme}"
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +232,7 @@ class Gem::RemoteFetcher
 | 
			
		|||
 | 
			
		||||
    case response
 | 
			
		||||
    when Net::HTTPOK, Net::HTTPNotModified then
 | 
			
		||||
      response.uri = uri if response.respond_to? :uri
 | 
			
		||||
      head ? response : response.body
 | 
			
		||||
    when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
 | 
			
		||||
         Net::HTTPTemporaryRedirect then
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +266,7 @@ class Gem::RemoteFetcher
 | 
			
		|||
 | 
			
		||||
    data = send "fetch_#{uri.scheme}", uri, mtime, head
 | 
			
		||||
 | 
			
		||||
    if data and !head and uri.to_s =~ /gz$/
 | 
			
		||||
    if data and !head and uri.to_s =~ /\.gz$/
 | 
			
		||||
      begin
 | 
			
		||||
        data = Gem.gunzip data
 | 
			
		||||
      rescue Zlib::GzipFile::Error
 | 
			
		||||
| 
						 | 
				
			
			@ -286,6 +287,11 @@ class Gem::RemoteFetcher
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def fetch_s3(uri, mtime = nil, head = false)
 | 
			
		||||
    public_uri = sign_s3_url(uri)
 | 
			
		||||
    fetch_https public_uri, mtime, head
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Downloads +uri+ to +path+ if necessary. If no path is given, it just
 | 
			
		||||
  # passes the data.
 | 
			
		||||
| 
						 | 
				
			
			@ -332,18 +338,57 @@ class Gem::RemoteFetcher
 | 
			
		|||
  # connections to reduce connect overhead.
 | 
			
		||||
 | 
			
		||||
  def request(uri, request_class, last_modified = nil)
 | 
			
		||||
    request = Gem::Request.new uri, request_class, last_modified, @proxy
 | 
			
		||||
    proxy = proxy_for @proxy, uri
 | 
			
		||||
    pool  = pools_for(proxy).pool_for uri
 | 
			
		||||
 | 
			
		||||
    request = Gem::Request.new uri, request_class, last_modified, pool
 | 
			
		||||
 | 
			
		||||
    request.fetch do |req|
 | 
			
		||||
      yield req if block_given?
 | 
			
		||||
    end
 | 
			
		||||
  ensure
 | 
			
		||||
    request.close if request
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def https?(uri)
 | 
			
		||||
    uri.scheme.downcase == 'https'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
  # we have our own signing code here to avoid a dependency on the aws-sdk gem
 | 
			
		||||
  # fortunately, a simple GET request isn't too complex to sign properly
 | 
			
		||||
  def sign_s3_url(uri, expiration = nil)
 | 
			
		||||
    require 'base64'
 | 
			
		||||
    require 'openssl'
 | 
			
		||||
 | 
			
		||||
    unless uri.user && uri.password
 | 
			
		||||
      raise FetchError.new("credentials needed in s3 source, like s3://key:secret@bucket-name/", uri.to_s)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expiration ||= s3_expiration
 | 
			
		||||
    canonical_path = "/#{uri.host}#{uri.path}"
 | 
			
		||||
    payload = "GET\n\n\n#{expiration}\n#{canonical_path}"
 | 
			
		||||
    digest = OpenSSL::HMAC.digest('sha1', uri.password, payload)
 | 
			
		||||
    # URI.escape is deprecated, and there isn't yet a replacement that does quite what we want
 | 
			
		||||
    signature = Base64.encode64(digest).gsub("\n", '').gsub(/[\+\/=]/) { |c| BASE64_URI_TRANSLATE[c] }
 | 
			
		||||
    URI.parse("https://#{uri.host}.s3.amazonaws.com#{uri.path}?AWSAccessKeyId=#{uri.user}&Expires=#{expiration}&Signature=#{signature}")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def s3_expiration
 | 
			
		||||
    (Time.now + 3600).to_i # one hour from now
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  BASE64_URI_TRANSLATE = { '+' => '%2B', '/' => '%2F', '=' => '%3D' }.freeze
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def proxy_for proxy, uri
 | 
			
		||||
    Gem::Request.proxy_uri(proxy || Gem::Request.get_proxy_from_env(uri.scheme))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pools_for proxy
 | 
			
		||||
    @pool_lock.synchronize do
 | 
			
		||||
      @pools[proxy] ||= Gem::Request::ConnectionPools.new proxy, @cert_files
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,41 +7,43 @@ class Gem::Request
 | 
			
		|||
 | 
			
		||||
  include Gem::UserInteraction
 | 
			
		||||
 | 
			
		||||
  attr_reader :proxy_uri
 | 
			
		||||
  ###
 | 
			
		||||
  # Legacy.  This is used in tests.
 | 
			
		||||
  def self.create_with_proxy uri, request_class, last_modified, proxy # :nodoc:
 | 
			
		||||
    cert_files = get_cert_files
 | 
			
		||||
    proxy ||= get_proxy_from_env(uri.scheme)
 | 
			
		||||
    pool       = ConnectionPools.new proxy_uri(proxy), cert_files
 | 
			
		||||
 | 
			
		||||
  def initialize(uri, request_class, last_modified, proxy)
 | 
			
		||||
    new(uri, request_class, last_modified, pool.pool_for(uri))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.proxy_uri proxy # :nodoc:
 | 
			
		||||
    case proxy
 | 
			
		||||
    when :no_proxy then nil
 | 
			
		||||
    when URI::HTTP then proxy
 | 
			
		||||
    else URI.parse(proxy)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def initialize(uri, request_class, last_modified, pool)
 | 
			
		||||
    @uri = uri
 | 
			
		||||
    @request_class = request_class
 | 
			
		||||
    @last_modified = last_modified
 | 
			
		||||
    @requests = Hash.new 0
 | 
			
		||||
    @connections = {}
 | 
			
		||||
    @connections_mutex = Mutex.new
 | 
			
		||||
    @user_agent = user_agent
 | 
			
		||||
 | 
			
		||||
    @proxy_uri =
 | 
			
		||||
      case proxy
 | 
			
		||||
      when :no_proxy then nil
 | 
			
		||||
      when nil       then get_proxy_from_env uri.scheme
 | 
			
		||||
      when URI::HTTP then proxy
 | 
			
		||||
      else URI.parse(proxy)
 | 
			
		||||
      end
 | 
			
		||||
    @env_no_proxy = get_no_proxy_from_env
 | 
			
		||||
    @connection_pool = pool
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def close
 | 
			
		||||
    @connections.each_value do |conn|
 | 
			
		||||
      conn.finish
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  def proxy_uri; @connection_pool.proxy_uri; end
 | 
			
		||||
  def cert_files; @connection_pool.cert_files; end
 | 
			
		||||
 | 
			
		||||
  def add_rubygems_trusted_certs(store)
 | 
			
		||||
  def self.get_cert_files
 | 
			
		||||
    pattern = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__))
 | 
			
		||||
    Dir.glob(pattern).each do |ssl_cert_file|
 | 
			
		||||
      store.add_file ssl_cert_file
 | 
			
		||||
    end
 | 
			
		||||
    Dir.glob(pattern)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def configure_connection_for_https(connection)
 | 
			
		||||
  def self.configure_connection_for_https(connection, cert_files)
 | 
			
		||||
    require 'net/https'
 | 
			
		||||
    connection.use_ssl = true
 | 
			
		||||
    connection.verify_mode =
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +57,9 @@ class Gem::Request
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    store.set_default_paths
 | 
			
		||||
    add_rubygems_trusted_certs(store)
 | 
			
		||||
    cert_files.each do |ssl_cert_file|
 | 
			
		||||
      store.add_file ssl_cert_file
 | 
			
		||||
    end
 | 
			
		||||
    if Gem.configuration.ssl_ca_cert
 | 
			
		||||
      if File.directory? Gem.configuration.ssl_ca_cert
 | 
			
		||||
        store.add_path Gem.configuration.ssl_ca_cert
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +68,7 @@ class Gem::Request
 | 
			
		|||
      end
 | 
			
		||||
    end
 | 
			
		||||
    connection.cert_store = store
 | 
			
		||||
    connection
 | 
			
		||||
  rescue LoadError => e
 | 
			
		||||
    raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
 | 
			
		||||
                 e.message =~ / -- openssl$/
 | 
			
		||||
| 
						 | 
				
			
			@ -77,31 +82,7 @@ class Gem::Request
 | 
			
		|||
  # connection, using a proxy if needed.
 | 
			
		||||
 | 
			
		||||
  def connection_for(uri)
 | 
			
		||||
    net_http_args = [uri.host, uri.port]
 | 
			
		||||
 | 
			
		||||
    if @proxy_uri and not no_proxy?(uri.host) then
 | 
			
		||||
      net_http_args += [
 | 
			
		||||
        @proxy_uri.host,
 | 
			
		||||
        @proxy_uri.port,
 | 
			
		||||
        Gem::UriFormatter.new(@proxy_uri.user).unescape,
 | 
			
		||||
        Gem::UriFormatter.new(@proxy_uri.password).unescape,
 | 
			
		||||
      ]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    connection_id = [Thread.current.object_id, *net_http_args].join ':'
 | 
			
		||||
 | 
			
		||||
    connection = @connections_mutex.synchronize do
 | 
			
		||||
      @connections[connection_id] ||= Net::HTTP.new(*net_http_args)
 | 
			
		||||
      @connections[connection_id]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if https?(uri) and not connection.started? then
 | 
			
		||||
      configure_connection_for_https(connection)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    connection.start unless connection.started?
 | 
			
		||||
 | 
			
		||||
    connection
 | 
			
		||||
    @connection_pool.checkout
 | 
			
		||||
  rescue defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : Errno::EHOSTDOWN,
 | 
			
		||||
         Errno::EHOSTDOWN => e
 | 
			
		||||
    raise Gem::RemoteFetcher::FetchError.new(e.message, uri)
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +106,37 @@ class Gem::Request
 | 
			
		|||
 | 
			
		||||
    yield request if block_given?
 | 
			
		||||
 | 
			
		||||
    perform_request request
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Returns a proxy URI for the given +scheme+ if one is set in the
 | 
			
		||||
  # environment variables.
 | 
			
		||||
 | 
			
		||||
  def self.get_proxy_from_env scheme = 'http'
 | 
			
		||||
    _scheme = scheme.downcase
 | 
			
		||||
    _SCHEME = scheme.upcase
 | 
			
		||||
    env_proxy = ENV["#{_scheme}_proxy"] || ENV["#{_SCHEME}_PROXY"]
 | 
			
		||||
 | 
			
		||||
    no_env_proxy = env_proxy.nil? || env_proxy.empty?
 | 
			
		||||
 | 
			
		||||
    return get_proxy_from_env 'http' if no_env_proxy and _scheme != 'http'
 | 
			
		||||
    return :no_proxy                 if no_env_proxy
 | 
			
		||||
 | 
			
		||||
    uri = URI(Gem::UriFormatter.new(env_proxy).normalize)
 | 
			
		||||
 | 
			
		||||
    if uri and uri.user.nil? and uri.password.nil? then
 | 
			
		||||
      user     = ENV["#{_scheme}_proxy_user"] || ENV["#{_SCHEME}_PROXY_USER"]
 | 
			
		||||
      password = ENV["#{_scheme}_proxy_pass"] || ENV["#{_SCHEME}_PROXY_PASS"]
 | 
			
		||||
 | 
			
		||||
      uri.user     = Gem::UriFormatter.new(user).escape
 | 
			
		||||
      uri.password = Gem::UriFormatter.new(password).escape
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    uri
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def perform_request request # :nodoc:
 | 
			
		||||
    connection = connection_for @uri
 | 
			
		||||
 | 
			
		||||
    retried = false
 | 
			
		||||
| 
						 | 
				
			
			@ -133,8 +145,7 @@ class Gem::Request
 | 
			
		|||
    begin
 | 
			
		||||
      @requests[connection.object_id] += 1
 | 
			
		||||
 | 
			
		||||
      say "#{request.method} #{@uri}" if
 | 
			
		||||
        Gem.configuration.really_verbose
 | 
			
		||||
      verbose "#{request.method} #{@uri}"
 | 
			
		||||
 | 
			
		||||
      file_name = File.basename(@uri.path)
 | 
			
		||||
      # perform download progress reporter only for gems
 | 
			
		||||
| 
						 | 
				
			
			@ -163,11 +174,10 @@ class Gem::Request
 | 
			
		|||
        response = connection.request request
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      say "#{response.code} #{response.message}" if
 | 
			
		||||
        Gem.configuration.really_verbose
 | 
			
		||||
      verbose "#{response.code} #{response.message}"
 | 
			
		||||
 | 
			
		||||
    rescue Net::HTTPBadResponse
 | 
			
		||||
      say "bad response" if Gem.configuration.really_verbose
 | 
			
		||||
      verbose "bad response"
 | 
			
		||||
 | 
			
		||||
      reset connection
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -182,8 +192,7 @@ class Gem::Request
 | 
			
		|||
           Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE
 | 
			
		||||
 | 
			
		||||
      requests = @requests[connection.object_id]
 | 
			
		||||
      say "connection reset after #{requests} requests, retrying" if
 | 
			
		||||
        Gem.configuration.really_verbose
 | 
			
		||||
      verbose "connection reset after #{requests} requests, retrying"
 | 
			
		||||
 | 
			
		||||
      raise Gem::RemoteFetcher::FetchError.new('too many connection resets', @uri) if retried
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -194,57 +203,8 @@ class Gem::Request
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    response
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Returns list of no_proxy entries (if any) from the environment
 | 
			
		||||
 | 
			
		||||
  def get_no_proxy_from_env
 | 
			
		||||
    env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
 | 
			
		||||
 | 
			
		||||
    return [] if env_no_proxy.nil?  or env_no_proxy.empty?
 | 
			
		||||
 | 
			
		||||
    env_no_proxy.split(/\s*,\s*/)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Returns a proxy URI for the given +scheme+ if one is set in the
 | 
			
		||||
  # environment variables.
 | 
			
		||||
 | 
			
		||||
  def get_proxy_from_env scheme = 'http'
 | 
			
		||||
    _scheme = scheme.downcase
 | 
			
		||||
    _SCHEME = scheme.upcase
 | 
			
		||||
    env_proxy = ENV["#{_scheme}_proxy"] || ENV["#{_SCHEME}_PROXY"]
 | 
			
		||||
 | 
			
		||||
    no_env_proxy = env_proxy.nil? || env_proxy.empty?
 | 
			
		||||
 | 
			
		||||
    return get_proxy_from_env 'http' if no_env_proxy and _scheme != 'http'
 | 
			
		||||
    return nil                       if no_env_proxy
 | 
			
		||||
 | 
			
		||||
    uri = URI(Gem::UriFormatter.new(env_proxy).normalize)
 | 
			
		||||
 | 
			
		||||
    if uri and uri.user.nil? and uri.password.nil? then
 | 
			
		||||
      user     = ENV["#{_scheme}_proxy_user"] || ENV["#{_SCHEME}_PROXY_USER"]
 | 
			
		||||
      password = ENV["#{_scheme}_proxy_pass"] || ENV["#{_SCHEME}_PROXY_PASS"]
 | 
			
		||||
 | 
			
		||||
      uri.user     = Gem::UriFormatter.new(user).escape
 | 
			
		||||
      uri.password = Gem::UriFormatter.new(password).escape
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    uri
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def https?(uri)
 | 
			
		||||
    uri.scheme.downcase == 'https'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def no_proxy? host
 | 
			
		||||
    host = host.downcase
 | 
			
		||||
    @env_no_proxy.each do |pattern|
 | 
			
		||||
      pattern = pattern.downcase
 | 
			
		||||
      return true if host[-pattern.length, pattern.length ] == pattern
 | 
			
		||||
    end
 | 
			
		||||
    return false
 | 
			
		||||
  ensure
 | 
			
		||||
    @connection_pool.checkin connection
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -278,3 +238,7 @@ class Gem::Request
 | 
			
		|||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
require 'rubygems/request/http_pool'
 | 
			
		||||
require 'rubygems/request/https_pool'
 | 
			
		||||
require 'rubygems/request/connection_pools'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										79
									
								
								lib/rubygems/request/connection_pools.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								lib/rubygems/request/connection_pools.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
require 'thread'
 | 
			
		||||
 | 
			
		||||
class Gem::Request::ConnectionPools # :nodoc:
 | 
			
		||||
 | 
			
		||||
  @client = Net::HTTP
 | 
			
		||||
 | 
			
		||||
  class << self
 | 
			
		||||
    attr_accessor :client
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def initialize proxy_uri, cert_files
 | 
			
		||||
    @proxy_uri  = proxy_uri
 | 
			
		||||
    @cert_files = cert_files
 | 
			
		||||
    @pools      = {}
 | 
			
		||||
    @pool_mutex = Mutex.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pool_for uri
 | 
			
		||||
    http_args = net_http_args(uri, @proxy_uri)
 | 
			
		||||
    key       = http_args + [https?(uri)]
 | 
			
		||||
    @pool_mutex.synchronize do
 | 
			
		||||
      @pools[key] ||=
 | 
			
		||||
        if https? uri then
 | 
			
		||||
          Gem::Request::HTTPSPool.new(http_args, @cert_files, @proxy_uri)
 | 
			
		||||
        else
 | 
			
		||||
          Gem::Request::HTTPPool.new(http_args, @cert_files, @proxy_uri)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Returns list of no_proxy entries (if any) from the environment
 | 
			
		||||
 | 
			
		||||
  def get_no_proxy_from_env
 | 
			
		||||
    env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
 | 
			
		||||
 | 
			
		||||
    return [] if env_no_proxy.nil?  or env_no_proxy.empty?
 | 
			
		||||
 | 
			
		||||
    env_no_proxy.split(/\s*,\s*/)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def https? uri
 | 
			
		||||
    uri.scheme.downcase == 'https'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def no_proxy? host, env_no_proxy
 | 
			
		||||
    host = host.downcase
 | 
			
		||||
 | 
			
		||||
    env_no_proxy.any? do |pattern|
 | 
			
		||||
      pattern = pattern.downcase
 | 
			
		||||
 | 
			
		||||
      host[-pattern.length, pattern.length] == pattern or
 | 
			
		||||
        (pattern.start_with? '.' and pattern[1..-1] == host)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def net_http_args uri, proxy_uri
 | 
			
		||||
    net_http_args = [uri.host, uri.port]
 | 
			
		||||
 | 
			
		||||
    no_proxy = get_no_proxy_from_env
 | 
			
		||||
 | 
			
		||||
    if proxy_uri and not no_proxy?(uri.host, no_proxy) then
 | 
			
		||||
      net_http_args + [
 | 
			
		||||
        proxy_uri.host,
 | 
			
		||||
        proxy_uri.port,
 | 
			
		||||
        Gem::UriFormatter.new(proxy_uri.user).unescape,
 | 
			
		||||
        Gem::UriFormatter.new(proxy_uri.password).unescape,
 | 
			
		||||
      ]
 | 
			
		||||
    elsif no_proxy? uri.host, no_proxy then
 | 
			
		||||
      net_http_args += [nil, nil]
 | 
			
		||||
    else
 | 
			
		||||
      net_http_args
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										38
									
								
								lib/rubygems/request/http_pool.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								lib/rubygems/request/http_pool.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
##
 | 
			
		||||
# A connection "pool" that only manages one connection for now.  Provides
 | 
			
		||||
# thread safe `checkout` and `checkin` methods.  The pool consists of one
 | 
			
		||||
# connection that corresponds to `http_args`.  This class is private, do not
 | 
			
		||||
# use it.
 | 
			
		||||
 | 
			
		||||
class Gem::Request::HTTPPool # :nodoc:
 | 
			
		||||
  attr_reader :cert_files, :proxy_uri
 | 
			
		||||
 | 
			
		||||
  def initialize http_args, cert_files, proxy_uri
 | 
			
		||||
    @http_args  = http_args
 | 
			
		||||
    @cert_files = cert_files
 | 
			
		||||
    @proxy_uri  = proxy_uri
 | 
			
		||||
    @queue      = SizedQueue.new 1
 | 
			
		||||
    @queue << nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def checkout
 | 
			
		||||
    @queue.pop || make_connection
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def checkin connection
 | 
			
		||||
    @queue.push connection
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def make_connection
 | 
			
		||||
    setup_connection Gem::Request::ConnectionPools.client.new(*@http_args)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def setup_connection connection
 | 
			
		||||
    connection.start
 | 
			
		||||
    connection
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								lib/rubygems/request/https_pool.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/rubygems/request/https_pool.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
class Gem::Request::HTTPSPool < Gem::Request::HTTPPool # :nodoc:
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def setup_connection connection
 | 
			
		||||
    Gem::Request.configure_connection_for_https(connection, @cert_files)
 | 
			
		||||
    super
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
require 'rubygems'
 | 
			
		||||
require 'tsort'
 | 
			
		||||
 | 
			
		||||
##
 | 
			
		||||
| 
						 | 
				
			
			@ -21,12 +20,22 @@ class Gem::RequestSet
 | 
			
		|||
  ##
 | 
			
		||||
  # Array of gems to install even if already installed
 | 
			
		||||
 | 
			
		||||
  attr_reader :always_install
 | 
			
		||||
  attr_accessor :always_install
 | 
			
		||||
 | 
			
		||||
  attr_reader :dependencies
 | 
			
		||||
 | 
			
		||||
  attr_accessor :development
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Errors fetching gems during resolution.
 | 
			
		||||
 | 
			
		||||
  attr_reader :errors
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Set to true if you want to install only direct development dependencies.
 | 
			
		||||
 | 
			
		||||
  attr_accessor :development_shallow
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The set of git gems imported via load_gemdeps.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,11 +47,20 @@ class Gem::RequestSet
 | 
			
		|||
 | 
			
		||||
  attr_accessor :ignore_dependencies
 | 
			
		||||
 | 
			
		||||
  attr_reader :install_dir # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # If true, allow dependencies to match prerelease gems.
 | 
			
		||||
 | 
			
		||||
  attr_accessor :prerelease
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # When false no remote sets are used for resolving gems.
 | 
			
		||||
 | 
			
		||||
  attr_accessor :remote
 | 
			
		||||
 | 
			
		||||
  attr_reader :resolver # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Sets used for resolution
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -71,11 +89,15 @@ class Gem::RequestSet
 | 
			
		|||
    @dependencies = deps
 | 
			
		||||
 | 
			
		||||
    @always_install      = []
 | 
			
		||||
    @conservative        = false
 | 
			
		||||
    @dependency_names    = {}
 | 
			
		||||
    @development         = false
 | 
			
		||||
    @development_shallow = false
 | 
			
		||||
    @errors              = []
 | 
			
		||||
    @git_set             = nil
 | 
			
		||||
    @ignore_dependencies = false
 | 
			
		||||
    @install_dir         = Gem.dir
 | 
			
		||||
    @prerelease          = false
 | 
			
		||||
    @remote              = true
 | 
			
		||||
    @requests            = []
 | 
			
		||||
    @sets                = []
 | 
			
		||||
| 
						 | 
				
			
			@ -116,12 +138,14 @@ class Gem::RequestSet
 | 
			
		|||
 | 
			
		||||
  def install options, &block # :yields: request, installer
 | 
			
		||||
    if dir = options[:install_dir]
 | 
			
		||||
      return install_into dir, false, options, &block
 | 
			
		||||
      requests = install_into dir, false, options, &block
 | 
			
		||||
      return requests
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    cache_dir = options[:cache_dir] || Gem.dir
 | 
			
		||||
    @prerelease = options[:prerelease]
 | 
			
		||||
 | 
			
		||||
    specs = []
 | 
			
		||||
    requests = []
 | 
			
		||||
 | 
			
		||||
    sorted_requests.each do |req|
 | 
			
		||||
      if req.installed? then
 | 
			
		||||
| 
						 | 
				
			
			@ -139,10 +163,30 @@ class Gem::RequestSet
 | 
			
		|||
 | 
			
		||||
      yield req, inst if block_given?
 | 
			
		||||
 | 
			
		||||
      specs << inst.install
 | 
			
		||||
      requests << inst.install
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    specs
 | 
			
		||||
    requests
 | 
			
		||||
  ensure
 | 
			
		||||
    raise if $!
 | 
			
		||||
    return requests if options[:gemdeps]
 | 
			
		||||
 | 
			
		||||
    specs = requests.map do |request|
 | 
			
		||||
      case request
 | 
			
		||||
      when Gem::Resolver::ActivationRequest then
 | 
			
		||||
        request.spec.spec
 | 
			
		||||
      else
 | 
			
		||||
        request
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    require 'rubygems/dependency_installer'
 | 
			
		||||
    inst = Gem::DependencyInstaller.new options
 | 
			
		||||
    inst.installed_gems.replace specs
 | 
			
		||||
 | 
			
		||||
    Gem.done_installing_hooks.each do |hook|
 | 
			
		||||
      hook.call inst, specs
 | 
			
		||||
    end unless Gem.done_installing_hooks.empty?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -156,17 +200,19 @@ class Gem::RequestSet
 | 
			
		|||
    gemdeps = options[:gemdeps]
 | 
			
		||||
 | 
			
		||||
    @install_dir = options[:install_dir] || Gem.dir
 | 
			
		||||
    @prerelease  = options[:prerelease]
 | 
			
		||||
    @remote      = options[:domain] != :local
 | 
			
		||||
    @conservative = true if options[:conservative]
 | 
			
		||||
 | 
			
		||||
    load_gemdeps gemdeps, options[:without_groups]
 | 
			
		||||
    gem_deps_api = load_gemdeps gemdeps, options[:without_groups], true
 | 
			
		||||
 | 
			
		||||
    resolve
 | 
			
		||||
 | 
			
		||||
    if options[:explain]
 | 
			
		||||
      puts "Gems to install:"
 | 
			
		||||
 | 
			
		||||
      specs.map { |s| s.full_name }.sort.each do |s|
 | 
			
		||||
        puts "  #{s}"
 | 
			
		||||
      sorted_requests.each do |spec|
 | 
			
		||||
        puts "  #{spec.full_name}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if Gem.configuration.really_verbose
 | 
			
		||||
| 
						 | 
				
			
			@ -175,8 +221,11 @@ class Gem::RequestSet
 | 
			
		|||
    else
 | 
			
		||||
      installed = install options, &block
 | 
			
		||||
 | 
			
		||||
      lockfile = Gem::RequestSet::Lockfile.new self, gemdeps
 | 
			
		||||
      if options.fetch :lock, true then
 | 
			
		||||
        lockfile =
 | 
			
		||||
          Gem::RequestSet::Lockfile.new self, gemdeps, gem_deps_api.dependencies
 | 
			
		||||
        lockfile.write
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      installed
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -192,8 +241,10 @@ class Gem::RequestSet
 | 
			
		|||
 | 
			
		||||
    installed = []
 | 
			
		||||
 | 
			
		||||
    options[:development] = false
 | 
			
		||||
    options[:install_dir] = dir
 | 
			
		||||
    options[:only_install_dir] = true
 | 
			
		||||
    @prerelease = options[:prerelease]
 | 
			
		||||
 | 
			
		||||
    sorted_requests.each do |request|
 | 
			
		||||
      spec = request.spec
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +269,7 @@ class Gem::RequestSet
 | 
			
		|||
  ##
 | 
			
		||||
  # Load a dependency management file.
 | 
			
		||||
 | 
			
		||||
  def load_gemdeps path, without_groups = []
 | 
			
		||||
  def load_gemdeps path, without_groups = [], installing = false
 | 
			
		||||
    @git_set    = Gem::Resolver::GitSet.new
 | 
			
		||||
    @vendor_set = Gem::Resolver::VendorSet.new
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -228,6 +279,7 @@ class Gem::RequestSet
 | 
			
		|||
    lockfile.parse
 | 
			
		||||
 | 
			
		||||
    gf = Gem::RequestSet::GemDependencyAPI.new self, path
 | 
			
		||||
    gf.installing = installing
 | 
			
		||||
    gf.without_groups = without_groups if without_groups
 | 
			
		||||
    gf.load
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -243,15 +295,29 @@ class Gem::RequestSet
 | 
			
		|||
 | 
			
		||||
    set = Gem::Resolver.compose_sets(*@sets)
 | 
			
		||||
    set.remote = @remote
 | 
			
		||||
    set.prerelease = @prerelease
 | 
			
		||||
 | 
			
		||||
    resolver = Gem::Resolver.new @dependencies, set
 | 
			
		||||
    resolver.development         = @development
 | 
			
		||||
    resolver.development_shallow = @development_shallow
 | 
			
		||||
    resolver.ignore_dependencies = @ignore_dependencies
 | 
			
		||||
    resolver.soft_missing        = @soft_missing
 | 
			
		||||
 | 
			
		||||
    if @conservative
 | 
			
		||||
      installed_gems = {}
 | 
			
		||||
      Gem::Specification.find_all do |spec|
 | 
			
		||||
        (installed_gems[spec.name] ||= []) << spec
 | 
			
		||||
      end
 | 
			
		||||
      resolver.skip_gems = installed_gems
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @resolver = resolver
 | 
			
		||||
 | 
			
		||||
    @requests = resolver.resolve
 | 
			
		||||
 | 
			
		||||
    @errors = set.errors
 | 
			
		||||
 | 
			
		||||
    @requests
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -284,17 +350,21 @@ class Gem::RequestSet
 | 
			
		|||
    node.spec.dependencies.each do |dep|
 | 
			
		||||
      next if dep.type == :development and not @development
 | 
			
		||||
 | 
			
		||||
      match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
 | 
			
		||||
      if match
 | 
			
		||||
      match = @requests.find { |r|
 | 
			
		||||
        dep.match? r.spec.name, r.spec.version, @prerelease
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      unless match then
 | 
			
		||||
        next if dep.type == :development and @development_shallow
 | 
			
		||||
        next if @soft_missing
 | 
			
		||||
        raise Gem::DependencyError,
 | 
			
		||||
              "Unresolved dependency found during sorting - #{dep} (requested by #{node.spec.full_name})"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
        yield match
 | 
			
		||||
      rescue TSort::Cyclic
 | 
			
		||||
      end
 | 
			
		||||
      else
 | 
			
		||||
        unless @soft_missing
 | 
			
		||||
          raise Gem::DependencyError, "Unresolved dependency found during sorting - #{dep} (requested by #{node.spec.full_name})"
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,33 @@
 | 
			
		|||
##
 | 
			
		||||
# A semi-compatible DSL for the Bundler Gemfile and Isolate formats.
 | 
			
		||||
# A semi-compatible DSL for the Bundler Gemfile and Isolate gem dependencies
 | 
			
		||||
# files.
 | 
			
		||||
#
 | 
			
		||||
# To work with both the Bundler Gemfile and Isolate formats this
 | 
			
		||||
# implementation takes some liberties to allow compatibility with each, most
 | 
			
		||||
# notably in #source.
 | 
			
		||||
#
 | 
			
		||||
# A basic gem dependencies file will look like the following:
 | 
			
		||||
#
 | 
			
		||||
#   source 'https://rubygems.org'
 | 
			
		||||
#
 | 
			
		||||
#   gem 'rails', '3.2.14a
 | 
			
		||||
#   gem 'devise', '~> 2.1', '>= 2.1.3'
 | 
			
		||||
#   gem 'cancan'
 | 
			
		||||
#   gem 'airbrake'
 | 
			
		||||
#   gem 'pg'
 | 
			
		||||
#
 | 
			
		||||
# RubyGems recommends saving this as gem.deps.rb over Gemfile or Isolate.
 | 
			
		||||
#
 | 
			
		||||
# To install the gems in this Gemfile use `gem install -g` to install it and
 | 
			
		||||
# create a lockfile.  The lockfile will ensure that when you make changes to
 | 
			
		||||
# your gem dependencies file a minimum amount of change is made to the
 | 
			
		||||
# dependencies of your gems.
 | 
			
		||||
#
 | 
			
		||||
# RubyGems can activate all the gems in your dependencies file at startup
 | 
			
		||||
# using the RUBYGEMS_GEMDEPS environment variable or through Gem.use_gemdeps.
 | 
			
		||||
# See Gem.use_gemdeps for details and warnings.
 | 
			
		||||
#
 | 
			
		||||
# See `gem help install` and `gem help gem_dependencies` for further details.
 | 
			
		||||
 | 
			
		||||
class Gem::RequestSet::GemDependencyAPI
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +49,8 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
    :ruby_21      => %w[ruby rbx maglev],
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  mswin     = Gem::Platform.new 'x86-mswin32'
 | 
			
		||||
  mswin64   = Gem::Platform.new 'x64-mswin64'
 | 
			
		||||
  x86_mingw = Gem::Platform.new 'x86-mingw32'
 | 
			
		||||
  x64_mingw = Gem::Platform.new 'x64-mingw32'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +69,15 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
    :mri_19       => Gem::Platform::RUBY,
 | 
			
		||||
    :mri_20       => Gem::Platform::RUBY,
 | 
			
		||||
    :mri_21       => Gem::Platform::RUBY,
 | 
			
		||||
    :mswin        => Gem::Platform::RUBY,
 | 
			
		||||
    :mswin        => mswin,
 | 
			
		||||
    :mswin_18     => mswin,
 | 
			
		||||
    :mswin_19     => mswin,
 | 
			
		||||
    :mswin_20     => mswin,
 | 
			
		||||
    :mswin_21     => mswin,
 | 
			
		||||
    :mswin64      => mswin64,
 | 
			
		||||
    :mswin64_19   => mswin64,
 | 
			
		||||
    :mswin64_20   => mswin64,
 | 
			
		||||
    :mswin64_21   => mswin64,
 | 
			
		||||
    :rbx          => Gem::Platform::RUBY,
 | 
			
		||||
    :ruby         => Gem::Platform::RUBY,
 | 
			
		||||
    :ruby_18      => Gem::Platform::RUBY,
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +111,14 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
    :mri_20       => tilde_gt_2_0_0,
 | 
			
		||||
    :mri_21       => tilde_gt_2_1_0,
 | 
			
		||||
    :mswin        => gt_eq_0,
 | 
			
		||||
    :mswin_18     => tilde_gt_1_8_0,
 | 
			
		||||
    :mswin_19     => tilde_gt_1_9_0,
 | 
			
		||||
    :mswin_20     => tilde_gt_2_0_0,
 | 
			
		||||
    :mswin_21     => tilde_gt_2_1_0,
 | 
			
		||||
    :mswin64      => gt_eq_0,
 | 
			
		||||
    :mswin64_19   => tilde_gt_1_9_0,
 | 
			
		||||
    :mswin64_20   => tilde_gt_2_0_0,
 | 
			
		||||
    :mswin64_21   => tilde_gt_2_1_0,
 | 
			
		||||
    :rbx          => gt_eq_0,
 | 
			
		||||
    :ruby         => gt_eq_0,
 | 
			
		||||
    :ruby_18      => tilde_gt_1_8_0,
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +142,14 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
    :mri_20       => :never,
 | 
			
		||||
    :mri_21       => :never,
 | 
			
		||||
    :mswin        => :only,
 | 
			
		||||
    :mswin_18     => :only,
 | 
			
		||||
    :mswin_19     => :only,
 | 
			
		||||
    :mswin_20     => :only,
 | 
			
		||||
    :mswin_21     => :only,
 | 
			
		||||
    :mswin64      => :only,
 | 
			
		||||
    :mswin64_19   => :only,
 | 
			
		||||
    :mswin64_20   => :only,
 | 
			
		||||
    :mswin64_21   => :only,
 | 
			
		||||
    :rbx          => :never,
 | 
			
		||||
    :ruby         => :never,
 | 
			
		||||
    :ruby_18      => :never,
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +161,11 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
    :x64_mingw_21 => :only,
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The gems required by #gem statements in the gem.deps.rb file
 | 
			
		||||
 | 
			
		||||
  attr_reader :dependencies
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # A set of gems that are loaded via the +:git+ option to #gem
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,14 +195,31 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
    @path = path
 | 
			
		||||
 | 
			
		||||
    @current_groups     = nil
 | 
			
		||||
    @current_platform   = nil
 | 
			
		||||
    @current_platforms  = nil
 | 
			
		||||
    @current_repository = nil
 | 
			
		||||
    @dependencies       = {}
 | 
			
		||||
    @default_sources    = true
 | 
			
		||||
    @git_set            = @set.git_set
 | 
			
		||||
    @git_sources        = {}
 | 
			
		||||
    @installing         = false
 | 
			
		||||
    @requires           = Hash.new { |h, name| h[name] = [] }
 | 
			
		||||
    @vendor_set         = @set.vendor_set
 | 
			
		||||
    @gem_sources        = {}
 | 
			
		||||
    @without_groups     = []
 | 
			
		||||
 | 
			
		||||
    git_source :github do |repo_name|
 | 
			
		||||
      repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"
 | 
			
		||||
 | 
			
		||||
      "git://github.com/#{repo_name}.git"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    git_source :bitbucket do |repo_name|
 | 
			
		||||
      repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include? "/"
 | 
			
		||||
 | 
			
		||||
      user, = repo_name.split "/", 2
 | 
			
		||||
 | 
			
		||||
      "https://#{user}@bitbucket.org/#{repo_name}.git"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -187,14 +263,26 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Loads the gem dependency file
 | 
			
		||||
  # Changes the behavior of gem dependency file loading to installing mode.
 | 
			
		||||
  # In installing mode certain restrictions are ignored such as ruby version
 | 
			
		||||
  # mismatch checks.
 | 
			
		||||
 | 
			
		||||
  def installing= installing # :nodoc:
 | 
			
		||||
    @installing = installing
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Loads the gem dependency file and returns self.
 | 
			
		||||
 | 
			
		||||
  def load
 | 
			
		||||
    instance_eval File.read(@path).untaint, @path, 1
 | 
			
		||||
 | 
			
		||||
    self
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  #
 | 
			
		||||
  # :call-seq:
 | 
			
		||||
  #   gem(name)
 | 
			
		||||
  #   gem(name, *requirements)
 | 
			
		||||
| 
						 | 
				
			
			@ -202,6 +290,66 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  #
 | 
			
		||||
  # Specifies a gem dependency with the given +name+ and +requirements+.  You
 | 
			
		||||
  # may also supply +options+ following the +requirements+
 | 
			
		||||
  #
 | 
			
		||||
  # +options+ include:
 | 
			
		||||
  #
 | 
			
		||||
  # require: ::
 | 
			
		||||
  #   RubyGems does not provide any autorequire features so requires in a gem
 | 
			
		||||
  #   dependencies file are recorded but ignored.
 | 
			
		||||
  #
 | 
			
		||||
  #   In bundler the require: option overrides the file to require during
 | 
			
		||||
  #   Bundler.require.  By default the name of the dependency is required in
 | 
			
		||||
  #   Bundler.  A single file or an Array of files may be given.
 | 
			
		||||
  #
 | 
			
		||||
  #   To disable requiring any file give +false+:
 | 
			
		||||
  #
 | 
			
		||||
  #     gem 'rake', require: false
 | 
			
		||||
  #
 | 
			
		||||
  # group: ::
 | 
			
		||||
  #   Place the dependencies in the given dependency group.  A single group or
 | 
			
		||||
  #   an Array of groups may be given.
 | 
			
		||||
  #
 | 
			
		||||
  #   See also #group
 | 
			
		||||
  #
 | 
			
		||||
  # platform: ::
 | 
			
		||||
  #   Only install the dependency on the given platform.  A single platform or
 | 
			
		||||
  #   an Array of platforms may be given.
 | 
			
		||||
  #
 | 
			
		||||
  #   See #platform for a list of platforms available.
 | 
			
		||||
  #
 | 
			
		||||
  # path: ::
 | 
			
		||||
  #   Install this dependency from an unpacked gem in the given directory.
 | 
			
		||||
  #
 | 
			
		||||
  #     gem 'modified_gem', path: 'vendor/modified_gem'
 | 
			
		||||
  #
 | 
			
		||||
  # git: ::
 | 
			
		||||
  #   Install this dependency from a git repository:
 | 
			
		||||
  #
 | 
			
		||||
  #     gem 'private_gem', git: git@my.company.example:private_gem.git'
 | 
			
		||||
  #
 | 
			
		||||
  # gist: ::
 | 
			
		||||
  #   Install this dependency from the gist ID:
 | 
			
		||||
  #
 | 
			
		||||
  #     gem 'bang', gist: '1232884'
 | 
			
		||||
  #
 | 
			
		||||
  # github: ::
 | 
			
		||||
  #   Install this dependency from a github git repository:
 | 
			
		||||
  #
 | 
			
		||||
  #     gem 'private_gem', github: 'my_company/private_gem'
 | 
			
		||||
  #
 | 
			
		||||
  # submodules: ::
 | 
			
		||||
  #   Set to +true+ to include submodules when fetching the git repository for
 | 
			
		||||
  #   git:, gist: and github: dependencies.
 | 
			
		||||
  #
 | 
			
		||||
  # ref: ::
 | 
			
		||||
  #   Use the given commit name or SHA for git:, gist: and github:
 | 
			
		||||
  #   dependencies.
 | 
			
		||||
  #
 | 
			
		||||
  # branch: ::
 | 
			
		||||
  #   Use the given branch for git:, gist: and github: dependencies.
 | 
			
		||||
  #
 | 
			
		||||
  # tag: ::
 | 
			
		||||
  #   Use the given tag for git:, gist: and github: dependencies.
 | 
			
		||||
 | 
			
		||||
  def gem name, *requirements
 | 
			
		||||
    options = requirements.pop if requirements.last.kind_of?(Hash)
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +361,18 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
 | 
			
		||||
    source_set ||= gem_path       name, options
 | 
			
		||||
    source_set ||= gem_git        name, options
 | 
			
		||||
    source_set ||= gem_github name, options
 | 
			
		||||
    source_set ||= gem_git_source name, options
 | 
			
		||||
 | 
			
		||||
    duplicate = @dependencies.include? name
 | 
			
		||||
 | 
			
		||||
    @dependencies[name] =
 | 
			
		||||
      if requirements.empty? and not source_set then
 | 
			
		||||
        nil
 | 
			
		||||
      elsif source_set then
 | 
			
		||||
        '!'
 | 
			
		||||
      else
 | 
			
		||||
        requirements
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    return unless gem_platforms options
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -225,6 +384,12 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
 | 
			
		||||
    gem_requires name, options
 | 
			
		||||
 | 
			
		||||
    if duplicate then
 | 
			
		||||
      warn <<-WARNING
 | 
			
		||||
Gem dependencies file #{@path} requires #{name} more than once.
 | 
			
		||||
      WARNING
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @set.gem name, *requirements
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -258,21 +423,27 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  private :gem_git
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Handles the github: option from +options+ for gem +name+.
 | 
			
		||||
  # Handles a git gem option from +options+ for gem +name+ for a git source
 | 
			
		||||
  # registered through git_source.
 | 
			
		||||
  #
 | 
			
		||||
  # Returns +true+ if the path option was handled.
 | 
			
		||||
  # Returns +true+ if the custom source option was handled.
 | 
			
		||||
 | 
			
		||||
  def gem_github name, options # :nodoc:
 | 
			
		||||
    return unless path = options.delete(:github)
 | 
			
		||||
  def gem_git_source name, options # :nodoc:
 | 
			
		||||
    return unless git_source = (@git_sources.keys & options.keys).last
 | 
			
		||||
 | 
			
		||||
    options[:git] = "git://github.com/#{path}.git"
 | 
			
		||||
    source_callback = @git_sources[git_source]
 | 
			
		||||
    source_param = options.delete git_source
 | 
			
		||||
 | 
			
		||||
    git_url = source_callback.call source_param
 | 
			
		||||
 | 
			
		||||
    options[:git] = git_url
 | 
			
		||||
 | 
			
		||||
    gem_git name, options
 | 
			
		||||
 | 
			
		||||
    true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private :gem_github
 | 
			
		||||
  private :gem_git_source
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Handles the :group and :groups +options+ for the gem with the given
 | 
			
		||||
| 
						 | 
				
			
			@ -314,8 +485,9 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  # platform matches the current platform.
 | 
			
		||||
 | 
			
		||||
  def gem_platforms options # :nodoc:
 | 
			
		||||
    platform_names = Array(options.delete :platforms)
 | 
			
		||||
    platform_names << @current_platform if @current_platform
 | 
			
		||||
    platform_names = Array(options.delete :platform)
 | 
			
		||||
    platform_names.concat Array(options.delete :platforms)
 | 
			
		||||
    platform_names.concat @current_platforms if @current_platforms
 | 
			
		||||
 | 
			
		||||
    return true if platform_names.empty?
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -343,7 +515,7 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  private :gem_platforms
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Handles the require: option from +options+ and adds those files, or the
 | 
			
		||||
  # Records the require: option from +options+ and adds those files, or the
 | 
			
		||||
  # default file to the require list for +name+.
 | 
			
		||||
 | 
			
		||||
  def gem_requires name, options # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -362,6 +534,11 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  #
 | 
			
		||||
  # Block form for specifying gems from a git +repository+.
 | 
			
		||||
  #
 | 
			
		||||
  #   git 'https://github.com/rails/rails.git' do
 | 
			
		||||
  #     gem 'activesupport'
 | 
			
		||||
  #     gem 'activerecord'
 | 
			
		||||
  #   end
 | 
			
		||||
 | 
			
		||||
  def git repository
 | 
			
		||||
    @current_repository = repository
 | 
			
		||||
| 
						 | 
				
			
			@ -372,6 +549,15 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
    @current_repository = nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Defines a custom git source that uses +name+ to expand git repositories
 | 
			
		||||
  # for use in gems built from git repositories.  You must provide a block
 | 
			
		||||
  # that accepts a git repository name for expansion.
 | 
			
		||||
 | 
			
		||||
  def git_source name, &callback
 | 
			
		||||
    @git_sources[name] = callback
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Returns the basename of the file the dependencies were loaded from
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -383,6 +569,23 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  #
 | 
			
		||||
  # Loads dependencies from a gemspec file.
 | 
			
		||||
  #
 | 
			
		||||
  # +options+ include:
 | 
			
		||||
  #
 | 
			
		||||
  # name: ::
 | 
			
		||||
  #   The name portion of the gemspec file.  Defaults to searching for any
 | 
			
		||||
  #   gemspec file in the current directory.
 | 
			
		||||
  #
 | 
			
		||||
  #     gemspec name: 'my_gem'
 | 
			
		||||
  #
 | 
			
		||||
  # path: ::
 | 
			
		||||
  #   The path the gemspec lives in.  Defaults to the current directory:
 | 
			
		||||
  #
 | 
			
		||||
  #     gemspec 'my_gem', path: 'gemspecs', name: 'my_gem'
 | 
			
		||||
  #
 | 
			
		||||
  # development_group: ::
 | 
			
		||||
  #   The group to add development dependencies to.  By default this is
 | 
			
		||||
  #   :development.  Only one group may be specified.
 | 
			
		||||
 | 
			
		||||
  def gemspec options = {}
 | 
			
		||||
    name              = options.delete(:name) || '{,*}'
 | 
			
		||||
| 
						 | 
				
			
			@ -404,7 +607,20 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
 | 
			
		||||
  ##
 | 
			
		||||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  #
 | 
			
		||||
  # Block form for placing a dependency in the given +groups+.
 | 
			
		||||
  #
 | 
			
		||||
  #   group :development do
 | 
			
		||||
  #     gem 'debugger'
 | 
			
		||||
  #   end
 | 
			
		||||
  #
 | 
			
		||||
  #   group :development, :test do
 | 
			
		||||
  #     gem 'minitest'
 | 
			
		||||
  #   end
 | 
			
		||||
  #
 | 
			
		||||
  # Groups can be excluded at install time using `gem install -g --without
 | 
			
		||||
  # development`.  See `gem help install` and `gem help gem_dependencies` for
 | 
			
		||||
  # further details.
 | 
			
		||||
 | 
			
		||||
  def group *groups
 | 
			
		||||
    @current_groups = groups
 | 
			
		||||
| 
						 | 
				
			
			@ -440,28 +656,72 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  ##
 | 
			
		||||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  #
 | 
			
		||||
  # Block form for restricting gems to a particular platform.
 | 
			
		||||
  # Block form for restricting gems to a set of platforms.
 | 
			
		||||
  #
 | 
			
		||||
  # The gem dependencies platform is different from Gem::Platform.  A platform
 | 
			
		||||
  # gem.deps.rb platform matches on the ruby engine, the ruby version and
 | 
			
		||||
  # whether or not windows is allowed.
 | 
			
		||||
  #
 | 
			
		||||
  # :ruby, :ruby_XY ::
 | 
			
		||||
  #   Matches non-windows, non-jruby implementations where X and Y can be used
 | 
			
		||||
  #   to match releases in the 1.8, 1.9, 2.0 or 2.1 series.
 | 
			
		||||
  #
 | 
			
		||||
  # :mri, :mri_XY ::
 | 
			
		||||
  #   Matches non-windows C Ruby (Matz Ruby) or only the 1.8, 1.9, 2.0 or
 | 
			
		||||
  #   2.1 series.
 | 
			
		||||
  #
 | 
			
		||||
  # :mingw, :mingw_XY ::
 | 
			
		||||
  #   Matches 32 bit C Ruby on MinGW or only the 1.8, 1.9, 2.0 or 2.1 series.
 | 
			
		||||
  #
 | 
			
		||||
  # :x64_mingw, :x64_mingw_XY ::
 | 
			
		||||
  #   Matches 64 bit C Ruby on MinGW or only the 1.8, 1.9, 2.0 or 2.1 series.
 | 
			
		||||
  #
 | 
			
		||||
  # :mswin, :mswin_XY ::
 | 
			
		||||
  #   Matches 32 bit C Ruby on Microsoft Windows or only the 1.8, 1.9, 2.0 or
 | 
			
		||||
  #   2.1 series.
 | 
			
		||||
  #
 | 
			
		||||
  # :mswin64, :mswin64_XY ::
 | 
			
		||||
  #   Matches 64 bit C Ruby on Microsoft Windows or only the 1.8, 1.9, 2.0 or
 | 
			
		||||
  #   2.1 series.
 | 
			
		||||
  #
 | 
			
		||||
  # :jruby, :jruby_XY ::
 | 
			
		||||
  #   Matches JRuby or JRuby in 1.8 or 1.9 mode.
 | 
			
		||||
  #
 | 
			
		||||
  # :maglev ::
 | 
			
		||||
  #   Matches Maglev
 | 
			
		||||
  #
 | 
			
		||||
  # :rbx ::
 | 
			
		||||
  #   Matches non-windows Rubinius
 | 
			
		||||
  #
 | 
			
		||||
  # NOTE:  There is inconsistency in what environment a platform matches.  You
 | 
			
		||||
  # may need to read the source to know the exact details.
 | 
			
		||||
 | 
			
		||||
  def platform what
 | 
			
		||||
    @current_platform = what
 | 
			
		||||
  def platform *platforms
 | 
			
		||||
    @current_platforms = platforms
 | 
			
		||||
 | 
			
		||||
    yield
 | 
			
		||||
 | 
			
		||||
  ensure
 | 
			
		||||
    @current_platform = nil
 | 
			
		||||
    @current_platforms = nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  #
 | 
			
		||||
  # Block form for restricting gems to a particular platform.
 | 
			
		||||
  # Block form for restricting gems to a particular set of platforms.  See
 | 
			
		||||
  # #platform.
 | 
			
		||||
 | 
			
		||||
  alias :platforms :platform
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  # Restricts this gem dependencies file to the given ruby +version+.  The
 | 
			
		||||
  # +:engine+ options from Bundler are currently ignored.
 | 
			
		||||
  #
 | 
			
		||||
  # Restricts this gem dependencies file to the given ruby +version+.
 | 
			
		||||
  #
 | 
			
		||||
  # You may also provide +engine:+ and +engine_version:+ options to restrict
 | 
			
		||||
  # this gem dependencies file to a particular ruby engine and its engine
 | 
			
		||||
  # version.  This matching is performed by using the RUBY_ENGINE and
 | 
			
		||||
  # engine_specific VERSION constants.  (For JRuby, JRUBY_VERSION).
 | 
			
		||||
 | 
			
		||||
  def ruby version, options = {}
 | 
			
		||||
    engine         = options[:engine]
 | 
			
		||||
| 
						 | 
				
			
			@ -471,6 +731,8 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
          'you must specify engine_version along with the ruby engine' if
 | 
			
		||||
            engine and not engine_version
 | 
			
		||||
 | 
			
		||||
    return true if @installing
 | 
			
		||||
 | 
			
		||||
    unless RUBY_VERSION == version then
 | 
			
		||||
      message = "Your Ruby version is #{RUBY_VERSION}, " +
 | 
			
		||||
                "but your #{gem_deps_file} requires #{version}"
 | 
			
		||||
| 
						 | 
				
			
			@ -503,7 +765,16 @@ class Gem::RequestSet::GemDependencyAPI
 | 
			
		|||
  ##
 | 
			
		||||
  # :category: Gem Dependencies DSL
 | 
			
		||||
  #
 | 
			
		||||
  # Sets +url+ as a source for gems for this dependency API.
 | 
			
		||||
  # Sets +url+ as a source for gems for this dependency API.  RubyGems uses
 | 
			
		||||
  # the default configured sources if no source was given.  If a source is set
 | 
			
		||||
  # only that source is used.
 | 
			
		||||
  #
 | 
			
		||||
  # This method differs in behavior from Bundler:
 | 
			
		||||
  #
 | 
			
		||||
  # * The +:gemcutter+, # +:rubygems+ and +:rubyforge+ sources are not
 | 
			
		||||
  #   supported as they are deprecated in bundler.
 | 
			
		||||
  # * The +prepend:+ option is not supported.  If you wish to order sources
 | 
			
		||||
  #   then list them in your preferred order.
 | 
			
		||||
 | 
			
		||||
  def source url
 | 
			
		||||
    Gem.sources.clear if @default_sources
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,11 +49,14 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
  # Creates a new Lockfile for the given +request_set+ and +gem_deps_file+
 | 
			
		||||
  # location.
 | 
			
		||||
 | 
			
		||||
  def initialize request_set, gem_deps_file
 | 
			
		||||
  def initialize request_set, gem_deps_file, dependencies = nil
 | 
			
		||||
    @set           = request_set
 | 
			
		||||
    @dependencies  = dependencies
 | 
			
		||||
    @gem_deps_file = File.expand_path(gem_deps_file)
 | 
			
		||||
    @gem_deps_dir  = File.dirname(@gem_deps_file)
 | 
			
		||||
 | 
			
		||||
    @gem_deps_file.untaint unless gem_deps_file.tainted?
 | 
			
		||||
 | 
			
		||||
    @current_token  = nil
 | 
			
		||||
    @line           = 0
 | 
			
		||||
    @line_pos       = 0
 | 
			
		||||
| 
						 | 
				
			
			@ -64,19 +67,42 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
  def add_DEPENDENCIES out # :nodoc:
 | 
			
		||||
    out << "DEPENDENCIES"
 | 
			
		||||
 | 
			
		||||
    @requests.sort_by { |r| r.name }.each do |request|
 | 
			
		||||
      spec = request.spec
 | 
			
		||||
 | 
			
		||||
      if [Gem::Resolver::VendorSpecification,
 | 
			
		||||
          Gem::Resolver::GitSpecification].include? spec.class then
 | 
			
		||||
        out << "  #{request.name}!"
 | 
			
		||||
    dependencies =
 | 
			
		||||
      if @dependencies then
 | 
			
		||||
        @dependencies.sort_by { |name,| name }.map do |name, requirement|
 | 
			
		||||
          requirement_string =
 | 
			
		||||
            if '!' == requirement then
 | 
			
		||||
              requirement
 | 
			
		||||
            else
 | 
			
		||||
              Gem::Requirement.new(requirement).for_lockfile
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
          [name, requirement_string]
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        @requests.sort_by { |r| r.name }.map do |request|
 | 
			
		||||
          spec        = request.spec
 | 
			
		||||
          name        = request.name
 | 
			
		||||
          requirement = request.request.dependency.requirement
 | 
			
		||||
 | 
			
		||||
        out << "  #{request.name}#{requirement.for_lockfile}"
 | 
			
		||||
          requirement_string =
 | 
			
		||||
            if [Gem::Resolver::VendorSpecification,
 | 
			
		||||
                Gem::Resolver::GitSpecification].include? spec.class then
 | 
			
		||||
              "!"
 | 
			
		||||
            else
 | 
			
		||||
              requirement.for_lockfile
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
          [name, requirement_string]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
    dependencies = dependencies.map do |name, requirement_string|
 | 
			
		||||
      "  #{name}#{requirement_string}"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    out.concat dependencies
 | 
			
		||||
 | 
			
		||||
    out << nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -93,12 +119,15 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
      out << "  specs:"
 | 
			
		||||
 | 
			
		||||
      requests.sort_by { |request| request.name }.each do |request|
 | 
			
		||||
        next if request.spec.name == 'bundler'
 | 
			
		||||
        platform = "-#{request.spec.platform}" unless
 | 
			
		||||
          Gem::Platform::RUBY == request.spec.platform
 | 
			
		||||
 | 
			
		||||
        out << "    #{request.name} (#{request.version}#{platform})"
 | 
			
		||||
 | 
			
		||||
        request.full_spec.dependencies.sort.each do |dependency|
 | 
			
		||||
          next if dependency.type == :development
 | 
			
		||||
 | 
			
		||||
          requirement = dependency.requirement
 | 
			
		||||
          out << "      #{dependency.name}#{requirement.for_lockfile}"
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -166,9 +195,8 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
    out << "PLATFORMS"
 | 
			
		||||
 | 
			
		||||
    platforms = @requests.map { |request| request.spec.platform }.uniq
 | 
			
		||||
    platforms.delete Gem::Platform::RUBY if platforms.length > 1
 | 
			
		||||
 | 
			
		||||
    platforms.each do |platform|
 | 
			
		||||
    platforms.sort.each do |platform|
 | 
			
		||||
      out << "  #{platform}"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -250,7 +278,7 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
          Gem::Resolver::VendorSet === set
 | 
			
		||||
        }.map { |set|
 | 
			
		||||
          set.specs[name]
 | 
			
		||||
        }.first
 | 
			
		||||
        }.compact.first
 | 
			
		||||
 | 
			
		||||
        requirements << spec.version
 | 
			
		||||
      when :l_paren then
 | 
			
		||||
| 
						 | 
				
			
			@ -277,26 +305,33 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def parse_GEM # :nodoc:
 | 
			
		||||
    sources = []
 | 
			
		||||
 | 
			
		||||
    while [:entry, 'remote'] == peek.first(2) do
 | 
			
		||||
      get :entry, 'remote'
 | 
			
		||||
      _, data, = get :text
 | 
			
		||||
 | 
			
		||||
    source = Gem::Source.new data
 | 
			
		||||
 | 
			
		||||
      skip :newline
 | 
			
		||||
 | 
			
		||||
      sources << Gem::Source.new(data)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    sources << Gem::Source.new(Gem::DEFAULT_HOST) if sources.empty?
 | 
			
		||||
 | 
			
		||||
    get :entry, 'specs'
 | 
			
		||||
 | 
			
		||||
    skip :newline
 | 
			
		||||
 | 
			
		||||
    set = Gem::Resolver::LockSet.new source
 | 
			
		||||
    last_spec = nil
 | 
			
		||||
    set = Gem::Resolver::LockSet.new sources
 | 
			
		||||
    last_specs = nil
 | 
			
		||||
 | 
			
		||||
    while not @tokens.empty? and :text == peek.first do
 | 
			
		||||
      _, name, column, = get :text
 | 
			
		||||
 | 
			
		||||
      case peek[0]
 | 
			
		||||
      when :newline then
 | 
			
		||||
        last_spec.add_dependency Gem::Dependency.new name if column == 6
 | 
			
		||||
        last_specs.each do |spec|
 | 
			
		||||
          spec.add_dependency Gem::Dependency.new name if column == 6
 | 
			
		||||
        end
 | 
			
		||||
      when :l_paren then
 | 
			
		||||
        get :l_paren
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -308,11 +343,13 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
          platform =
 | 
			
		||||
            platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
 | 
			
		||||
 | 
			
		||||
          last_spec = set.add name, version, platform
 | 
			
		||||
          last_specs = set.add name, version, platform
 | 
			
		||||
        else
 | 
			
		||||
          dependency = parse_dependency name, data
 | 
			
		||||
 | 
			
		||||
          last_spec.add_dependency dependency
 | 
			
		||||
          last_specs.each do |spec|
 | 
			
		||||
            spec.add_dependency dependency
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        get :r_paren
 | 
			
		||||
| 
						 | 
				
			
			@ -337,11 +374,21 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
 | 
			
		||||
    skip :newline
 | 
			
		||||
 | 
			
		||||
    type, value = peek.first 2
 | 
			
		||||
    if type == :entry and %w[branch ref tag].include? value then
 | 
			
		||||
      get
 | 
			
		||||
      get :text
 | 
			
		||||
 | 
			
		||||
      skip :newline
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    get :entry, 'specs'
 | 
			
		||||
 | 
			
		||||
    skip :newline
 | 
			
		||||
 | 
			
		||||
    set = Gem::Resolver::GitSet.new
 | 
			
		||||
    set.root_dir = @set.install_dir
 | 
			
		||||
 | 
			
		||||
    last_spec = nil
 | 
			
		||||
 | 
			
		||||
    while not @tokens.empty? and :text == peek.first do
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +407,7 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
        else
 | 
			
		||||
          dependency = parse_dependency name, data
 | 
			
		||||
 | 
			
		||||
          last_spec.spec.dependencies << dependency
 | 
			
		||||
          last_spec.add_dependency dependency
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        get :r_paren
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +450,7 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
        else
 | 
			
		||||
          dependency = parse_dependency name, data
 | 
			
		||||
 | 
			
		||||
          last_spec.spec.dependencies << dependency
 | 
			
		||||
          last_spec.dependencies << dependency
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        get :r_paren
 | 
			
		||||
| 
						 | 
				
			
			@ -432,7 +479,7 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
  # the first token of the requirements and returns a Gem::Dependency object.
 | 
			
		||||
 | 
			
		||||
  def parse_dependency name, op # :nodoc:
 | 
			
		||||
    return Gem::Dependency.new name unless peek[0] == :text
 | 
			
		||||
    return Gem::Dependency.new name, op unless peek[0] == :text
 | 
			
		||||
 | 
			
		||||
    _, version, = get :text
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -575,8 +622,10 @@ class Gem::RequestSet::Lockfile
 | 
			
		|||
  # Writes the lock file alongside the gem dependencies file
 | 
			
		||||
 | 
			
		||||
  def write
 | 
			
		||||
    content = to_s
 | 
			
		||||
 | 
			
		||||
    open "#{@gem_deps_file}.lock", 'w' do |io|
 | 
			
		||||
      io.write to_s
 | 
			
		||||
      io.write content
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,9 @@ Gem.load_yaml if defined? ::YAML
 | 
			
		|||
##
 | 
			
		||||
# A Requirement is a set of one or more version restrictions. It supports a
 | 
			
		||||
# few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators.
 | 
			
		||||
#
 | 
			
		||||
# See Gem::Version for a description on how versions and requirements work
 | 
			
		||||
# together in RubyGems.
 | 
			
		||||
 | 
			
		||||
class Gem::Requirement
 | 
			
		||||
  OPS = { #:nodoc:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
require 'rubygems'
 | 
			
		||||
require 'rubygems/dependency'
 | 
			
		||||
require 'rubygems/exceptions'
 | 
			
		||||
require 'rubygems/util/list'
 | 
			
		||||
| 
						 | 
				
			
			@ -21,16 +20,23 @@ class Gem::Resolver
 | 
			
		|||
 | 
			
		||||
  DEBUG_RESOLVER = !ENV['DEBUG_RESOLVER'].nil?
 | 
			
		||||
 | 
			
		||||
  require 'pp' if DEBUG_RESOLVER
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Contains all the conflicts encountered while doing resolution
 | 
			
		||||
 | 
			
		||||
  attr_reader :conflicts
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Set to true if development dependencies should be considered.
 | 
			
		||||
  # Set to true if all development dependencies should be considered.
 | 
			
		||||
 | 
			
		||||
  attr_accessor :development
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Set to true if immediate development dependencies should be considered.
 | 
			
		||||
 | 
			
		||||
  attr_accessor :development_shallow
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # When true, no dependencies are looked up for requested gems.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +49,12 @@ class Gem::Resolver
 | 
			
		|||
 | 
			
		||||
  attr_reader :stats
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Hash of gems to skip resolution.  Keyed by gem name, with arrays of
 | 
			
		||||
  # gem specifications as values.
 | 
			
		||||
 | 
			
		||||
  attr_accessor :skip_gems
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # When a missing dependency, don't stop. Just go on and record what was
 | 
			
		||||
  # missing.
 | 
			
		||||
| 
						 | 
				
			
			@ -100,26 +112,27 @@ class Gem::Resolver
 | 
			
		|||
 | 
			
		||||
    @conflicts           = []
 | 
			
		||||
    @development         = false
 | 
			
		||||
    @development_shallow = false
 | 
			
		||||
    @ignore_dependencies = false
 | 
			
		||||
    @missing             = []
 | 
			
		||||
    @skip_gems           = {}
 | 
			
		||||
    @soft_missing        = false
 | 
			
		||||
    @stats               = Gem::Resolver::Stats.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def explain stage, *data # :nodoc:
 | 
			
		||||
    if DEBUG_RESOLVER
 | 
			
		||||
      d = data.map { |x| x.inspect }.join(", ")
 | 
			
		||||
      STDOUT.printf "%20s %s\n", stage.to_s.upcase, d
 | 
			
		||||
    end
 | 
			
		||||
    return unless DEBUG_RESOLVER
 | 
			
		||||
 | 
			
		||||
    d = data.map { |x| x.pretty_inspect }.join(", ")
 | 
			
		||||
    $stderr.printf "%10s %s\n", stage.to_s.upcase, d
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def explain_list stage, data # :nodoc:
 | 
			
		||||
    if DEBUG_RESOLVER
 | 
			
		||||
      STDOUT.printf "%20s (%d entries)\n", stage.to_s.upcase, data.size
 | 
			
		||||
      data.each do |d|
 | 
			
		||||
        STDOUT.printf "%20s %s\n", "", d
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  def explain_list stage # :nodoc:
 | 
			
		||||
    return unless DEBUG_RESOLVER
 | 
			
		||||
 | 
			
		||||
    data = yield
 | 
			
		||||
    $stderr.printf "%10s (%d entries)\n", stage.to_s.upcase, data.size
 | 
			
		||||
    PP.pp data, $stderr unless data.empty?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -132,6 +145,7 @@ class Gem::Resolver
 | 
			
		|||
    spec = possible.pop
 | 
			
		||||
 | 
			
		||||
    explain :activate, [spec.full_name, possible.size]
 | 
			
		||||
    explain :possible, possible
 | 
			
		||||
 | 
			
		||||
    activation_request =
 | 
			
		||||
      Gem::Resolver::ActivationRequest.new spec, dep, possible
 | 
			
		||||
| 
						 | 
				
			
			@ -142,8 +156,15 @@ class Gem::Resolver
 | 
			
		|||
  def requests s, act, reqs=nil # :nodoc:
 | 
			
		||||
    return reqs if @ignore_dependencies
 | 
			
		||||
 | 
			
		||||
    s.fetch_development_dependencies if @development
 | 
			
		||||
 | 
			
		||||
    s.dependencies.reverse_each do |d|
 | 
			
		||||
      next if d.type == :development and not @development
 | 
			
		||||
      next if d.type == :development and @development_shallow and
 | 
			
		||||
              act.development?
 | 
			
		||||
      next if d.type == :development and @development_shallow and
 | 
			
		||||
              act.parent
 | 
			
		||||
 | 
			
		||||
      reqs.add Gem::Resolver::DependencyRequest.new(d, act)
 | 
			
		||||
      @stats.requirement!
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -186,6 +207,15 @@ class Gem::Resolver
 | 
			
		|||
 | 
			
		||||
  def find_possible dependency # :nodoc:
 | 
			
		||||
    all = @set.find_all dependency
 | 
			
		||||
 | 
			
		||||
    if (skip_dep_gems = skip_gems[dependency.name]) && !skip_dep_gems.empty?
 | 
			
		||||
      matching = all.select do |api_spec|
 | 
			
		||||
        skip_dep_gems.any? { |s| api_spec.version == s.version }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      all = matching unless matching.empty?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    matching_platform = select_local_platforms all
 | 
			
		||||
 | 
			
		||||
    return matching_platform, all
 | 
			
		||||
| 
						 | 
				
			
			@ -270,8 +300,8 @@ class Gem::Resolver
 | 
			
		|||
 | 
			
		||||
      dep = needed.remove
 | 
			
		||||
      explain :try, [dep, dep.requester ? dep.requester.request : :toplevel]
 | 
			
		||||
      explain_list :next5, needed.next5
 | 
			
		||||
      explain_list :specs, Array(specs).map { |x| x.full_name }.sort
 | 
			
		||||
      explain_list(:next5) { needed.next5 }
 | 
			
		||||
      explain_list(:specs) { Array(specs).map { |x| x.full_name }.sort }
 | 
			
		||||
 | 
			
		||||
      # If there is already a spec activated for the requested name...
 | 
			
		||||
      if specs && existing = specs.find { |s| dep.name == s.name }
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +433,10 @@ class Gem::Resolver
 | 
			
		|||
    @missing << dep
 | 
			
		||||
 | 
			
		||||
    unless @soft_missing
 | 
			
		||||
      raise Gem::UnsatisfiableDependencyError.new(dep, platform_mismatch)
 | 
			
		||||
      exc = Gem::UnsatisfiableDependencyError.new dep, platform_mismatch
 | 
			
		||||
      exc.errors = @set.errors
 | 
			
		||||
 | 
			
		||||
      raise exc
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,13 @@ class Gem::Resolver::ActivationRequest
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Is this activation request for a development dependency?
 | 
			
		||||
 | 
			
		||||
  def development?
 | 
			
		||||
    @request.development?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Downloads a gem at +path+ and returns the file path.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,8 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
    @data   = Hash.new { |h,k| h[k] = [] }
 | 
			
		||||
    @source = Gem::Source.new @uri
 | 
			
		||||
 | 
			
		||||
    @to_fetch = []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +47,10 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
    return res unless @remote
 | 
			
		||||
 | 
			
		||||
    if @to_fetch.include?(req.name)
 | 
			
		||||
      prefetch_now
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    versions(req.name).each do |ver|
 | 
			
		||||
      if req.dependency.match? req.name, ver[:number]
 | 
			
		||||
        res << Gem::Resolver::APISpecification.new(self, ver)
 | 
			
		||||
| 
						 | 
				
			
			@ -61,9 +67,13 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
 | 
			
		|||
  def prefetch reqs
 | 
			
		||||
    return unless @remote
 | 
			
		||||
    names = reqs.map { |r| r.dependency.name }
 | 
			
		||||
    needed = names - @data.keys
 | 
			
		||||
    needed = names - @data.keys - @to_fetch
 | 
			
		||||
 | 
			
		||||
    return if needed.empty?
 | 
			
		||||
    @to_fetch += needed
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def prefetch_now
 | 
			
		||||
    needed, @to_fetch = @to_fetch, []
 | 
			
		||||
 | 
			
		||||
    uri = @dep_uri + "?gems=#{needed.sort.join ','}"
 | 
			
		||||
    str = Gem::RemoteFetcher.fetcher.fetch_path uri
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,12 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
 | 
			
		|||
      @dependencies == other.dependencies
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def fetch_development_dependencies # :nodoc:
 | 
			
		||||
    spec = source.fetch_spec Gem::NameTuple.new @name, @version, @platform
 | 
			
		||||
 | 
			
		||||
    @dependencies = spec.dependencies
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def installable_platform? # :nodoc:
 | 
			
		||||
    Gem::Platform.match @platform
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,10 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
 | 
			
		|||
    pick_sets if @remote and @sets.empty?
 | 
			
		||||
 | 
			
		||||
    super
 | 
			
		||||
  rescue Gem::RemoteFetcher::FetchError => e
 | 
			
		||||
    replace_failed_api_set e
 | 
			
		||||
 | 
			
		||||
    retry
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def prefetch reqs # :nodoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -46,5 +50,29 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Replaces a failed APISet for the URI in +error+ with an IndexSet.
 | 
			
		||||
  #
 | 
			
		||||
  # If no matching APISet can be found the original +error+ is raised.
 | 
			
		||||
  #
 | 
			
		||||
  # The calling method must retry the exception to repeat the lookup.
 | 
			
		||||
 | 
			
		||||
  def replace_failed_api_set error # :nodoc:
 | 
			
		||||
    uri = error.uri
 | 
			
		||||
    uri = URI uri unless URI === uri
 | 
			
		||||
    uri.query = nil
 | 
			
		||||
 | 
			
		||||
    raise error unless api_set = @sets.find { |set|
 | 
			
		||||
      Gem::Resolver::APISet === set and set.dep_uri == uri
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    index_set = Gem::Resolver::IndexSet.new api_set.source
 | 
			
		||||
 | 
			
		||||
    @sets.map! do |set|
 | 
			
		||||
      next set unless set == api_set
 | 
			
		||||
      index_set
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,18 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
 | 
			
		|||
    @sets = sets
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # When +allow_prerelease+ is set to +true+ prereleases gems are allowed to
 | 
			
		||||
  # match dependencies.
 | 
			
		||||
 | 
			
		||||
  def prerelease= allow_prerelease
 | 
			
		||||
    super
 | 
			
		||||
 | 
			
		||||
    sets.each do |set|
 | 
			
		||||
      set.prerelease = allow_prerelease
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Sets the remote network access for all composed sets.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +42,10 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set
 | 
			
		|||
    @sets.each { |set| set.remote = remote }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def errors
 | 
			
		||||
    @errors + @sets.map { |set| set.errors }.flatten
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Finds all specs matching +req+ in all sets.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,11 +52,40 @@ class Gem::Resolver::Conflict
 | 
			
		|||
 | 
			
		||||
  def explanation
 | 
			
		||||
    activated   = @activated.spec.full_name
 | 
			
		||||
    requirement = @failed_dep.dependency.requirement
 | 
			
		||||
    dependency  = @failed_dep.dependency
 | 
			
		||||
    requirement = dependency.requirement
 | 
			
		||||
    alternates  = dependency.matching_specs.map { |spec| spec.full_name }
 | 
			
		||||
 | 
			
		||||
    "  Activated %s via:\n    %s\n  instead of (%s) via:\n    %s\n" % [
 | 
			
		||||
      activated,   request_path(@activated).join(', '),
 | 
			
		||||
      requirement, request_path(requester).join(', '),
 | 
			
		||||
    unless alternates.empty? then
 | 
			
		||||
      matching = <<-MATCHING.chomp
 | 
			
		||||
 | 
			
		||||
  Gems matching %s:
 | 
			
		||||
    %s
 | 
			
		||||
      MATCHING
 | 
			
		||||
 | 
			
		||||
      matching = matching % [
 | 
			
		||||
        dependency,
 | 
			
		||||
        alternates.join(', '),
 | 
			
		||||
      ]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    explanation = <<-EXPLANATION
 | 
			
		||||
  Activated %s
 | 
			
		||||
  which does not match conflicting dependency (%s)
 | 
			
		||||
 | 
			
		||||
  Conflicting dependency chains:
 | 
			
		||||
    %s
 | 
			
		||||
 | 
			
		||||
  versus:
 | 
			
		||||
    %s
 | 
			
		||||
%s
 | 
			
		||||
    EXPLANATION
 | 
			
		||||
 | 
			
		||||
    explanation % [
 | 
			
		||||
      activated, requirement,
 | 
			
		||||
      request_path(@activated).reverse.join(", depends on\n    "),
 | 
			
		||||
      request_path(@failed_dep).reverse.join(", depends on\n    "),
 | 
			
		||||
      matching,
 | 
			
		||||
    ]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,10 +124,19 @@ class Gem::Resolver::Conflict
 | 
			
		|||
    path = []
 | 
			
		||||
 | 
			
		||||
    while current do
 | 
			
		||||
      requirement = current.request.dependency.requirement
 | 
			
		||||
      path << "#{current.spec.full_name} (#{requirement})"
 | 
			
		||||
      case current
 | 
			
		||||
      when Gem::Resolver::ActivationRequest then
 | 
			
		||||
        path <<
 | 
			
		||||
          "#{current.request.dependency}, #{current.spec.version} activated"
 | 
			
		||||
 | 
			
		||||
        current = current.parent
 | 
			
		||||
      when Gem::Resolver::DependencyRequest then
 | 
			
		||||
        path << "#{current.dependency}"
 | 
			
		||||
 | 
			
		||||
        current = current.requester
 | 
			
		||||
      else
 | 
			
		||||
        raise Gem::Exception, "[BUG] unknown request class #{current.class}"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    path = ['user request (gem command or Gemfile)'] if path.empty?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,26 @@ class Gem::Resolver::DependencyRequest
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Does this dependency request match +spec+
 | 
			
		||||
  # Is this dependency a development dependency?
 | 
			
		||||
 | 
			
		||||
  def development?
 | 
			
		||||
    @dependency.type == :development
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Does this dependency request match +spec+?
 | 
			
		||||
  #
 | 
			
		||||
  # NOTE:  #match? only matches prerelease versions when #dependency is a
 | 
			
		||||
  # prerelease dependency.
 | 
			
		||||
 | 
			
		||||
  def match? spec, allow_prerelease = false
 | 
			
		||||
    @dependency.match? spec, nil, allow_prerelease
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Does this dependency request match +spec+?
 | 
			
		||||
  #
 | 
			
		||||
  # NOTE:  #matches_spec? matches prerelease versions.  See also #match?
 | 
			
		||||
 | 
			
		||||
  def matches_spec?(spec)
 | 
			
		||||
    @dependency.matches_spec? spec
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set
 | 
			
		|||
    prefetch nil
 | 
			
		||||
 | 
			
		||||
    specs.values.select do |spec|
 | 
			
		||||
      req.matches_spec? spec
 | 
			
		||||
      req.match? spec
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,11 +12,15 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
 | 
			
		|||
      @source == other.source
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def add_dependency dependency # :nodoc:
 | 
			
		||||
    spec.dependencies << dependency
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Installing a git gem only involves building the extensions and generating
 | 
			
		||||
  # the executables.
 | 
			
		||||
 | 
			
		||||
  def install options
 | 
			
		||||
  def install options = {}
 | 
			
		||||
    require 'rubygems/installer'
 | 
			
		||||
 | 
			
		||||
    installer = Gem::Installer.new '', options
 | 
			
		||||
| 
						 | 
				
			
			@ -31,5 +35,25 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
 | 
			
		|||
    installer.run_post_install_hooks
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pretty_print q # :nodoc:
 | 
			
		||||
    q.group 2, '[GitSpecification', ']' do
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "name: #{name}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "version: #{version}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text 'dependencies:'
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.pp dependencies
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "source:"
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.pp @source
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,9 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
    @all = Hash.new { |h,k| h[k] = [] }
 | 
			
		||||
 | 
			
		||||
    list, = @f.available_specs :released
 | 
			
		||||
    list, errors = @f.available_specs :complete
 | 
			
		||||
 | 
			
		||||
    @errors.concat errors
 | 
			
		||||
 | 
			
		||||
    list.each do |uri, specs|
 | 
			
		||||
      specs.each do |n|
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +43,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set
 | 
			
		|||
    name = req.dependency.name
 | 
			
		||||
 | 
			
		||||
    @all[name].each do |uri, n|
 | 
			
		||||
      if req.dependency.match? n then
 | 
			
		||||
      if req.match? n, @prerelease then
 | 
			
		||||
        res << Gem::Resolver::IndexSpecification.new(
 | 
			
		||||
          self, n.name, n.version, uri, n.platform)
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
 | 
			
		|||
  # This is a null install as this specification is already installed.
 | 
			
		||||
  # +options+ are ignored.
 | 
			
		||||
 | 
			
		||||
  def install options
 | 
			
		||||
  def install options = {}
 | 
			
		||||
    yield nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +29,24 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
 | 
			
		|||
    super
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pretty_print q # :nodoc:
 | 
			
		||||
    q.group 2, '[InstalledSpecification', ']' do
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "name: #{name}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "version: #{version}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "platform: #{platform}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text 'dependencies:'
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.pp spec.dependencies
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The source for this specification
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,11 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
  attr_accessor :ignore_installed # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The remote_set looks up remote gems for installation.
 | 
			
		||||
 | 
			
		||||
  attr_reader :remote_set # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Creates a new InstallerSet that will look for gems in +domain+.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,10 +39,52 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
 | 
			
		|||
    @always_install      = []
 | 
			
		||||
    @ignore_dependencies = false
 | 
			
		||||
    @ignore_installed    = false
 | 
			
		||||
    @local               = {}
 | 
			
		||||
    @remote_set          = Gem::Resolver::BestSet.new
 | 
			
		||||
    @specs               = {}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Looks up the latest specification for +dependency+ and adds it to the
 | 
			
		||||
  # always_install list.
 | 
			
		||||
 | 
			
		||||
  def add_always_install dependency
 | 
			
		||||
    request = Gem::Resolver::DependencyRequest.new dependency, nil
 | 
			
		||||
 | 
			
		||||
    found = find_all request
 | 
			
		||||
 | 
			
		||||
    found.delete_if { |s|
 | 
			
		||||
      s.version.prerelease? and not s.local?
 | 
			
		||||
    } unless dependency.prerelease?
 | 
			
		||||
 | 
			
		||||
    found = found.select do |s|
 | 
			
		||||
      Gem::Source::SpecificFile === s.source or
 | 
			
		||||
        Gem::Platform::RUBY == s.platform or
 | 
			
		||||
        Gem::Platform.local === s.platform
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if found.empty? then
 | 
			
		||||
      exc = Gem::UnsatisfiableDependencyError.new request
 | 
			
		||||
      exc.errors = errors
 | 
			
		||||
 | 
			
		||||
      raise exc
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    newest = found.max_by do |s|
 | 
			
		||||
      [s.version, s.platform == Gem::Platform::RUBY ? -1 : 1]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @always_install << newest.spec
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Adds a local gem requested using +dep_name+ with the given +spec+ that can
 | 
			
		||||
  # be loaded and installed using the +source+.
 | 
			
		||||
 | 
			
		||||
  def add_local dep_name, spec, source
 | 
			
		||||
    @local[dep_name] = [spec, source]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Should local gems should be considered?
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +99,13 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
 | 
			
		|||
    @domain == :both or @domain == :remote
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Errors encountered while resolving gems
 | 
			
		||||
 | 
			
		||||
  def errors
 | 
			
		||||
    @errors + @remote_set.errors
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Returns an array of IndexSpecification objects matching DependencyRequest
 | 
			
		||||
  # +req+.
 | 
			
		||||
| 
						 | 
				
			
			@ -62,30 +116,53 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
 | 
			
		|||
    dep  = req.dependency
 | 
			
		||||
 | 
			
		||||
    return res if @ignore_dependencies and
 | 
			
		||||
              @always_install.none? { |spec| dep.matches_spec? spec }
 | 
			
		||||
              @always_install.none? { |spec| dep.match? spec }
 | 
			
		||||
 | 
			
		||||
    name = dep.name
 | 
			
		||||
 | 
			
		||||
    dep.matching_specs.each do |gemspec|
 | 
			
		||||
      next if @always_install.include? gemspec
 | 
			
		||||
      next if @always_install.any? { |spec| spec.name == gemspec.name }
 | 
			
		||||
 | 
			
		||||
      res << Gem::Resolver::InstalledSpecification.new(self, gemspec)
 | 
			
		||||
    end unless @ignore_installed
 | 
			
		||||
 | 
			
		||||
    if consider_local? then
 | 
			
		||||
      matching_local = @local.values.select do |spec, _|
 | 
			
		||||
        req.match? spec
 | 
			
		||||
      end.map do |spec, source|
 | 
			
		||||
        Gem::Resolver::LocalSpecification.new self, spec, source
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      res.concat matching_local
 | 
			
		||||
 | 
			
		||||
      local_source = Gem::Source::Local.new
 | 
			
		||||
 | 
			
		||||
      if spec = local_source.find_gem(name, dep.requirement) then
 | 
			
		||||
      if local_spec = local_source.find_gem(name, dep.requirement) then
 | 
			
		||||
        res << Gem::Resolver::IndexSpecification.new(
 | 
			
		||||
          self, spec.name, spec.version, local_source, spec.platform)
 | 
			
		||||
          self, local_spec.name, local_spec.version,
 | 
			
		||||
          local_source, local_spec.platform)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    res.delete_if do |spec|
 | 
			
		||||
      spec.version.prerelease? and not dep.prerelease?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    res.concat @remote_set.find_all req if consider_remote?
 | 
			
		||||
 | 
			
		||||
    res
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def prefetch(reqs)
 | 
			
		||||
    @remote_set.prefetch(reqs)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def prerelease= allow_prerelease
 | 
			
		||||
    super
 | 
			
		||||
 | 
			
		||||
    @remote_set.prerelease = allow_prerelease
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def inspect # :nodoc:
 | 
			
		||||
    always_install = @always_install.map { |s| s.full_name }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +185,15 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Has a local gem for +dep_name+ been added to this set?
 | 
			
		||||
 | 
			
		||||
  def local? dep_name # :nodoc:
 | 
			
		||||
    spec, = @local[dep_name]
 | 
			
		||||
 | 
			
		||||
    spec
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pretty_print q # :nodoc:
 | 
			
		||||
    q.group 2, '[InstallerSet', ']' do
 | 
			
		||||
      q.breakable
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,5 +12,30 @@ class Gem::Resolver::LocalSpecification < Gem::Resolver::SpecSpecification
 | 
			
		|||
    super
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def local? # :nodoc:
 | 
			
		||||
    true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pretty_print q # :nodoc:
 | 
			
		||||
    q.group 2, '[LocalSpecification', ']' do
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "name: #{name}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "version: #{version}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "platform: #{platform}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text 'dependencies:'
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.pp dependencies
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "source: #{@source.path}"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,12 +6,15 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
 | 
			
		|||
  attr_reader :specs # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Creates a new LockSet from the given +source+
 | 
			
		||||
  # Creates a new LockSet from the given +sources+
 | 
			
		||||
 | 
			
		||||
  def initialize source
 | 
			
		||||
  def initialize sources
 | 
			
		||||
    super()
 | 
			
		||||
 | 
			
		||||
    @source = Gem::Source::Lock.new source
 | 
			
		||||
    @sources = sources.map do |source|
 | 
			
		||||
      Gem::Source::Lock.new source
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @specs   = []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,13 +28,14 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
 | 
			
		|||
  def add name, version, platform # :nodoc:
 | 
			
		||||
    version = Gem::Version.new version
 | 
			
		||||
 | 
			
		||||
    spec =
 | 
			
		||||
      Gem::Resolver::LockSpecification.new self, name, version, @source,
 | 
			
		||||
    specs = @sources.map do |source|
 | 
			
		||||
      Gem::Resolver::LockSpecification.new self, name, version, source,
 | 
			
		||||
                                           platform
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @specs << spec
 | 
			
		||||
    @specs.concat specs
 | 
			
		||||
 | 
			
		||||
    spec
 | 
			
		||||
    specs
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +44,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
  def find_all req
 | 
			
		||||
    @specs.select do |spec|
 | 
			
		||||
      req.matches_spec? spec
 | 
			
		||||
      req.match? spec
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
 | 
			
		|||
  # This is a null install as a locked specification is considered installed.
 | 
			
		||||
  # +options+ are ignored.
 | 
			
		||||
 | 
			
		||||
  def install options
 | 
			
		||||
  def install options = {}
 | 
			
		||||
    destination = options[:install_dir] || Gem.dir
 | 
			
		||||
 | 
			
		||||
    if File.exist? File.join(destination, 'specifications', spec.spec_name) then
 | 
			
		||||
| 
						 | 
				
			
			@ -41,10 +41,36 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification
 | 
			
		|||
    @dependencies << dependency
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pretty_print q # :nodoc:
 | 
			
		||||
    q.group 2, '[LockSpecification', ']' do
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "name: #{@name}"
 | 
			
		||||
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text "version: #{@version}"
 | 
			
		||||
 | 
			
		||||
      unless @platform == Gem::Platform::RUBY then
 | 
			
		||||
        q.breakable
 | 
			
		||||
        q.text "platform: #{@platform}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      unless @dependencies.empty? then
 | 
			
		||||
        q.breakable
 | 
			
		||||
        q.text 'dependencies:'
 | 
			
		||||
        q.breakable
 | 
			
		||||
        q.pp @dependencies
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # A specification constructed from the lockfile is returned
 | 
			
		||||
 | 
			
		||||
  def spec
 | 
			
		||||
    @spec ||= Gem::Specification.find { |spec|
 | 
			
		||||
      spec.name == @name and spec.version == @version
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @spec ||= Gem::Specification.new do |s|
 | 
			
		||||
      s.name     = @name
 | 
			
		||||
      s.version  = @version
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,20 @@ class Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
  attr_accessor :remote
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Errors encountered when resolving gems
 | 
			
		||||
 | 
			
		||||
  attr_accessor :errors
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # When true, allows matching of requests to prerelease gems.
 | 
			
		||||
 | 
			
		||||
  attr_accessor :prerelease
 | 
			
		||||
 | 
			
		||||
  def initialize # :nodoc:
 | 
			
		||||
    @prerelease = false
 | 
			
		||||
    @remote     = true
 | 
			
		||||
    @errors     = []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,8 +4,6 @@
 | 
			
		|||
 | 
			
		||||
class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
 | 
			
		||||
 | 
			
		||||
  attr_reader :spec # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # A SpecSpecification is created for a +set+ for a Gem::Specification in
 | 
			
		||||
  # +spec+.  The +source+ is either where the +spec+ came from, or should be
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,14 @@ class Gem::Resolver::Specification
 | 
			
		|||
 | 
			
		||||
  attr_reader :source
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The Gem::Specification for this Resolver::Specification.
 | 
			
		||||
  #
 | 
			
		||||
  # Implementers, note that #install updates @spec, so be sure to cache the
 | 
			
		||||
  # Gem::Specification in @spec when overriding.
 | 
			
		||||
 | 
			
		||||
  attr_reader :spec
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The version of the gem for this specification.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +55,13 @@ class Gem::Resolver::Specification
 | 
			
		|||
    @version      = nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Fetches development dependencies if the source does not provide them by
 | 
			
		||||
  # default (see APISpecification).
 | 
			
		||||
 | 
			
		||||
  def fetch_development_dependencies # :nodoc:
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The name and version of the specification.
 | 
			
		||||
  #
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +76,11 @@ class Gem::Resolver::Specification
 | 
			
		|||
  # install method yields a Gem::Installer instance, which indicates the
 | 
			
		||||
  # gem will be installed, or +nil+, which indicates the gem is already
 | 
			
		||||
  # installed.
 | 
			
		||||
  #
 | 
			
		||||
  # After installation #spec is updated to point to the just-installed
 | 
			
		||||
  # specification.
 | 
			
		||||
 | 
			
		||||
  def install options
 | 
			
		||||
  def install options = {}
 | 
			
		||||
    require 'rubygems/installer'
 | 
			
		||||
 | 
			
		||||
    destination = options[:install_dir] || Gem.dir
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +93,7 @@ class Gem::Resolver::Specification
 | 
			
		|||
 | 
			
		||||
    yield installer if block_given?
 | 
			
		||||
 | 
			
		||||
    installer.install
 | 
			
		||||
    @spec = installer.install
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -85,5 +103,8 @@ class Gem::Resolver::Specification
 | 
			
		|||
    Gem::Platform.match spec.platform
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def local? # :nodoc:
 | 
			
		||||
    false
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,8 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
    @specs[spec.name]  = spec
 | 
			
		||||
    @directories[spec] = directory
 | 
			
		||||
 | 
			
		||||
    spec
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +53,7 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set
 | 
			
		|||
 | 
			
		||||
  def find_all req
 | 
			
		||||
    @specs.values.select do |spec|
 | 
			
		||||
      req.matches_spec? spec
 | 
			
		||||
      req.match? spec
 | 
			
		||||
    end.map do |spec|
 | 
			
		||||
      source = Gem::Source::Vendor.new @directories[spec]
 | 
			
		||||
      Gem::Resolver::VendorSpecification.new self, spec, source
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ class Gem::Resolver::VendorSpecification < Gem::Resolver::SpecSpecification
 | 
			
		|||
  # This is a null install as this gem was unpacked into a directory.
 | 
			
		||||
  # +options+ are ignored.
 | 
			
		||||
 | 
			
		||||
  def install options
 | 
			
		||||
  def install options = {}
 | 
			
		||||
    yield nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -218,6 +218,7 @@ class Gem::Security::Policy
 | 
			
		|||
        # against
 | 
			
		||||
      else
 | 
			
		||||
        alert_warning "#{full_name} is not signed"
 | 
			
		||||
        return
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -530,6 +530,36 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def prerelease_specs req, res
 | 
			
		||||
    reset_gems
 | 
			
		||||
 | 
			
		||||
    res['content-type'] = 'application/x-gzip'
 | 
			
		||||
 | 
			
		||||
    add_date res
 | 
			
		||||
 | 
			
		||||
    specs = Gem::Specification.select do |spec|
 | 
			
		||||
      spec.version.prerelease?
 | 
			
		||||
    end.sort.map do |spec|
 | 
			
		||||
      platform = spec.original_platform || Gem::Platform::RUBY
 | 
			
		||||
      [spec.name, spec.version, platform]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    specs = Marshal.dump specs
 | 
			
		||||
 | 
			
		||||
    if req.path =~ /\.gz$/ then
 | 
			
		||||
      specs = Gem.gzip specs
 | 
			
		||||
      res['content-type'] = 'application/x-gzip'
 | 
			
		||||
    else
 | 
			
		||||
      res['content-type'] = 'application/octet-stream'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if req.request_method == 'HEAD' then
 | 
			
		||||
      res['content-length'] = specs.length
 | 
			
		||||
    else
 | 
			
		||||
      res.body << specs
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def quick(req, res)
 | 
			
		||||
    reset_gems
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -537,7 +567,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
 | 
			
		|||
    add_date res
 | 
			
		||||
 | 
			
		||||
    case req.request_uri.path
 | 
			
		||||
    when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+)(-.*?)?\.gemspec\.rz$| then
 | 
			
		||||
    when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+[^-]*?)(-.*?)?\.gemspec\.rz$| then
 | 
			
		||||
      marshal_format, name, version, platform = $1, $2, $3, $4
 | 
			
		||||
      specs = Gem::Specification.find_all_by_name name, version
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -757,6 +787,11 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
 | 
			
		|||
    @server.mount_proc "/latest_specs.#{Gem.marshal_version}.gz",
 | 
			
		||||
                       method(:latest_specs)
 | 
			
		||||
 | 
			
		||||
    @server.mount_proc "/prerelease_specs.#{Gem.marshal_version}",
 | 
			
		||||
                       method(:prerelease_specs)
 | 
			
		||||
    @server.mount_proc "/prerelease_specs.#{Gem.marshal_version}.gz",
 | 
			
		||||
                       method(:prerelease_specs)
 | 
			
		||||
 | 
			
		||||
    @server.mount_proc "/quick/", method(:quick)
 | 
			
		||||
 | 
			
		||||
    @server.mount_proc("/gem-server-rdoc-style.css") do |req, res|
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,17 +78,23 @@ class Gem::Source
 | 
			
		|||
  # Returns a Set that can fetch specifications from this source.
 | 
			
		||||
 | 
			
		||||
  def dependency_resolver_set # :nodoc:
 | 
			
		||||
    return Gem::Resolver::IndexSet.new self if 'file' == api_uri.scheme
 | 
			
		||||
 | 
			
		||||
    bundler_api_uri = api_uri + './api/v1/dependencies'
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
      fetcher = Gem::RemoteFetcher.fetcher
 | 
			
		||||
      fetcher.fetch_path bundler_api_uri, nil, true
 | 
			
		||||
      response = fetcher.fetch_path bundler_api_uri, nil, true
 | 
			
		||||
    rescue Gem::RemoteFetcher::FetchError
 | 
			
		||||
      Gem::Resolver::IndexSet.new self
 | 
			
		||||
    else
 | 
			
		||||
      if response.respond_to? :uri then
 | 
			
		||||
        Gem::Resolver::APISet.new response.uri
 | 
			
		||||
      else
 | 
			
		||||
        Gem::Resolver::APISet.new bundler_api_uri
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def hash # :nodoc:
 | 
			
		||||
    @uri.hash
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +106,8 @@ class Gem::Source
 | 
			
		|||
  def cache_dir(uri)
 | 
			
		||||
    # Correct for windows paths
 | 
			
		||||
    escaped_path = uri.path.sub(/^\/([a-z]):\//i, '/\\1-/')
 | 
			
		||||
    escaped_path.untaint
 | 
			
		||||
 | 
			
		||||
    File.join Gem.spec_cache_dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ class Gem::Source::Git < Gem::Source
 | 
			
		|||
  # will be checked out when the gem is installed.
 | 
			
		||||
 | 
			
		||||
  def initialize name, repository, reference, submodules = false
 | 
			
		||||
    super(nil)
 | 
			
		||||
    super repository
 | 
			
		||||
 | 
			
		||||
    @name            = name
 | 
			
		||||
    @repository      = repository
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ class Gem::Source::Git < Gem::Source
 | 
			
		|||
    case other
 | 
			
		||||
    when Gem::Source::Git then
 | 
			
		||||
      0
 | 
			
		||||
    when Gem::Source::Installed,
 | 
			
		||||
    when Gem::Source::Vendor,
 | 
			
		||||
         Gem::Source::Lock then
 | 
			
		||||
      -1
 | 
			
		||||
    when Gem::Source then
 | 
			
		||||
| 
						 | 
				
			
			@ -101,7 +101,7 @@ class Gem::Source::Git < Gem::Source
 | 
			
		|||
    Dir.chdir install_dir do
 | 
			
		||||
      system @git, 'fetch', '--quiet', '--force', '--tags', install_dir
 | 
			
		||||
 | 
			
		||||
      success = system @git, 'reset', '--quiet', '--hard', @reference
 | 
			
		||||
      success = system @git, 'reset', '--quiet', '--hard', rev_parse
 | 
			
		||||
 | 
			
		||||
      success &&=
 | 
			
		||||
        Gem::Util.silent_system @git, 'submodule', 'update',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,8 @@ class Gem::Source::Installed < Gem::Source
 | 
			
		|||
 | 
			
		||||
  def <=> other
 | 
			
		||||
    case other
 | 
			
		||||
    when Gem::Source::Lock,
 | 
			
		||||
    when Gem::Source::Git,
 | 
			
		||||
         Gem::Source::Lock,
 | 
			
		||||
         Gem::Source::Vendor then
 | 
			
		||||
      -1
 | 
			
		||||
    when Gem::Source::Installed then
 | 
			
		||||
| 
						 | 
				
			
			@ -31,5 +32,9 @@ class Gem::Source::Installed < Gem::Source
 | 
			
		|||
    nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pretty_print q # :nodoc:
 | 
			
		||||
    q.text '[Installed]'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,11 @@
 | 
			
		|||
 | 
			
		||||
class Gem::Source::SpecificFile < Gem::Source
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The path to the gem for this specific file.
 | 
			
		||||
 | 
			
		||||
  attr_reader :path
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Creates a new SpecificFile for the gem in +file+
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +42,7 @@ class Gem::Source::SpecificFile < Gem::Source
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def pretty_print q # :nodoc:
 | 
			
		||||
    q.group 2, '[Local:', ']' do
 | 
			
		||||
    q.group 2, '[SpecificFile:', ']' do
 | 
			
		||||
      q.breakable
 | 
			
		||||
      q.text @path
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -186,7 +186,7 @@ class Gem::SpecFetcher
 | 
			
		|||
  def suggest_gems_from_name gem_name
 | 
			
		||||
    gem_name        = gem_name.downcase.tr('_-', '')
 | 
			
		||||
    max             = gem_name.size / 2
 | 
			
		||||
    names           = available_specs(:complete).first.values.flatten(1)
 | 
			
		||||
    names           = available_specs(:latest).first.values.flatten(1)
 | 
			
		||||
 | 
			
		||||
    matches = names.map { |n|
 | 
			
		||||
      next unless n.match_platform?
 | 
			
		||||
| 
						 | 
				
			
			@ -258,19 +258,12 @@ class Gem::SpecFetcher
 | 
			
		|||
  # etc.).  If +gracefully_ignore+ is true, errors are ignored.
 | 
			
		||||
 | 
			
		||||
  def tuples_for(source, type, gracefully_ignore=false) # :nodoc:
 | 
			
		||||
    cache = @caches[type]
 | 
			
		||||
 | 
			
		||||
    tuples =
 | 
			
		||||
      begin
 | 
			
		||||
        cache[source.uri] ||=
 | 
			
		||||
    @caches[type][source.uri] ||=
 | 
			
		||||
      source.load_specs(type).sort_by { |tup| tup.name }
 | 
			
		||||
  rescue Gem::RemoteFetcher::FetchError
 | 
			
		||||
    raise unless gracefully_ignore
 | 
			
		||||
    []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
    tuples
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,12 +14,6 @@ require 'rubygems/basic_specification'
 | 
			
		|||
require 'rubygems/stub_specification'
 | 
			
		||||
require 'rubygems/util/stringio'
 | 
			
		||||
 | 
			
		||||
# :stopdoc:
 | 
			
		||||
# date.rb can't be loaded for `make install` due to miniruby
 | 
			
		||||
# Date is needed for old gems that stored #date as Date instead of Time.
 | 
			
		||||
class Date; end
 | 
			
		||||
# :startdoc:
 | 
			
		||||
 | 
			
		||||
##
 | 
			
		||||
# The Specification class contains the information for a Gem.  Typically
 | 
			
		||||
# defined in a .gemspec file or a Rakefile, and looks like this:
 | 
			
		||||
| 
						 | 
				
			
			@ -218,9 +212,11 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  # Usage:
 | 
			
		||||
  #
 | 
			
		||||
  #   # If all library files are in the root directory...
 | 
			
		||||
  #   spec.require_path = '.'
 | 
			
		||||
  #   spec.require_paths = ['.']
 | 
			
		||||
 | 
			
		||||
  attr_writer :require_paths
 | 
			
		||||
  def require_paths=(val)
 | 
			
		||||
    @require_paths = Array(val)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The version of RubyGems used to create this gem.
 | 
			
		||||
| 
						 | 
				
			
			@ -373,7 +369,9 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  ##
 | 
			
		||||
  # A long description of this gem
 | 
			
		||||
  #
 | 
			
		||||
  # The description should be more detailed than the summary.
 | 
			
		||||
  # The description should be more detailed than the summary but not
 | 
			
		||||
  # excessively long.  A few paragraphs is a recommended length with no
 | 
			
		||||
  # examples or formatting.
 | 
			
		||||
  #
 | 
			
		||||
  # Usage:
 | 
			
		||||
  #
 | 
			
		||||
| 
						 | 
				
			
			@ -412,6 +410,16 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
 | 
			
		||||
  attr_accessor :post_install_message
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The version of Ruby required by this gem
 | 
			
		||||
 | 
			
		||||
  attr_reader :required_ruby_version
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The RubyGems version required by this gem
 | 
			
		||||
 | 
			
		||||
  attr_reader :required_rubygems_version
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The key used to sign this gem.  See Gem::Security for details.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -472,6 +480,9 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  # found in bindir.  These files must be executable Ruby files.  Files that
 | 
			
		||||
  # use bash or other interpreters will not work.
 | 
			
		||||
  #
 | 
			
		||||
  # Executables included may only be ruby scripts, not scripts for other
 | 
			
		||||
  # languages or compiled binaries.
 | 
			
		||||
  #
 | 
			
		||||
  # Usage:
 | 
			
		||||
  #
 | 
			
		||||
  #   spec.executables << 'rake'
 | 
			
		||||
| 
						 | 
				
			
			@ -532,20 +543,26 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
 | 
			
		||||
  ##
 | 
			
		||||
  # :category: Recommended gemspec attributes
 | 
			
		||||
  #
 | 
			
		||||
  # The license for this gem.
 | 
			
		||||
  #
 | 
			
		||||
  # The license must be a short name, no more than 64 characters.
 | 
			
		||||
  # The license must be no more than 64 characters.
 | 
			
		||||
  #
 | 
			
		||||
  # This should just be the name of your license. The full
 | 
			
		||||
  # text of the license should be inside of the gem when you build it.
 | 
			
		||||
  # This should just be the name of your license. The full text of the license
 | 
			
		||||
  # should be inside of the gem (at the top level) when you build it.
 | 
			
		||||
  #
 | 
			
		||||
  # See http://opensource.org/licenses/alphabetical for a list of licenses and
 | 
			
		||||
  # their abbreviations (or short names).  GitHub also provides a
 | 
			
		||||
  # license picker at http://choosealicense.com/
 | 
			
		||||
  # The simplest way, is to specify the standard SPDX ID
 | 
			
		||||
  # https://spdx.org/licenses/ for the license.
 | 
			
		||||
  # Ideally you should pick one that is OSI (Open Source Initiative)
 | 
			
		||||
  # http://opensource.org/licenses/alphabetical approved.
 | 
			
		||||
  #
 | 
			
		||||
  #  According to copyright law, not having an OSI-approved open source license
 | 
			
		||||
  #  means you have no rights to use the code for any purpose-- in other words,
 | 
			
		||||
  #  "all rights reserved".
 | 
			
		||||
  # The most commonly used OSI approved licenses are BSD-3-Clause and MIT.
 | 
			
		||||
  # GitHub also provides a license picker at http://choosealicense.com/.
 | 
			
		||||
  #
 | 
			
		||||
  # You should specify a license for your gem so that people know how they are
 | 
			
		||||
  # permitted to use it, and any restrictions you're placing on it.  Not
 | 
			
		||||
  # specifying a license means all rights are reserved; others have no rights
 | 
			
		||||
  # to use the code for any purpose.
 | 
			
		||||
  #
 | 
			
		||||
  # You can set multiple licenses with #licenses=
 | 
			
		||||
  #
 | 
			
		||||
| 
						 | 
				
			
			@ -607,6 +624,13 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
    @required_ruby_version = Gem::Requirement.create req
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The RubyGems version required by this gem
 | 
			
		||||
 | 
			
		||||
  def required_rubygems_version= req
 | 
			
		||||
    @required_rubygems_version = Gem::Requirement.create req
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Lists the external (to RubyGems) requirements that must be met for this gem
 | 
			
		||||
  # to work.  It's simply information for the user.
 | 
			
		||||
| 
						 | 
				
			
			@ -628,7 +652,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  #   spec.test_files = Dir.glob('test/tc_*.rb')
 | 
			
		||||
  #   spec.test_files = ['tests/test-suite.rb']
 | 
			
		||||
 | 
			
		||||
  def test_files= files
 | 
			
		||||
  def test_files= files # :nodoc:
 | 
			
		||||
    @test_files = Array files
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -661,16 +685,6 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
 | 
			
		||||
  attr_writer :original_platform # :nodoc:
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The version of Ruby required by this gem
 | 
			
		||||
 | 
			
		||||
  attr_reader :required_ruby_version
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The RubyGems version required by this gem
 | 
			
		||||
 | 
			
		||||
  attr_reader :required_rubygems_version
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The rubyforge project this gem lives under.  i.e. RubyGems'
 | 
			
		||||
  # rubyforge_project is "rubygems".
 | 
			
		||||
| 
						 | 
				
			
			@ -1259,9 +1273,13 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  # there are conflicts upon activation.
 | 
			
		||||
 | 
			
		||||
  def activate
 | 
			
		||||
    raise_if_conflicts
 | 
			
		||||
    other = Gem.loaded_specs[self.name]
 | 
			
		||||
    if other then
 | 
			
		||||
      check_version_conflict other
 | 
			
		||||
      return false
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return false if Gem.loaded_specs[self.name]
 | 
			
		||||
    raise_if_conflicts
 | 
			
		||||
 | 
			
		||||
    activate_dependencies
 | 
			
		||||
    add_self_to_load_path
 | 
			
		||||
| 
						 | 
				
			
			@ -1403,7 +1421,10 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
 | 
			
		||||
  def build_args
 | 
			
		||||
    if File.exist? build_info_file
 | 
			
		||||
      File.readlines(build_info_file).map { |x| x.strip }
 | 
			
		||||
      build_info = File.readlines build_info_file
 | 
			
		||||
      build_info = build_info.map { |x| x.strip }
 | 
			
		||||
      build_info.delete ""
 | 
			
		||||
      build_info
 | 
			
		||||
    else
 | 
			
		||||
      []
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -1418,8 +1439,8 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
    return if extensions.empty?
 | 
			
		||||
    return if installed_by_version < Gem::Version.new('2.2.0.preview.2')
 | 
			
		||||
    return if File.exist? gem_build_complete_path
 | 
			
		||||
    return if !File.writable?(base_dir) &&
 | 
			
		||||
              !File.exist?(File.join(base_dir, 'extensions'))
 | 
			
		||||
    return if !File.writable?(base_dir)
 | 
			
		||||
    return if !File.exist?(File.join(base_dir, 'extensions'))
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
      # We need to require things in $LOAD_PATH without looking for the
 | 
			
		||||
| 
						 | 
				
			
			@ -1477,13 +1498,12 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
 | 
			
		||||
  def conflicts
 | 
			
		||||
    conflicts = {}
 | 
			
		||||
    Gem.loaded_specs.values.each do |spec|
 | 
			
		||||
      bad = self.runtime_dependencies.find_all { |dep|
 | 
			
		||||
        spec.name == dep.name and not spec.satisfies_requirement? dep
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      conflicts[spec] = bad unless bad.empty?
 | 
			
		||||
    self.runtime_dependencies.each { |dep|
 | 
			
		||||
      spec = Gem.loaded_specs[dep.name]
 | 
			
		||||
      if spec and not spec.satisfies_requirement? dep
 | 
			
		||||
        (conflicts[spec] ||= []) << dep
 | 
			
		||||
      end
 | 
			
		||||
    }
 | 
			
		||||
    conflicts
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1496,6 +1516,11 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
    @date ||= TODAY
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  DateLike = Object.new # :nodoc:
 | 
			
		||||
  def DateLike.===(obj) # :nodoc:
 | 
			
		||||
    defined?(::Date) and Date === obj
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  DateTimeFormat = # :nodoc:
 | 
			
		||||
    /\A
 | 
			
		||||
     (\d{4})-(\d{2})-(\d{2})
 | 
			
		||||
| 
						 | 
				
			
			@ -1525,7 +1550,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
                raise(Gem::InvalidSpecificationException,
 | 
			
		||||
                      "invalid date format in specification: #{date.inspect}")
 | 
			
		||||
              end
 | 
			
		||||
            when Time, Date then
 | 
			
		||||
            when Time, DateLike then
 | 
			
		||||
              Time.utc(date.year, date.month, date.day)
 | 
			
		||||
            else
 | 
			
		||||
              TODAY
 | 
			
		||||
| 
						 | 
				
			
			@ -1779,7 +1804,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  ##
 | 
			
		||||
  # True if this gem has files in test_files
 | 
			
		||||
 | 
			
		||||
  def has_unit_tests?
 | 
			
		||||
  def has_unit_tests? # :nodoc:
 | 
			
		||||
    not test_files.empty?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1952,6 +1977,19 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Is this specification missing its extensions?  When this returns true you
 | 
			
		||||
  # probably want to build_extensions
 | 
			
		||||
 | 
			
		||||
  def missing_extensions?
 | 
			
		||||
    return false if default_gem?
 | 
			
		||||
    return false if extensions.empty?
 | 
			
		||||
    return false if installed_by_version < Gem::Version.new('2.2.0.preview.2')
 | 
			
		||||
    return false if File.exist? gem_build_complete_path
 | 
			
		||||
 | 
			
		||||
    true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Normalize the list of files so that:
 | 
			
		||||
  # * All file lists have redundancies removed.
 | 
			
		||||
| 
						 | 
				
			
			@ -2036,12 +2074,12 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Check the spec for possible conflicts and freak out if there are any.
 | 
			
		||||
  # Raise an exception if the version of this spec conflicts with the one
 | 
			
		||||
  # that is already loaded (+other+)
 | 
			
		||||
 | 
			
		||||
  def raise_if_conflicts
 | 
			
		||||
    other = Gem.loaded_specs[self.name]
 | 
			
		||||
  def check_version_conflict other # :nodoc:
 | 
			
		||||
    return if self.version == other.version
 | 
			
		||||
 | 
			
		||||
    if other and self.version != other.version then
 | 
			
		||||
    # This gem is already loaded.  If the currently loaded gem is not in the
 | 
			
		||||
    # list of candidate gems, then we have a version conflict.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2054,16 +2092,16 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
    raise e
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private :check_version_conflict
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Check the spec for possible conflicts and freak out if there are any.
 | 
			
		||||
 | 
			
		||||
  def raise_if_conflicts # :nodoc:
 | 
			
		||||
    conf = self.conflicts
 | 
			
		||||
 | 
			
		||||
    unless conf.empty? then
 | 
			
		||||
      y = conf.map { |act,con|
 | 
			
		||||
        "#{act.full_name} conflicts with #{con.join(", ")}"
 | 
			
		||||
      }.join ", "
 | 
			
		||||
 | 
			
		||||
      # TODO: improve message by saying who activated `con`
 | 
			
		||||
 | 
			
		||||
      raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}"
 | 
			
		||||
      raise Gem::ConflictError.new self, conf
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2087,14 +2125,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  # Singular accessor for #require_paths
 | 
			
		||||
 | 
			
		||||
  def require_path= path
 | 
			
		||||
    self.require_paths = [path]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # The RubyGems version required by this gem
 | 
			
		||||
 | 
			
		||||
  def required_rubygems_version= req
 | 
			
		||||
    @required_rubygems_version = Gem::Requirement.create req
 | 
			
		||||
    self.require_paths = Array(path)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -2129,7 +2160,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
      seg = obj.keys.sort.map { |k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" }
 | 
			
		||||
      "{ #{seg.join(', ')} }"
 | 
			
		||||
    when Gem::Version      then obj.to_s.dump
 | 
			
		||||
    when Date              then obj.strftime('%Y-%m-%d').dump
 | 
			
		||||
    when DateLike          then obj.strftime('%Y-%m-%d').dump
 | 
			
		||||
    when Time              then obj.strftime('%Y-%m-%d').dump
 | 
			
		||||
    when Numeric           then obj.inspect
 | 
			
		||||
    when true, false, nil  then obj.inspect
 | 
			
		||||
| 
						 | 
				
			
			@ -2217,14 +2248,14 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  ##
 | 
			
		||||
  # Singular accessor for #test_files
 | 
			
		||||
 | 
			
		||||
  def test_file
 | 
			
		||||
  def test_file # :nodoc:
 | 
			
		||||
    val = test_files and val.first
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Singular mutator for #test_files
 | 
			
		||||
 | 
			
		||||
  def test_file= file
 | 
			
		||||
  def test_file= file # :nodoc:
 | 
			
		||||
    self.test_files = [file]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2232,7 +2263,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
  # Test files included in this gem.  You cannot append to this accessor, you
 | 
			
		||||
  # must assign to it.
 | 
			
		||||
 | 
			
		||||
  def test_files
 | 
			
		||||
  def test_files # :nodoc:
 | 
			
		||||
    # Handle the possibility that we have @test_suite_file but not
 | 
			
		||||
    # @test_files.  This will happen when an old gem is loaded via
 | 
			
		||||
    # YAML.
 | 
			
		||||
| 
						 | 
				
			
			@ -2256,7 +2287,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
    mark_version
 | 
			
		||||
    result = []
 | 
			
		||||
    result << "# -*- encoding: utf-8 -*-"
 | 
			
		||||
    result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{@require_paths.join("\0")}"
 | 
			
		||||
    result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{raw_require_paths.join("\0")}"
 | 
			
		||||
    result << "#{Gem::StubSpecification::PREFIX}#{extensions.join "\0"}" unless
 | 
			
		||||
      extensions.empty?
 | 
			
		||||
    result << nil
 | 
			
		||||
| 
						 | 
				
			
			@ -2273,7 +2304,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
    if metadata and !metadata.empty?
 | 
			
		||||
      result << "  s.metadata = #{ruby_code metadata} if s.respond_to? :metadata="
 | 
			
		||||
    end
 | 
			
		||||
    result << "  s.require_paths = #{ruby_code @require_paths}"
 | 
			
		||||
    result << "  s.require_paths = #{ruby_code raw_require_paths}"
 | 
			
		||||
 | 
			
		||||
    handled = [
 | 
			
		||||
      :dependencies,
 | 
			
		||||
| 
						 | 
				
			
			@ -2443,7 +2474,7 @@ class Gem::Specification < Gem::BasicSpecification
 | 
			
		|||
            "invalid value for attribute name: \"#{name.inspect}\""
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if @require_paths.empty? then
 | 
			
		||||
    if raw_require_paths.empty? then
 | 
			
		||||
      raise Gem::InvalidSpecificationException,
 | 
			
		||||
            'specification must have at least one require_path'
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -2627,7 +2658,8 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
 | 
			
		|||
        dep.requirement.requirements.any? do |op, version|
 | 
			
		||||
          op == '~>' and
 | 
			
		||||
            not version.prerelease? and
 | 
			
		||||
            version.segments.length > 2
 | 
			
		||||
            version.segments.length > 2 and
 | 
			
		||||
            version.segments.first != 0
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
      if overly_strict then
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,6 +120,13 @@ class Gem::StubSpecification < Gem::BasicSpecification
 | 
			
		|||
    super
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def missing_extensions?
 | 
			
		||||
    return false if default_gem?
 | 
			
		||||
    return false if extensions.empty?
 | 
			
		||||
 | 
			
		||||
    to_spec.missing_extensions?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Name of the gem
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +154,14 @@ class Gem::StubSpecification < Gem::BasicSpecification
 | 
			
		|||
  # The full Gem::Specification for this gem, loaded from evalling its gemspec
 | 
			
		||||
 | 
			
		||||
  def to_spec
 | 
			
		||||
    @spec ||= Gem.loaded_specs.values.find { |spec|
 | 
			
		||||
      spec.name == @name and spec.version == @version
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @spec ||= Gem::Specification.load(loaded_from)
 | 
			
		||||
    @spec.ignored = @ignored if instance_variable_defined? :@ignored
 | 
			
		||||
 | 
			
		||||
    @spec
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -220,6 +220,9 @@ class Gem::TestCase < MiniTest::Unit::TestCase
 | 
			
		|||
 | 
			
		||||
    @orig_gem_home   = ENV['GEM_HOME']
 | 
			
		||||
    @orig_gem_path   = ENV['GEM_PATH']
 | 
			
		||||
    @orig_gem_vendor = ENV['GEM_VENDOR']
 | 
			
		||||
 | 
			
		||||
    ENV['GEM_VENDOR'] = nil
 | 
			
		||||
 | 
			
		||||
    @current_dir = Dir.pwd
 | 
			
		||||
    @fetcher     = nil
 | 
			
		||||
| 
						 | 
				
			
			@ -349,6 +352,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase
 | 
			
		|||
 | 
			
		||||
    ENV['GEM_HOME']   = @orig_gem_home
 | 
			
		||||
    ENV['GEM_PATH']   = @orig_gem_path
 | 
			
		||||
    ENV['GEM_VENDOR'] = @orig_gem_vendor
 | 
			
		||||
 | 
			
		||||
    Gem.ruby = @orig_ruby if @orig_ruby
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1263,7 +1267,7 @@ Also, a list:
 | 
			
		|||
  # The StaticSet is a static set of gem specifications used for testing only.
 | 
			
		||||
  # It is available by requiring Gem::TestCase.
 | 
			
		||||
 | 
			
		||||
  class StaticSet
 | 
			
		||||
  class StaticSet < Gem::Resolver::Set
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
    # A StaticSet ignores remote because it has a fixed set of gems.
 | 
			
		||||
| 
						 | 
				
			
			@ -1274,6 +1278,8 @@ Also, a list:
 | 
			
		|||
    # Creates a new StaticSet for the given +specs+
 | 
			
		||||
 | 
			
		||||
    def initialize(specs)
 | 
			
		||||
      super()
 | 
			
		||||
 | 
			
		||||
      @specs = specs
 | 
			
		||||
 | 
			
		||||
      @remote = true
 | 
			
		||||
| 
						 | 
				
			
			@ -1299,7 +1305,7 @@ Also, a list:
 | 
			
		|||
    # Finds all gems matching +dep+ in this set.
 | 
			
		||||
 | 
			
		||||
    def find_all(dep)
 | 
			
		||||
      @specs.find_all { |s| dep.matches_spec? s }
 | 
			
		||||
      @specs.find_all { |s| dep.match? s, @prerelease }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,8 @@ class Gem::FakeFetcher
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def find_data(path)
 | 
			
		||||
    return File.read path.path if URI === path and 'file' == path.scheme
 | 
			
		||||
 | 
			
		||||
    if URI === path and "URI::#{path.scheme.upcase}" != path.class.name then
 | 
			
		||||
      raise ArgumentError,
 | 
			
		||||
        "mismatch for scheme #{path.scheme} and class #{path.class}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,16 @@ module Gem::Text
 | 
			
		|||
    result.join("\n").gsub(/^/, " " * indent)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def min3 a, b, c # :nodoc:
 | 
			
		||||
    if a < b && a < c
 | 
			
		||||
      a
 | 
			
		||||
    elsif b < a && b < c
 | 
			
		||||
      b
 | 
			
		||||
    else
 | 
			
		||||
      c
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -42,16 +52,16 @@ module Gem::Text
 | 
			
		|||
    d = (0..m).to_a
 | 
			
		||||
    x = nil
 | 
			
		||||
 | 
			
		||||
    n.times do |i|
 | 
			
		||||
    str1.each_char.each_with_index do |char1,i|
 | 
			
		||||
      e = i+1
 | 
			
		||||
 | 
			
		||||
      m.times do |j|
 | 
			
		||||
        cost = (s[i] == t[j]) ? 0 : 1
 | 
			
		||||
        x = [
 | 
			
		||||
      str2.each_char.each_with_index do |char2,j|
 | 
			
		||||
        cost = (char1 == char2) ? 0 : 1
 | 
			
		||||
        x = min3(
 | 
			
		||||
             d[j+1] + 1, # insertion
 | 
			
		||||
             e + 1,      # deletion
 | 
			
		||||
             d[j] + cost # substitution
 | 
			
		||||
            ].min
 | 
			
		||||
            )
 | 
			
		||||
        d[j] = e
 | 
			
		||||
        e = x
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,6 +96,8 @@ class Gem::Uninstaller
 | 
			
		|||
        (@user_install and spec.base_dir == Gem.user_dir)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    list.sort!
 | 
			
		||||
 | 
			
		||||
    if list.empty? then
 | 
			
		||||
      if other_repo_specs.empty?
 | 
			
		||||
        if default_specs.empty?
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +122,8 @@ class Gem::Uninstaller
 | 
			
		|||
      remove_all list
 | 
			
		||||
 | 
			
		||||
    elsif list.size > 1 then
 | 
			
		||||
      gem_names = list.collect {|gem| gem.full_name} + ["All versions"]
 | 
			
		||||
      gem_names = list.map { |gem| gem.full_name }
 | 
			
		||||
      gem_names << "All versions"
 | 
			
		||||
 | 
			
		||||
      say
 | 
			
		||||
      _, index = choose_from_list "Select gem to uninstall:", gem_names
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,6 +157,14 @@ module Gem::UserInteraction
 | 
			
		|||
  def terminate_interaction exit_code = 0
 | 
			
		||||
    ui.terminate_interaction exit_code
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Calls +say+ with +msg+ or the results of the block if really_verbose
 | 
			
		||||
  # is true.
 | 
			
		||||
 | 
			
		||||
  def verbose msg = nil
 | 
			
		||||
    say(msg || yield) if Gem.configuration.really_verbose
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
##
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -143,6 +143,10 @@
 | 
			
		|||
#   "~> 3.0.0"    3.0.0 ... 3.1
 | 
			
		||||
#   "~> 3.5"      3.5   ... 4.0
 | 
			
		||||
#   "~> 3.5.0"    3.5.0 ... 3.6
 | 
			
		||||
#   "~> 3"        3.0   ... 4.0
 | 
			
		||||
#
 | 
			
		||||
# For the last example, single-digit versions are automatically extended with
 | 
			
		||||
# a zero to give a sensible result.
 | 
			
		||||
 | 
			
		||||
class Gem::Version
 | 
			
		||||
  autoload :Requirement, 'rubygems/requirement'
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +193,7 @@ class Gem::Version
 | 
			
		|||
  @@all = {}
 | 
			
		||||
 | 
			
		||||
  def self.new version # :nodoc:
 | 
			
		||||
    return super unless Gem::VERSION == self.class
 | 
			
		||||
    return super unless Gem::Version == self
 | 
			
		||||
 | 
			
		||||
    @@all[version] ||= super
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,21 @@ class TestGem < Gem::TestCase
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_install
 | 
			
		||||
    spec_fetcher do |f|
 | 
			
		||||
      f.gem  'a', 1
 | 
			
		||||
      f.spec 'a', 2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    gemhome2 = "#{@gemhome}2"
 | 
			
		||||
 | 
			
		||||
    installed = Gem.install 'a', '= 1', :install_dir => gemhome2
 | 
			
		||||
 | 
			
		||||
    assert_equal %w[a-1], installed.map { |spec| spec.full_name }
 | 
			
		||||
 | 
			
		||||
    assert_path_exists File.join(gemhome2, 'gems', 'a-1')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_require_missing
 | 
			
		||||
    save_loaded_features do
 | 
			
		||||
      assert_raises ::LoadError do
 | 
			
		||||
| 
						 | 
				
			
			@ -216,6 +231,58 @@ class TestGem < Gem::TestCase
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_default_path
 | 
			
		||||
    orig_vendordir = RbConfig::CONFIG['vendordir']
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor'
 | 
			
		||||
 | 
			
		||||
    FileUtils.rm_rf Gem.user_home
 | 
			
		||||
 | 
			
		||||
    expected = [Gem.default_dir]
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, Gem.default_path
 | 
			
		||||
  ensure
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = orig_vendordir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_default_path_missing_vendor
 | 
			
		||||
    orig_vendordir = RbConfig::CONFIG['vendordir']
 | 
			
		||||
    RbConfig::CONFIG.delete 'vendordir'
 | 
			
		||||
 | 
			
		||||
    FileUtils.rm_rf Gem.user_home
 | 
			
		||||
 | 
			
		||||
    expected = [Gem.default_dir]
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, Gem.default_path
 | 
			
		||||
  ensure
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = orig_vendordir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_default_path_user_home
 | 
			
		||||
    orig_vendordir = RbConfig::CONFIG['vendordir']
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor'
 | 
			
		||||
 | 
			
		||||
    expected = [Gem.user_dir, Gem.default_dir]
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, Gem.default_path
 | 
			
		||||
  ensure
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = orig_vendordir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_default_path_vendor_dir
 | 
			
		||||
    orig_vendordir = RbConfig::CONFIG['vendordir']
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor'
 | 
			
		||||
 | 
			
		||||
    FileUtils.mkdir_p Gem.vendor_dir
 | 
			
		||||
 | 
			
		||||
    FileUtils.rm_rf Gem.user_home
 | 
			
		||||
 | 
			
		||||
    expected = [Gem.default_dir, Gem.vendor_dir]
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, Gem.default_path
 | 
			
		||||
  ensure
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = orig_vendordir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_default_sources
 | 
			
		||||
    assert_equal %w[https://rubygems.org/], Gem.default_sources
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -816,6 +883,23 @@ class TestGem < Gem::TestCase
 | 
			
		|||
    assert_match %r%Could not find 'b' %, e.message
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_try_activate_missing_extensions
 | 
			
		||||
    util_spec 'ext', '1' do |s|
 | 
			
		||||
      s.extensions = %w[ext/extconf.rb]
 | 
			
		||||
      s.mark_version
 | 
			
		||||
      s.installed_by_version = v('2.2')
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    _, err = capture_io do
 | 
			
		||||
      refute Gem.try_activate 'nonexistent'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = "Ignoring ext-1 because its extensions are not built.  " +
 | 
			
		||||
               "Try: gem pristine ext-1\n"
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, err
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_use_paths
 | 
			
		||||
    util_ensure_gem_dirs
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -951,6 +1035,30 @@ class TestGem < Gem::TestCase
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_vendor_dir
 | 
			
		||||
    expected =
 | 
			
		||||
      File.join RbConfig::CONFIG['vendordir'], 'gems',
 | 
			
		||||
                RbConfig::CONFIG['ruby_version']
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, Gem.vendor_dir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_vendor_dir_ENV_GEM_VENDOR
 | 
			
		||||
    ENV['GEM_VENDOR'] = File.join @tempdir, 'vendor', 'gems'
 | 
			
		||||
 | 
			
		||||
    assert_equal ENV['GEM_VENDOR'], Gem.vendor_dir
 | 
			
		||||
    refute Gem.vendor_dir.frozen?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_vendor_dir_missing
 | 
			
		||||
    orig_vendordir = RbConfig::CONFIG['vendordir']
 | 
			
		||||
    RbConfig::CONFIG.delete 'vendordir'
 | 
			
		||||
 | 
			
		||||
    assert_nil Gem.vendor_dir
 | 
			
		||||
  ensure
 | 
			
		||||
    RbConfig::CONFIG['vendordir'] = orig_vendordir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_load_plugins
 | 
			
		||||
    skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
 | 
			
		||||
    plugin_path = File.join "lib", "rubygems_plugin.rb"
 | 
			
		||||
| 
						 | 
				
			
			@ -1251,13 +1359,28 @@ class TestGem < Gem::TestCase
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps
 | 
			
		||||
    gem_deps_file = 'gem.deps.rb'.untaint
 | 
			
		||||
    spec = util_spec 'a', 1
 | 
			
		||||
 | 
			
		||||
    refute spec.activated?
 | 
			
		||||
 | 
			
		||||
    open gem_deps_file, 'w' do |io|
 | 
			
		||||
      io.write 'gem "a"'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    Gem.use_gemdeps gem_deps_file
 | 
			
		||||
 | 
			
		||||
    assert spec.activated?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_ENV
 | 
			
		||||
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil
 | 
			
		||||
 | 
			
		||||
    spec = util_spec 'a', 1
 | 
			
		||||
 | 
			
		||||
    refute spec.activated?
 | 
			
		||||
 | 
			
		||||
    open 'Gemfile', 'w' do |io|
 | 
			
		||||
    open 'gem.deps.rb', 'w' do |io|
 | 
			
		||||
      io.write 'gem "a"'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1268,6 +1391,29 @@ class TestGem < Gem::TestCase
 | 
			
		|||
    ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_argument_missing
 | 
			
		||||
    e = assert_raises ArgumentError do
 | 
			
		||||
      Gem.use_gemdeps 'gem.deps.rb'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_equal 'Unable to find gem dependencies file at gem.deps.rb',
 | 
			
		||||
                 e.message
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_argument_missing_match_ENV
 | 
			
		||||
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] =
 | 
			
		||||
      ENV['RUBYGEMS_GEMDEPS'], 'gem.deps.rb'
 | 
			
		||||
 | 
			
		||||
    e = assert_raises ArgumentError do
 | 
			
		||||
      Gem.use_gemdeps 'gem.deps.rb'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_equal 'Unable to find gem dependencies file at gem.deps.rb',
 | 
			
		||||
                 e.message
 | 
			
		||||
  ensure
 | 
			
		||||
    ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_automatic
 | 
			
		||||
    skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
 | 
			
		||||
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-'
 | 
			
		||||
| 
						 | 
				
			
			@ -1287,6 +1433,17 @@ class TestGem < Gem::TestCase
 | 
			
		|||
    ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_automatic_missing
 | 
			
		||||
    skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
 | 
			
		||||
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-'
 | 
			
		||||
 | 
			
		||||
    Gem.use_gemdeps
 | 
			
		||||
 | 
			
		||||
    assert true # count
 | 
			
		||||
  ensure
 | 
			
		||||
    ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_disabled
 | 
			
		||||
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], ''
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1294,7 +1451,7 @@ class TestGem < Gem::TestCase
 | 
			
		|||
 | 
			
		||||
    refute spec.activated?
 | 
			
		||||
 | 
			
		||||
    open 'Gemfile', 'w' do |io|
 | 
			
		||||
    open 'gem.deps.rb', 'w' do |io|
 | 
			
		||||
      io.write 'gem "a"'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1305,6 +1462,27 @@ class TestGem < Gem::TestCase
 | 
			
		|||
    ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_missing_gem
 | 
			
		||||
    skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7"
 | 
			
		||||
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x'
 | 
			
		||||
 | 
			
		||||
    open 'x', 'w' do |io|
 | 
			
		||||
      io.write 'gem "a"'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = <<-EXPECTED
 | 
			
		||||
Unable to resolve dependency: user requested 'a (>= 0)'
 | 
			
		||||
You may need to `gem install -g` to install missing gems
 | 
			
		||||
 | 
			
		||||
    EXPECTED
 | 
			
		||||
 | 
			
		||||
    assert_output nil, expected do
 | 
			
		||||
      Gem.use_gemdeps
 | 
			
		||||
    end
 | 
			
		||||
  ensure
 | 
			
		||||
    ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_use_gemdeps_specific
 | 
			
		||||
    skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7"
 | 
			
		||||
    rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ require 'rubygems/available_set'
 | 
			
		|||
require 'rubygems/security'
 | 
			
		||||
 | 
			
		||||
class TestGemAvailableSet < Gem::TestCase
 | 
			
		||||
 | 
			
		||||
  def setup
 | 
			
		||||
    super
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24,21 +25,23 @@ class TestGemAvailableSet < Gem::TestCase
 | 
			
		|||
 | 
			
		||||
  def test_find_all
 | 
			
		||||
    a1,  a1_gem  = util_gem 'a', 1
 | 
			
		||||
    a1a, a1a_gem = util_gem 'a', '1.a'
 | 
			
		||||
 | 
			
		||||
    source = Gem::Source::SpecificFile.new a1_gem
 | 
			
		||||
    a1_source  = Gem::Source::SpecificFile.new a1_gem
 | 
			
		||||
    a1a_source = Gem::Source::SpecificFile.new a1a_gem
 | 
			
		||||
 | 
			
		||||
    set = Gem::AvailableSet.new
 | 
			
		||||
    set.add a1, source
 | 
			
		||||
    set.add a1,  a1_source
 | 
			
		||||
    set.add a1a, a1a_source
 | 
			
		||||
 | 
			
		||||
    dep = Gem::Resolver::DependencyRequest.new dep('a'), nil
 | 
			
		||||
 | 
			
		||||
    specs = set.find_all dep
 | 
			
		||||
    assert_equal %w[a-1], set.find_all(dep).map { |spec| spec.full_name }
 | 
			
		||||
 | 
			
		||||
    spec = specs.first
 | 
			
		||||
    dep = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil
 | 
			
		||||
 | 
			
		||||
    assert_kind_of Gem::Resolver::LocalSpecification, spec
 | 
			
		||||
 | 
			
		||||
    assert_equal 'a-1', spec.full_name
 | 
			
		||||
    assert_equal %w[a-1 a-1.a],
 | 
			
		||||
                 set.find_all(dep).map { |spec| spec.full_name }.sort
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_match_platform
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -184,5 +184,60 @@ class TestGemCommand < Gem::TestCase
 | 
			
		|||
    assert_equal ['-h', 'command'], args
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_show_lookup_failure_suggestions_local
 | 
			
		||||
    correct    = "non_existent_with_hint"
 | 
			
		||||
    misspelled = "nonexistent_with_hint"
 | 
			
		||||
 | 
			
		||||
    spec_fetcher do |fetcher|
 | 
			
		||||
      fetcher.spec correct, 2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      @cmd.show_lookup_failure misspelled, Gem::Requirement.default, [], :local
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = <<-EXPECTED
 | 
			
		||||
ERROR:  Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository
 | 
			
		||||
    EXPECTED
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_show_lookup_failure_suggestions_none
 | 
			
		||||
    spec_fetcher do |fetcher|
 | 
			
		||||
      fetcher.spec 'correct', 2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      @cmd.show_lookup_failure 'other', Gem::Requirement.default, [], :remote
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = <<-EXPECTED
 | 
			
		||||
ERROR:  Could not find a valid gem 'other' (>= 0) in any repository
 | 
			
		||||
    EXPECTED
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_show_lookup_failure_suggestions_remote
 | 
			
		||||
    correct    = "non_existent_with_hint"
 | 
			
		||||
    misspelled = "nonexistent_with_hint"
 | 
			
		||||
 | 
			
		||||
    spec_fetcher do |fetcher|
 | 
			
		||||
      fetcher.spec correct, 2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      @cmd.show_lookup_failure misspelled, Gem::Requirement.default, [], :remote
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = <<-EXPECTED
 | 
			
		||||
ERROR:  Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository
 | 
			
		||||
ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		||||
    EXPECTED
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,6 +179,7 @@ Added '/CN=alternate/DC=example'
 | 
			
		|||
    assert_empty @ui.error
 | 
			
		||||
 | 
			
		||||
    assert_path_exists File.join(@tempdir, 'gem-public_cert.pem')
 | 
			
		||||
    refute_path_exists File.join(@tempdir, 'gem-private_key.pem')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_build_encrypted_key
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase
 | 
			
		|||
    @cmd = Gem::Commands::ContentsCommand.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def gem name
 | 
			
		||||
    spec = quick_gem name do |gem|
 | 
			
		||||
  def gem name, version = 2
 | 
			
		||||
    spec = quick_gem name, version do |gem|
 | 
			
		||||
      gem.files = %W[lib/#{name}.rb Rakefile]
 | 
			
		||||
    end
 | 
			
		||||
    write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
 | 
			
		||||
| 
						 | 
				
			
			@ -135,6 +135,40 @@ class TestGemCommandsContentsCommand < Gem::TestCase
 | 
			
		|||
    assert_equal "", @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_show_install_dir
 | 
			
		||||
    @cmd.options[:args] = %w[foo]
 | 
			
		||||
    @cmd.options[:show_install_dir] = true
 | 
			
		||||
 | 
			
		||||
    gem 'foo'
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      @cmd.execute
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = File.join @gemhome, 'gems', 'foo-2'
 | 
			
		||||
 | 
			
		||||
    assert_equal "#{expected}\n", @ui.output
 | 
			
		||||
    assert_equal "", @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_show_install_dir_version
 | 
			
		||||
    @cmd.options[:args] = %w[foo]
 | 
			
		||||
    @cmd.options[:show_install_dir] = true
 | 
			
		||||
    @cmd.options[:version] = Gem::Requirement.new '= 1'
 | 
			
		||||
 | 
			
		||||
    gem 'foo', 1
 | 
			
		||||
    gem 'foo', 2
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      @cmd.execute
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = File.join @gemhome, 'gems', 'foo-1'
 | 
			
		||||
 | 
			
		||||
    assert_equal "#{expected}\n", @ui.output
 | 
			
		||||
    assert_equal "", @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_no_prefix
 | 
			
		||||
    @cmd.options[:args] = %w[foo]
 | 
			
		||||
    @cmd.options[:prefix] = false
 | 
			
		||||
| 
						 | 
				
			
			@ -183,13 +217,22 @@ lib/foo.rb
 | 
			
		|||
    assert @cmd.options[:prefix]
 | 
			
		||||
    assert_empty @cmd.options[:specdirs]
 | 
			
		||||
    assert_nil @cmd.options[:version]
 | 
			
		||||
    refute @cmd.options[:show_install_dir]
 | 
			
		||||
 | 
			
		||||
    @cmd.send :handle_options, %w[-l -s foo --version 0.0.2 --no-prefix]
 | 
			
		||||
    @cmd.send :handle_options, %w[
 | 
			
		||||
      -l
 | 
			
		||||
      -s
 | 
			
		||||
      foo
 | 
			
		||||
      --version 0.0.2
 | 
			
		||||
      --no-prefix
 | 
			
		||||
      --show-install-dir
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    assert @cmd.options[:lib_only]
 | 
			
		||||
    refute @cmd.options[:prefix]
 | 
			
		||||
    assert_equal %w[foo], @cmd.options[:specdirs]
 | 
			
		||||
    assert_equal Gem::Requirement.new('0.0.2'), @cmd.options[:version]
 | 
			
		||||
    assert @cmd.options[:show_install_dir]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase
 | 
			
		|||
    assert_match %r|RUBYGEMS PREFIX: |, @ui.output
 | 
			
		||||
    assert_match %r|RUBY EXECUTABLE:.*#{RbConfig::CONFIG['ruby_install_name']}|,
 | 
			
		||||
                 @ui.output
 | 
			
		||||
    assert_match %r|SYSTEM CONFIGURATION DIRECTORY:|, @ui.output
 | 
			
		||||
    assert_match %r|EXECUTABLE DIRECTORY:|, @ui.output
 | 
			
		||||
    assert_match %r|RUBYGEMS PLATFORMS:|, @ui.output
 | 
			
		||||
    assert_match %r|- #{Gem::Platform.local}|, @ui.output
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,13 @@ class TestGemCommandsHelpCommand < Gem::TestCase
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_gem_help_gem_dependencies
 | 
			
		||||
    util_gem 'gem_dependencies' do |out, err|
 | 
			
		||||
      assert_match 'gem.deps.rb', out
 | 
			
		||||
      assert_equal '', err
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_gem_help_platforms
 | 
			
		||||
    util_gem 'platforms' do |out, err|
 | 
			
		||||
      assert_match(/x86-freebsd/, out)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
 | 
			
		|||
 | 
			
		||||
    Gem::Command.build_args = @orig_args
 | 
			
		||||
    File.unlink @gemdeps if File.file? @gemdeps
 | 
			
		||||
    File.unlink "#{@gemdeps}.lock" if File.file? "#{@gemdeps}.lock"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_exclude_prerelease
 | 
			
		||||
| 
						 | 
				
			
			@ -194,6 +195,32 @@ class TestGemCommandsInstallCommand < Gem::TestCase
 | 
			
		|||
    assert_match(%r!Unable to download data from http://not-there.nothing!, errs.shift)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_nonexistent_hint_disabled
 | 
			
		||||
    misspelled = "nonexistent_with_hint"
 | 
			
		||||
    correctly_spelled = "non_existent_with_hint"
 | 
			
		||||
 | 
			
		||||
    spec_fetcher do |fetcher|
 | 
			
		||||
      fetcher.spec correctly_spelled, 2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @cmd.options[:args] = [misspelled]
 | 
			
		||||
    @cmd.options[:suggest_alternate] = false
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      e = assert_raises Gem::MockGemUi::TermError do
 | 
			
		||||
        @cmd.execute
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      assert_equal 2, e.exit_code
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = <<-EXPECTED
 | 
			
		||||
ERROR:  Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository
 | 
			
		||||
    EXPECTED
 | 
			
		||||
 | 
			
		||||
    assert_equal expected, @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_nonexistent_with_hint
 | 
			
		||||
    misspelled = "nonexistent_with_hint"
 | 
			
		||||
    correctly_spelled = "non_existent_with_hint"
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +265,10 @@ ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		|||
      assert_equal 2, e.exit_code
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    expected = ["ERROR:  Could not find a valid gem 'non-existent_with-hint' (>= 0) in any repository", "ERROR:  Possible alternatives: nonexistent-with_hint"]
 | 
			
		||||
    expected = [
 | 
			
		||||
      "ERROR:  Could not find a valid gem 'non-existent_with-hint' (>= 0) in any repository",
 | 
			
		||||
      "ERROR:  Possible alternatives: nonexistent-with_hint"
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    output = @ui.error.split "\n"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -535,6 +565,11 @@ ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def test_install_gem_ignore_dependencies_both
 | 
			
		||||
    done_installing = false
 | 
			
		||||
    Gem.done_installing do
 | 
			
		||||
      done_installing = true
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    spec = quick_spec 'a', 2
 | 
			
		||||
 | 
			
		||||
    util_build_gem spec
 | 
			
		||||
| 
						 | 
				
			
			@ -546,6 +581,8 @@ ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		|||
    @cmd.install_gem 'a', '>= 0'
 | 
			
		||||
 | 
			
		||||
    assert_equal %w[a-2], @cmd.installed_specs.map { |s| s.full_name }
 | 
			
		||||
 | 
			
		||||
    assert done_installing, 'documentation was not generated'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_install_gem_ignore_dependencies_remote
 | 
			
		||||
| 
						 | 
				
			
			@ -622,8 +659,8 @@ ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    assert_equal 2, e.exit_code
 | 
			
		||||
    assert_match %r!Could not find a valid gem 'blah' \(>= 0\)!, @ui.error
 | 
			
		||||
    assert_match %r!Unable to download data from http://not-there\.nothing!, @ui.error
 | 
			
		||||
 | 
			
		||||
    assert_match 'Unable to download data', @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_show_source_problems_even_on_success
 | 
			
		||||
| 
						 | 
				
			
			@ -648,7 +685,7 @@ ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		|||
 | 
			
		||||
    e = @ui.error
 | 
			
		||||
 | 
			
		||||
    x = "WARNING:  Unable to pull data from 'http://nonexistent.example': no data for http://nonexistent.example/latest_specs.4.8.gz (http://nonexistent.example/latest_specs.4.8.gz)\n"
 | 
			
		||||
    x = "WARNING:  Unable to pull data from 'http://nonexistent.example': no data for http://nonexistent.example/specs.4.8.gz (http://nonexistent.example/specs.4.8.gz)\n"
 | 
			
		||||
    assert_equal x, e
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -672,6 +709,56 @@ ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		|||
    assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name }
 | 
			
		||||
 | 
			
		||||
    assert_match "Using a (2)", @ui.output
 | 
			
		||||
    assert File.exist?("#{@gemdeps}.lock")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_uses_from_a_gemdeps_with_no_lock
 | 
			
		||||
    spec_fetcher do |fetcher|
 | 
			
		||||
      fetcher.gem 'a', 2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    File.open @gemdeps, "w" do |f|
 | 
			
		||||
      f << "gem 'a'"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @cmd.handle_options %w[--no-lock]
 | 
			
		||||
    @cmd.options[:gemdeps] = @gemdeps
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
 | 
			
		||||
        @cmd.execute
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name }
 | 
			
		||||
 | 
			
		||||
    assert_match "Using a (2)", @ui.output
 | 
			
		||||
    assert !File.exist?("#{@gemdeps}.lock")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_installs_from_a_gemdeps_with_conservative
 | 
			
		||||
    spec_fetcher do |fetcher|
 | 
			
		||||
      fetcher.gem 'a', 2
 | 
			
		||||
      fetcher.clear
 | 
			
		||||
      fetcher.gem 'a', 1
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    File.open @gemdeps, "w" do |f|
 | 
			
		||||
      f << "gem 'a'"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @cmd.handle_options %w[--conservative]
 | 
			
		||||
    @cmd.options[:gemdeps] = @gemdeps
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
 | 
			
		||||
        @cmd.execute
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name }
 | 
			
		||||
 | 
			
		||||
    assert_match "Using a (1)", @ui.output
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_installs_from_a_gemdeps
 | 
			
		||||
| 
						 | 
				
			
			@ -885,6 +972,18 @@ ERROR:  Possible alternatives: non_existent_with_hint
 | 
			
		|||
    assert_equal 'gem.deps.rb', @cmd.options[:gemdeps]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_handle_options_suggest
 | 
			
		||||
    assert @cmd.options[:suggest_alternate]
 | 
			
		||||
 | 
			
		||||
    @cmd.handle_options %w[--no-suggestions]
 | 
			
		||||
 | 
			
		||||
    refute @cmd.options[:suggest_alternate]
 | 
			
		||||
 | 
			
		||||
    @cmd.handle_options %w[--suggestions]
 | 
			
		||||
 | 
			
		||||
    assert @cmd.options[:suggest_alternate]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_handle_options_without
 | 
			
		||||
    @cmd.handle_options %w[--without test]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										46
									
								
								test/rubygems/test_gem_commands_open_command.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								test/rubygems/test_gem_commands_open_command.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
require 'rubygems/test_case'
 | 
			
		||||
require 'rubygems/commands/open_command'
 | 
			
		||||
 | 
			
		||||
class TestGemCommandsOpenCommand < Gem::TestCase
 | 
			
		||||
 | 
			
		||||
  def setup
 | 
			
		||||
    super
 | 
			
		||||
 | 
			
		||||
    @cmd = Gem::Commands::OpenCommand.new
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def gem name
 | 
			
		||||
    spec = quick_gem name do |gem|
 | 
			
		||||
      gem.files = %W[lib/#{name}.rb Rakefile]
 | 
			
		||||
    end
 | 
			
		||||
    write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
 | 
			
		||||
    write_file File.join(*%W[gems #{spec.full_name} Rakefile])
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute
 | 
			
		||||
    @cmd.options[:args] = %w[foo]
 | 
			
		||||
    @cmd.options[:editor] = "#{Gem.ruby} -e0 --"
 | 
			
		||||
 | 
			
		||||
    gem 'foo'
 | 
			
		||||
 | 
			
		||||
    use_ui @ui do
 | 
			
		||||
      @cmd.execute
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_equal "", @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_execute_bad_gem
 | 
			
		||||
    @cmd.options[:args] = %w[foo]
 | 
			
		||||
 | 
			
		||||
    assert_raises Gem::MockGemUi::TermError do
 | 
			
		||||
      use_ui @ui do
 | 
			
		||||
        @cmd.execute
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_match %r|Unable to find gem 'foo'|, @ui.output
 | 
			
		||||
    assert_equal "", @ui.error
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue