lib/reap/task.rb in reap-5.0.0 vs lib/reap/task.rb in reap-5.10.10

- old
+ new

@@ -3,251 +3,185 @@ require 'fileutils' require 'facet/fileutils/safe_ln' require 'facet/string/tabto' require 'facet/module/basename' -require 'facet/module/attr_setter' -require 'facet/filelist' unless defined?( FileList ) -require 'facet/openobject' +require 'carat/filelist' require 'reap/projectinfo' -# _____ _ ___ ___ _ -# |_ _|_ _ __| |__ | _ ) __ _ ___ ___ / __| |__ _ ______ -# | |/ _` (_-< / / | _ \/ _` (_-</ -_) | (__| / _` (_-<_-< -# |_|\__,_/__/_\_\ |___/\__,_/__/\___| \___|_\__,_/__/__/ -# - # Base class for reap tasks. # -# Here's a simple example: +# Here's an oh so simple example: # # class MyTask < Reap::Task # -# task_desc 'this is a custom reap task' +# register 'mytask' # -# task_attr :mytask +# default_desc 'this is a custom reap task' # -# def run +# attr_accessor :message # -# mytask.message ||= 'None Found!' +# def init +# @message ||= master['default'] || 'None Found!' +# end # -# puts mytask.message #=> Hello! -# puts master.default #=> Yo! -# puts mytask.default #=> Yo! (inherited from master) +# def run +# puts @message # end # end # -# With the corresponding settings in the ProjectInfo file as: +# The corresponding settings in the ProjectInfo file will then be: # -# default: Yo! +# default: Default text, if any. # -# mytask: -# message: Hello! +# myname: +# TASK: mytask +# message: Message text, if any. # - module Reap - def self.registry - Task.registry - end + def self.registry ; @registry ; end - # Task base class. - - class Task - - #include ::Config - include ::FileUtils - - RUBY = ::Config::CONFIG['ruby_install_name'] - - class << self - - # When this class is inherited the new task is registered. - def inherited( base ) - registry << base - YAML.add_private_type( base.basename.downcase ) do |type, val| - base.new( val ) + def self.register + @registry ||= {} + ObjectSpace.each_object(Class) { |klass| + if klass < ::Reap::Task + if klass.verify + @registry[klass.basename.downcase] = klass end end + } + end - # List of task classes. - def registry - @registry ||= [] - end + def self.tasks ; @tasks ; end - # Task DSL + def self.initialize + @tasks ||= {} + registry.each do |name, klass| + @tasks[name] = klass.new + end + end - # Provides tasks type. - def task_class - basename.downcase - end - # Short one-line description of the task. - def task_desc( text=nil, &block ) - return @task_desc = proc { text } if text - return @task_desc = block if block_given? - return @task_desc.call - end - alias_method :desc, :task_desc + class Task - # Takes a string or a block the evaluates to a string - # providing detailed help information about the task. - def task_help( text=nil, &block ) - return @task_help = proc { text } if text - return @task_help = block if block_given? - return @task_help.call - end - alias_method :help, :task_help + include ::Config + include ::FileUtils - # Set alias for 'task' attribute, which provides - # inherited (from master) access to section data. - # (Deprecate? You can use "alias_method name, :task") - def task_attr( name ) - define_method(name) { @task } - end + RUBY = CONFIG['ruby_install_name'] - # How to determine if a task is available for use. - # By default a taks is only available if the Project - # file exists and the task's section also exists. - # Common was to loosen this resriction are to - # only require the file, not the seciton: - # - # task_available { Reap.projectfile? } - # - # Or have no restrictions: - # - # task_available true - # - def task_available( bool=false, &block ) - if bool - (class << self; self; end).class_eval { - define_method( :available? ){ |app| true } - } - else - (class << self; self; end).class_eval { - define_method( :available?, &block ) - } - end - end + # class methods - # Is the task available for use? By default - # a task is only made available if the - # ProjectInfo file has a task for it. + def self.task_desc ; '(no desciption given)' ; end + def self.task_name ; basename.downcase ; end - def available?(app) - false - end + def self.section_required( val ) ; @section_required = val ;end + def self.section_required? ; @section_required ; end - # Class-level access to Project file's master data - # provided via a CascadingOpenObject. - def master - @master ||= ProjectInfo.instance.to_cascading_open_object + def self.verify + assume = true + if section_required? + assume = ::ProjectInfo.info.key?(task_name) end + assume + end - end #<< class - # instance methods - attr_accessor :task_name - def name ; task_name ; end + def task_name ; self.class.task_name ; end + def task_desc ; self.class.task_desc ; end - def task_desc ; @section[:desc] || self.class.task_desc ; end - def task_help ; self.class.task_help ; end + def master ; ::ProjectInfo.info ; end - def master ; self.class.master ; end - def setting ; @task ; end + def section ; @section ; end - attr :section + def section_required? ; self.class.section_required? ; end - def initialize( section ) - case section when Hash, nil - @section = CascadingOpenObject.new( section || {} ) - else - @section = section - end - end - - # Run task. - - def execute( *args ) - #@section = CascadingOpenObject.new( section ) - - task = section.dup - if task.respond_to?(:__parent__) - task.__parent__ = master - end - @task = task - - # deprecate init ? - if respond_to?( :init ) - if method(:init).arity == 0 + def initialize + sect = master[task_name] + if sect.is_a?(Array) + sect.each do |s| + section_parameters_set( s ) init - else - init( *args ) end - end - - if method(:run).arity == 0 - run else - run( *args ) + section_parameters_set( sect || {} ) + init end end - # interface - - #def init - # raise "not implemented for '#{name}' task" - #end - - def run - raise "no action defined for task #{task_name}" + def section_parameters_set( s ) + @section = s + @section.each { |k,v| send("#{k}=", v) } end - # delegate to section hash - def method_missing( *args, &block ) - @section.send( *args, &block ) + def init + raise "not implemented for '#{task_name}' task" end - # Task support methods - - def use_subsection( name ) - subsection = @section.__send__(task_name) - if subsection - subsection.__parent__ = @section - @task = subsection - end + def run( *args ) + raise "no action defined for task #{task_name}" end + # task support methods + def sh( arg ) puts arg system arg unless $PRETEND end - def ask( question, answers=nil ) - print "#{question}" - print " [#{answers}] " if answers - until inp = $stdin.gets[0,1] ; sleep 1 ; end ; puts - inp - end +# o = nil +# o = yld.call(self) if yld +# if String === o +# begin +# section( o ).each { |k,v| send("#{k}=", v ) } +# end +# end +# +# init +# +# task_name ||= default_name +# task_desc = @desc || default_desc +# +# if subtask +# desc task_desc +# task task_name => subtask do +# run +# end +# else +# desc task_desc +# task task_name do +# run +# end +# end +# end - def tell( statement ) - puts statement - end - - def provide_setup_rb - return true if File.exists?( 'setup.rb') - # copy from data dir to current directory (Won't work with Gem!) - f = File.join( Config::CONFIG['datadir'], 'reap', 'setup_rb', 'setup.rb' ) - if File.exists?(f) - File.cp( f, '.' ) - true - else - nil - end - end - end #class Task end #module Reap + + +## +# Convenience methods for built-in rake tasks +## +# module RakeTask +# extend self +# +# def gem_package_task(*args,&blk) +# ::Rake::GemPackageTask.new(*args,&blk) +# end +# +# def package_task(*args,&blk) +# ::Rake::PackageTask.new(*args,&blk) +# end +# +# def test_task(*args,&blk) +# ::Rake::TestTask.new(*args,&blk) +# end +# +# def rdoc_task(*args,&blk) +# ::Rake::RDocTask.new(*args,&blk) +# end +# +# end