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"]
TODO: remove this typo name at RubyGems 3.0
Array of gems to install even if already installed
Errors fetching gems during resolution.
Set
to true if you want to install only direct development dependencies.
When true, dependency resolution is not performed, only the requested gems are installed.
If true, allow dependencies to match prerelease gems.
When false no remote sets are used for resolving gems.
Treat missing dependencies as silent errors
The set of source gems imported via load_gemdeps.
# File tmp/rubies/ruby-2.4.10/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
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
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 122
def gem name, *reqs
if dep = @dependency_names[name] then
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.
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 135
def import deps
@dependencies.concat deps
end
Add deps
Gem::Dependency
objects to the set.
# File tmp/rubies/ruby-2.4.10/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 = []
sorted_requests.each do |req|
if req.installed? then
req.spec.spec.build_extensions
if @always_install.none? { |spec| spec == req.spec.spec } then
yield req, nil if block_given?
next
end
end
spec = req.spec.install options do |installer|
yield req, installer if block_given?
end
requests << spec
end
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?
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.
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 202
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 then
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
.
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 237
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 } then
yield request, nil if block_given?
next
end
spec.install options do |installer|
yield request, installer if block_given?
end
installed << request
end
installed
ensure
ENV['GEM_HOME'] = gem_home
end
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 275
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".dup.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
Load a dependency management file.
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 342
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.
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 379
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.
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 383
def sorted_requests
@sorted ||= strongly_connected_components.flatten
end
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 387
def specs
@specs ||= @requests.map { |r| r.full_spec }
end
# File tmp/rubies/ruby-2.4.10/lib/rubygems/request_set.rb, line 391
def specs_in dir
Dir["#{dir}/specifications/*.gemspec"].map do |g|
Gem::Specification.load g
end
end