perlsloc - Count Perl Source Lines with Perl::Tidy
While spending some time putting together my own perltidyrc file, I became intimately familiar with the Perl::Tidy documentation.
One day, I decided to find out exactly how much code I was maintaining. Since perltidy can strip comments and POD, and also normalize the source code to make a fair measurement, it's a perfect tool for counting Source Lines of Code (SLOC).
Here's a small shell script using ack
, perltidy
, xargs
, and wc
to count
the source lines of code in any number of directories.
ack -f --perl $@ | xargs -L 1 perltidy --noprofile --delete-pod --mbl=0 --standard-output | wc -l
ack -f
lists the files that would be searched, and --perl
searches Perl
files, so we get ack's heuristics for finding Perl files. xargs -L 1
invokes
the following command for every 1 line of input. The perltidy
command strips
the pod and tightens up the whitespace and writes the result to stdout, which
wc -l
will then count, line by line.
So, as an example, the current Statocles release has 50% more test lines than source lines:
» perlsloc lib bin
1034
» perlsloc t
1633
One comment, one question:
First, this seems to leave a few blank lines in the stream, mostly between files. A "
egrep -v '^$'
" will get rid of those.Second, does SLOC include source comments? I don't know, and I am asking because you make a point to remove POD. If it does include comments, then that's OK. But if it should not count comments, adding another egrep would remove them:
egrep -v '^\s*#'
I was on the fence about comments. This does not get rid of them, but perltidy has options to remove comments as well: --delete-block-comments --delete-side-comments (though the latter doesn't add to SLOC really).
I can't seem to find the perltidy option to get rid of __END__ and that trailing blank. The "^1;$" could probably go too, which would remove 3 lines per file. Looks like my test code doesn't do that, so between __END__ and =pod (the start of the docs) seems to do it. I have a habit of putting blank lines around every POD directive, though I think the need for that is long gone...