1 ##############################################################################
2 # $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/Policy/Documentation/RequirePodSections.pm $
3 # $Date: 2008-07-03 10:19:10 -0500 (Thu, 03 Jul 2008) $
6 ##############################################################################
8 package Perl::Critic::Policy::Documentation::RequirePodSections;
15 use Perl::Critic::Utils qw{ :booleans :characters :severities :classification };
16 use base 'Perl::Critic::Policy';
18 our $VERSION = '1.088';
20 #-----------------------------------------------------------------------------
22 Readonly::Scalar my $EXPL => [133, 138];
24 Readonly::Scalar my $BOOK => 'book';
25 Readonly::Scalar my $BOOK_FIRST_EDITION => 'book_first_edition';
26 Readonly::Scalar my $MODULE_STARTER_PBP => 'module_starter_pbp';
27 Readonly::Scalar my $M_S_PBP_0_0_3 => 'module_starter_pbp_0_0_3';
29 Readonly::Scalar my $DEFAULT_SOURCE => $BOOK_FIRST_EDITION;
31 my %SOURCE_TRANSLATION = (
32 $BOOK => $BOOK_FIRST_EDITION,
33 $BOOK_FIRST_EDITION => $BOOK_FIRST_EDITION,
34 $MODULE_STARTER_PBP => $M_S_PBP_0_0_3,
35 $M_S_PBP_0_0_3 => $M_S_PBP_0_0_3,
38 Readonly::Scalar my $EN_AU => 'en_AU';
39 Readonly::Scalar my $EN_US => 'en_US';
40 Readonly::Scalar my $ORIGINAL_MODULE_VERSION => 'original';
42 Readonly::Hash my %SOURCE_DEFAULT_LANGUAGE => (
43 $BOOK_FIRST_EDITION => $ORIGINAL_MODULE_VERSION,
44 $M_S_PBP_0_0_3 => $EN_AU,
47 Readonly::Scalar my $BOOK_FIRST_EDITION_US_LIB_SECTIONS =>
53 'SUBROUTINES/METHODS',
55 'CONFIGURATION AND ENVIRONMENT',
58 'BUGS AND LIMITATIONS',
60 'LICENSE AND COPYRIGHT',
63 Readonly::Hash my %DEFAULT_LIB_SECTIONS => (
64 $BOOK_FIRST_EDITION => {
65 $ORIGINAL_MODULE_VERSION => $BOOK_FIRST_EDITION_US_LIB_SECTIONS,
71 'SUBROUTINES/METHODS',
73 'CONFIGURATION AND ENVIRONMENT',
76 'BUGS AND LIMITATIONS',
78 'LICENCE AND COPYRIGHT',
80 $EN_US => $BOOK_FIRST_EDITION_US_LIB_SECTIONS,
90 'CONFIGURATION AND ENVIRONMENT',
93 'BUGS AND LIMITATIONS',
95 'LICENCE AND COPYRIGHT',
96 'DISCLAIMER OF WARRANTY',
105 'CONFIGURATION AND ENVIRONMENT',
108 'BUGS AND LIMITATIONS',
110 'LICENSE AND COPYRIGHT',
111 'DISCLAIMER OF WARRANTY'
116 Readonly::Hash my %DEFAULT_SCRIPT_SECTIONS => (
117 $BOOK_FIRST_EDITION => {
118 $ORIGINAL_MODULE_VERSION => [
122 'REQUIRED ARGUMENTS',
129 'BUGS AND LIMITATIONS',
131 'LICENSE AND COPYRIGHT',
137 'REQUIRED ARGUMENTS',
141 'CONFIGURATION AND ENVIRONMENT',
144 'BUGS AND LIMITATIONS',
146 'LICENCE AND COPYRIGHT',
152 'REQUIRED ARGUMENTS',
156 'CONFIGURATION AND ENVIRONMENT',
159 'BUGS AND LIMITATIONS',
161 'LICENSE AND COPYRIGHT',
169 'REQUIRED ARGUMENTS',
173 'CONFIGURATION AND ENVIRONMENT',
176 'BUGS AND LIMITATIONS',
178 'LICENCE AND COPYRIGHT',
179 'DISCLAIMER OF WARRANTY',
185 'REQUIRED ARGUMENTS',
189 'CONFIGURATION AND ENVIRONMENT',
192 'BUGS AND LIMITATIONS',
194 'LICENSE AND COPYRIGHT',
195 'DISCLAIMER OF WARRANTY',
200 #-----------------------------------------------------------------------------
202 sub supported_parameters {
205 name => 'lib_sections',
206 description => 'The sections to require for modules (separated by qr/\s* [|] \s*/xm).',
207 default_string => $EMPTY,
208 parser => \&_parse_lib_sections,
211 name => 'script_sections',
212 description => 'The sections to require for programs (separated by qr/\s* [|] \s*/xm).',
213 default_string => $EMPTY,
214 parser => \&_parse_script_sections,
218 description => 'The origin of sections to use.',
219 default_string => $DEFAULT_SOURCE,
220 behavior => 'enumeration',
221 enumeration_values => [ keys %SOURCE_TRANSLATION ],
225 description => 'The spelling of sections to use.',
226 default_string => $EMPTY,
227 behavior => 'enumeration',
228 enumeration_values => [ $EN_AU, $EN_US ],
233 sub default_severity { return $SEVERITY_LOW }
234 sub default_themes { return qw(core pbp maintenance) }
235 sub applies_to { return 'PPI::Document' }
237 #-----------------------------------------------------------------------------
239 sub _parse_sections {
240 my $config_string = shift;
242 my @sections = split m{ \s* [|] \s* }mx, $config_string;
244 return map { uc $_ } @sections; # Normalize CaSe!
247 sub _parse_lib_sections {
248 my ($self, $parameter, $config_string) = @_;
250 if ( defined $config_string ) {
251 $self->{_lib_sections} = [ _parse_sections( $config_string ) ];
257 sub _parse_script_sections {
258 my ($self, $parameter, $config_string) = @_;
260 if ( defined $config_string ) {
261 $self->{_script_sections} = [ _parse_sections( $config_string ) ];
267 #-----------------------------------------------------------------------------
269 sub initialize_if_enabled {
270 my ($self, $config) = @_;
272 my $source = $self->{_source};
273 if ( not defined $source or not defined $DEFAULT_LIB_SECTIONS{$source} ) {
274 $source = $DEFAULT_SOURCE;
277 my $language = $self->{_language};
279 not defined $language
280 or not defined $DEFAULT_LIB_SECTIONS{$source}{$language}
282 $language = $SOURCE_DEFAULT_LANGUAGE{$source};
285 if ( not $self->_sections_specified('_lib_sections') ) {
286 $self->{_lib_sections} = $DEFAULT_LIB_SECTIONS{$source}{$language};
288 if ( not $self->_sections_specified('_script_sections') ) {
289 $self->{_script_sections} =
290 $DEFAULT_SCRIPT_SECTIONS{$source}{$language};
296 sub _sections_specified {
297 my ( $self, $sections_key ) = @_;
299 my $sections = $self->{$sections_key};
301 return 0 if not defined $sections;
303 return scalar @{ $sections };
306 #-----------------------------------------------------------------------------
309 my ( $self, $elem, $doc ) = @_;
311 # This policy does not apply unless there is some real code in the
312 # file. For example, if this file is just pure POD, then
313 # presumably this file is ancillary documentation and you can use
314 # whatever headings you want.
315 return if ! $doc->schild(0);
317 my %found_sections = ();
320 my @required_sections = is_script($doc) ? @{ $self->{_script_sections} }
321 : @{ $self->{_lib_sections} };
323 my $pods_ref = $doc->find('PPI::Token::Pod');
324 return if not $pods_ref;
326 # Round up the names of all the =head1 sections
327 for my $pod ( @{ $pods_ref } ) {
328 for my $found ( $pod =~ m{ ^ =head1 \s+ ( .+? ) \s* $ }gmx ) {
329 #Leading/trailing whitespace is already removed
330 $found_sections{ uc $found } = 1;
334 # Compare the required sections against those we found
335 for my $required ( @required_sections ) {
336 if ( not exists $found_sections{$required} ) {
337 my $desc = qq{Missing "$required" section in POD};
338 push @violations, $self->violation( $desc, $EXPL, $doc );
349 #-----------------------------------------------------------------------------
353 =for stopwords licence
357 Perl::Critic::Policy::Documentation::RequirePodSections - Organize your POD into the customary sections.
361 This Policy is part of the core L<Perl::Critic> distribution.
366 This Policy requires your POD to contain certain C<=head1> sections.
367 If the file doesn't contain any POD at all, then this Policy does not
368 apply. Tools like L<Module::Starter> make it really easy to ensure
369 that every module has the same documentation framework, and they can
370 save you lots of keystrokes.
374 Different POD sections are required, depending on whether the file is
375 a library or program (which is determined by the presence or absence
376 of a perl shebang line).
378 Default Required POD Sections
380 Perl Libraries Perl Programs
381 ------------------------------------------------------
385 DESCRIPTION DESCRIPTION
386 SUBROUTINES/METHODS REQUIRED ARGUMENTS
388 DIAGNOSTICS DIAGNOSTICS
390 CONFIGURATION AND ENVIRONMENT CONFIGURATION
391 DEPENDENCIES DEPENDENCIES
392 INCOMPATIBILITIES INCOMPATIBILITIES
393 BUGS AND LIMITATIONS BUGS AND LIMITATIONS
395 LICENSE AND COPYRIGHT LICENSE AND COPYRIGHT
399 The default sections above are derived from Damian Conway's I<Perl
400 Best Practices> book. Since the book has been published, Conway has
401 released L<Module::Starter::PBP>, which has different names for some
402 of the sections, and adds some more. Also, the book and module use
403 Australian spelling, while the authors of this module have previously
404 used American spelling. To sort this all out, there are a couple of
405 options that can be used: C<source> and C<language>.
407 The C<source> option has two generic values, C<book> and
408 C<module_starter_pbp>, and two version-specific values,
409 C<book_first_edition> and C<module_starter_pbp_0_0_3>. Currently, the
410 generic values map to the corresponding version-specific values, but
411 may change as new versions of the book and module are released, so use
412 these if you want to keep up with the latest and greatest. If you
413 want things to remain stable, use the version-specific values.
415 The C<language> option has a default, unnamed value but also accepts
416 values of C<en_AU> and C<en_US>. The reason the unnamed value exists
417 is because the default values for programs don't actually match the
418 book, even taking spelling into account, i.e. C<CONFIGURATION> instead
419 of C<CONFIGURATION AND ENVIRONMENT>, the removal of C<VERSION>, and
420 the addition of C<EXIT STATUS>. To get precisely the sections as
421 specified in the book, put the following in your F<.perlcriticrc>
424 [Documentation::RequirePodSections]
425 source = book_first_edition
430 [Documentation::RequirePodSections]
431 source = module_starter_pbp
434 you will need to modify your F<~/.module-starter/PBP/Module.pm>
435 template because it is generated using Australian spelling.
437 Presently, the difference between C<en_AU> and C<en_US> is in how the
438 word "licence" is spelled.
440 The sections required for modules and programs can be independently
441 customized, overriding any values for C<source> and C<language>, by
442 giving values for C<script_sections> and C<lib_sections> of a string
443 of pipe-delimited required POD section names. An example of entries
444 in a F<.perlcriticrc> file:
446 [Documentation::RequirePodSections]
447 lib_sections = NAME | SYNOPSIS | BUGS AND LIMITATIONS | AUTHOR
448 script_sections = NAME | USAGE | OPTIONS | EXIT STATUS | AUTHOR
452 Currently, this Policy does not look for the required POD sections
453 below the C<=head1> level. Also, it does not require the sections to
454 appear in any particular order.
458 Jeffrey Ryan Thalhammer <thaljef@cpan.org>
462 Copyright (c) 2006-2008 Jeffrey Ryan Thalhammer. All rights reserved.
464 This program is free software; you can redistribute it and/or modify
465 it under the same terms as Perl itself. The full text of this license
466 can be found in the LICENSE file included with this module
472 # cperl-indent-level: 4
474 # indent-tabs-mode: nil
475 # c-indentation-style: bsd
477 # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :