This patch allows tasks to have Proc objects among their dependencies.
The Proc is executed on demand; it's return value is interpreted as a
list of files to be added to the dependy list.

This functionality can save a lot of execution time when using many
(automatically generated) file tasks that have slow dependency
discovery methods. The alternative, creating a rule for each of them,
gets pretty slow when defining more than a few hundred of them, as
they need to be regexp matched.
--- rake-stack.rb	2008-04-23 12:58:37.445634500 +0200
+++ rake.rb	2008-04-23 13:41:17.783189338 +0200
@@ -470,7 +470,7 @@
 
     # Enhance a task with prerequisites or actions.  Returns self.
     def enhance(deps=nil, &block)
-      @prerequisites |= deps if deps
+      @prerequisites.include_without_glob deps
       @actions << block if block_given?
       self
     end
@@ -1242,6 +1242,24 @@
       self
     end
     alias :add :include
+   
+
+    # Add file names without doing glob resolution, while still allowing Procs.
+    def include_without_glob(deps)
+      deps = [deps] unless deps.respond_to?(:to_ary)
+      deps.compact.each do |d|
+        case d
+        when Proc
+          # get results from proc lazily 
+          @pending_add << d
+          @pending = true
+        else
+          # don't do globbing
+          @items << d.to_s
+        end
+      end
+    end
+
 
     # Register a list of file name patterns that should be excluded from the
     # list.  Patterns may be regular expressions, glob patterns or regular
@@ -1349,6 +1367,8 @@
 
     def resolve_add(fn)
       case fn
+      when Proc
+        include_without_glob fn.call
       when %r{[*?\[\{]}
         add_matching(fn)
       else
@@ -1622,8 +1642,6 @@
     def define_task(task_class, *args, &block)
       task_name, arg_names, deps = resolve_args(args)
       task_name = task_class.scope_name(@scope, task_name)
-      deps = [deps] unless deps.respond_to?(:to_ary)
-      deps = deps.collect {|d| d.to_s }
       task = intern(task_class, task_name)
       task.set_arg_names(arg_names) unless arg_names.empty?
       task.add_description(@last_description)
_______________________________________________
Rake-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rake-devel

Reply via email to