Class: Terraspace::Dependency::Graph
- Inherits:
-
Object
- Object
- Terraspace::Dependency::Graph
- Includes:
- Util::Logging
- Defined in:
- lib/terraspace/dependency/graph.rb
Constant Summary collapse
- MAX_CYCLE_DEPTH =
Integer(ENV['TS_MAX_CYCLE_DEPTH'] || 100)
Instance Attribute Summary collapse
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
Instance Method Summary collapse
- #apply_filter(parent, keep = false) ⇒ Object
- #build ⇒ Object
- #build_batch(leaf, depth = 1) ⇒ Object
- #build_batches ⇒ Object
- #build_nodes_with_dependencies ⇒ Object
- #check_circular_dependencies! ⇒ Object
- #check_cycle(node, depth = 0, list = []) ⇒ Object
-
#check_empty_nodes! ⇒ Object
Only check when stacks option is pass.
-
#clean_batches ⇒ Object
So stack nodes dont get deployed more than once and too early.
- #filter_nodes ⇒ Object
-
#initialize(stack_names, dependencies, options = {}) ⇒ Graph
constructor
A new instance of Graph.
- #leaves ⇒ Object
- #precreate_all_nodes ⇒ Object
- #save_node(node) ⇒ Object
- #save_node_parent(parent_name, child_name) ⇒ Object
- #top_nodes ⇒ Object
-
#update_parents! ⇒ Object
remove missing parents references since they will be filtered out.
Methods included from Util::Logging
Constructor Details
#initialize(stack_names, dependencies, options = {}) ⇒ Graph
Returns a new instance of Graph.
6 7 8 9 10 |
# File 'lib/terraspace/dependency/graph.rb', line 6 def initialize(stack_names, dependencies, ={}) @stack_names, @dependencies, @options = stack_names, dependencies, @nodes = [] @batches = [] end |
Instance Attribute Details
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
5 6 7 |
# File 'lib/terraspace/dependency/graph.rb', line 5 def nodes @nodes end |
Instance Method Details
#apply_filter(parent, keep = false) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 |
# 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 ⇒ Object
12 13 14 15 16 17 18 19 20 21 |
# 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) ⇒ Object
92 93 94 95 96 97 98 |
# 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 ⇒ Object
69 70 71 72 73 74 75 76 |
# 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 ⇒ Object
54 55 56 57 58 59 |
# 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! ⇒ Object
30 31 32 33 34 |
# 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 = []) ⇒ Object
37 38 39 40 41 42 43 44 45 |
# 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! ⇒ Object
Only check when stacks option is pass. Edge case: There can be app/modules but no app/stacks yet
24 25 26 27 28 |
# 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 ⇒ Object
So stack nodes dont get deployed more than once and too early
79 80 81 82 83 84 85 86 87 88 89 90 |
# 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 ⇒ Object
100 101 102 103 104 105 106 |
# 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 ⇒ Object
128 129 130 |
# File 'lib/terraspace/dependency/graph.rb', line 128 def leaves @nodes.select { |n| n.children.empty? }.sort_by(&:name) end |
#precreate_all_nodes ⇒ Object
47 48 49 50 51 52 |
# 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) ⇒ Object
136 137 138 |
# 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) ⇒ Object
61 62 63 64 65 66 67 |
# 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 ⇒ Object
132 133 134 |
# File 'lib/terraspace/dependency/graph.rb', line 132 def top_nodes @nodes.select { |n| n.parents.empty? }.sort_by(&:name) end |
#update_parents! ⇒ Object
remove missing parents references since they will be filtered out
109 110 111 112 113 114 |
# 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 |