require 'set' module Ramaze ## # The AppGraph class can be used to generate a graph of all the URLs mapped in # a Ramaze application and saves this graph as an image. # # In order to generate a graph of your application all you need to do is the # following: # # require 'ramaze/app_graph' # # graph = Ramaze::AppGraph.new graph.generate graph.show # # Once this code is executed you can find the .dot and PNG files in the root # directory of your application. # # @author Michael Fellinger # class AppGraph ## # Creates a new instance of the class. # # @author Michael Fellinger # def initialize @out = Set.new end ## # Generates the graph based on all the current routes. The graph is saved in # the application directory. # # @author Michael Fellinger # def generate Ramaze::AppMap.to_hash.each do |location, app| connect(location => app.name) app.url_map.to_hash.each do |c_location, c_node| connect(app.name => c_node) connect(c_node.mapping => c_node) c_node.update_template_mappings c_node.view_templates.each do |wish, mapping| mapping.each do |action_name, template| action_path = File.join(c_node.mapping, action_name) connect(c_node => action_path, action_path => template) end end c_node.update_method_arities c_node.method_arities.each do |method, arity| action_path = File.join(c_node.mapping, method.to_s) connect( action_path => "#{c_node}##{method}[#{arity}]", c_node => action_path ) end end end end ## # Connects various elements in the graph to each other. # # @author Michael Fellinger # def connect(hash) hash.each do |from, to| @out << (" %p -> %p;" % [from.to_s, to.to_s]) end end ## # Writes the dot file containing the graph data. # # @author Michael Fellinger # def write_dot File.open('graph.dot', 'w+') do |dot| dot.puts 'digraph appmap {' dot.puts(*@out) dot.puts '}' end end ## # Generates a PNG file based on the .dot file. # # @author Michael Fellinger # def show write_dot options = { 'rankdir' => 'LR', 'splines' => 'true', 'overlap' => 'false', } args = options.map{|k,v| "-G#{k}=#{v}" } system("dot -O -Tpng #{args.join(' ')} graph.dot") system('feh graph.dot.png') end end # AppGraph end # Ramaze