summaryrefslogtreecommitdiff
path: root/lib/rubygems/request_set.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/request_set.rb')
-rw-r--r--lib/rubygems/request_set.rb251
1 files changed, 126 insertions, 125 deletions
diff --git a/lib/rubygems/request_set.rb b/lib/rubygems/request_set.rb
index 6c52b90c40..a45c64e0b4 100644
--- a/lib/rubygems/request_set.rb
+++ b/lib/rubygems/request_set.rb
@@ -5,178 +5,179 @@ require 'rubygems/dependency_list'
require 'rubygems/installer'
require 'tsort'
-module Gem
- class RequestSet
+class Gem::RequestSet
- include TSort
+ include TSort
- def initialize(*deps)
- @dependencies = deps
+ ##
+ # Array of gems to install even if already installed
- yield self if block_given?
- end
+ attr_reader :always_install
- attr_reader :dependencies
+ attr_reader :dependencies
- # Declare that a gem of name +name+ with +reqs+ requirements
- # is needed.
- #
- def gem(name, *reqs)
- @dependencies << Gem::Dependency.new(name, reqs)
- end
+ attr_accessor :development
- # Add +deps+ Gem::Depedency objects to the set.
- #
- def import(deps)
- @dependencies += deps
- end
+ ##
+ # Treat missing dependencies as silent errors
- # Resolve the requested dependencies and return an Array of
- # Specification objects to be activated.
- #
- def resolve(set=nil)
- r = Gem::DependencyResolver.new(@dependencies, set)
- @requests = r.resolve
- end
+ attr_accessor :soft_missing
- # Resolve the requested dependencies against the gems
- # available via Gem.path and return an Array of Specification
- # objects to be activated.
- #
- def resolve_current
- resolve DependencyResolver::CurrentSet.new
- end
+ def initialize *deps
+ @dependencies = deps
- # Load a dependency management file.
- #
- def load_gemdeps(path)
- gf = GemDepedencyAPI.new(self, path)
- gf.load
- end
+ @always_install = []
+ @development = false
+ @requests = []
+ @soft_missing = false
+ @sorted = nil
+ @specs = nil
- def specs
- @specs ||= @requests.map { |r| r.full_spec }
- end
+ yield self if block_given?
+ end
- def tsort_each_node(&block)
- @requests.each(&block)
- end
+ ##
+ # Declare that a gem of name +name+ with +reqs+ requirements is needed.
- def tsort_each_child(node)
- node.spec.dependencies.each do |dep|
- next if dep.type == :development
-
- match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
- if match
- begin
- yield match
- rescue TSort::Cyclic
- end
- else
- raise Gem::DependencyError, "Unresolved depedency found during sorting - #{dep}"
- end
- end
- end
+ def gem name, *reqs
+ @dependencies << Gem::Dependency.new(name, reqs)
+ end
+
+ ##
+ # Add +deps+ Gem::Dependency objects to the set.
+
+ def import deps
+ @dependencies += deps
+ end
- def sorted_requests
- @sorted ||= strongly_connected_components.flatten
+ def install options, &block
+ if dir = options[:install_dir]
+ return install_into dir, false, options, &block
end
- def specs_in(dir)
- Dir["#{dir}/specifications/*.gemspec"].map do |g|
- Gem::Specification.load g
+ cache_dir = options[:cache_dir] || Gem.dir
+
+ specs = []
+
+ sorted_requests.each do |req|
+ if req.installed? and
+ @always_install.none? { |spec| spec == req.spec.spec } then
+ yield req, nil if block_given?
+ next
end
- end
- def install_into(dir, force=true, &b)
- existing = force ? [] : specs_in(dir)
+ path = req.download cache_dir
- dir = File.expand_path dir
+ inst = Gem::Installer.new path, options
- installed = []
+ yield req, inst if block_given?
- sorted_requests.each do |req|
- if existing.find { |s| s.full_name == req.spec.full_name }
- b.call req, nil if b
- next
- end
+ specs << inst.install
+ end
- path = req.download(dir)
+ specs
+ end
- inst = Gem::Installer.new path, :install_dir => dir,
- :only_install_dir => true
+ def install_into dir, force = true, options = {}
+ existing = force ? [] : specs_in(dir)
+ existing.delete_if { |s| @always_install.include? s }
- b.call req, inst if b
+ dir = File.expand_path dir
- inst.install
+ installed = []
- installed << req
+ sorted_requests.each do |req|
+ if existing.find { |s| s.full_name == req.spec.full_name }
+ yield req, nil if block_given?
+ next
end
- installed
- end
+ path = req.download(dir)
- def install(options, &b)
- if dir = options[:install_dir]
- return install_into(dir, false, &b)
+ unless path then # already installed
+ yield req, nil if block_given?
+ next
end
- cache_dir = options[:cache_dir] || Gem.dir
+ options[:install_dir] = dir
+ options[:only_install_dir] = true
- specs = []
+ inst = Gem::Installer.new path, options
- sorted_requests.each do |req|
- if req.installed?
- b.call req, nil if b
- next
- end
+ yield req, inst if block_given?
- path = req.download cache_dir
+ inst.install
- inst = Gem::Installer.new path, options
+ installed << req
+ end
- b.call req, inst if b
+ installed
+ end
- specs << inst.install
- end
+ ##
+ # Load a dependency management file.
- specs
- end
+ def load_gemdeps path
+ gf = Gem::RequestSet::GemDepedencyAPI.new self, path
+ gf.load
+ end
- # A semi-compatible DSL for Bundler's Gemfile format
- #
- class GemDepedencyAPI
- def initialize(set, path)
- @set = set
- @path = path
- end
+ ##
+ # Resolve the requested dependencies and return an Array of Specification
+ # objects to be activated.
- def load
- instance_eval File.read(@path).untaint, @path, 1
- end
+ def resolve set = nil
+ resolver = Gem::DependencyResolver.new @dependencies, set
+ resolver.development = @development
+ resolver.soft_missing = @soft_missing
- # DSL
+ @requests = resolver.resolve
+ end
- def source(url)
- end
+ ##
+ # Resolve the requested dependencies against the gems available via Gem.path
+ # and return an Array of Specification objects to be activated.
- def gem(name, *reqs)
- # Ignore the opts for now.
- reqs.pop if reqs.last.kind_of?(Hash)
+ def resolve_current
+ resolve Gem::DependencyResolver::CurrentSet.new
+ end
- @set.gem name, *reqs
- end
+ def sorted_requests
+ @sorted ||= strongly_connected_components.flatten
+ end
- def platform(what)
- if what == :ruby
- yield
- end
- end
+ def specs
+ @specs ||= @requests.map { |r| r.full_spec }
+ end
+
+ def specs_in dir
+ Dir["#{dir}/specifications/*.gemspec"].map do |g|
+ Gem::Specification.load g
+ end
+ end
+
+ def tsort_each_node &block # :nodoc:
+ @requests.each(&block)
+ end
- alias_method :platforms, :platform
+ def tsort_each_child node # :nodoc:
+ node.spec.dependencies.each do |dep|
+ next if dep.type == :development and not @development
- def group(*what)
+ match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
+ if match
+ begin
+ yield match
+ rescue TSort::Cyclic
+ end
+ else
+ unless @soft_missing
+ raise Gem::DependencyError, "Unresolved depedency found during sorting - #{dep}"
+ end
end
end
end
+
end
+
+require 'rubygems/request_set/gem_dependency_api'