# Task node in the capistrano namespace, task hierarchy. class Capitate::TaskNode include Capitate::Plugins::Base attr_reader :name, :nodes, :tasks, :parent # Create task node with name and parent # For root not use name = "top" # # ==== Options # +name+:: Node name (namespace name) # +parent+:: Parent node # def initialize(name, parent = nil) @name = name @parent = parent @nodes = [] @tasks = [] end # Add "child" node. # # ==== Options # +task_node+:: Node # def add_node(task_node) @nodes << task_node end # Find node with name (namespace). # # ==== Options # +name+:: Name to look for # def find(name) @nodes.each do |node| return node if node.name == name end nil end # Add task to this node. # # ==== Options # +task+:: Add task associated with this node (namespace). # def add_task(task) @tasks << task end # Get "child" nodes (sorted). def sorted_nodes nodes.sort_by(&:name) end # Get tasks (sorted). def sorted_tasks tasks.sort_by(&:fully_qualified_name) # { |t| t.name.to_s } end # Iterate over ALL "child" nodes, depth first. # Yields |node, level|. # # ==== Options # +level+:: Current level # def each_node(level = 0, &block) sorted_nodes.each do |node| yield(node, level) node.each_node(level + 1, &block) end end # Get the full name, using delimeter # # ==== Options # +delimeter+:: Delimeter # # ==== Examples # node.full_name(":") => "mysql:centos" # On node mysql centos node (top -> mysql -> centos) # def full_name(delimeter = "-") if parent parent_name = parent.full_name return [ parent_name, name ].compact.join(delimeter) end # Return nil for top node name == "top" ? nil : name end # Write textile documentation for node (recursively). # # Uses task desc attribute for task details. # # ==== Options # +dir+:: Dir to write to # +file_name+:: File name to write to, defaults to full name # +title+:: Title and h1 for page, defaults to name # +options+:: Options # def write_doc(dir, file_name = nil, title = nil, options = {}, &block) file_name ||= full_name title ||= full_name(":") path = "#{dir}/#{file_name}.txt" puts "%10s %-30s" % [ "create", path ] File.open(path, "w") do |file| file.puts "h1. #{title}\n\n" # # Breadcrumb generate # bc_full_name = full_name(":") links = [] if bc_full_name names = bc_full_name.split(":") links << " #{names.pop} " # Pop off current while(!names.empty?) do links << %{ "#{names.last}":#{names.join("-")}.html } names.pop end end # Write breadcrumb file.puts %{ "home":../index.html > "recipes":index.html > #{links.reverse.join(" > ")} } # Write task count # count = 0 # each_node do |snode, level| # count += snode.tasks.length # end # file.puts %{\n\n*#{count}* tasks!\n\n} # # Namespace # unless nodes.empty? file.puts "\n\nh2. Namespaces\n\n" each_node do |snode, level| #li_level = (0..level).collect { "*" }.join li_level = "*" if snode.tasks.length > 0 file.puts %{#{li_level} "#{snode.full_name(":")}":#{snode.full_name}.html (#{snode.tasks.length}) \n} end end end # # Tasks # unless tasks.empty? file.puts "\n\nh2. Tasks\n\n" sorted_tasks.each do |task| file.puts %{* "#{task.fully_qualified_name}":##{task.fully_qualified_name} \n} end end # # Task details # unless tasks.empty? file.puts "\n\nh2. Task documentation\n\n" sorted_tasks.each do |task| file.puts %{