# class Gem::RequestSet

A `RequestSet` groups a request to activate a set of dependencies.

    nokogiri = Gem::Dependency.new 'nokogiri', '~> 1.6'
    pg = Gem::Dependency.new 'pg', '~> 0.14'

    set = Gem::RequestSet.new nokogiri, pg

    requests = set.resolve

    p requests.map { |r| r.full_name }
    #=> ["nokogiri-1.6.0", "mini_portile-0.5.1", "pg-0.17.0"]

### Attributes

always_install [RW]

`Array` of gems to install even if already installed

dependencies [R]
development [RW]
development_shallow [RW]

`Set` to true if you want to install only direct development dependencies.

errors [R]

Errors fetching gems during resolution.

ignore_dependencies [RW]

When true, dependency resolution is not performed, only the requested gems are installed.

prerelease [RW]

If true, allow dependencies to match prerelease gems.

remote [RW]

When false no remote sets are used for resolving gems.

soft_missing [RW]

Treat missing dependencies as silent errors

source_set [R]

The set of source gems imported via load_gemdeps.

### Public Class Methods

new (*deps) { |self| ... }
Source

    # File lib/rubygems/request_set.rb, line 94
    def initialize(*deps)
      @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                = []
      @soft_missing        = false
      @sorted_requests     = nil
      @specs               = nil
      @vendor_set          = nil
      @source_set          = nil

      yield self if block_given?
    end

Creates a `RequestSet` for a list of `Gem::Dependency` objects, `deps`. You can then `resolve` and `install` the resolved list of dependencies.

    nokogiri = Gem::Dependency.new 'nokogiri', '~> 1.6'
    pg = Gem::Dependency.new 'pg', '~> 0.14'

    set = Gem::RequestSet.new nokogiri, pg

### Public Instance Methods

gem (name, *reqs)
Source

    # File lib/rubygems/request_set.rb, line 122
    def gem(name, *reqs)
      if dep = @dependency_names[name]
        dep.requirement.concat reqs
      else
        dep = Gem::Dependency.new name, *reqs
        @dependency_names[name] = dep
        @dependencies << dep
      end
    end

Declare that a gem of name `name` with `reqs` requirements is needed.

import (deps)
Source

    # File lib/rubygems/request_set.rb, line 135
    def import(deps)
      @dependencies.concat deps
    end

Add `deps` `Gem::Dependency` objects to the set.

install (options) { |request, installer| ... }
Source

    # File lib/rubygems/request_set.rb, line 146
    def install(options, &block) # :yields: request, installer
      if dir = options[:install_dir]
        requests = install_into dir, false, options, &block
        return requests
      end

      @prerelease = options[:prerelease]

      requests = []
      download_queue = Thread::Queue.new

      # Create a thread-safe list of gems to download
      sorted_requests.each do |req|
        download_queue << req
      end

      # Create N threads in a pool, have them download all the gems
      threads = Array.new(Gem.configuration.concurrent_downloads) do
        # When a thread pops this item, it knows to stop running. The symbol
        # is queued here so that there will be one symbol per thread.
        download_queue << :stop

        Thread.new do
          # The pop method will block waiting for items, so the only way
          # to stop a thread from running is to provide a final item that
          # means the thread should stop.
          while req = download_queue.pop
            break if req == :stop
            req.spec.download options unless req.installed?
          end
        end
      end

      # Wait for all the downloads to finish before continuing
      threads.each(&:value)

      # Install requested gems after they have been downloaded
      sorted_requests.each do |req|
        if req.installed?
          req.spec.spec.build_extensions

          if @always_install.none? {|spec| spec == req.spec.spec }
            yield req, nil if block_given?
            next
          end
        end

        spec =
          begin
            req.spec.install options do |installer|
              yield req, installer if block_given?
            end
          rescue Gem::RuntimeRequirementNotMetError => e
            suggestion = "There are no versions of #{req.request} compatible with your Ruby & RubyGems"
            suggestion += ". Maybe try installing an older version of the gem you're looking for?" unless @always_install.include?(req.spec.spec)
            e.suggestion = suggestion
            raise
          end

        requests << spec
      end

      return requests if options[:gemdeps]

      install_hooks requests, options

      requests
    end

Installs gems for this `RequestSet` using the `Gem::Installer` `options`.

If a `block` is given an activation `request` and `installer` are yielded. The `installer` will be `nil` if a gem matching the request was already installed.

install_from_gemdeps (options, &block)
Source

    # File lib/rubygems/request_set.rb, line 222
    def install_from_gemdeps(options, &block)
      gemdeps = options[:gemdeps]

      @install_dir = options[:install_dir] || Gem.dir
      @prerelease  = options[:prerelease]
      @remote      = options[:domain] != :local
      @conservative = true if options[:conservative]

      gem_deps_api = load_gemdeps gemdeps, options[:without_groups], true

      resolve

      if options[:explain]
        puts "Gems to install:"

        sorted_requests.each do |spec|
          puts "  #{spec.full_name}"
        end

        if Gem.configuration.really_verbose
          @resolver.stats.display
        end
      else
        installed = install options, &block

        if options.fetch :lock, true
          lockfile =
            Gem::RequestSet::Lockfile.build self, gemdeps, gem_deps_api.dependencies
          lockfile.write
        end

        installed
      end
    end

Installs from the gem dependencies files in the `:gemdeps` option in `options`, yielding to the `block` as in `install`.

If `:without_groups` is given in the `options`, those groups in the gem dependencies file are not used. See `Gem::Installer` for other `options`.

install_hooks (requests, options)
Source

    # File lib/rubygems/request_set.rb, line 298
    def install_hooks(requests, options)
      specs = requests.map do |request|
        case request
        when Gem::Resolver::ActivationRequest then
          request.spec.spec
        else
          request
        end
      end

      require_relative "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

Call hooks on installed gems

install_into (dir, force = true, options = {}) { |request, nil| ... }
Source

    # File lib/rubygems/request_set.rb, line 257
    def install_into(dir, force = true, options = {})
      gem_home = ENV["GEM_HOME"]
      ENV["GEM_HOME"] = dir

      existing = force ? [] : specs_in(dir)
      existing.delete_if {|s| @always_install.include? s }

      dir = File.expand_path dir

      installed = []

      options[:development] = false
      options[:install_dir] = dir
      options[:only_install_dir] = true
      @prerelease = options[:prerelease]

      sorted_requests.each do |request|
        spec = request.spec

        if existing.find {|s| s.full_name == spec.full_name }
          yield request, nil if block_given?
          next
        end

        spec.install options do |installer|
          yield request, installer if block_given?
        end

        installed << request
      end

      install_hooks installed, options

      installed
    ensure
      ENV["GEM_HOME"] = gem_home
    end

load_gemdeps (path, without_groups = [], installing = false)
Source

    # File lib/rubygems/request_set.rb, line 320
    def load_gemdeps(path, without_groups = [], installing = false)
      @git_set    = Gem::Resolver::GitSet.new
      @vendor_set = Gem::Resolver::VendorSet.new
      @source_set = Gem::Resolver::SourceSet.new

      @git_set.root_dir = @install_dir

      lock_file = "#{File.expand_path(path)}.lock"
      begin
        tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file lock_file
        parser = tokenizer.make_parser self, []
        parser.parse
      rescue Errno::ENOENT
      end

      gf = Gem::RequestSet::GemDependencyAPI.new self, path
      gf.installing = installing
      gf.without_groups = without_groups if without_groups
      gf.load
    end

Load a dependency management file.

resolve (set = Gem::Resolver::BestSet.new)
Source

    # File lib/rubygems/request_set.rb, line 387
    def resolve(set = Gem::Resolver::BestSet.new)
      @sets << set
      @sets << @git_set
      @sets << @vendor_set
      @sets << @source_set

      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

Resolve the requested dependencies and return an `Array` of Specification objects to be activated.

resolve_current ()
Source

    # File lib/rubygems/request_set.rb, line 424
    def resolve_current
      resolve Gem::Resolver::CurrentSet.new
    end

Resolve the requested dependencies against the gems available via `Gem.path` and return an `Array` of Specification objects to be activated.

sorted_requests ()
Source

    # File lib/rubygems/request_set.rb, line 428
    def sorted_requests
      @sorted_requests ||= strongly_connected_components.flatten
    end

specs ()
Source

    # File lib/rubygems/request_set.rb, line 432
    def specs
      @specs ||= @requests.map(&:full_spec)
    end

specs_in (dir)
Source

    # File lib/rubygems/request_set.rb, line 436
    def specs_in(dir)
      Gem::Util.glob_files_in_dir("*.gemspec", File.join(dir, "specifications")).map do |g|
        Gem::Specification.load g
      end
    end