Skip to content

Instantly share code, notes, and snippets.

@bheeshmar
Forked from emad-elsaid/ruby-analytics.rb
Last active August 29, 2015 13:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bheeshmar/9229219 to your computer and use it in GitHub Desktop.
Save bheeshmar/9229219 to your computer and use it in GitHub Desktop.
def counts_of_files_by_extension(dir)
Dir["#{dir}/**/*"].reduce(Hash.new(0)) do |extension_counts, filepath|
extension_counts[File.extname(filepath)] += 1
extension_counts
end
end
directory = ARGV.shift || Dir.pwd
counts = counts_of_files_by_extension(directory)
if counts.empty?
puts 'No files found that matches your criteria.'
else
extension_map = {
'rb' => 'Ruby',
'erb' => 'Ruby HTML Templates',
'yml' => 'YAML',
'rdoc' => 'RDoc',
'js' => 'Javascript',
'css' => 'CSS',
'scss' => 'Sass',
'coffee' => 'CoffeeScript',
}
puts counts.map { |k,v| "#{extension_map[k]} : #{v} Files" }
end
@bheeshmar
Copy link
Author

@blazeeboy, compared to yours, this has the weakness of only being able to see the LAST extension, so it does not distinguish between foo.html.erb and foo.erb. On the other hand, it's O(N) with no recursion.

One minor difference from your original gist is that I don't preserve the print order of the extensions. If you want that, reduce the extension_map:
puts extension_map.reduce([]) { |s,(ext,name)| s.push("#{name} : #{counts[ext]} Files") }

Interesting points:

  • Dir["**/*"] means glob all files at any depth. You can refine just like you would at shell: Dir["app/**/*.rb"]
  • The glob is enumerable, so you can call reduce on it to return the hash of counts.
  • Hash.new takes a default value, so you can avoid initializing when not found. Beware when using objects as the default value, as the provided argument is used for ALL defaults and you probably will be confused: Hash.new([]) should be Hash.new { |h,k| h[k] = [] }
  • File has many good helpers to tear apart pieces like File.extname and File.basename
  • puts ["one", "two"] will put newlines in for you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment