module Ratch # = Buildable mixin # module Buildable # Reference task manager. def build_manager @build_manager ||= BuildManager.new end # Define a build target. def file(name, &block) name, deps, block = *parse_build_dependencies(name, &block) @build_manager.define_file(name, *deps, &block) end # Build a file. def build(file) @build_manager.call(file) end private # def parse_build_dependencies 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 # = BuildManager class # class BuildManager attr :builds def initialize @builds = {} end def define_file(name, *depend, &block) build = Build.new(name, *depend, &block) builds[build.name] = task end # def call(file) plan.each{ |name| @@tasks[name].action_call } #action_call end # TODO Check for circular dependencies. def plan(list=[]) if list.include?(name) raise "Circular dependency #{name}." end @preqs.each do |need| need = need.to_s next if list.include?(need) @@tasks[need].plan(list) end list << name return list end end # = Build class # class Build attr :name attr :preqs attr :action # def initialize(name, *preqs, &action) @name = name.to_s @preqs = preqs @action = action end # def call files = Dir.glob(@name) files.each do |name| if File.exist?(name) mtime = File.mtime(name) needs = @preqs.find do |file| !File.exist?(file) || File.mtime(file) > mtime end else needs = true end @action.call(@name) if needs end end end end