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.

Reply via email to