2009-06-12 18:00:04 +00:00
|
|
|
module Compass::CommandLineHelper
|
|
|
|
def compass(*arguments)
|
2009-06-20 17:25:44 +00:00
|
|
|
options = arguments.last.is_a?(Hash) ? arguments.pop : {}
|
|
|
|
options[:wait] = 0.25
|
2009-06-12 18:00:04 +00:00
|
|
|
if block_given?
|
|
|
|
responder = Responder.new
|
|
|
|
yield responder
|
|
|
|
IO.popen("-", "w+") do |io|
|
|
|
|
if io
|
|
|
|
#parent process
|
|
|
|
output = ""
|
|
|
|
eof_at = nil
|
2009-06-20 17:25:44 +00:00
|
|
|
while !eof_at || (Time.now - eof_at < options[:wait])
|
2009-06-12 18:00:04 +00:00
|
|
|
if io.eof?
|
|
|
|
eof_at ||= Time.now
|
|
|
|
sleep 0.1
|
|
|
|
else
|
|
|
|
eof_at = nil
|
|
|
|
timeout(1) do
|
|
|
|
output << io.readpartial(1024)
|
|
|
|
end
|
|
|
|
prompt = output.split("\n").last
|
|
|
|
if response = responder.response_for(prompt)
|
|
|
|
io.puts response
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
responder.assert_required_responses!
|
|
|
|
@last_result = output
|
|
|
|
else
|
|
|
|
#child process
|
|
|
|
execute *arguments
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
@last_result = capture_output do
|
|
|
|
execute *arguments
|
|
|
|
end
|
|
|
|
end
|
|
|
|
rescue Timeout::Error
|
|
|
|
fail "Read from child process timed out"
|
|
|
|
end
|
|
|
|
|
|
|
|
class Responder
|
|
|
|
Response = Struct.new(:prompt, :text, :required, :responded)
|
|
|
|
def initialize
|
|
|
|
@responses = []
|
|
|
|
end
|
|
|
|
def respond_to(prompt, options = {})
|
|
|
|
@responses << Response.new(prompt, options[:with], options[:required])
|
|
|
|
end
|
|
|
|
def response_for(prompt)
|
|
|
|
response = @responses.detect{|r| r.prompt == prompt}
|
|
|
|
if response
|
|
|
|
response.responded = true
|
|
|
|
response.text
|
|
|
|
end
|
|
|
|
end
|
|
|
|
def assert_required_responses!
|
|
|
|
@responses.each do |response|
|
|
|
|
if response.required && !response.responded
|
|
|
|
raise "Prompt not encountered: \"#{response.prompt}\""
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def assert_action_performed(action, path)
|
|
|
|
actions_found = []
|
|
|
|
@last_result.split("\n").each do |line|
|
|
|
|
line = line.split
|
|
|
|
return if line.first == action.to_s && line.last == path
|
|
|
|
actions_found << line.first if line.last == path
|
|
|
|
end
|
|
|
|
message = "Action #{action.inspect} was not performed on: #{path}."
|
|
|
|
message += "The following actions were performed: #{actions_found.join(", ")}" if actions_found.any?
|
|
|
|
puts @last_result
|
|
|
|
fail message
|
|
|
|
end
|
|
|
|
|
|
|
|
def within_tmp_directory(dir = "tmp")
|
|
|
|
d = absolutize(dir)
|
|
|
|
FileUtils.mkdir_p(d)
|
|
|
|
Dir.chdir(d) do
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
ensure
|
2009-06-20 17:33:47 +00:00
|
|
|
FileUtils.rm_rf(d)
|
2009-06-12 18:00:04 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def capture_output
|
|
|
|
real_stdout, $stdout = $stdout, StringIO.new
|
|
|
|
yield
|
|
|
|
$stdout.string
|
|
|
|
ensure
|
|
|
|
$stdout = real_stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute(*arguments)
|
|
|
|
Compass::Exec::Compass.new(arguments).run!
|
|
|
|
end
|
|
|
|
end
|