#!/usr/bin/env perl use strict; use warnings; use Carp qw(croak); use Getopt::Long; use Perl::Metrics::Simple 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.3'; 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 /,/sxm, $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() or croak 'Failed to print!'; } elsif ( $options->{'json'} ) { my $json = Perl::Metrics::Simple::Output::JSON->new($analysis); print $json->make_report() or croak 'Failed to print!'; } else { my $plain = Perl::Metrics::Simple::Output::PlainText->new($analysis); print $plain->make_report() or croak 'Failed to print!'; } 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