How to save rspec stdout on terminal to log/rspec.log at the same time

In travis, I can see stdout show on console, and I get a build.log when
“rake spec” finish, so how to implement this? I have try to
$stdout.reopen(a_file_io), but it will not show any msg in console

I find a way with IO.pipe

r, w = IO.pipe

fork do
$stdout.reopen(w)
10.times do
puts “foo at #{Time.now}”
puts “game over”
end
end

line = r.readline
while line
begin
if line.match(%r{game over})
break
else
puts line

  file = File.open(File.expand_path("../foo.log", __FILE__), 'w+')
  file.puts line
  file.close
end

rescue => e

ensure
line = r.readline
end
end

Is there better way to make it?

Roro Co wrote in post #1151952:

In travis, I can see stdout show on console, and I get a build.log

class Tee
def initialize(io,fn)
@io=io
@fn=fn
end
def <<(str) write(str) end
def print(str) write(str) end
def puts(str) write("#{str}\n") end
def putc© write( (c.is_a? Numeric) ? c.chr.to_s : c[0,1]) end
def write(str)
@io.print(str)
File.open(@fn,“a+”) { |f| f.write(str) }
end
end

test…

$stdout=Tee.new($stdout,“trace.log”)

2.times { |i| puts “Hello #{i}” ; sleep 0.1 }
$stdout << “1\n”
puts “E”
print “H?\n”
putc 72
putc “e”
putc “abc”

here a thread safe version:

class Tee
def initialize(io,fn)
@io=io
@fn=fn
@acc=[]
File.open(@fn,“w”) { |f| }
@m=Monitor.new
@th=Thread.new { loop {
@m.synchronize { purge }
sleep 1
} }
there=self
at_exit { there.purge }
end
def purge()
if @acc.size>0
File.open(@fn,“a+”) { |f| f.write((@acc).join("") ) }
@acc.clear
end
end
def <<(str) write(str) end
def print(str) write(str) end
def puts(str) write("#{str}\n") end
def putc© write( (c.is_a? Numeric) ? c.chr.to_s : c[0,1]) end
def write(str)
@m.synchronize {
@io.print(str)
@acc << str
}
end
end

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs