I wanted to get a sense of my test to code ratio today for one of my projects and knew that the *nix command wc would give me a count of all the lines in some files, but the man page didn’t seem to have any information about filtering those lines. Thankfully this is *nix land where we are encouraged to slice and dice our own solutions. So, grep to the rescue.
My initial attempt was to filter out empty lines and lines that had some number of spaces followed by # (the comment character in Ruby), but I failed to find a combination that would work so I settled on a two pass grep solution.
grep -v '^[ t]*#' ./lib/**/*.rb | grep '[^ t]' | wc -l
The -v option for grep says to match lines that do not match this pattern. So the first grep pattern matches a line that does not have zero or more spaces followed by the # character. The ./lib/**/*.rb is the “file” to check. Now a lot of *nix utilites can take what’s known as a dir glob, a pattern that describes a list of files. In this case I want every file and subdirectory in the lib directory that ends in .rb. The second pattern does somewhat the same thing but simply matches a line that does not consist entirely of spaces and tabs. Finally the wc -l gives a count of just line numbers (vs words like it normally reports).
So now I can get a count of non whitespace, non-comment lines in my app (the lib directory): 1615
Then the number of lines in my spec directory: 1561
Hmm, not so hot, guess it’s time to get back to spec writing.