lib/sprout/daemon.rb in sprout-1.1.2.pre vs lib/sprout/daemon.rb in sprout-1.1.3.pre

- old
+ new

@@ -200,25 +200,22 @@ # an input prompt, so that another action # can be submitted, or user input can be # collected. def wait_for_prompt expected_prompt=nil expected_prompt = expected_prompt || prompt - line = '' - while process_runner.alive? do - #puts ">> ERROR #{process_runner.readpartial_err 1}" + fake_stderr = Sprout::OutputBuffer.new + fake_stdout = Sprout::OutputBuffer.new + stderr = read_from process_runner.e, fake_stderr + stdout = read_from process_runner.r, fake_stdout, expected_prompt + stdout.join && stderr.kill - return false if process_runner.r.eof? - char = process_runner.readpartial 1 - line << char - if char == "\n" - line = '' - end - Sprout.stdout.printf char - Sprout.stdout.flush - return true unless line.match(expected_prompt).nil? - end + stdout_str = fake_stdout.read + stderr_str = fake_stderr.read + + Sprout.stderr.printf(stderr_str) + Sprout.stdout.printf(stdout_str) end ## # Expose the running process to manual # input on the terminal, and write stdout @@ -231,10 +228,49 @@ end end protected + ## + # This is the ass-hattery that we need to go + # through in order to read from stderr and + # stdout from a long-running process without + # eternally blocking the parent - and providing + # the ability to asynchronously write into the + # input stream. + # + # If you know how to better do this accross + # platforms (mac, win and nix) without losing + # information (i.e. combining stderr and stdout + # into a single stream), I'm all ears! + def read_from pipe, to, until_prompt=nil + line = '' + lines = '' + Thread.new do + Thread.current.abort_on_exception = true + while true do + break if pipe.eof? + char = pipe.readpartial 1 + line << char + if char == "\n" + to.puts line + to.flush + lines << line + line = '' + end + if !until_prompt.nil? && line.match(until_prompt) + lines << line + to.printf line + to.flush + line = '' + break + end + end + lines + end + end + def process_launched? @process_launched end ## @@ -284,10 +320,10 @@ ## # Execute a single action. def execute_action action, silence=false action = action.strip - Sprout.stdout.puts(action) unless silence + Sprout.stdout.puts("#{action}\n") unless silence process_runner.puts action wait_for_prompt end end