summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Pittman <daniel@rimspace.net>2011-01-27 00:02:52 -0800
committerDaniel Pittman <daniel@rimspace.net>2011-02-03 17:02:16 -0800
commitadc9244ecf4bfb59a98a2dd5472b03f685b6303e (patch)
treea8026e0e89924b1174a9caf600bd11e5b053533b
parent2cf45283d7eea90461f1c9606af710bf5645076a (diff)
downloadpuppet-adc9244ecf4bfb59a98a2dd5472b03f685b6303e.tar.gz
puppet-adc9244ecf4bfb59a98a2dd5472b03f685b6303e.tar.xz
puppet-adc9244ecf4bfb59a98a2dd5472b03f685b6303e.zip
Feature #2597 -- generate a DOT graph of cycles on request.
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.
-rw-r--r--lib/puppet/simple_graph.rb35
-rwxr-xr-xspec/unit/simple_graph_spec.rb10
2 files changed, 37 insertions, 8 deletions
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index 1b5ffdc52..e39aa8770 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 e7c875f50..2c6af063b 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