lib/rubocop/formatter/pacman_formatter.rb
# 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("%<line>s\r", line: @progress_line)
return unless /ᗣ|\./.match?(@progress_line[-1])
@repetitions += 1
output.puts
update_progress_line
end
end
end
end