6 use Pod::Find qw(pod_where);
8 BEGIN { defined &TRACE_ALL or eval 'sub TRACE_ALL () { 0 }' }
10 use vars qw/ $VERSION /;
15 Pod::Coverage - Checks if the documentation of a module is comprehensive
19 # in the beginnning...
20 perl -MPod::Coverage=Pod::Coverage -e666
22 # all in one invocation
23 use Pod::Coverage package => 'Fishy';
27 my $pc = Pod::Coverage->new(package => 'Pod::Coverage');
28 print "We rock!" if $pc->coverage == 1;
33 Developers hate writing documentation. They'd hate it even more if
34 their computer tattled on them, but maybe they'll be even more
35 thankful in the long run. Even if not, F<perlmodstyle> tells you to, so
38 This module provides a mechanism for determining if the pod for a
39 given module is comprehensive.
41 It expects to find either a C<< =head(n>1) >> or an C<=item> block documenting a
60 In this example C<Foo::foo> is covered, but C<Foo::bar> is not, so the C<Foo>
61 package is only 50% (0.5) covered
67 =item Pod::Coverage->new(package => $package)
69 Creates a new Pod::Coverage object.
71 C<package> the name of the package to analyse
73 C<private> an array of regexen which define what symbols are regarded
74 as private (and so need not be documented) defaults to [ qr/^_/,
75 qr/^import$/, qr/^DESTROY$/, qr/^AUTOLOAD$/, qr/^bootstrap$/,
76 qr/^(TIE( SCALAR | ARRAY | HASH | HANDLE ) |
77 FETCH | STORE | UNTIE | FETCHSIZE | STORESIZE |
78 POP | PUSH | SHIFT | UNSHIFT | SPLICE | DELETE |
79 EXISTS | EXTEND | CLEAR | FIRSTKEY | NEXTKEY | PRINT | PRINTF |
80 WRITE | READLINE | GETC | READ | CLOSE | BINMODE | OPEN |
81 EOF | FILENO | SEEK | TELL)$/x,
82 qr/^( MODIFY | FETCH )_( REF | SCALAR | ARRAY | HASH | CODE |
83 GLOB | FORMAT | IO)_ATTRIBUTES$/x,
87 This should cover all the usual magical methods for tie()d objects,
88 attributes, generally all the methods that are typically not called by
89 a user, but instead being used internally by perl.
91 C<also_private> items are appended to the private list
93 C<trustme> an array of regexen which define what symbols you just want
94 us to assume are properly documented even if we can't find any docs
97 If C<pod_from> is supplied, that file is parsed for the documentation,
98 rather than using Pod::Find
100 If C<nonwhitespace> is supplied, then only POD sections which have
101 non-whitespace characters will count towards being documented.
106 my $referent = shift;
108 my $class = ref $referent || $referent;
110 my $private = $args{private} || [
117 qr/^(TIE( SCALAR | ARRAY | HASH | HANDLE ) |
118 FETCH | STORE | UNTIE | FETCHSIZE | STORESIZE |
119 POP | PUSH | SHIFT | UNSHIFT | SPLICE | DELETE |
120 EXISTS | EXTEND | CLEAR | FIRSTKEY | NEXTKEY | PRINT | PRINTF |
121 WRITE | READLINE | GETC | READ | CLOSE | BINMODE | OPEN |
122 EOF | FILENO | SEEK | TELL)$/x,
123 qr/^( MODIFY | FETCH )_( REF | SCALAR | ARRAY | HASH | CODE |
124 GLOB | FORMAT | IO)_ATTRIBUTES $/x,
127 push @$private, @{ $args{also_private} || [] };
128 my $trustme = $args{trustme} || [];
129 my $nonwhitespace = $args{nonwhitespace} || undef;
135 nonwhitespace => $nonwhitespace
139 =item $object->coverage
141 Gives the coverage as a value in the range 0 to 1
148 my $package = $self->{package};
149 my $pods = $self->_get_pods;
152 my %symbols = map { $_ => 0 } $self->_get_syms($package);
154 print "tying shoelaces\n" if TRACE_ALL;
155 for my $pod (@$pods) {
156 $symbols{$pod} = 1 if exists $symbols{$pod};
159 foreach my $sym ( keys %symbols ) {
160 $symbols{$sym} = 1 if $self->_trustme_check($sym);
163 # stash the results for later
164 $self->{symbols} = \%symbols;
167 require Data::Dumper;
168 print Data::Dumper::Dumper($self);
171 my $symbols = scalar keys %symbols;
172 my $documented = scalar grep {$_} values %symbols;
174 $self->{why_unrated} = "no public symbols defined";
177 return $documented / $symbols;
180 =item $object->why_unrated
182 C<< $object->coverage >> may return C<undef>, to indicate that it was
183 unable to deduce coverage for a package. If this happens you should
184 be able to check C<why_unrated> to get a useful excuse.
190 $self->{why_unrated};
193 =item $object->naked/$object->uncovered
195 Returns a list of uncovered routines, will implicitly call coverage if
196 it's not already been called.
198 Note, private and 'trustme' identifiers will be skipped.
204 $self->{symbols} or $self->coverage;
205 return unless $self->{symbols};
206 return grep { !$self->{symbols}{$_} } keys %{ $self->{symbols} };
209 *uncovered = \&naked;
211 =item $object->covered
213 Returns a list of covered routines, will implicitly call coverage if
214 it's not previously been called.
216 As with C<naked>, private and 'trustme' identifiers will be skipped.
222 $self->{symbols} or $self->coverage;
223 return unless $self->{symbols};
224 return grep { $self->{symbols}{$_} } keys %{ $self->{symbols} };
231 # one argument - just a package
232 scalar @_ == 1 and unshift @_, 'package';
234 # we were called with arguments
235 my $pc = $self->new(@_);
236 my $rating = $pc->coverage;
237 $rating = 'unrated (' . $pc->why_unrated . ')'
238 unless defined $rating;
239 print $pc->{package}, " has a $self rating of $rating\n";
240 my @looky_here = $pc->naked;
241 if ( @looky_here > 1 ) {
242 print "The following are uncovered: ", join( ", ", sort @looky_here ),
244 } elsif (@looky_here) {
245 print "'$looky_here[0]' is uncovered\n";
251 =head2 Debugging support
253 In order to allow internals debugging, while allowing the optimiser to
254 do its thang, C<Pod::Coverage> uses constant subs to define how it traces.
258 sub Pod::Coverage::TRACE_ALL () { 1 }
261 Supported constants are:
269 Well that's all there is so far, are you glad you came?
273 =head2 Inheritance interface
275 These abstract methods while functional in C<Pod::Coverage> may make
276 your life easier if you want to extend C<Pod::Coverage> to fit your
277 house style more closely.
279 B<NOTE> Please consider this interface as in a state of flux until
280 this comment goes away.
284 =item $object->_CvGV($symbol)
286 Return the GV for the coderef supplied. Used by C<_get_syms> to identify
287 locally defined code.
289 You probably won't need to override this one.
291 =item $object->_get_syms($package)
293 return a list of symbols to check for from the specified packahe
297 # this one walks the symbol tree
302 print "requiring '$package'\n" if TRACE_ALL;
303 eval qq{ require $package };
304 print "require failed with $@\n" if TRACE_ALL and $@;
307 print "walking symbols\n" if TRACE_ALL;
308 my $syms = Devel::Symdump->new($package);
311 for my $sym ( $syms->functions ) {
313 # see if said method wasn't just imported from elsewhere
314 my $glob = do { no strict 'refs'; \*{$sym} };
315 my $o = B::svref_2object($glob);
317 # in 5.005 this flag is not exposed via B, though it exists
318 my $imported_cv = eval { B::GVf_IMPORTED_CV() } || 0x80;
319 next if $o->GvFLAGS & $imported_cv;
321 # check if it's on the whitelist
322 $sym =~ s/$self->{package}:://;
323 next if $self->_private_check($sym);
332 Extract pod markers from the currently active package.
334 Return an arrayref or undef on fail.
341 my $package = $self->{package};
343 print "getting pod location for '$package'\n" if TRACE_ALL;
344 $self->{pod_from} ||= pod_where( { -inc => 1 }, $package );
346 my $pod_from = $self->{pod_from};
348 $self->{why_unrated} = "couldn't find pod";
352 print "parsing '$pod_from'\n" if TRACE_ALL;
353 my $pod = Pod::Coverage::Extractor->new;
354 $pod->{nonwhitespace} = $self->{nonwhitespace};
355 $pod->parse_from_file( $pod_from, '/dev/null' );
357 return $pod->{identifiers} || [];
360 =item _private_check($symbol)
362 return true if the symbol should be considered private
369 return grep { $sym =~ /$_/ } @{ $self->{private} };
372 =item _trustme_check($symbol)
374 return true if the symbol is a 'trustme' symbol
379 my ( $self, $sym ) = @_;
380 return grep { $sym =~ /$_/ } @{ $self->{trustme} };
386 my $b_cv = B::svref_2object($cv);
388 # perl 5.6.2's B doesn't have an object_2svref. in 5.8 you can
390 # return *{ $b_cv->GV->object_2svref };
391 # but for backcompat we're forced into this uglyness:
393 return *{ $b_cv->GV->STASH->NAME . "::" . $b_cv->GV->NAME };
396 package Pod::Coverage::Extractor;
398 use base 'Pod::Parser';
400 use constant debug => 0;
402 # extract subnames from a pod stream
405 my ( $command, $text, $line_num ) = @_;
406 if ( $command eq 'item' || $command =~ /^head(?:2|3|4)/ ) {
409 my @pods = ( $text =~ /\s*([^\s\|,\/]+)/g );
410 $self->{recent} = [];
412 foreach my $pod (@pods) {
413 print "Considering: '$pod'\n" if debug;
415 # it's dressed up like a method cal
416 $pod =~ /-E<\s*gt\s*>(.*)/ and $pod = $1;
417 $pod =~ /->(.*)/ and $pod = $1;
419 # it's used as a (bare) fully qualified name
420 $pod =~ /\w+(?:::\w+)*::(\w+)/ and $pod = $1;
422 # it's wrapped in a pod style B<>
426 # has arguments, or a semicolon
427 $pod =~ /(\w+)\s*[;\(]/ and $pod = $1;
429 print "Adding: '$pod'\n" if debug;
430 push @{ $self->{ $self->{nonwhitespace}
432 : "identifiers" } }, $pod;
439 my ( $text, $line_num ) = shift;
440 if ( $self->{nonwhitespace} and $text =~ /\S/ and $self->{recent} ) {
441 push @{ $self->{identifiers} }, @{ $self->{recent} };
442 $self->{recent} = [];
454 Due to the method used to identify documented subroutines
455 C<Pod::Coverage> may completely miss your house style and declare your
456 code undocumented. Patches and/or failing tests welcome.
462 =item Widen the rules for identifying documentation
464 =item Improve the code coverage of the test suite. C<Devel::Cover> rocks so hard.
470 L<Test::More>, L<Devel::Cover>
474 Richard Clamp <richardc@unixbeard.net>
476 Michael Stevens <mstevens@etla.org>
478 some contributions from David Cantrell <david@cantrell.org.uk>
482 Copyright (c) 2001, 2003, 2004, 2006, 2007 Richard Clamp, Michael
483 Stevens. All rights reserved. This program is free software; you can
484 redistribute it and/or modify it under the same terms as Perl itself.