lib/tailor/critic.rb in tailor-1.0.0.alpha2 vs lib/tailor/critic.rb in tailor-1.0.0

- old
+ new

@@ -1,162 +1,112 @@ -require 'erb' -require 'yaml' -require 'fileutils' -require_relative 'configuration' require_relative 'lexer' require_relative 'logger' require_relative 'ruler' require_relative 'rulers' -require_relative 'runtime_error' class Tailor + + # An object of this type provides for starting the process of critiquing + # files. It handles initializing the Ruler objects it needs based on the + # configuration given to it. class Critic include Tailor::Logger::Mixin include Tailor::Rulers - RULER_OBSERVERS = { - spaces_before_lbrace: [:add_lbrace_observer], - spaces_after_lbrace: [ - :add_comment_observer, - :add_ignored_nl_observer, - :add_lbrace_observer, - :add_nl_observer - ], - spaces_before_rbrace: [ - :add_embexpr_beg_observer, - :add_lbrace_observer, - :add_rbrace_observer - ], - spaces_after_lbracket: [ - :add_comment_observer, - :add_ignored_nl_observer, - :add_lbracket_observer, - :add_nl_observer - ], - spaces_before_rbracket: [:add_rbracket_observer], - spaces_after_lparen: [ - :add_comment_observer, - :add_ignored_nl_observer, - :add_lparen_observer, - :add_nl_observer - ], - spaces_before_rparen: [:add_rparen_observer], - spaces_in_empty_braces: [ - :add_embexpr_beg_observer, - :add_lbrace_observer, - :add_rbrace_observer - ], - spaces_before_comma: [ - :add_comma_observer, - :add_comment_observer, - :add_ignored_nl_observer, - :add_nl_observer - ], - spaces_after_comma: [ - :add_comma_observer, - :add_comment_observer, - :add_ignored_nl_observer, - :add_nl_observer - ], - max_line_length: [:add_ignored_nl_observer, :add_nl_observer], - indentation_spaces: [ - :add_comment_observer, - :add_embexpr_beg_observer, - :add_embexpr_end_observer, - :add_ignored_nl_observer, - :add_kw_observer, - :add_lbrace_observer, - :add_lbracket_observer, - :add_lparen_observer, - :add_nl_observer, - :add_rbrace_observer, - :add_rbracket_observer, - :add_rparen_observer, - :add_tstring_beg_observer, - :add_tstring_end_observer - ], - allow_trailing_line_spaces: [:add_ignored_nl_observer, :add_nl_observer], - allow_hard_tabs: [:add_sp_observer], - allow_camel_case_methods: [:add_ident_observer], - allow_screaming_snake_case_classes: [:add_const_observer], - max_code_lines_in_class: [ - :add_ignored_nl_observer, - :add_kw_observer, - :add_nl_observer - ], - max_code_lines_in_method: [ - :add_ignored_nl_observer, - :add_kw_observer, - :add_nl_observer - ], - trailing_newlines: [:add_file_observer] - } + # The instance method that starts the process of looking for problems in + # files. It checks for problems in each file in each file set. It yields + # the problems found and the label they were found for. + # + # @param [Hash] file_sets The file sets to critique. + # @yieldparam [Hash] problems The problems found for the label. + # @yieldparam [Symbol] label The label the problems were found for. + def critique(file_sets) + log "file sets keys: #{file_sets.keys}" - def initialize(configuration) - @file_sets = configuration - end - - def critique - log "file sets keys: #{@file_sets.keys}" - @file_sets.each do |label, file_set| + file_sets.each do |label, file_set| log "Critiquing file_set: #{file_set}" file_set[:file_list].each do |file| log "Critiquing file: #{file}" - problems = check_file(file, file_set[:style]) + + begin + problems = check_file(file, file_set[:style]) + rescue => ex + $stderr.puts "Error while parsing file #{file}" + raise(ex) + end + yield [problems, label] if block_given? end end end - def init_rulers(style, lexer, parent_ruler) - style.each do |ruler_name, value| - ruler = - instance_eval( - "Tailor::Rulers::#{camelize(ruler_name.to_s)}Ruler.new(#{value})" - ) - parent_ruler.add_child_ruler(ruler) - RULER_OBSERVERS[ruler_name].each do |observer| - log "Adding #{observer} to lexer..." - lexer.send(observer, ruler) - end - end + # @return [Hash] + def problems + @problems ||= {} end - # Converts a snake-case String to a camel-case String. - # - # @param [String] string The String to convert. - # @return [String] The converted String. - def camelize(string) - string.split(/_/).map { |word| word.capitalize }.join + # @return [Fixnum] The number of problems found so far. + def problem_count + problems.values.flatten.size end - # Adds problems found from Lexing to the {problems} list. + # Adds problems found from Lexing to the +#problems+ list. # # @param [String] file The file to open, read, and check. # @return [Hash] The Problems for that file. def check_file(file, style) log "<#{self.class}> Checking style of file: #{file}." lexer = Tailor::Lexer.new(file) ruler = Ruler.new - log "Style: #{style}" + log "Style:" + style.each { |property, values| log "#{property}: #{values}" } init_rulers(style, lexer, ruler) lexer.lex - lexer.check_added_newline problems[file] = ruler.problems { file => problems[file] } end - # @return [Hash] - def problems - @problems ||= {} + private + + # Creates Rulers for each ruler given in +style+ and adds the Ruler's + # defined observers to the given +lexer+. + # + # @param [Hash] style The Hash that defines the style to be measured + # against. + # @param [Tailor::Lexer] lexer The Lexer object the Rulers should observe. + # @param [Tailor::Ruler] parent_ruler The main Ruler to add the child + # Rulers to. + def init_rulers(style, lexer, parent_ruler) + style.each do |ruler_name, values| + ruler = "Tailor::Rulers::#{camelize(ruler_name.to_s)}Ruler" + + if values.last[:level] == :off || values.last[:level] == "off" + msg = "Style option set to '#{values.last[:level]}'; " + log msg << "skipping init of '#{ruler}'" + next + end + + log "Initializing ruler: #{ruler}" + ruler = instance_eval("#{ruler}.new(#{values.first}, #{values.last})") + parent_ruler.add_child_ruler(ruler) + + ruler.lexer_observers.each do |observer| + log "Adding #{observer} to lexer..." + meth = "add_#{observer}_observer".to_sym + lexer.send(meth, ruler) + end + end end - # @return [Fixnum] The number of problems found so far. - def problem_count - problems.values.flatten.size + # Converts a snake-case String to a camel-case String. + # + # @param [String] string The String to convert. + # @return [String] The converted String. + def camelize(string) + string.split(/_/).map { |word| word.capitalize }.join end end end