Class: Churn::ChurnCalculator

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

Overview

The work horse of the the churn library. This class takes user input, determines 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 on the command line. It can also output a yaml format readable by other tools such as metric_fu and Caliper.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ ChurnCalculator

intialize the churn calculator object



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/churn/calculator.rb', line 32

def initialize(options={})
  @churn_options = ChurnOptions.new.set_options(options)

  @minimum_churn_count = @churn_options.minimum_churn_count
  @ignores             = @churn_options.ignores
  @source_control      = SourceControl.set_source_control(@churn_options.start_date)

  @changes          = {}
  @revision_changes = {}
  @class_changes    = {}
  @method_changes   = {}
end

Class Method Details

.to_s(hash) ⇒ Object

Pretty print the data as a string for the user



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/churn/calculator.rb', line 127

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

Instance Method Details

#analyzeObject

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



90
91
92
93
94
95
96
97
98
99
100
# File 'lib/churn/calculator.rb', line 90

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 analyzed later… Currently this is broken up like this as a throwback to metric_fu



83
84
85
86
# File 'lib/churn/calculator.rb', line 83

def emit
  @changes   = reject_ignored_files(reject_low_churn_files(parse_log_for_changes))
  @revisions = parse_log_for_revision_changes
end

#generate_historyObject

this method generates the past history of a churn project from first commit to current running the report for oldest commits first so they are built up correctly



75
76
77
78
79
# File 'lib/churn/calculator.rb', line 75

def generate_history
  history_starting_point = Chronic.parse(@churn_options.history)
  @source_control.generate_history(history_starting_point)
  "churn history complete, this has manipulated your source control system so please make sure you are back on HEAD where you expect to be"
end

#remote_reportObject



62
63
64
65
66
67
68
69
70
# File 'lib/churn/calculator.rb', line 62

def remote_report
  if @churn_options.report_host
    puts "posting churn results to #{@churn_options.report_host}"
    data = {:name => @churn_options.name, :revision => @revisions.first, :data => self.to_h}.to_json
    RestClient.post @churn_options.report_host, {"results" => data}, :content_type => :json, :accept => :json
  end
rescue Errno::ECONNREFUSED
  puts "error posting churn results connection refused to host: #{@churn_options.report_host}"
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. churn of the project

Parameters:

  • format (Boolean)

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

Returns:

  • (Object)

    returns either a pretty string or a hash representing the



51
52
53
54
55
56
57
58
59
60
# File 'lib/churn/calculator.rb', line 51

def report(print = true)
  if @churn_options.history
    generate_history
  else
    emit
    analyze
    remote_report
    print ? self.to_s : self.to_h
  end
end

#to_hObject

collect all the data into a single hash data structure.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/churn/calculator.rb', line 103

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, @churn_options.data_directory)
  hash
end

#to_sObject



122
123
124
# File 'lib/churn/calculator.rb', line 122

def to_s
  ChurnCalculator.to_s(to_h[:churn])
end