Refactor Requirement.expand

This commit is contained in:
Jack Nagel 2013-06-03 15:08:46 -05:00
parent ceb01c3124
commit 3937d2bb84

View File

@ -120,60 +120,64 @@ class Requirement
end end
end end
# Expand the requirements of dependent recursively, optionally yielding class << self
# [dependent, req] pairs to allow callers to apply arbitrary filters to # Expand the requirements of dependent recursively, optionally yielding
# the list. # [dependent, req] pairs to allow callers to apply arbitrary filters to
# The default filter, which is applied when a block is not given, omits # the list.
# optionals and recommendeds based on what the dependent has asked for. # The default filter, which is applied when a block is not given, omits
def self.expand(dependent, &block) # optionals and recommendeds based on what the dependent has asked for.
reqs = ComparableSet.new def expand(dependent, &block)
reqs = ComparableSet.new
formulae = dependent.recursive_dependencies.map(&:to_formula) formulae = dependent.recursive_dependencies.map(&:to_formula)
formulae.unshift(dependent) formulae.unshift(dependent)
formulae.map(&:requirements).each do |requirements| formulae.map(&:requirements).each do |requirements|
requirements.each do |req| requirements.each do |req|
prune = catch(:prune) do if prune?(dependent, req, &block)
if block_given? next
yield dependent, req # TODO: Do this in a cleaner way, perhaps with another type of
elsif req.optional? || req.recommended? # dependency type.
Requirement.prune unless dependent.build.with?(req.name) elsif req.class.default_formula
dependent.class.depends_on(req.class.default_formula)
next
else
reqs << req
end end
end end
end
next if prune # We special case handling of X11Dependency and its subclasses to
# ensure the correct dependencies are present in the final list.
# If an X11Dependency is present after filtering, we eliminate
# all X11Dependency::Proxy objects from the list. If there aren't
# any X11Dependency objects, then we eliminate all but one of the
# proxy objects.
proxy = unless reqs.any? { |r| r.instance_of?(X11Dependency) }
reqs.find { |r| r.kind_of?(X11Dependency::Proxy) }
end
# TODO: Do this in a cleaner way, perhaps with another type of reqs.reject! do |r|
# dependency type. r.kind_of?(X11Dependency::Proxy)
if req.class.default_formula end
dependent.class.depends_on(req.class.default_formula)
next reqs << proxy unless proxy.nil?
reqs
end
def prune?(dependent, req, &block)
catch(:prune) do
if block_given?
yield dependent, req
elsif req.optional? || req.recommended?
prune unless dependent.build.with?(req.name)
end end
reqs << req
end end
end end
# We special case handling of X11Dependency and its subclasses to # Used to prune requirements when calling expand with a block.
# ensure the correct dependencies are present in the final list. def prune
# If an X11Dependency is present after filtering, we eliminate throw(:prune, true)
# all X11Dependency::Proxy objects from the list. If there aren't
# any X11Dependency objects, then we eliminate all but one of the
# proxy objects.
proxy = unless reqs.any? { |r| r.instance_of?(X11Dependency) }
reqs.find { |r| r.kind_of?(X11Dependency::Proxy) }
end end
reqs.reject! do |r|
r.kind_of?(X11Dependency::Proxy)
end
reqs << proxy unless proxy.nil?
reqs
end
# Used to prune requirements when calling expand with a block.
def self.prune
throw(:prune, true)
end end
end end