Project

General

Profile

Download (1.12 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
@steps_by_labels = @collection.group_by(&:label)
generate_label_graph
end

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

graph[key] = dependencies
end

def tsort_each_node(&block)
@collection.each(&block)
end

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

private

def generate_label_graph
collection.each do |object|
klass = object.is_a?(Class) ? object : object.class
klass.before.each do |label|
add_to_graph(labels_to_objects(label).first, [object])
end
add_to_graph(object, labels_to_objects(klass.after))
end
end

def labels_to_objects(labels)
labels = Array(labels)
labels.map { |label| @steps_by_labels[label] }.compact.flatten
end
end
end
(6-6/20)