module Ratch # = Taskable Mixin # module Taskable # Reference task manager. def task_manager @task_manager ||= TaskManager.new end # Define a main task. def main(name, &block) name, deps, block = *parse_task_dependencies(name, &block) task_manager.define_main(name, *deps, &block) end # Define a task. def task(name, &block) name, deps, block = *parse_task_dependencies(name, &block) task_manager.define_task(name, *deps, &block) end # Run a task. def run(name) task_manager.call(name) end private # def parse_task_dependencies(name_deps, &block) if Hash===name_deps name = name_deps.keys[0] deps = name_deps.values[0] else name = name_deps deps = [] end [name, deps, block] end end # = TaskManager Class # class TaskManager attr :main attr :tasks def initialize @main = nil @tasks = {} end def define_main(name=nil, *depend, &block) @main = Task.new(name, *depend, &block) tasks[@main.name] = @main end def define_task(name, *depend, &block) task = Task.new(name, *depend, &block) tasks[task.name] = task end def call_main return unless @main call(@main.name) end # Call task. def call(name) plan(name).each{ |name| @tasks[name].call } #action_call end # Prepare plan, checking for circular dependencies. def plan(name, list=[]) if list.include?(name) raise "Circular dependency #{name}." end task = @tasks[name] task.preqs.each do |need| need = need.to_s next if list.include?(need) @tasks[need].plan(need, list) end list << task.name return list end end # = Task class # class Task attr :name attr :preqs attr :action # def initialize(name, *preqs, &action) @name = name.to_s @preqs = preqs @action = action end # def call @action.call if @action end end end #module Ratch