# frozen_string_literal: true module RuboCop module Formatter # This formatter prints a PACDOT per every file to be analyzed. # Pacman will "eat" one PACDOT per file when no offense is detected. # Otherwise it will print a Ghost. # This is inspired by the Pacman formatter for RSpec by Carlos Rojas. # https://github.com/go-labs/rspec_pacman_formatter class PacmanFormatter < ClangStyleFormatter include TextUtil attr_accessor :progress_line FALLBACK_TERMINAL_WIDTH = 80 GHOST = 'ᗣ' PACMAN = Rainbow('ᗧ').yellow.bright PACDOT = Rainbow('•').yellow.bright def initialize(output, options = {}) super @progress_line = '' @total_files = 0 @repetitions = 0 end def started(target_files) super @total_files = target_files.size output.puts "Eating #{pluralize(target_files.size, 'file')}" update_progress_line end def file_started(_file, _options) step(PACMAN) end def file_finished(file, offenses) count_stats(offenses) unless offenses.empty? next_step(offenses) report_file(file, offenses) end def next_step(offenses) return step('.') if offenses.empty? ghost_color = COLOR_FOR_SEVERITY[offenses.last.severity.name] step(colorize(GHOST, ghost_color)) end def cols @cols ||= begin _height, width = $stdout.winsize width.nil? || width.zero? ? FALLBACK_TERMINAL_WIDTH : width end end def update_progress_line return pacdots(@total_files) unless @total_files > cols return pacdots(cols) unless (@total_files / cols).eql?(@repetitions) pacdots((@total_files - (cols * @repetitions))) end def pacdots(number) @progress_line = PACDOT * number end def step(character) regex = /#{Regexp.quote(PACMAN)}|#{Regexp.quote(PACDOT)}/ @progress_line = @progress_line.sub(regex, character) output.printf("%s\r", line: @progress_line) return unless @progress_line[-1] =~ /ᗣ|\./ @repetitions += 1 output.puts update_progress_line end end end end