#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;
use Perl::Metrics::Simple qw(0.13);
use Perl::Metrics::Simple::Output::HTML;
use Perl::Metrics::Simple::Output::JSON;
use Perl::Metrics::Simple::Output::PlainText;
use Pod::Usage qw(pod2usage);
our $VERSION = 'v1.0.1';
exit main() if not caller;
#-------------------------------------------------------------------------------
sub main {
my ( $options, @files ) = parse_opts(@ARGV);
if ( $options->{'help'} ) {
pod2usage( -verbose => 2, -exitval => 1 ); # exits program
}
if ( my $modifiers = $options->{'method-modifiers'} ) {
push @Perl::Metrics::Simple::Analysis::File::METHOD_MODIFIERS,
split( /,/, $modifiers );
}
my $analysis = Perl::Metrics::Simple->new()->analyze_files(@files);
if ( $options->{'html'} ) {
my $html = Perl::Metrics::Simple::Output::HTML->new($analysis);
print $html->make_report();
}
elsif ( $options->{'json'} ) {
my $json = Perl::Metrics::Simple::Output::JSON->new($analysis);
print $json->make_report();
}
else {
my $plain = Perl::Metrics::Simple::Output::PlainText->new($analysis);
print $plain->make_report();
}
return 0;
}
sub parse_opts {
my (@command_line_arguments) = @_;
if ( !@command_line_arguments ) {
pod2usage(
-msg => "Missing required argument(s).\n",
-exitval => 1,
-verbose => 1,
); # exits program
}
my %options;
my $parsed_ok = Getopt::Long::GetOptionsFromArray(
\@command_line_arguments,
\%options,
'html',
'json',
'method-modifiers:s',
);
if ( !$parsed_ok ) {
pod2usage(
-msg => "Failed to parse command line.\n",
-exitval => 1,
-verbose => 1,
); # exits program
}
return ( \%options, @command_line_arguments );
}
__END__
=head1 NAME
countperl - count lines, packages, subs and complexity of Perl files.
=head1 USAGE
B<countperl> F<FILE_OR_DIRECTORY> [F<FILE_OR_DIRECTORY> ...] [--html] [--help] [--method-modifiers=a,b,c]
=head1 REQUIRED ARGUMENTS
At least one file or directory path must be supplied.
=head1 OPTIONS
=over 4
=item --help
Prints documentation to STDERR.
=item --html
Produces HTML output instead of the plain-text default.
=item --json
Produces JSON output instead of the plain-text default.
=item --method-modifiers=a,b,c
A comma-separated list of method modifiers to be recognised, see
L<Moose::Manual::MethodModifiers> for details. If unspecified, the
default list is before,after,around.
=back
=head1 CONFIGURATION
N/A. Currently no support for any configuration files.
=head1 EXIT STATUS
Exits zero on success, non-zero on failure.
=head1 DESCRIPTION
F<countperl> uses B<Perl::Metrics::Simple> to examines the named files and
recursivesly searches named directories for Perl files.
Perl files are identified by B<Perl::Metrics::Simple-E<gt>is_perl_file>. Basically
if the file ends in C<.pl>, C<.pm>, or C<.t> or has what appears to be a perl
I<shebang> line.
F<countperl> produces a report on F<STDOUT> of counts of total lines,
packages, subroutines/methods,
the minimum, maximum, mean, standard deviation, and median size and
mccabe_complexity (cyclomatic complexity) of subroutines and
the 'main' portion of each file (everything not in a subroutine.)
=head2 Output Format
Line counts do not include comments nor pod.
The current output format is human-readable text:
Perl files found: 3
Counts
------
total code lines: 856
lines of non-sub code: 450
packages found: 3
subs/methods: 42
Subroutine/Method Size
----------------------
min: 3 lines
max: 32 lines
mean: 9.67 lines
std. deviation: 7.03
median: 7.50
McCabe Complexity
-----------------
Code not in any subroutine::
min: 1
max 1
mean: 1.00
std. deviation: 0.00
median: 1.00
Subroutines/Methods:
min: 1
max: 5
avg: 1.00
std. deviation: 1.36
median: 1.00
Tab-delimited list of subroutines, with most complex at top
-----------------------------------------------------------
complexity sub path size
5 is_perl_file lib/Perl/Metrics/Simple.pm 11
5 _has_perl_shebang lib/Perl/Metrics/Simple.pm 13
5 _init lib/Perl/Metrics/Simple/Analysis/File.pm 30
4 find_files lib/Perl/Metrics/Simple.pm 11
4 new lib/Perl/Metrics/Simple/Analysis.pm 10
4 is_ref lib/Perl/Metrics/Simple/Analysis.pm 8
With --html switch output format is HTML.
=head1 VERSION
This is version 0.031 of F<countperl>.
=head1 DIAGNOSTICS
Prints usage message to STDERR if required arguments are not provided.
=head1 INCOMPATIBILITIES
None known.
=head1 BUGS AND LIMITATIONS
=head2 Bugs
No bugs reported yet :-)
See: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Perl-Metrics-Simple
=head2 Limitations
=over 4
=item Does not accept input from STDIN.
=item No machine-readable report format available (e.g. XML, tab-delimited)
=back
=head1 SUPPORT
Via CPAN:
=head2 Disussion Forum
http://www.cpanforum.com/dist/Perl-Metrics-Simple
=head2 Bug Reports
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Perl-Metrics-Simple
=head1 DEPENDENCIES
=over 4
=item L<Perl::Metrics::Simple|Perl::Metrics::Simple> 0.13 (which depends upon L<PPI|PPI>.)
=item L<Pod::Usage|Pod::Usage>
=back
=head1 SEE ALSO
=over 4
=item L<PPI|PPI>
=item L<Perl::Critic|Perl::Critic>
=item L<Perl::Metrics|Perl::Metrics>
=item http://en.wikipedia.org/wiki/Cyclomatic_complexity
=back
=head1 AUTHOR
Matisse Enzer
CPAN ID: MATISSE
Eigenstate Consulting, LLC
matisse@eigenstate.net
http://www.eigenstate.net/
=head1 LICENSE AND COPYRIGHT
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the
LICENSE file included with this module.
=cut