Class: Churn::ChurnCalculator

Inherits:
Object
  • Object
show all
Defined in:
lib/churn/churn_calculator.rb

Overview

The work horse of the the churn library. This class takes user input, determins the SCM the user is using. It then determines changes made during this revision. Finally it reads all the changes from previous revisions and displays human readable output to the command line. It can also ouput a yaml format readable by other tools such as metric_fu and Caliper.

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ ChurnCalculator

intialized the churn calculator object



25
26
27
28
29
30
31
32
33
# File 'lib/churn/churn_calculator.rb', line 25

def initialize(options={})
  start_date = options.fetch(:start_date) { '3 months ago' }
  @minimum_churn_count = options.fetch(:minimum_churn_count) { 5 }
  @source_control = set_source_control(start_date)
  @changes          = {}
  @revision_changes = {}
  @class_changes    = {}
  @method_changes   = {}
end

Instance Method Details

#analyzeObject

Analyze the source control data, filter, sort, and find more information on the editted files



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/churn/churn_calculator.rb', line 52

def analyze
  @changes = sort_changes(@changes)
  @changes = @changes.map {|file_path, times_changed| {:file_path => file_path, :times_changed => times_changed }}

  calculate_revision_changes

  @method_changes = sort_changes(@method_changes)
  @method_changes = @method_changes.map {|method, times_changed| {'method' => method, 'times_changed' => times_changed }}
  @class_changes  = sort_changes(@class_changes)
  @class_changes  = @class_changes.map {|klass, times_changed| {'klass' => klass, 'times_changed' => times_changed }}
end

#emitObject

Emits various data from source control to be analyses later… Currently this is broken up like this as a throwback to metric_fu



46
47
48
49
# File 'lib/churn/churn_calculator.rb', line 46

def emit
  @changes   = parse_log_for_changes.reject {|file, change_count| change_count < @minimum_churn_count}
  @revisions = parse_log_for_revision_changes  
end

#report(print = true) ⇒ Object

prepares the data for the given project to be reported. reads git/svn logs analyzes the output, generates a report and either formats as a nice string or returns hash.

Parameters:

  • format (Bolean)

    to return the data, true for string or false for hash

Returns:

  • (Object)

    returns either a pretty string or a hash representing the chrun of the project



39
40
41
42
43
# File 'lib/churn/churn_calculator.rb', line 39

def report(print = true)
  self.emit 
  self.analyze
  print ? self.to_s : self.to_h
end

#to_hObject

collect all the data into a single hash data structure.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/churn/churn_calculator.rb', line 65

def to_h
  hash                        = {:churn => {:changes => @changes}}
  hash[:churn][:class_churn]  = @class_changes
  hash[:churn][:method_churn] = @method_changes
  #detail the most recent changes made this revision
  first_revision         = @revisions.first
  first_revision_changes = @revision_changes[first_revision]
  if first_revision_changes
    changes = first_revision_changes
    hash[:churn][:changed_files]   = changes[:files]
    hash[:churn][:changed_classes] = changes[:classes]
    hash[:churn][:changed_methods] = changes[:methods]
  end
  #TODO crappy place to do this but save hash to revision file but while entirely under metric_fu only choice
  ChurnHistory.store_revision_history(first_revision, hash)
  hash
end

#to_sObject

Pretty print the data as a string for the user



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/churn/churn_calculator.rb', line 84

def to_s
  hash   = to_h[:churn]
  result = seperator 
  result +="* Revision Changes \n"
  result += seperator
  result += "Files: \n"
  result += display_array(hash[:changed_files], :fields=>[:to_str], :headers=>{:to_str=>'file'})
  result += "\nClasses: \n"
  result += display_array(hash[:changed_classes])
  result += "\nMethods: \n"
  result += display_array(hash[:changed_methods]) + "\n"
  result += seperator 
  result +="* Project Churn \n"
  result += seperator
  result += "Files: \n"
  result += display_array(hash[:changes])
  result += "\nClasses: \n"
  class_churn = collect_items(hash[:class_churn], 'klass')
  result += display_array(class_churn)
  result += "\nMethods: \n"
  method_churn = collect_items(hash[:method_churn], 'method')
  result += display_array(method_churn)
end