Author: vborja
Date: Mon Oct 20 13:48:32 2008
New Revision: 706405

URL: http://svn.apache.org/viewvc?rev=706405&view=rev
Log:
Fixed to pass specs

Modified:
    incubator/buildr/trunk/addon/buildr/drb.rb

Modified: incubator/buildr/trunk/addon/buildr/drb.rb
URL: 
http://svn.apache.org/viewvc/incubator/buildr/trunk/addon/buildr/drb.rb?rev=706405&r1=706404&r2=706405&view=diff
==============================================================================
--- incubator/buildr/trunk/addon/buildr/drb.rb (original)
+++ incubator/buildr/trunk/addon/buildr/drb.rb Mon Oct 20 13:48:32 2008
@@ -52,50 +52,104 @@
     port = ENV['DRB_PORT'] || 2111
     PORT = port.to_i
 
-    # save the tasks,rules,layout defined by buildr
-    # based on the code from the sandbox
-    @tasks = Buildr.application.tasks.collect do |original|
-      prerequisites = original.send(:prerequisites).map(&:to_s)
-      actions = original.instance_eval { @actions }.clone
-      lambda do
-        original.class.send(:define_task, original.name=>prerequisites).tap do 
|task|
+    class SavedTask #:nodoc:
+      attr_reader :original, :prerequisites, :actions
+      
+      def initialize(original)
+        @original = original.dup
+        @prerequisites = original.send(:prerequisites).map(&:to_s)
+        @actions = original.instance_eval { @actions }.clone
+      end
+      
+      def name
+        original.name
+      end
+      
+      def define!
+        original.class.send(:define_task, original.name => prerequisites).tap 
do |task|
           task.comment = original.comment
           actions.each { |action| task.enhance &action }
         end
       end
-    end
-    @rules = Buildr.application.instance_variable_get(:@rules)
-    @layout = Layout.default.clone
-    
-    class << self
-      attr_accessor :tasks, :rules, :layout
+    end # SavedTask
 
-      def server_uri
-        "druby://:#{PORT}"
-      end
+    class Snapshot #:nodoc:
       
-      def client_uri
-        "druby://:#{PORT + 1}"
+      attr_accessor :projects, :tasks, :rules, :layout
+      
+      # save the tasks,rules,layout defined by buildr
+      def initialize
+        @projects = Project.instance_variable_get(:@projects) || {}
+        @tasks = Buildr.application.tasks.inject({}) do |hash, original|
+          unless projects.key? original.name # don't save project definitions
+            hash.update original.name => SavedTask.new(original)
+          end
+          hash
+        end
+        @rules = Buildr.application.instance_variable_get(:@rules)
+        @layout = Layout.default.clone
       end
+      
+    end # Snapshot
+
+    # The tasks,rules,layout defined by buildr
+    # before loading any project
+    @original = Snapshot.new
+
+    class << self
+      
+      attr_accessor :original, :snapshot
 
       def run
         begin
-          run_client
-        rescue DRb::DRbConnError
+          client = connect
+        rescue DRb::DRbConnError => e
           run_server!
+        else
+          run_client(client)
         end
       end
 
-      def run_client
+      def client_uri
+        "druby://:#{PORT + 1}"
+      end
+
+      def remote_run(cfg)
+        with_config(cfg) { Buildr.application.remote_run(self) }
+      rescue => e
+        cfg[:err].puts e.message
+        e.backtrace.each { |b| cfg[:err].puts "\tfrom #{b}" }
+        raise e
+      end
+
+      def save_snapshot(app)
+        app.extend self
+        if app.instance_eval { @rakefile }
+          @snapshot = self::Snapshot.new
+          app.buildfile_reloaded!
+        end
+      end
+
+    private
+
+      def server_uri
+        "druby://:#{PORT}"
+      end
+      
+      def connect
         buildr = DRbObject.new(nil, server_uri)
         uri = buildr.client_uri # obtain our uri from the server
         DRb.start_service(uri)
-        buildr.remote_run :dir => Dir.pwd, :argv => ARGV,
+        buildr
+      end
+
+      def run_client(client)
+        client.remote_run :dir => Dir.pwd, :argv => ARGV,
                           :in  => $stdin, :out => $stdout, :err => $stderr
       end
 
       def run_server
-        Application.module_eval { include DRbApplication }
+        save_snapshot(Buildr.application)
         DRb.start_service(server_uri, self)
         puts "#{self} waiting on #{server_uri}"
       end
@@ -117,6 +171,7 @@
       end
       
       def with_config(remote)
+        @invoked = true
         set = lambda do |env|
           ARGV.replace env[:argv]
           $stdin, $stdout, $stderr = env.values_at(:in, :out, :err)
@@ -124,10 +179,7 @@
         end
         original = { 
           :dir => Buildr.application.instance_variable_get(:@original_dir), 
-          :in => $stdin, 
-          :out => $stdout, 
-          :err => $stderr, 
-          :argv => ARGV 
+          :argv => ARGV, :in => $stdin, :out => $stdout, :err => $stderr
         }
         begin
           set[remote]
@@ -137,58 +189,54 @@
         end
       end
 
-      def remote_run(cfg)
-        with_config(cfg) { Buildr.application.remote_run }
-      rescue => e
-        puts e
-      end
-
     end # class << DRbApplication
 
-    def remote_run
+    def remote_run(server)
       init 'Distributed Buildr'
       if @rakefile
-        if [EMAIL PROTECTED] || buildfile.timestamp > @last_loaded
-          # buildfile updated, need to reload
-          Project.clear
-          @tasks = {}
-          DRbApplication.tasks.each { |block| block.call }
-          @rules = DRbApplication.rules.clone
-          Layout.default = DRbApplication.layout.clone
-          @last_loaded = buildfile.timestamp
-          load_buildfile
+        if buildfile_needs_reload?
+          reload_buildfile(server.original)
+          server.save_snapshot(self)
         else
-          clear_invoked_tasks
+          clear_invoked_tasks(server.snapshot || server.original)
         end
       else
-        load_buildfile
-        @last_loaded = buildfile.timestamp
-      end      
+        reload_buildfile(server.original)
+        server.save_snapshot(self)
+      end
       top_level
     end
 
-    def clear_invoked_tasks
-      lookup('buildr:initialize').instance_eval do
-        @already_invoked = true
-        @actions = []
-      end
-      projects = Project.instance_variable_get(:@projects) || {}
-      @tasks.each_pair do |name, task|
-        is_project = projects.key?(task.name)
-        task.instance_variable_set(:@already_invoked, false) unless is_project
-      end
+    def buildfile_reloaded!
+      @last_loaded = buildfile.timestamp if @rakefile
     end
 
-    drb_tasks = lambda do
-      task('start') { run_server! }
-    end
+  private
     
-    if Buildr.respond_to?(:application)
-      Buildr.application.instance_eval do
-        @rakefile = "" unless @rakefile
-        in_namespace(:drb, &drb_tasks)
-      end
+    def buildfile_needs_reload?
+      [EMAIL PROTECTED] || @last_loaded < buildfile.timestamp
     end
+
+    def reload_buildfile(snapshot)
+      clear_for_reload(snapshot)
+      load_buildfile
+      buildfile_reloaded!
+    end
+
+    def clear_for_reload(snapshot)
+      Project.clear
+      @tasks = {}
+      snapshot.tasks.each_pair { |name, saved| saved.define! }
+      @rules = snapshot.rules.clone
+      Layout.default = snapshot.layout.clone
+    end
+
+    def clear_invoked_tasks(snapshot)
+      @tasks = {}
+      snapshot.tasks.each_pair { |name, saved| saved.define! }
+    end
+
+    namespace(:drb) { task('start') { run_server! } }
     
   end # DRbApplication
 


Reply via email to