summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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