class Librarian::Resolver

Attributes

cyclic[RW]
environment[RW]

Public Class Methods

new(environment, options = { }) click to toggle source

Options:

cyclic: truthy if the resolver should permit cyclic resolutions
# File lib/librarian/resolver.rb, line 14
def initialize(environment, options = { })
  unrecognized_options = options.keys - [:cyclic]
  unrecognized_options.empty? or raise Error,
    "unrecognized options: #{unrecognized_options.join(", ")}"
  self.environment = environment
  self.cyclic = !!options[:cyclic]
end

Public Instance Methods

resolve(spec, partial_manifests = []) click to toggle source
# File lib/librarian/resolver.rb, line 22
def resolve(spec, partial_manifests = [])
  manifests = implementation(spec).resolve(partial_manifests)
  manifests or return
  enforce_consistency!(spec.dependencies, manifests)
  enforce_acyclicity!(manifests) unless cyclic
  manifests = sort(manifests)
  Resolution.new(spec.dependencies, manifests)
end

Private Instance Methods

debug(*args, &block) click to toggle source
# File lib/librarian/resolver.rb, line 89
def debug(*args, &block)
  environment.logger.debug(*args, &block)
end
enforce_acyclicity!(manifests) click to toggle source
# File lib/librarian/resolver.rb, line 79
def enforce_acyclicity!(manifests)
  ManifestSet.cyclic?(manifests) or return
  debug { "Resolver Malfunctioned!" }
  raise Error, "Resolver Malfunctioned!"
end
enforce_consistency!(dependencies, manifests) click to toggle source
# File lib/librarian/resolver.rb, line 37
def enforce_consistency!(dependencies, manifests)
  manifest_set = ManifestSet.new(manifests)
  return if manifest_set.in_compliance_with?(dependencies)
  return if manifest_set.consistent?

  debug { "Resolver Malfunctioned!" }
  errors = []
  dependencies.sort_by(&:name).each do |d|
    m = manifests[d.name]
    if !m
      errors << ["Depends on #{d}", "Missing!"]
    elsif !d.satisfied_by?(m)
      errors << ["Depends on #{d}", "Found: #{m}"]
    end
  end
  unless errors.empty?
    errors.each do |a, b|
      debug { "  #{a}" }
      debug { "    #{b}" }
    end
  end
  manifests.values.sort_by(&:name).each do |manifest|
    errors = []
    manifest.dependencies.sort_by(&:name).each do |d|
      m = manifests[d.name]
      if !m
        errors << ["Depends on: #{d}", "Missing!"]
      elsif !d.satisfied_by?(m)
        errors << ["Depends on: #{d}", "Found: #{m}"]
      end
    end
    unless errors.empty?
      debug { "  #{manifest}" }
      errors.each do |a, b|
        debug { "    #{a}" }
        debug { "      #{b}" }
      end
    end
  end
  raise Error, "Resolver Malfunctioned!"
end
implementation(spec) click to toggle source
# File lib/librarian/resolver.rb, line 33
def implementation(spec)
  Implementation.new(self, spec, :cyclic => cyclic)
end
sort(manifests) click to toggle source
# File lib/librarian/resolver.rb, line 85
def sort(manifests)
  ManifestSet.sort(manifests)
end