require 'rbconfig' require 'yaml' require 'fileutils' require 'rake' require 'rake/tasklib' #require 'mega/filelist' require 'nano/hash/traverse' module Reap ; end # Base class for reap tasks. # # When creating a specifc task, subclass this one and create two class-level # methods #task and #desc. #task will return the name of the task and # #desc a description of the task. Then create an instance method called # #setup to do any initial preping. Usually that means assigning # some instance vars from the Reapfile configutration. You can use # section[] for settings from the task's particular section (as # determined by self.task method above) and/or use master[] # for top-level settings. Finally write a #run method that preforms the # actual task. # # Here's an oh so simple example: # # class MyTask < Task # def self.task ; 'mytask' ; end # def self.desc ; 'This is my first custom task.' ; end # # def setup # @message = section['message'] || master['default'] || 'None Found!' # end # # def run # puts @message # end # end # # This corresponding settings in the Reapfile will then be: # # default: Default text, if any. # # mytask: # message: Message text, if any. # # Reap automatically handles multiple task runs if an array is provided # under the task section instead of a single mapping. For example: # # mytask: # - # message: First Run. # - # message: Second Run. # class Reap::Task < Rake::TaskLib RUBY = Config::CONFIG['ruby_install_name'] DEFAULT_INCLUDE = [ '[A-Z]*', 'setup.rb', 'lib/**/*', 'bin/**/*', 'data/**/*', 'doc/**/*', 'rdoc/**/*', 'test/**/*', 'bench/**/*', 'demo/**/*', 'samples/**/*', 'examples/**/*' ] MUST_EXCLUDE = [ 'InstalledFiles', '**/CVS/**/*', '**/*~' ] def initialize #:yield: load_config init yield( self ) if block_given? define end def init raise "not implemented" end def define raise "not implemented" end attr_reader :config def load_config( config_file=nil ) config_file ||= 'Reapfile' if File.file?( config_file ) # load config file @config = ::YAML.load( File.open( config_file ) ).traverse{ |k,v| [k.downcase, v] } # required main parameters raise "TITLE is a required configuration field" unless @config['title'] raise "NAME is a required configuration field" unless @config['name'] raise "VERSION is a required configuration field" unless @config['version'] else @config = {} end end def master ; @config ; end def section sect = @config[self.class.section_name] || {} end # Class Methods class << self def section_name(n=nil) @sname = n.to_s if n @sname end end =begin class << self def inherited( klass ) (@task_registry ||= []) << klass end def registry ; @task_registry ||= [] ; end def tasks ; @task ||= registry.collect { |t| t.task_name } ; end def task_name(n=nil) ; @tname = n.to_sym if n ; @tname ; end def task_desc(d=nil) ; @tdesc = d.to_s if d ; @tdesc ; end end attr_reader :master, :section def initialize( master_config, section_config ) @master = master_config @section = section_config setup if respond_to?(:setup) end def [](x) ; @section[x] ; end # Run the system command +cmd+. # # Example: # sh %{ls -ltr} # def sh(cmd, options={}) FileUtils.send( :fu_check_options, options, :noop, :verbose ) FileUtils.send( :fu_output_message, cmd ) if options[:verbose] unless options[:noop] system(cmd) or fail "Command Failed: [#{cmd}]" end end # Run a Ruby interpreter with the given arguments. # # Example: # ruby %{-pe '$_.upcase!'