module Inch module CLI module Command module Output class Inspect < Base attr_reader :objects COLOR = :color198 # magenta-ish BG_COLOR = :color207 # magenta-ish LJUST = 20 def initialize(options, objects) @options = options @objects = objects display_objects end private def display_objects objects.each do |o| print_object(o) end end def print_object(o) ui.trace ui.header(o.fullname, COLOR, BG_COLOR) print_file_info(o, COLOR) print_code_info(o) print_namespace_info(o) print_roles_info(o) print_score_summary(o) end def print_score_summary(o) min = o.evaluation.min_score max = o.evaluation.max_score echo "Score (min: #{min}, max: #{max})".ljust(40) + "#{o.score}".rjust(5) + "#{o.priority.to_i}".rjust(4) echo end def print_code_info(o) if o.method? CommentAndAbbrevSource.new(o).lines.each do |line| echo line.gsub(/\n$/m, '').dark end echo separator end end def print_roles_info(o) if o.roles.empty? echo "No roles assigned.".dark else o.roles.each do |role| print_role_info(role) end end echo separator end def print_role_info(role) name = role.class.to_s.split('::Role::').last score = colored_role_score(role) priority = role.priority.to_s.rjust(4) if role.priority == 0 priority = priority.dark end echo name.ljust(40) + score + priority print_min_max_score(role) end def print_min_max_score(role) if role.max_score echo " (set max score to #{role.max_score})" elsif role.min_score echo " (set min score to #{role.min_score})" end end def print_namespace_info(o) if o.namespace? echo "Children:" o.children.each do |child| echo "+ " + child.fullname.color(COLOR) end echo separator end end def colored_role_score(role) if role.potential_score "(#{role.potential_score})".rjust(5).yellow.dark else value = role.score colored_score value, value.abs.to_s.rjust(4) end end def colored_score(value, score) if value < 0 ("-" + score).red elsif value > 0 ("+" + score).green else " " + score end end def echo(msg = "") ui.edged(COLOR, msg) end def separator "-".color(COLOR) * (CLI::COLUMNS - 2) end class CommentAndAbbrevSource < Struct.new(:code_object) extend Forwardable def_delegators :code_object, :source, :files def lines to_s.lines end def to_s comments.join('') + abbrev_source end private def abbrev_source lines = code_object.source.to_s.lines.to_a if lines.size >= 5 indent = lines[1].scan(/^(\s+)/).flatten.join('') lines = lines[0..1] + ["#{indent}# ... snip ...\n"] + lines[-2..-1] end lines.join('') end def comments @comments ||= code_object.files.map do |declaration| get_lines_up_while(declaration.filename, declaration.line_no - 1) do |line| line =~ /^\s*#/ end.flatten.join('') end end def get_lines_up_while(filename, line_no, &block) lines = [] line = get_line_no(filename, line_no) if yield(line) && line_no > 0 lines << line.gsub(/^(\s+)/, '') lines << get_lines_up_while(filename, line_no - 1, &block) end lines.reverse end # Returns a +line_number+ from a file # # @param filename [String] # @param line_number [Fixnum] # @return [String] def get_line_no(filename, line_number) f = File.open(filename) line_number.times{f.gets} result = $_ f.close result end end end end end end end