Skip to content

Instantly share code, notes, and snippets.

@mleon
Created April 19, 2009 02:36
Show Gist options
  • Save mleon/97877 to your computer and use it in GitHub Desktop.
Save mleon/97877 to your computer and use it in GitHub Desktop.
counting code
#!/usr/bin/env ruby
require 'yaml'
USAGE = %Q(
Name
lines_of_code.rb
Synopsis
find <find_options> | lines_of_code.rb [--order_by <code|totals|files>] [--reverse_order] [help|--help|-h]
this script expects to be fed a bunch of filenames separated by line feeds
something like:
find app -type f|grep -v "\.svn"|./lines_of_code.rb
options:
--help | -h | help
shows this help text
--order_by
can be ordered by (uncommented lines of) code, total (lines), or (number of) files
--reverse_order
default order is descending. the use of this option displays results in ascending order
)
# To do
# allow user-defined comment syntax via something like a --commentor
# take in command line options
#
order_by = ARGV.index("--order_by") ? ARGV.delete_at(ARGV.index('--order_by') +1) : "code"
ARGV.delete("--order_by")
order_by_options = %w(code files total)
puts "can only order by one of: #{p order_by_options}" unless order_by_options.include?(order_by)
reverse_order = ARGV.delete("--reverse_order")
help = ARGV.size == 1 && %w(help --help -h).include?(ARGV.first)
abort USAGE if(help) # or ARGV.empty?)
paths = ARGF.readlines
count_by = Hash.new{|hash, key| hash[key] = {"files" => 0, "total" => 0, "code" => 0}}
totals = {"files" => 0, "total" => 0, "code" => 0}
paths.each {|path| path = path.strip
type = File.extname(path)
begin
lines = IO.readlines(path) rescue next
total= lines.size
code = lines.select { |line| line !~ /^\s*#|^\s*$/ }.size
rescue
puts "exception! skipping file or line in: #{path}"
next
end
count_by[type]['files'] += 1
count_by[type]['total'] += total
count_by[type]['code'] += code
totals["files"] += 1
totals["total"] += total
totals["code"] += code
}
puts "\nTotals: #{totals.to_yaml}"
descending = reverse_order ? "ascending" : "descending"
puts "\nCounts by file type - ordered by #{order_by}, #{descending} :"
if reverse_order
# puts count_by.sort{|a,b| b[1][order_by]<=>a[1][order_by]}.to_yaml
puts count_by.sort_by{|a,b| b[order_by]}.to_yaml
else
# puts count_by.sort{|a,b| a[1][order_by]<=>b[1][order_by]}.to_yaml
puts count_by.sort_by{|a,b| b[order_by]}.reverse.to_yaml
end
=begin
# the below four lines expect to be fed lines from every file as in something
# like: find app -type f|xargs -n1 cat|./ml_loc2.rb
all_lines = ARGF.readlines
total_count = all_lines.size
non_comment_count = all_lines.select { |line| line !~ /^\s*#|^\s*$/ }.size
puts "Non-comment total count: #{non_comment_count}, Total count: #{total_count}"
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment