class MetricFu::ReekGenerator

Public Class Methods

metric() click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 3
def self.metric
  :reek
end

Public Instance Methods

analyze() click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 26
def analyze
  @matches = @output.group_by(&:source).collect do |file_path, smells|
    { file_path: file_path,
      code_smells: analyze_smells(smells) }
  end
  @total = []
  @total << "Detected #{@matches.size} files"
  @total << "Found #{@matches.sum { |m| m[:code_smells].size }} code smells"
end
emit() click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 7
def emit
  files = files_to_analyze
  if files.empty?
    mf_log "Skipping Reek, no files found to analyze"
    @output = run!([], config_files)
  else
    @output = run!(files, config_files)
  end
end
per_file_info(out) click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 40
def per_file_info(out)
  @matches.each do |file_data|
    file_path = file_data[:file_path]
    next if File.extname(file_path) =~ /\.erb|\.html|\.haml/
    begin
      line_numbers = MetricFu::LineNumbers.new(File.read(file_path), file_path)
    rescue StandardError => e
      raise e unless e.message =~ /you shouldn't be able to get here/
      mf_log "ruby_parser blew up while trying to parse #{file_path}. You won't have method level reek information for this file."
      next
    end

    file_data[:code_smells].each do |smell_data|
      line = line_numbers.start_line_for_method(smell_data[:method])
      out[file_data[:file_path]][line.to_s] << { type: :reek,
                                                 description: "#{smell_data[:type]} - #{smell_data[:message]}" }
    end
  end
end
run!(files, config_files) click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 17
def run!(files, config_files)
  smells = []
  files.each do |file|
    e = examiner.new(File.new(file))
    smells += e.smells
  end
  smells
end
to_h() click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 36
def to_h
  { reek: { matches: @matches, total: @total } }
end

Private Instance Methods

analyze_smells(smells) click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 73
def analyze_smells(smells)
  smells.collect(&method(:smell_data))
end
config_files() click to toggle source

TODO: Check that specified line config file exists

# File lib/metric_fu/metrics/reek/generator.rb, line 69
def config_files
  Array(options[:config_file_pattern])
end
examiner() click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 90
def examiner
  require "reek"
  # To load any changing dependencies such as "reek/configuration/app_configuration"
  #   Added in 1.6.0 https://github.com/troessner/reek/commit/7f4ed2be442ca926e08ccc41945e909e8f710947
  #   But not always loaded
  require "reek/cli/application"

  Reek.const_defined?(:Examiner) ? Reek.const_get(:Examiner) : Reek.const_get(:Core).const_get(:Examiner)
end
files_to_analyze() click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 62
def files_to_analyze
  dirs_to_reek = options[:dirs_to_reek]
  files_to_reek = dirs_to_reek.map { |dir| Dir[File.join(dir, "**", "*.rb")] }.flatten
  remove_excluded_files(files_to_reek)
end
smell_data(smell) click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 77
def smell_data(smell)
  { method: smell.context,
    message: smell.message,
    type: smell_type(smell),
    lines: smell.lines }
end
smell_type(smell) click to toggle source
# File lib/metric_fu/metrics/reek/generator.rb, line 84
def smell_type(smell)
  return smell.subclass if smell.respond_to?(:subclass)

  smell.smell_type
end