183: def topsort
184: degree = {}
185: zeros = []
186: result = []
187:
188:
189: @vertices.each do |name, wrapper|
190: edges = wrapper.in_edges
191: zeros << wrapper if edges.length == 0
192: degree[wrapper.vertex] = edges
193: end
194:
195:
196:
197: while wrapper = zeros.pop
198: result << wrapper.vertex
199: wrapper.out_edges.each do |edge|
200: degree[edge.target].delete(edge)
201: zeros << @vertices[edge.target] if degree[edge.target].length == 0
202: end
203: end
204:
205:
206: if cycles = degree.find_all { |vertex, edges| edges.length > 0 } and cycles.length > 0
207: message = cycles.collect { |vertex, edges| edges.collect { |e| e.to_s }.join(", ") }.join(", ")
208: raise Puppet::Error, "Found dependency cycles in the following relationships: #{message}; try using the '--graph' option and open the '.dot' files in OmniGraffle or GraphViz"
209: end
210:
211: result
212: end