require 'pathname' require 'term/ansicolor' require_relative '../formatter' class Tailor module Formatters class Text < Tailor::Formatter include Term::ANSIColor PROBLEM_LEVEL_COLORS = { error: 'red', warn: 'yellow' } # @return [String] A line of "#----#-", with length determined by +length+. def line(length=78) "##{'-' * length}#\n" end # @return [String] The portion of the header that displays the file info. def file_header(file) file = Pathname(file) message = "# " message << underscore { "File:\n" } message << "# #{file.relative_path_from(@pwd)}\n" message << "#\n" message end # @return [String] The portion of the header that displays the file_set # label info. def file_set_header(file_set) message = "# " message << underscore { "File Set:\n" } message << "# #{file_set}\n" message << "#\n" message end # @return [String] The portion of the report that displays all of the # problems for the file. def problems_header(problem_list) message = "# " message << underscore { "Problems:\n" } problem_list.each_with_index do |problem, i| color = PROBLEM_LEVEL_COLORS[problem[:level]] || 'white' position = position(problem[:line], problem[:column]) message << "# " + bold { "#{(i + 1)}." } + "\n" message << "# * position: " message << bold { instance_eval("#{color} position") } + "\n" message << "# * property: " message << instance_eval("#{color} problem[:type].to_s") + "\n" message << "# * message: " message << instance_eval("#{color} problem[:message].to_s") + "\n" end message end # @param [Fixnum] line # @param [Fixnum] column # @return [String] The position the problem was found at. def position(line, column) line == '' ? '' : "#{line}:#{column}" end # Prints the report on the file that just got checked. # # @param [Hash] problems Value should be the file name; keys should be # problems with the file. def file_report(problems, file_set_label) return if problems.values.first.empty? file = problems.keys.first problem_list = problems.values.first message = line message << file_header(file) message << file_set_header(file_set_label) message << problems_header(problem_list) message << "#\n" message << line puts message end MAX_STRING_SIZE = 68 # Prints the report on all of the files that just got checked. # # @param [Hash] problems Values are filenames; keys are problems for each # of those files. def summary_report(problems) summary_table = summary_header i = 0 problems.each do |file, problem_list| report_line = summary_file_line(file, problem_list) report_line = if i % 2 == 1 on_intense_black { report_line } else bold { report_line } end summary_table << "# " << report_line << reset << "|\n" i += 1 end summary_table << line summary_table << summary_level_totals(problems) summary_table << "# " << bold{ summary_first_col('TOTAL', 67) } summary_table << "|" summary_table << bold { total_problems(problems).to_s.rjust(6) } summary_table << " |\n" summary_table << line puts summary_table end def summary_header summary_table = line summary_table << "# " summary_table << bold { 'Tailor Summary'.rjust(40) } summary_table << "|\n".rjust(39) summary_table << line summary_table << '# ' << summary_first_col('File', 67) + '| ' summary_table << 'Probs'.rjust(1) summary_table << " |\n".rjust(2) summary_table << line summary_table end def summary_file_line(file, problem_list) file = Pathname(file) relative_path = file.relative_path_from(@pwd) problem_count = problem_list.size "#{summary_first_col(relative_path)} | " + problem_count.to_s.rjust(5) + " " end def summary_first_col(path, string_size=MAX_STRING_SIZE) fp = path.to_s.ljust(string_size) offset = fp.size - string_size end_of_string = fp[offset..-1] end_of_string.sub!(/^.{3}/, '...') unless offset.zero? end_of_string end def summary_level_totals(problems) return "" if total_problems(problems).zero? output = problem_levels(problems).inject("") do |result, level| color = PROBLEM_LEVEL_COLORS[level] || 'white' result << "# " result << instance_eval("#{color} { summary_first_col(level.capitalize, 67) }") result << "|" result << instance_eval("#{color} { problems_at_level(problems, level).size.to_s.rjust(6) }") result << " |\n" end output << line output end def total_problems(problems) problems.values.flatten.size end end end end