class ForemanMaintain::Reporter::CLIReporter

Attributes

last_line[R]
max_length[R]
select_option_counter[RW]

Public Class Methods

new(stdout = STDOUT, stdin = STDIN, options = {}) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 76
def initialize(stdout = STDOUT, stdin = STDIN, options = {})
  @stdout = stdout
  @stdin = stdin
  options.validate_options!(:assumeyes)
  @assumeyes = options.fetch(:assumeyes, false)
  @plaintext = options.fetch(:plaintext, false)
  @hl = HighLine.new(@stdin, @stdout)
  @max_length = 80
  @line_char = '-'
  @cell_char = '|'
  @spinner = Spinner.new(self)
  @spinner.start_spinner if @stdout.tty?
  @last_line = ''
  @select_option_counter = 0
end

Public Instance Methods

after_execution_finishes(execution) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 153
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
after_scenario_finishes(scenario) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 162
def after_scenario_finishes(scenario)
  scenario_failure_message(scenario)
  puts "\n"
  logger.info("=== Scenario '#{scenario.description || scenario.class}' finished ===")
end
ask(message, options = {}) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 123
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
ask_decision(message, actions_msg: 'y(yes), n(no), q(quit)', ignore_assumeyes: false, run_strategy: :fail_fast) click to toggle source

rubocop:disable Metrics/LineLength

# File lib/foreman_maintain/reporter/cli_reporter.rb, line 199
def ask_decision(message, actions_msg: 'y(yes), n(no), q(quit)', ignore_assumeyes: false, run_strategy: :fail_fast)
  actions_msg = 'y(yes), n(no)' if run_strategy == :fail_slow
  if !ignore_assumeyes && assumeyes?
    print("#{message} (assuming yes)\n")
    return :yes
  end
  until_valid_decision do
    filter_decision(ask("#{message}, [#{actions_msg}]"))
  end
ensure
  clear_line
end
ask_to_select(message, steps, run_strategy) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/foreman_maintain/reporter/cli_reporter.rb, line 223
def ask_to_select(message, steps, run_strategy)
  if assumeyes?
    step = steps[@select_option_counter]
    @select_option_counter += 1
    puts("(assuming option #{@select_option_counter})")
    return step
  end

  until_valid_decision do
    actions = run_strategy == :fail_slow ? 'n(next)' : 'n(next), q(quit)'
    answer = ask("#{message}, [#{actions}]")
    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
assumeyes?() click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 176
def assumeyes?
  @assumeyes
end
before_execution_starts(execution) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 98
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
before_scenario_starts(scenario) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 92
def before_scenario_starts(scenario)
  logger.info("=== Scenario '#{scenario.description || scenario.class}' started ===")
  puts "Running #{scenario.description || scenario.class}"
  hline('=')
end
clear_line() click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 168
def clear_line
  if plaintext?
    print "\n"
  else
    print "\r" + ' ' * @max_length + "\r"
  end
end
execution_info(execution, text) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 257
def execution_info(execution, text)
  prefix = "#{execution.name}:"
  "#{prefix} #{text}"
end
filter_decision(answer) click to toggle source

rubocop:enable Metrics/LineLength

# File lib/foreman_maintain/reporter/cli_reporter.rb, line 213
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
hline(line_char = @line_char) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 289
def hline(line_char = @line_char)
  puts line_char * @max_length
end
multiple_steps_decision(steps, run_strategy) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 190
def multiple_steps_decision(steps, run_strategy)
  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, run_strategy)
end
new_line_if_needed() click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 135
def new_line_if_needed
  if @new_line_next_time
    @stdout.print("\n")
    @stdout.flush
    @new_line_next_time = false
  end
end
print(string) click to toggle source
puts(string) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 111
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
puts_status(status) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 262
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
record_last_line(string) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 293
def record_last_line(string)
  @last_line = string.lines.to_a.last
end
single_step_decision(step, run_strategy) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 180
def single_step_decision(step, run_strategy)
  answer = ask_decision("Continue with step [#{step.runtime_message}]?",
                        run_strategy: run_strategy)
  if answer == :yes
    step
  else
    answer
  end
end
status_label(status) click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 273
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]
  if @plaintext
    properties[:label]
  else
    @hl.color(properties[:label], properties[:color], :bold)
  end
end
until_valid_decision() { |until decision| ... } click to toggle source

loop over the block until it returns some non-false value

# File lib/foreman_maintain/reporter/cli_reporter.rb, line 251
def until_valid_decision
  decision = nil
  decision = yield until decision
  decision
end
with_spinner(message) { |spinner| ... } click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 143
def with_spinner(message)
  new_line_if_needed
  @spinner.activate
  @spinner.update(message)
  yield @spinner
ensure
  @spinner.deactivate
  @new_line_next_time = true
end

Private Instance Methods

already_run_msg() click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 374
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
format_steps(steps, join_with = ', ', indent = 0) click to toggle source

rubocop:enable Metrics/MethodLength, Metrics/AbcSize

# File lib/foreman_maintain/reporter/cli_reporter.rb, line 370
def format_steps(steps, join_with = ', ', indent = 0)
  steps.map { |s| "#{' ' * indent}[#{s.label_dashed}]" }.join(join_with)
end
scenario_failure_message(scenario) click to toggle source

rubocop:disable Metrics/MethodLength, Metrics/AbcSize

# File lib/foreman_maintain/reporter/cli_reporter.rb, line 300
      def scenario_failure_message(scenario)
        return if scenario.passed? && !scenario.warning?

        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)
        steps_with_skipped = scenario.steps_with_skipped(:whitelisted => true)
        not_skippable_steps = scenario.steps_with_error.select do |step|
          step.metadata[:do_not_whitelist] == true
        end

        steps_to_whitelist = steps_with_error + steps_with_skipped - not_skippable_steps
        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_to_whitelist.map(&:label_dashed).join(',')
          unless whitelist_labels.empty?
            recommend << if scenario.detector.feature(:instance).downstream
                           format("              Resolve the failed steps and rerun the command.

              If the situation persists and, you are unclear what to do next,
              contact Red Hat Technical Support.

              In case the failures are false positives, use
              --whitelist="%s"
".strip_heredoc, whitelist_labels)
                         else
                           format("              Resolve the failed steps and rerun the command.
              In case the failures are false positives, use
              --whitelist="%s"
".strip_heredoc, whitelist_labels)
                         end
          end
        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