Project

General

Profile

Download (1.74 KB) Statistics
| Branch: | Tag: | Revision:
require 'tsort'

module ForemanMaintain
class DependencyGraph
include TSort

attr_reader :graph, :collection, :labels

def self.sort(collection)
new(collection).tsort.map(&:ensure_instance)
end

def initialize(collection)
@graph = Hash.new([])
@collection = collection
@labels = extract_labels
generate_label_graph
convert_label_graph_to_object_graph
end

def add_to_graph(key, dependencies = [])
return unless key

dependencies = dependencies.map do |dep|
next unless labels.include?(dep)
dep
end.compact

graph[key] = dependencies
end

def tsort_each_node(&block)
graph.each_key(&block)
end

def tsort_each_child(node, &block)
graph.fetch(node).each(&block)
end

private

def cache
ForemanMaintain.cache
end

def convert_label_graph_to_object_graph
graph.keys.each do |key|
graph[cache.fetch(key)] = graph[key].map { |dep| cache.fetch(dep) }
graph.delete(key)
end

graph
end

def extract_labels
collection.map(&:label)
end

def find_class(dep)
case dep
when Class
dep
when String
if dep.include?('::')
dep.split('::').reduce(Object) { |o, e| o.const_get(e) }
else
cache.fetch(dep)
end
else
cache.fetch(dep)
end
end

def generate_label_graph
collection.each do |object|
klass = object.class
key = object.label

add_to_graph(klass.before.first, [key])
add_to_graph(key, klass.after)
map_label_to_object(object)
end
end

def map_label_to_object(object)
cache.fetch(object.label, object)
end
end
end
(5-5/19)