A small snippet to interact with commandline applications that ask questions on stdin, particularly useful for testing.
Usage
interact "rails new foo -m template.rb", /RSpec/ => 'y', /MySql/ => 'n'
Code
# https://gist.github.com/2166521
# capture commandline output and send responses if nothing was read
def interact(command, answers)
puts command
line = ""
write = false
PTY.spawn(command) do |output, input, pid|
loop do
rs, ws, = IO.select([output], [input])
# read into the buffer
if r = rs[0]
write = false
ret = r.read(1)
print ret
return unless ret
line << ret
line = "" if ret == "\n"
end
# time to write ?
if w = ws[0]
if write and line != ""
text = line.gsub(/\e\[\d+m/,'').strip
answer = answers.detect do |question, answer|
text =~ question
end || raise("Question #{text.inspect} has no answer!")
w.write(answer.last + "\n")
line = ""
else
write = true
end
end
end
end
$?.success?
end