From 22456374556172cee16386e535e9879c5a4c225c Mon Sep 17 00:00:00 2001 From: James Coglan Date: Thu, 19 Mar 2009 16:49:11 +0000 Subject: [PATCH] Include modules in code statistics, and do a better job of counting reopened and nested namespaces. --- railties/lib/code_statistics.rb | 32 ++++++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 8 deletions(-) diff --git a/railties/lib/code_statistics.rb b/railties/lib/code_statistics.rb index 740d8a1..9e6ed29 100644 --- a/railties/lib/code_statistics.rb +++ b/railties/lib/code_statistics.rb @@ -26,32 +26,47 @@ class CodeStatistics #:nodoc: @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 } + def calculate_directory_statistics(directory, pattern = /.*\.rb$/, klasses = nil) + stats = { "lines" => 0, "codelines" => 0, "modules" => 0, "classes" => 0, "methods" => 0 } + klasses ||= { "modules" => [], "classes" => [] } Dir.foreach(directory) do |file_name| if File.stat(directory + "/" + file_name).directory? and (/^\./ !~ file_name) - newstats = calculate_directory_statistics(directory + "/" + file_name, pattern) + newstats = calculate_directory_statistics(directory + "/" + file_name, pattern, klasses) stats.each { |k, v| stats[k] += newstats[k] } end next unless file_name =~ pattern f = File.open(directory + "/" + file_name) + namespaces = [] while line = f.gets + namespaces << [$3, $1, $2] if line =~ /^(\s*)(module|class)\s+([A-Z][^\s]*)/ 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*#/ end + + file_klasses = { "module" => [], "class" => [] } + namespaces.inject([]) do |stack, klass| + stack.pop while not stack.empty? and stack.last[1].length >= klass[1].length + stack << klass + name = stack.map { |ns| ns.first } * "::" + file_klasses[klass[2]] << name + stack + end + + klasses["modules"] = (klasses["modules"] + file_klasses["module"]).uniq + klasses["classes"] = (klasses["classes"] + file_klasses["class"]).uniq end + %w(modules classes).each { |ns| stats[ns] = klasses[ns].size } stats end def calculate_total - total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 } + total = { "lines" => 0, "codelines" => 0, "modules" => 0, "classes" => 0, "methods" => 0 } @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } } total end @@ -70,16 +85,16 @@ class CodeStatistics #:nodoc: def print_header print_splitter - puts "| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |" + puts "| Name | Lines | LOC | Modules | Classes | Methods | M/C | LOC/M |" print_splitter end def print_splitter - puts "+----------------------+-------+-------+---------+---------+-----+-------+" + puts "+----------------------+-------+-------+---------+---------+---------+-----+-------+" end def print_line(name, statistics) - m_over_c = (statistics["methods"] / statistics["classes"]) rescue m_over_c = 0 + m_over_c = (statistics["methods"] / (statistics["modules"] + statistics["classes"])) rescue m_over_c = 0 loc_over_m = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0 start = if TEST_TYPES.include? name @@ -91,6 +106,7 @@ class CodeStatistics #:nodoc: puts start + "| #{statistics["lines"].to_s.rjust(5)} " + "| #{statistics["codelines"].to_s.rjust(5)} " + + "| #{statistics["modules"].to_s.rjust(7)} " + "| #{statistics["classes"].to_s.rjust(7)} " + "| #{statistics["methods"].to_s.rjust(7)} " + "| #{m_over_c.to_s.rjust(3)} " + -- 1.5.6.3