diff options
author | Kornelius Kalnbach <murphy@rubychan.de> | 2016-02-13 16:12:48 +0100 |
---|---|---|
committer | Kornelius Kalnbach <murphy@rubychan.de> | 2016-02-13 16:12:48 +0100 |
commit | 0b8c69cfb7a65bec04c44e58e5776e323d2aa1af (patch) | |
tree | fd81bf6229bfc0d173f5b744534a76b5c70eb440 /rake_tasks/code_statistics.rb | |
parent | 916711c9983483c39f9a68c29e21a0ed40004bd2 (diff) | |
parent | 0a1f500d524ff0fb5eeafef051ccbb641954a87a (diff) | |
download | coderay-paint-integration.tar.gz |
Merge branch 'master' into paint-integrationpaint-integration
Diffstat (limited to 'rake_tasks/code_statistics.rb')
-rw-r--r-- | rake_tasks/code_statistics.rb | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/rake_tasks/code_statistics.rb b/rake_tasks/code_statistics.rb new file mode 100644 index 0000000..0a2016b --- /dev/null +++ b/rake_tasks/code_statistics.rb @@ -0,0 +1,171 @@ +# From rails (http://rubyonrails.com) +# +# Improved by murphy +class CodeStatistics + + TEST_TYPES = /\btest/i + + # Create a new Code Statistic. + # + # Rakefile Example: + # + # desc 'Report code statistics (LOC) from the application' + # task :stats => :copy_files do + # require 'rake_helpers/code_statistics' + # CodeStatistics.new( + # ["Main", "lib"], + # ["Tests", "test"], + # ["Demos", "demo"] + # ).to_s + # end + def initialize(*pairs) + @pairs = pairs + @statistics = calculate_statistics + @total = if pairs.empty? then nil else calculate_total end + end + + # Print a textual table viewing the stats + # + # Intended for console output. + def print + print_header + @pairs.each { |name, path| print_line name, @statistics[name] } + print_splitter + + if @total + print_line 'Total', @total + print_splitter + end + + print_code_test_stats + end + +private + + DEFAULT_FILE_PATTERN = /\.rb$/ + + def calculate_statistics + @pairs.inject({}) do |stats, (name, path, pattern, is_ruby_code)| + pattern ||= DEFAULT_FILE_PATTERN + path = File.join path, '*.rb' + stats[name] = calculate_directory_statistics path, pattern, is_ruby_code + stats + end + end + + def calculate_directory_statistics directory, pattern = DEFAULT_FILE_PATTERN, is_ruby_code = true + is_ruby_code = true if is_ruby_code.nil? + stats = Hash.new 0 + + Dir[directory].each do |file_name| + p "Scanning #{file_name}..." if $VERBOSE + next unless file_name =~ pattern + + lines = codelines = classes = modules = methods = 0 + empty_lines = comment_lines = 0 + in_comment_block = false + + File.readlines(file_name).each do |line| + lines += 1 + if line[/^\s*$/] + empty_lines += 1 + elsif is_ruby_code + case line + when /^=end\b/ + comment_lines += 1 + in_comment_block = false + when in_comment_block + comment_lines += 1 + when /^\s*class\b/ + classes += 1 + when /^\s*module\b/ + modules += 1 + when /^\s*def\b/ + methods += 1 + when /^\s*#/ + comment_lines += 1 + when /^=begin\b/ + in_comment_block = false + comment_lines += 1 + when /^__END__$/ + in_comment_block = true + end + end + end + + codelines = lines - comment_lines - empty_lines + + stats[:lines] += lines + stats[:comments] += comment_lines + stats[:codelines] += codelines + stats[:classes] += classes + stats[:modules] += modules + stats[:methods] += methods + stats[:files] += 1 + end + + stats + end + + def calculate_total + total = Hash.new 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[TEST_TYPES] } + code_loc + end + + def calculate_tests + test_loc = 0 + @statistics.each { |k, v| test_loc += v[:codelines] if k[TEST_TYPES] } + test_loc + end + + def print_header + print_splitter + puts "| T=Test Name | Files | Lines | LOC | Comments | Classes | Modules | Methods | M/C | LOC/M |" + print_splitter + end + + def print_splitter + puts "+---------------------------+-------+-------+-------+----------+---------+---------+---------+-----+-------+" + end + + def print_line name, statistics + m_over_c = (statistics[:methods] / (statistics[:classes] + statistics[:modules])) rescue m_over_c = 0 + loc_over_m = (statistics[:codelines] / statistics[:methods]) - 2 rescue loc_over_m = 0 + + if name[TEST_TYPES] + name = "T #{name}" + else + name = " #{name}" + end + + line = "| %-25s | %5d | %5d | %5d | %8d | %7d | %7d | %7d | %3d | %5d |" % ( + [name, *statistics.values_at(:files, :lines, :codelines, :comments, :classes, :modules, :methods)] + + [m_over_c, loc_over_m] ) + + puts line + end + + def print_code_test_stats + code = calculate_code + tests = calculate_tests + + puts " Code LOC = #{code} Test LOC = #{tests} Code:Test Ratio = [1 : #{sprintf("%.2f", tests.to_f/code)}]" + puts "" + end + +end + +# Run a test script. +if $0 == __FILE__ + $VERBOSE = true + CodeStatistics.new( + ['This dir', File.dirname(__FILE__)] + ).print +end |