class Terraspace::Dependency::Graph
Constants
- MAX_CYCLE_DEPTH
Attributes
nodes[R]
Public Class Methods
new(stack_names, dependencies, options={})
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 6 def initialize(stack_names, dependencies, options={}) @stack_names, @dependencies, @options = stack_names, dependencies, options @nodes = [] @batches = [] end
Public Instance Methods
apply_filter(parent, keep=false)
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 116 def apply_filter(parent, keep=false) keep ||= @options[:stacks].blank? keep ||= @options[:stacks].include?(parent.name) # apply filter if keep parent.filtered = true @filtered << parent end parent.children.sort_by(&:name).each do |child| apply_filter(child, keep) end end
build()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 12 def build precreate_all_nodes build_nodes_with_dependencies # @nodes has dependency graph info afterwards check_circular_dependencies! @nodes = filter_nodes check_empty_nodes! build_batches clean_batches @batches end
build_batch(leaf, depth=1)
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 92 def build_batch(leaf, depth=1) @batches[depth] ||= Set.new @batches[depth] << leaf leaf.parents.each do |parent| build_batch(parent, depth+1) end end
build_batches()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 69 def build_batches @batches[0] = Set.new(leaves) leaves.each do |leaf| leaf.parents.each do |parent| build_batch(parent) end end end
build_nodes_with_dependencies()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 54 def build_nodes_with_dependencies @dependencies.each do |item| parent_name, child_name = item.split(':') save_node_parent(parent_name, child_name) end end
check_circular_dependencies!()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 30 def check_circular_dependencies! @nodes.each do |node| check_cycle(node) end end
check_cycle(node, depth=0, list=[])
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 37 def check_cycle(node, depth=0, list=[]) if depth > MAX_CYCLE_DEPTH logger.error "ERROR: It seems like there is a circular dependency! Stacks involved: #{list.uniq}".color(:red) exit 1 end node.parents.each do |parent| check_cycle(parent, depth+1, list += [parent]) end end
check_empty_nodes!()
click to toggle source
Only check when stacks option is pass. Edge case: There can be app/modules but no app/stacks yet
# File lib/terraspace/dependency/graph.rb, line 24 def check_empty_nodes! return unless @nodes.empty? && @options[:stacks] logger.error "ERROR: No stacks were found that match: #{@options[:stacks].join(' ')}".color(:red) exit 1 end
clean_batches()
click to toggle source
So stack nodes dont get deployed more than once and too early
# File lib/terraspace/dependency/graph.rb, line 79 def clean_batches all = Set.new # batch is a set @batches.reverse.each do |batch| batch.each do |node| batch.delete(node) if all.include?(node) end all += batch end @batches.reject! { |batch| batch.empty? } @batches end
filter_nodes()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 100 def filter_nodes @filtered = [] top_nodes.each { |node| apply_filter(node) } # draw_full_graph option is only used internally by All::Grapher update_parents! unless @options[:draw_full_graph] @options[:draw_full_graph] ? @nodes : @filtered end
leaves()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 128 def leaves @nodes.select { |n| n.children.empty? }.sort_by(&:name) end
precreate_all_nodes()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 47 def precreate_all_nodes @stack_names.each do |name| node = Node.find_or_create_by(name: name) save_node(node) end end
save_node(node)
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 136 def save_node(node) @nodes << node unless @nodes.detect { |n| n.name == node.name } end
save_node_parent(parent_name, child_name)
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 61 def save_node_parent(parent_name, child_name) parent = Node.find_by(name: parent_name) child = Node.find_by(name: child_name) child.parent!(parent) save_node(parent) save_node(child) end
top_nodes()
click to toggle source
# File lib/terraspace/dependency/graph.rb, line 132 def top_nodes @nodes.select { |n| n.parents.empty? }.sort_by(&:name) end
update_parents!()
click to toggle source
remove missing parents references since they will be filtered out
# File lib/terraspace/dependency/graph.rb, line 109 def update_parents! @filtered.each do |node| new_parents = node.parents & @filtered node.parents = new_parents end end