Created
March 4, 2017 21:40
-
-
Save swillits/addbe0b6c31ed09c95e0c9c4c50ed054 to your computer and use it in GitHub Desktop.
This file contains 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
#!/usr/bin/ruby | |
# Keith Bauer made this. | |
require 'find' | |
require 'getoptlong' | |
EXTS = Regexp.compile('^.*\.(' + %w[ | |
h hh hpp H | |
c cc cpp cxx C | |
m mm M | |
rb py pl sh | |
lua | |
scm hs lisp | |
java | |
swift].join('|') + ')$') | |
OPTS = [ | |
[ '--exclude', '-x', GetoptLong::REQUIRED_ARGUMENT ], | |
[ '--no-blank-lines', '-n', GetoptLong::NO_ARGUMENT ], | |
[ '--help', '-h', GetoptLong::NO_ARGUMENT ]] | |
HELP = { | |
'--exclude' => { | |
:argument_placeholder => 'pattern', | |
:help_text => 'exclude files matching glob pattern <pattern>' | |
}, | |
'--no-blank-lines' => { | |
:help_text => "don't count blank lines in source files" | |
}, | |
'--help' => { | |
:help_text => "this help text" | |
} | |
} | |
opts = GetoptLong.new(*OPTS) | |
REGEXP_METACHARACTERS = '\\$^*(){}+.?' | |
exclusions = nil | |
blank_lines = true | |
opts.each do |opt, arg| | |
if opt == '--exclude' then | |
re = '' | |
arg.each_byte do |b| | |
if b == ?* then | |
re += '.*' | |
elsif b == ?? then | |
re += '.' | |
else | |
if REGEXP_METACHARACTERS.include?(b) then | |
re += '\\' | |
end | |
re << b | |
end | |
end | |
re += '$' | |
if exclusions then | |
exclusions += "|(#{re})" | |
else | |
exclusions = "(#{re})" | |
end | |
elsif opt == '--no-blank-lines' then | |
blank_lines = false | |
elsif opt == '--help' then | |
puts "Usage: #{$0} [options] [paths to search]\n\nOptions:" | |
puts OPTS.map { |option| | |
if option[-1] == GetoptLong::REQUIRED_ARGUMENT then | |
joiner = " <#{HELP[option[0]][:argument_placeholder]}>\n " | |
elsif option[-1] == GetoptLong::OPTIONAL_ARGUMENT then | |
joiner = " [#{HELP[option[0]][:argument_placeholder]}]\n " | |
elsif option[-1] == GetoptLong::NO_ARGUMENT then | |
joiner = "\n " | |
end | |
" " + option[0..-2].map { |o| o + joiner }.join + | |
" " + HELP[option[0]][:help_text] + "\n" | |
}.join("\n") | |
puts | |
exit | |
end | |
end | |
if ARGV.size == 0 then | |
ARGV << '.' | |
end | |
exclusions_re = if exclusions then Regexp.compile(exclusions) else nil end | |
lc = 0 | |
ARGV.each do |root| | |
Find.find(root) do |path| | |
if exclusions_re && exclusions_re =~ path then | |
Find.prune | |
next | |
end | |
if EXTS =~ path then | |
begin | |
File.read(path).each_line do |line| | |
unless line == "\n" && !blank_lines then | |
lc += 1 | |
end | |
end | |
rescue => e | |
$stderr.puts(e) | |
end | |
end | |
end | |
end | |
puts lc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment