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 on the command line. It can also ouput a yaml format readable by other tools such as metric_fu and Caliper.
intialized the churn calculator object
# File lib/churn/calculator.rb, line 30 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
Pretty print the data as a string for the user
# File lib/churn/calculator.rb, line 135 def self.to_s(hash) result = seperator result +="* Revision Changes \n" result += seperator 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 += seperator result +="* Project Churn \n" result += seperator 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
Analyze the source control data, filter, sort, and find more information on the editted files
# File lib/churn/calculator.rb, line 99 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
Emits various data from source control to be analyses later… Currently this is broken up like this as a throwback to metric_fu
# File lib/churn/calculator.rb, line 93 def emit @changes = parse_log_for_changes.reject {|file, change_count| change_count < @minimum_churn_count || @ignores.any?{ |ignore| file.match(/#{ignore}/) } } @revisions = parse_log_for_revision_changes end
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
# File lib/churn/calculator.rb, line 70 def generate_history if @source_control.is_a?(GitAnalyzer) begin history_starting_point = Chronic.parse(@churn_options.history) @source_control.get_commit_history.each do |commit| %xgit checkout #{commit}` commit_date = %xgit show -s --format="%ci"` commit_date = Time.parse(commit_date) next if commit_date < history_starting_point #7776000 == 3.months without adding active support depenancy start_date = (commit_date - 7776000) %xchurn -s "#{start_date}"` end ensure %xgit checkout master` end "churn history complete, this has munipulated git please make sure you are back on HEAD where you expect to be" else raise "currently generate history only supports git" end end
# File lib/churn/calculator.rb, line 58 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
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. @param [Bolean] format to return the data, true for string or false for hash @return [Object] returns either a pretty string or a hash representing the chrun of the project
# File lib/churn/calculator.rb, line 47 def report(print = true) if @churn_options.history generate_history else emit analyze remote_report print ? self.to_s : self.to_h end end
collect all the data into a single hash data structure.
# File lib/churn/calculator.rb, line 112 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
# File lib/churn/calculator.rb, line 130 def to_s ChurnCalculator.to_s(to_h[:churn]) end