# File lib/foreman_maintain/reporter/cli_reporter.rb, line 73 def initialize(stdout = STDOUT, stdin = STDIN, options = {}) @stdout = stdout @stdin = stdin options.validate_options!(:assumeyes) @assumeyes = options.fetch(:assumeyes, false) @hl = HighLine.new(@stdin, @stdout) @max_length = 80 @line_char = '-' @cell_char = '|' @spinner = Spinner.new(self) @last_line = '' end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 147 def after_execution_finishes(execution) puts_status(execution.status) puts(execution.output) unless execution.output.empty? puts(already_run_msg) if execution.status == :already_run hline new_line_if_needed logger.info("--- Execution step '#{execution.name}' finished ---") end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 156 def after_scenario_finishes(scenario) scenario_failure_message(scenario) puts "\n" logger.info("=== Scenario '#{scenario.description || scenario.class}' finished ===") end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 117 def ask(message, options = {}) new_line_if_needed options.validate_options!(:password) # the answer is confirmed by ENTER which will emit a new line @new_line_next_time = false @last_line = '' # add space at the end as otherwise highline would add new line there :/ message = "#{message} " unless message =~ /\s\Z/ answer = @hl.ask(message) { |q| q.echo = false if options[:password] } answer.to_s.chomp if answer end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 187 def ask_decision(message, options = 'y(yes), n(no), q(quit)') if assumeyes? print("#{message} (assuming yes)") return :yes end until_valid_decision do filter_decision(ask("#{message}, [#{options}]")) end ensure clear_line end
rubocop:disable Metrics/MethodLength
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 209 def ask_to_select(message, steps) if assumeyes? puts('(assuming first option)') return steps.first end until_valid_decision do answer = ask("#{message}, [n(next), q(quit)]") if answer =~ /^\d+$/ && (answer.to_i - 1) < steps.size steps[answer.to_i - 1] else decision = filter_decision(answer) if decision == :yes steps.first else decision end end end ensure clear_line end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 166 def assumeyes? @assumeyes end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 92 def before_execution_starts(execution) label = execution.step.label.to_s.tr('_', '-') logger.info("--- Execution step '#{execution.name}' [#{label}] started ---") puts(execution_info(execution, '')) end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 86 def before_scenario_starts(scenario) logger.info("=== Scenario '#{scenario.description || scenario.class}' started ===") puts "Running #{scenario.description || scenario.class}" hline('=') end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 162 def clear_line print "\r" + ' ' * @max_length + "\r" end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 239 def execution_info(execution, text) prefix = "#{execution.name}:" "#{prefix} #{text}" end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 199 def filter_decision(answer) decision = nil answer = answer.downcase DECISION_MAPPER.each do |options, decision_label| decision = decision_label if options.include?(answer) end decision end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 267 def hline(line_char = @line_char) puts line_char * @max_length end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 179 def multiple_steps_decision(steps) puts 'There are multiple steps to proceed:' steps.each_with_index do |step, index| puts "#{index + 1}) #{step.runtime_message}" end ask_to_select('Select step to continue', steps, &:runtime_message) end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 129 def new_line_if_needed if @new_line_next_time @stdout.print("\n") @stdout.flush @new_line_next_time = false end end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 98 def print(string) new_line_if_needed @stdout.print(string) @stdout.flush record_last_line(string) end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 105 def puts(string) # we don't print the new line right away, as we want to be able to put # the status label at the end of the last line, if possible. # Therefore, we just mark that we need to print the new line next time # we are printing something. new_line_if_needed @stdout.print(string) @stdout.flush @new_line_next_time = true record_last_line(string) end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 244 def puts_status(status) label_offset = 10 padding = @max_length - @last_line.to_s.size - label_offset if padding < 0 new_line_if_needed padding = @max_length - label_offset end @stdout.print(' ' * padding + status_label(status)) @new_line_next_time = true end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 271 def record_last_line(string) @last_line = string.lines.to_a.last end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 170 def single_step_decision(step) answer = ask_decision("Continue with step [#{step.runtime_message}]?") if answer == :yes step else answer end end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 255 def status_label(status) mapping = { :success => { :label => '[OK]', :color => :green }, :fail => { :label => '[FAIL]', :color => :red }, :abort => { :label => '[ABORTED]', :color => :red }, :running => { :label => '[RUNNING]', :color => :blue }, :skipped => { :label => '[SKIPPED]', :color => :yellow }, :already_run => { :label => '[ALREADY RUN]', :color => :yellow }, :warning => { :label => '[WARNING]', :color => :yellow } } properties = mapping[status] @hl.color(properties[:label], properties[:color], :bold) end
loop over the block until it returns some non-false value
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 233 def until_valid_decision decision = nil decision = yield until decision decision end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 137 def with_spinner(message) new_line_if_needed @spinner.activate @spinner.update(message) yield @spinner ensure @spinner.deactivate @new_line_next_time = true end
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 331 def already_run_msg 'The step was skipped as it was already run and it is marked' ' as run_once. Use --force to enforce the execution.' end
rubocop:enable Metrics/MethodLength, Metrics/AbcSize
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 327 def format_steps(steps, join_with = ', ', indent = 0) steps.map { |s| "#{' ' * indent}[#{s.label_dashed}]" }.join(join_with) end
rubocop:disable Metrics/MethodLength, Metrics/AbcSize
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 278 def scenario_failure_message(scenario) return if scenario.passed? message = [] message << " Scenario [#{scenario.description}] failed. ".strip_heredoc recommend = [] steps_with_abort = scenario.steps_with_abort(:whitelisted => false) unless steps_with_abort.empty? message << format(" The processing was aborted by user during the following steps: %s ".strip_heredoc, format_steps(steps_with_abort, "\n", 2)) end steps_with_error = scenario.steps_with_error(:whitelisted => false) unless steps_with_error.empty? message << format(" The following steps ended up in failing state: %s ".strip_heredoc, format_steps(steps_with_error, "\n", 2)) whitelist_labels = steps_with_error.map(&:label_dashed).join(',') recommend << format(" Resolve the failed steps and rerun the command. In case the failures are false positives, use --whitelist="%s" ".strip_heredoc, whitelist_labels) end steps_with_warning = scenario.steps_with_warning(:whitelisted => false) unless steps_with_warning.empty? message << format(" The following steps ended up in warning state: %s ".strip_heredoc, format_steps(steps_with_warning, "\n", 2)) recommend << " The steps in warning state itself might not mean there is an error, but it should be reviewed to ensure the behavior is expected ".strip_heredoc end puts((message + recommend).join("\n")) end