diff --git a/lib/terraspace/logger.rb b/lib/terraspace/logger.rb index a4c00042..e54854aa 100644 --- a/lib/terraspace/logger.rb +++ b/lib/terraspace/logger.rb @@ -20,8 +20,12 @@ def format_message(severity, datetime, progname, msg) # Used to allow terraform output to always go to stdout # Terraspace output goes to stderr by default # See: terraspace/shell.rb - def stdout(msg) - print msg + def stdout(msg, newline: true) + if newline + puts msg + else + print msg + end end end end diff --git a/lib/terraspace/shell.rb b/lib/terraspace/shell.rb index b99d4456..2e523576 100644 --- a/lib/terraspace/shell.rb +++ b/lib/terraspace/shell.rb @@ -59,7 +59,7 @@ def handle_streams(stdin, stdout, stderr) lines = buffer.split("\n") lines.each do |line| if f.fileno == stdout.fileno - handle_stdout(line) + handle_stdout(line, newline: !suppress_newline(line)) handle_input(stdin, line) else handle_stderr(line) @@ -71,6 +71,11 @@ def handle_streams(stdin, stdout, stderr) end end + def suppress_newline(line) + line.size == 8192 && line[-1] != "\n" || # when buffer is very large buffer.split("\n") only gives 8192 chars at a time + line.include?("Enter a value:") # prompt + end + def handle_stderr(line) @error ||= Error.new @error.lines << line # aggregate all error lines @@ -87,19 +92,14 @@ def all_eof?(files) files.find { |f| !f.eof }.nil? end - # Terraform doesnt seem to stream the line that prompts with "Enter a value:" when using Open3.popen3 - # Hack around it by mimicking the "Enter a value:" prompt - # - # Note: system does stream the prompt but using Open3.popen3 so we can capture output to save to logs. def handle_input(stdin, line) - # stdout doesnt seem to flush and show "Enter a value: " look for earlier output patterns = [ - "Only 'yes' will be accepted", # prompt for apply. can happen on apply + "Enter a value:", "\e[0m\e[1mvar.", # prompts for variable input. can happen on plan or apply. looking for bold marker also in case "var." shows up somewhere else ] if patterns.any? { |pattern| line.include?(pattern) } - print "\n Enter a value: ".bright - stdin.write_nonblock($stdin.gets) + answer = $stdin.gets + stdin.write_nonblock(answer) end end @@ -115,16 +115,12 @@ def exit_status(status) end end - def handle_stdout(line) - prompted = line.include?('Enter a value') - @prompt_shown ||= prompted - return if @prompt_shown && prompted - + def handle_stdout(line, newline: true) # Terraspace logger has special stdout method so original terraform output # can be piped to jq. IE: # terraspace show demo --json | jq if logger.respond_to?(:stdout) && !@options[:log_to_stderr] - logger.stdout(line) + logger.stdout(line, newline: newline) else logger.info(line) end