Class: Gem::RequestSet
| Relationships & Source Files | |
| Namespace Children | |
| Classes: | |
| Super Chains via Extension / Inclusion / Inheritance | |
| Instance Chain: 
          self,
          TSort
         | |
| Inherits: | Object | 
| Defined in: | lib/rubygems/request_set.rb | 
Overview
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"]Class Method Summary
- 
    
      .new(*deps) {|_self| ... } ⇒ RequestSet 
    
    constructor
    Creates a RequestSetfor a list ofDependencyobjects,deps.
Instance Attribute Summary
- 
    
      #always_install  
    
    rw
    Array of gems to install even if already installed. 
- #dependencies readonly
- #development rw
- 
    
      #development_shallow  
    
    rw
    Set to true if you want to install only direct development dependencies. 
- 
    
      #errors  
    
    readonly
    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  
    
    readonly
    The set of source gems imported via load_gemdeps. 
- 
    
      #git_set  
    
    readonly
    Internal use only
    The set of git gems imported via load_gemdeps. 
- #install_dir readonly Internal use only
- #resolver readonly Internal use only
- 
    
      #sets  
    
    readonly
    Internal use only
    Sets used for resolution. 
- 
    
      #vendor_set  
    
    readonly
    Internal use only
    The set of vendor gems imported via load_gemdeps. 
Instance Method Summary
- 
    
      #gem(name, *reqs)  
    
    Declare that a gem of name namewithreqsrequirements is needed.
- 
    
      #import(deps)  
    
    Add depsDependencyobjects to the set.
- 
    
      #install(options, &block)  
    
    Installs gems for this RequestSetusing theInstalleroptions.
- 
    
      #install_from_gemdeps(options, &block)  
    
    Installs from the gem dependencies files in the :gemdepsoption inoptions, yielding to theblockas in #install.
- 
    
      #install_hooks(requests, options)  
    
    Call hooks on installed gems. 
- #install_into(dir, force = true, options = {})
- 
    
      #load_gemdeps(path, without_groups = [], installing = false)  
    
    Load a dependency management file. 
- 
    
      #resolve(set = Gem::Resolver::BestSet.new)  
    
    Resolve the requested dependencies and return an Array of Specificationobjects to be activated.
- 
    
      #resolve_current  
    
    Resolve the requested dependencies against the gems available via path and return an Array of Specificationobjects to be activated.
- #sorted_requests
- #specs
- #specs_in(dir)
- #pretty_print(q) Internal use only
- #tsort_each_child(node) Internal use only
- #tsort_each_node(&block) Internal use only
Constructor Details
    .new(*deps) {|_self| ... } ⇒ RequestSet 
  
Creates a RequestSet for a list of 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# 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 = nil @specs = nil @vendor_set = nil @source_set = nil yield self if block_given? end
Instance Attribute Details
#always_install (rw)
Array of gems to install even if already installed
# File 'lib/rubygems/request_set.rb', line 24
attr_accessor :always_install
#dependencies (readonly)
[ GitHub ]# File 'lib/rubygems/request_set.rb', line 26
attr_reader :dependencies
#development (rw)
[ GitHub ]# File 'lib/rubygems/request_set.rb', line 28
attr_accessor :development
#development_shallow (rw)
Set to true if you want to install only direct development dependencies.
# File 'lib/rubygems/request_set.rb', line 38
attr_accessor :development_shallow
#errors (readonly)
Errors fetching gems during resolution.
# File 'lib/rubygems/request_set.rb', line 33
attr_reader :errors
#git_set (readonly)
The set of git gems imported via load_gemdeps.
# File 'lib/rubygems/request_set.rb', line 43
attr_reader :git_set # :nodoc:
#ignore_dependencies (rw)
When true, dependency resolution is not performed, only the requested gems are installed.
# File 'lib/rubygems/request_set.rb', line 49
attr_accessor :ignore_dependencies
#install_dir (readonly)
# File 'lib/rubygems/request_set.rb', line 51
attr_reader :install_dir # :nodoc:
#prerelease (rw)
If true, allow dependencies to match prerelease gems.
# File 'lib/rubygems/request_set.rb', line 56
attr_accessor :prerelease
#remote (rw)
When false no remote sets are used for resolving gems.
# File 'lib/rubygems/request_set.rb', line 61
attr_accessor :remote
#resolver (readonly)
# File 'lib/rubygems/request_set.rb', line 63
attr_reader :resolver # :nodoc:
#sets (readonly)
Sets used for resolution
# File 'lib/rubygems/request_set.rb', line 68
attr_reader :sets # :nodoc:
#soft_missing (rw)
Treat missing dependencies as silent errors
# File 'lib/rubygems/request_set.rb', line 73
attr_accessor :soft_missing
#source_set (readonly)
The set of source gems imported via load_gemdeps.
# File 'lib/rubygems/request_set.rb', line 83
attr_reader :source_set
#vendor_set (readonly)
The set of vendor gems imported via load_gemdeps.
# File 'lib/rubygems/request_set.rb', line 78
attr_reader :vendor_set # :nodoc:
Instance Method Details
#gem(name, *reqs)
Declare that a gem of name name with reqs requirements is needed.
# 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
#import(deps)
Add deps Dependency objects to the set.
# File 'lib/rubygems/request_set.rb', line 135
def import(deps) @dependencies.concat deps end
#install(options, &block)
Installs gems for this RequestSet using the 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.
# File 'lib/rubygems/request_set.rb', line 146
def install(, &block) # :yields: request, installer if dir = [:install_dir] requests = install_into dir, false, , &block return requests end @prerelease = [:prerelease] requests = [] download_queue = 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 = Gem.configuration.concurrent_downloads.times.map 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 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 do |installer| yield req, installer if block_given? end rescue Gem::RuntimeRequirementNotMetError => e recent_match = req.spec.set.find_all(req.request).sort_by(&:version).reverse_each.find do |s| s = s.spec s.required_ruby_version.satisfied_by?(Gem.ruby_version) && s.required_rubygems_version.satisfied_by?(Gem.rubygems_version) && Gem::Platform.installable?(s) end if recent_match suggestion = "The last version of #{req.request} to support your Ruby & RubyGems was #{recent_match.version}. Try installing it with `gem install #{recent_match.name} -v #{recent_match.version}`" suggestion += " and then running the current command again" unless @always_install.include?(req.spec.spec) else 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) end e.suggestion = suggestion raise end requests << spec end return requests if [:gemdeps] install_hooks requests, requests end
#install_from_gemdeps(options, &block)
# File 'lib/rubygems/request_set.rb', line 233
def install_from_gemdeps(, &block) gemdeps = [:gemdeps] @install_dir = [:install_dir] || Gem.dir @prerelease = [:prerelease] @remote = [:domain] != :local @conservative = true if [:conservative] gem_deps_api = load_gemdeps gemdeps, [:without_groups], true resolve if [: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 , &block if .fetch :lock, true lockfile = Gem::RequestSet::Lockfile.build self, gemdeps, gem_deps_api.dependencies lockfile.write end installed end end
#install_hooks(requests, options)
Call hooks on installed gems
# File 'lib/rubygems/request_set.rb', line 308
def install_hooks(requests, ) 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 inst.installed_gems.replace specs Gem.done_installing_hooks.each do |hook| hook.call inst, specs end unless Gem.done_installing_hooks.empty? end
#install_into(dir, force = true, options = {})
[ GitHub ]# File 'lib/rubygems/request_set.rb', line 268
def install_into(dir, force = true, = {}) gem_home, ENV['GEM_HOME'] = ENV['GEM_HOME'], dir existing = force ? [] : specs_in(dir) existing.delete_if { |s| @always_install.include? s } dir = File. dir installed = [] [:development] = false [:install_dir] = dir [:only_install_dir] = true @prerelease = [: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 do |installer| yield request, installer if block_given? end installed << request end install_hooks installed, installed ensure ENV['GEM_HOME'] = gem_home end
#load_gemdeps(path, without_groups = [], installing = false)
Load a dependency management file.
# File 'lib/rubygems/request_set.rb', line 330
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.(path)}.lock".dup.tap(&Gem::UNTAINT) 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
#pretty_print(q)
# File 'lib/rubygems/request_set.rb', line 351
def pretty_print(q) # :nodoc: q.group 2, '[RequestSet:', ']' do q.breakable if @remote q.text 'remote' q.breakable end if @prerelease q.text 'prerelease' q.breakable end if @development_shallow q.text 'shallow development' q.breakable elsif @development q.text 'development' q.breakable end if @soft_missing q.text 'soft missing' end q.group 2, '[dependencies:', ']' do q.breakable @dependencies.map do |dep| q.text dep.to_s q.breakable end end q.breakable q.text 'sets:' q.breakable q.pp @sets.map { |set| set.class } end end
#resolve(set = Gem::Resolver::BestSet.new)
Resolve the requested dependencies and return an Array of Specification objects to be activated.
# File 'lib/rubygems/request_set.rb', line 397
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_current
Resolve the requested dependencies against the gems available via Gem.path and return an Array of Specification objects to be activated.
# File 'lib/rubygems/request_set.rb', line 434
def resolve_current resolve Gem::Resolver::CurrentSet.new end
#sorted_requests
[ GitHub ]# File 'lib/rubygems/request_set.rb', line 438
def sorted_requests @sorted ||= strongly_connected_components.flatten end
#specs
[ GitHub ]# File 'lib/rubygems/request_set.rb', line 442
def specs @specs ||= @requests.map { |r| r.full_spec } end
#specs_in(dir)
[ GitHub ]# File 'lib/rubygems/request_set.rb', line 446
def specs_in(dir) Gem::Util.glob_files_in_dir("*.gemspec", File.join(dir, "specifications")).map do |g| Gem::Specification.load g end end
#tsort_each_child(node)
# File 'lib/rubygems/request_set.rb', line 456
def tsort_each_child(node) # :nodoc: node.spec.dependencies.each do |dep| next if dep.type == :development and not @development match = @requests.find do |r| dep.match? r.spec.name, r.spec.version, @prerelease end unless match 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 yield match end end
#tsort_each_node(&block)
# File 'lib/rubygems/request_set.rb', line 452
def tsort_each_node(&block) # :nodoc: @requests.each(&block) end