Created
February 12, 2014 08:51
-
-
Save TimLang/8952038 to your computer and use it in GitHub Desktop.
Code statistics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ruby code_statistics.rb [<source dir> <test or spec dir>] | |
| class CodeStatistics | |
| def initialize(src, test) | |
| @pairs = [ | |
| ["Codes",src + "/"], | |
| ["Tests",test + "/"] | |
| ].collect { |name, dir| [ name, "#{dir}" ] }.select { |name, dir| File.directory?(dir) } | |
| @statistics = calculate_statistics | |
| @total = calculate_total if @pairs.length > 1 | |
| end | |
| def to_s | |
| print_header | |
| @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) } | |
| print_splitter | |
| if @total | |
| print_line("Total", @total) | |
| print_splitter | |
| end | |
| print_code_test_stats | |
| end | |
| private | |
| def calculate_statistics | |
| @pairs.inject({}) { |stats, pair| stats[pair.first] = calculate_directory_statistics(pair.last); stats } | |
| end | |
| def calculate_directory_statistics(directory, pattern = /.*\.rb$/) | |
| stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0, "comments" => 0} | |
| Dir.foreach(directory) do |file_name| | |
| if File.stat(directory + "/" + file_name).directory? and (/^\./ !~ file_name) | |
| newstats = calculate_directory_statistics(directory + "/" + file_name, pattern) | |
| stats.each { |k, v| stats[k] += newstats[k] } | |
| end | |
| next unless file_name =~ pattern | |
| f = File.open(directory + "/" + file_name) | |
| while line = f.gets | |
| stats["lines"] += 1 | |
| stats["classes"] += 1 if line =~ /class [A-Z]/ | |
| stats["methods"] += 1 if line =~ /def [a-z]/ | |
| stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/ | |
| stats["comments"] += 1 if line =~ /^\s*#/ || line =~ /^.*#/ | |
| end | |
| end | |
| stats | |
| end | |
| def calculate_total | |
| total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0, "comments" => 0 } | |
| @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } } | |
| total | |
| end | |
| def calculate_code | |
| code_loc = 0 | |
| @statistics.each { |k, v| code_loc += v['codelines'] unless k == "Tests" } | |
| code_loc | |
| end | |
| def calculate_tests | |
| test_loc = 0 | |
| @statistics.each { |k, v| test_loc += v['codelines'] if k == "Tests" } | |
| test_loc | |
| end | |
| def calculate_comments | |
| comments = 0 | |
| @statistics.each { |k, v| comments += v['comments']} | |
| comments | |
| end | |
| def print_header | |
| print_splitter | |
| puts "| Name | Lines | LOC | Classes | Methods | Comments | M/C | LOC/M | Cm/LOC |" | |
| print_splitter | |
| end | |
| def print_splitter | |
| puts "+-------+-------+-------+---------+---------+----------+-----+-------+--------|" | |
| end | |
| def print_line(name, statistics) | |
| m_over_c = (statistics["methods"] / statistics["classes"]) rescue m_over_c = 0 | |
| loc_over_m = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0 | |
| cm_over_loc = (statistics["comments"].to_f / statistics["codelines"]) rescue cm_over_loc = 0.0 | |
| start = "| #{name.ljust(5)} " | |
| puts start + | |
| "| #{statistics["lines"].to_s.rjust(5)} " + | |
| "| #{statistics["codelines"].to_s.rjust(5)} " + | |
| "| #{statistics["classes"].to_s.rjust(7)} " + | |
| "| #{statistics["methods"].to_s.rjust(7)} " + | |
| "| #{statistics["comments"].to_s.rjust(8)} " + | |
| "| #{m_over_c.to_s.rjust(3)} " + | |
| "| #{loc_over_m.to_s.rjust(5)} " + | |
| "| #{sprintf("%.2f", cm_over_loc.to_s)} |" | |
| end | |
| def print_code_test_stats | |
| code = calculate_code | |
| tests = calculate_tests | |
| commnets = calculate_comments | |
| puts " Code LOC: #{code} Test LOC: #{tests} Code:Test = 1:#{sprintf("%.1f", tests.to_f/code)} LOC:Comments = 1:#{sprintf("%.1f", commnets.to_f/(code + tests))}" | |
| puts "" | |
| end | |
| end | |
| unless ARGV[0].nil? && ARGV[1].nil? | |
| CodeStatistics.new(ARGV[0], ARGV[1]).to_s | |
| else | |
| CodeStatistics.new("src", "test").to_s | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment