This is awesome, Daniel - thanks. On Feb 3, 2011, at 5:33 PM, Daniel Pittman wrote:
> From: Daniel Pittman <[email protected]> > > When the '--graph' option is specified, generate a new 'cycles.dot' file and > report the location of that to the user. This contains only the cycles, in > dot format, allowing a visual representation of the cycle to be obtained > quickly. > > This will include up to 10 paths through the cycle in the graph, and only one > in the display to the user, to reduce information overload. > --- > lib/puppet/simple_graph.rb | 35 ++++++++++++++++++++++++++++++++--- > spec/unit/simple_graph_spec.rb | 10 +++++----- > 2 files changed, 37 insertions(+), 8 deletions(-) > > diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb > index 1b5ffdc..e39aa87 100644 > --- a/lib/puppet/simple_graph.rb > +++ b/lib/puppet/simple_graph.rb > @@ -191,7 +191,7 @@ class Puppet::SimpleGraph > # BFS is preferred because it will generally report the shortest paths > # through the graph first, which are more likely to be interesting to the > # user. I think; it would be interesting to verify that. --daniel > 2011-01-23 > - def all_paths_in_cycle(cycle, max_paths = 10) > + def paths_in_cycle(cycle, max_paths = 1) > raise ArgumentError, "negative or zero max_paths" if max_paths < 1 > > # Calculate our filtered outbound vertex lists... > @@ -225,14 +225,43 @@ class Puppet::SimpleGraph > > message = "Found #{n} dependency cycle#{s}:\n" > cycles.each do |cycle| > - paths = all_paths_in_cycle(cycle) > + paths = paths_in_cycle(cycle) > message += paths.map{ |path| '(' + path.join(" => ") + ')'}.join("\n") > + "\n" > end > - message += "Try the '--graph' option and opening the '.dot' file in > OmniGraffle or GraphViz" > + > + if Puppet[:graph] then > + filename = write_cycles_to_graph(cycles) > + message += "Cycle graph written to #{filename}." > + else > + message += "Try the '--graph' option and opening the " > + message += "resulting '.dot' file in OmniGraffle or GraphViz" > + end > > raise Puppet::Error, message > end > > + def write_cycles_to_graph(cycles) > + # This does not use the DOT graph library, just writes the content > + # directly. Given the complexity of this, there didn't seem much point > + # using a heavy library to generate exactly the same content. --daniel > 2011-01-27 > + Puppet.settings.use(:graphing) > + > + graph = ["digraph Resource_Cycles {"] > + graph << ' label = "Resource Cycles"' > + > + cycles.each do |cycle| > + paths_in_cycle(cycle, 10).each do |path| > + graph << path.map { |v| '"' + v.to_s.gsub(/"/, '\\"') + '"' }.join(" > -> ") > + end > + end > + > + graph << '}' > + > + filename = File.join(Puppet[:graphdir], "cycles.dot") > + File.open(filename, "w") { |f| f.puts graph } > + return filename > + end > + > # Provide a topological sort. > def topsort > degree = {} > diff --git a/spec/unit/simple_graph_spec.rb b/spec/unit/simple_graph_spec.rb > index e7c875f..2c6af06 100755 > --- a/spec/unit/simple_graph_spec.rb > +++ b/spec/unit/simple_graph_spec.rb > @@ -362,7 +362,7 @@ describe Puppet::SimpleGraph do > add_edges "a" => "b", "b" => "c", "c" => "a" > > cycles = @graph.find_cycles_in_graph.sort > - paths = @graph.all_paths_in_cycle(cycles.first) > + paths = @graph.paths_in_cycle(cycles.first, 100) > paths.should be == [%w{a b c a}] > end > > @@ -374,7 +374,7 @@ describe Puppet::SimpleGraph do > cycles = @graph.find_cycles_in_graph.sort > cycles.length.should be == 1 > > - paths = @graph.all_paths_in_cycle(cycles.first) > + paths = @graph.paths_in_cycle(cycles.first, 100) > paths.sort.should be == [%w{a b1 a}, %w{a b2 a}] > end > > @@ -385,7 +385,7 @@ describe Puppet::SimpleGraph do > cycles = @graph.find_cycles_in_graph.sort > cycles.length.should be == 1 > > - paths = @graph.all_paths_in_cycle(cycles.first) > + paths = @graph.paths_in_cycle(cycles.first, 100) > paths.should be == [%w{a b a}, %w{a b c a}] > end > > @@ -396,11 +396,11 @@ describe Puppet::SimpleGraph do > cycles.length.should be == 1 > > (1..20).each do |n| > - paths = @graph.all_paths_in_cycle(cycles.first, n) > + paths = @graph.paths_in_cycle(cycles.first, n) > paths.length.should be == n > end > > - paths = @graph.all_paths_in_cycle(cycles.first, 21) > + paths = @graph.paths_in_cycle(cycles.first, 21) > paths.length.should be == 20 > end > > -- > 1.7.3.5 > > -- > You received this message because you are subscribed to the Google Groups > "Puppet Developers" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/puppet-dev?hl=en. > -- Morgan's Second Law: To a first approximation all appointments are canceled. --------------------------------------------------------------------- Luke Kanies -|- http://puppetlabs.com -|- +1(615)594-8199 -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
