When Rake is run from another Ruby process (using IO.popen) the stdout
is not flushed appropriately, so stdout arrives at the parent process
later than it should - and in one big batch.

Here is why this matters: I'm running rake from Ruby with --trace,
looking for lines that match /^\*\* Execute (.*)$/. For each match I
record the timestamps for each task invocation. This allows me to
measure how long each task takes. I can store this information and
track how the duration of certain tasks evolve over time.

I'm attaching a patch that makes Rake flush stdout - plus a functional
test. The attached files go to test/test_flush.rb and
test/data/flush/Rakefile

It could be that the flush statements should go somewhere else - like
at the beginning and end of a task invocation, but this works for me.

Cheers,
Aslak

Attachment: flush_stdout_when_executing_tasks.patch
Description: Binary data

require 'test/unit'

class TestFlush < Test::Unit::TestCase
  def test_flushes_stdout_for_each_executed_task
    times = []
    rake = File.expand_path(File.dirname(__FILE__) + '/../bin/rake')
    lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
    rakefile = File.expand_path(File.dirname(__FILE__) + '/data/flush/Rakefile')
    cmd = "ruby -I#{lib} #{rake} --trace -f #{rakefile}"
    puts cmd
    IO.popen(cmd) do |io|
      io.each_line do |line|
        times << Time.new
      end
    end
    duration = times.max - times.min
    assert 3 < duration, "Duration should be at least 3 seconds, but was #{duration} seconds"
  end
end

Attachment: Rakefile
Description: Binary data

_______________________________________________
Rake-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rake-devel

Reply via email to