class Attractor::BaseCalculator

calculates churn and complexity

Attributes

type[R]

Public Class Methods

new(file_prefix: "", ignores: "", file_extension: "rb", minimum_churn_count: 3, start_ago: "5y") click to toggle source
# File lib/attractor/calculators/base_calculator.rb, line 12
def initialize(file_prefix: "", ignores: "", file_extension: "rb", minimum_churn_count: 3, start_ago: "5y")
  @file_prefix = file_prefix
  @file_extension = file_extension
  @minimum_churn_count = minimum_churn_count
  @start_date = Date.today - Attractor::DurationParser.new(start_ago).duration
  @ignores = ignores
end

Public Instance Methods

calculate() { |change| ... } click to toggle source
# File lib/attractor/calculators/base_calculator.rb, line 20
def calculate
  churn = ::Churn::ChurnCalculator.new(
    file_extension: @file_extension,
    file_prefix: @file_prefix,
    minimum_churn_count: @minimum_churn_count,
    start_date: @start_date,
    ignores: @ignores
  ).report(false)

  puts "Calculating churn and complexity values for #{churn[:churn][:changes].size} #{type} files"

  values = churn[:churn][:changes].map do |change|
    history = git_history_for_file(file_path: change[:file_path])
    commit = history&.first&.first

    cached_value = Cache.read(file_path: change[:file_path])

    if !cached_value.nil? && !cached_value.current_commit.nil? && cached_value.current_commit == commit
      value = cached_value
    else
      complexity, details = yield(change)

      value = Value.new(file_path: change[:file_path],
                        churn: change[:times_changed],
                        complexity: complexity,
                        details: details,
                        history: history)
      Cache.write(file_path: change[:file_path], value: value)
    end

    print "."
    value
  end

  Cache.persist!

  print "\n\n"

  values
end

Private Instance Methods

git_history_for_file(file_path:, limit: 10) click to toggle source
# File lib/attractor/calculators/base_calculator.rb, line 63
def git_history_for_file(file_path:, limit: 10)
  history = `git log --oneline -n #{limit} -- #{file_path}`
  history.split("\n")
    .map do |log_entry|
    log_entry.partition(/\A(\S+)\s/)
      .map(&:strip)
      .reject(&:empty?)
  end
end