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 75 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 152 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 161 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 122 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 /\s\Z/.match?(message) answer = @hl.ask(message) { |q| q.echo = false if options[:password] } answer&.to_s&.chomp 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 198 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 222 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 175 def assumeyes? @assumeyes end
before_execution_starts(execution)
click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 97 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 91 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 167 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 256 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 212 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 189 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 134 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
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 103 def print(string) new_line_if_needed @stdout.print(string) @stdout.flush record_last_line(string) end
puts(string)
click to toggle source
# File lib/foreman_maintain/reporter/cli_reporter.rb, line 110 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 261 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 179 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 272 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 }, :info_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 250 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 142 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 << <<~MESSAGE Scenario [#{scenario.description}] failed. MESSAGE recommend = [] steps_with_abort = scenario.steps_with_abort(:whitelisted => false) unless steps_with_abort.empty? message << format(<<~MESSAGE, format_steps(steps_with_abort, "\n", 2)) The processing was aborted by user during the following steps: %s MESSAGE 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(<<~MESSAGE, format_steps(steps_with_error, "\n", 2)) The following steps ended up in failing state: %s MESSAGE whitelist_labels = steps_to_whitelist.map(&:label_dashed).join(',') unless whitelist_labels.empty? recommend << if scenario.detector.feature(:instance).downstream format(<<~MESSAGE) Resolve the failed steps and rerun the command. If the situation persists and, you are unclear what to do next, contact #{scenario.detector.feature(:instance).project_support_entity}. In case the failures are false positives, use --whitelist="#{whitelist_labels}" MESSAGE else format(<<~MESSAGE) Resolve the failed steps and rerun the command. In case the failures are false positives, use --whitelist="#{whitelist_labels}" MESSAGE end end end steps_with_warning = scenario.steps_with_warning(:whitelisted => false) unless steps_with_warning.empty? message << format(<<~MESSAGE, format_steps(steps_with_warning, "\n", 2)) The following steps ended up in warning state: %s MESSAGE recommend << <<~MESSAGE The steps in warning state itself might not mean there is an error, but it should be reviewed to ensure the behavior is expected MESSAGE end puts((message + recommend).join("\n")) end