Login
Importing Perl-Critic-0.13.
[gknop/Perl-Critic.git] / bin / perlcritic
CommitLineData
59b05e08
JRT
1#!/usr/bin/perl
2
3package main;
4
5use strict;
6use warnings;
7use Pod::Usage;
8use Getopt::Long;
9use English qw(-no_match_vars);
10use Perl::Critic::Utils;
11use Perl::Critic;
12
13our $VERSION = '0.13';
14$VERSION = eval $VERSION; ## no critic
15
16#---------------------------------------------------------------
17# Begin script
18
19my %opts = get_options();
20my @input = get_input( @ARGV );
21my %config = map { ("-$_" => $opts{$_}) } keys %opts;
22my $violations = critique( \%config, @input );
23my $status = $violations ? 2 : 0;
24exit $status;
25
26#----------------------------------------------------------------
27# Begin subroutines
28
29sub get_options {
30
31 my %opts = ();
32 my @opt_specs = qw(priority=s profile=s noprofile verbose=s
33 force help|? man Version safari
34 include=s@ exclude=s@);
35
36 Getopt::Long::Configure('no_ignore_case');
37 GetOptions( \%opts, @opt_specs ) || pod2usage(); #Exits
38
39 if ( $opts{help} ) { pod2usage( -verbose => 0 ) } #Exits
40 if ( $opts{man} ) { pod2usage( -verbose => 2 ) } #Exits
41 if ( $opts{Version} ) { print "$VERSION\n"; exit 0; } #Exits
42
43 #Sanity checks
44 if ( $opts{noprofile} && $opts{profile} ) {
45 my $msg = 'Cannot use -noprofile with -profile';
46 pod2usage( -exitstatus => 1, -message => $msg ); #Exits
47 }
48
49 #Warn users who might forget that -verbose requires a value
50 if ( $opts{verbose} && $opts{verbose} !~ m{ (?: \d+ | %[fmlcdp] ) }mx ) {
51 my $msg = qq{Warning: -verbose value '$opts{verbose}' looks odd.\n};
52 warn $msg;
53 }
54
55 #Override profile, if -noprofile
56 if ( $opts{noprofile} ) { $opts{profile} = $EMPTY }
57
58 #All good!
59 return %opts;
60}
61
62sub get_input {
63
64 if ( @_ ) {
65
66 #Reading code from a file...
67 for (@_ ) { -f $_ || die qq{'$_' is not a file} }
68 return @_;
69 }
70 else {
71
72 #Reading code from STDIN
73 my $code_string = do { local $RS; <STDIN> }; #Slurping
74 $code_string =~ m{ \S+ }mx || die 'Nothing to critique';
75 return \$code_string; #Convert to SCALAR ref for PPI
76 }
77}
78
79sub critique {
80 my $config = shift;
81 my $count = 0;
82
83 #Construct Critic
84 my $critic = Perl::Critic->new( %{$config} );
85
86 for my $file (@_) {
87 my @violations = $critic->critique($file);
88 $count += scalar @violations;
89
90 #HACK! This is so I can recycle the same $critic
91 for ( @{ $critic->policies() } ) { $_->{_tested} = 0 }
92 print_report($file, $config->{-verbose}, @violations);
93 }
94 return $count;
95}
96
97
98sub print_report {
99 my ($file, $verbosity, @violations) = @_;
100 $file = -f $file ? $file : 'stdin';
101 $verbosity ||= @ARGV > 1 ? 3 : 2;
102
103 my %FORMAT_OF = (
104 1 => "%f:%l:%c:%m\n",
105 2 => "%m at line %l, column %c. %e.\n",
106 3 => "%f: %m at line %l, column %c. %e.\n",
107 4 => "[%p] %m at line %l, column %c. %e.\n",
108 5 => "[%p] %m at line %l, column %c. %e.\n%d\n",
109 );
110
111 my $fmt = $verbosity =~ m{ \A [+-]? \d+ \z }mx ?
112 ($FORMAT_OF{abs $verbosity} || $FORMAT_OF{2}) : _interpolate($verbosity);
113 $fmt =~ s{\%f}{$file}mxg; #HACK! Vilation objects don't know the file
114
115 no warnings 'once'; #Ugh. It's tough to be a perfectionist.
116 local $Perl::Critic::Violation::FORMAT = $fmt; ## no critic
117 print @violations;
118 return 1;
119}
120
121sub _interpolate {
122 my $literal = shift;
123 my $interpolated = undef;
124 eval "\$interpolated = \"$literal\""; ## no critic
125 return $interpolated;
126}
127
1281;
129
130__END__
131
132=pod
133
134=head1 NAME
135
136perlcritic - Command-line interface to critique Perl source
137
138=head1 SYNOPSIS
139
140 perlcritic [options] FILE1 [ FILE2 FILE3... ] #Read from FILE(s)
141 perlcritic [options] #Read from STDIN
142 perlciritc -man #To see the manual
143
144=head1 DESCRIPTION
145
146C<perlcritic> is a Perl source code analyzer. It is the executable
147front-end to the L<Perl::Critic> engine, which attempts to identify
148awkward, hard to read, error-prone, or unconventional constructs in
149your code. Most of the rules are based on Damian Conway's book B<Perl
150Best Practices>. I highly recommend that you get a copy!
151
152If you want to integrate perlcritic with your build process, the
153L<Test::Perl::Critic> module provides a nice interface that is
154suitable for test scripts.
155
156=head1 ARGUMENTS
157
158The arguments are paths to the files you wish to analyze. You may
159specify multiple files. If no file is specified, then the input is
160read from STDIN.
161
162=head1 OPTIONS
163
164Option names can be abbreviated to uniqueness and can be stated with
165singe or double dashes, and option values can be separated from the
166option name by a space or '=' (a la L<Getopt::Long>). Option names
167are case-sensitive.
168
169=over 8
170
171=item -profile FILE
172
173Directs perlcritic to use a profile named by FILE rather than looking
174for the default F<.perlcriticrc> file in the current directory or your
175home directory. See L<"CONFIGURATION"> for more information.
176
177=item -noprofile
178
179Directs perlcritic not to load any configuration file, thus defaulting
180to load all the Policy modules that are distributed with
181L<Perl::Critic>.
182
183=item -priority N
184
185Sets the the maximum priority value of Policies that should be loaded
186from the C<-profile>. 1 is the "highest" priority, and all numbers
187larger than 1 have "lower" priority. Only Policies that have been
188configured with a priority value less than or equal to N will be
189loaded. For a given C<-profile>, increasing N will result in more
190violations. The default priority is 1. See L<"CONFIGURATION"> for
191more information.
192
193=item -include PATTERN
194
195Directs perlcritic to load only Policy modules from your C<-profile>
196that match the regex C</PATTERN/imx>. The idea here is to provide a
197compact interface for selecting Policies at the command-line. You can
198specify multiple C<-include> options and you can use it in conjunction
199with the C<-exclude> option. Note that C<-exclude> takes precedence
200over C<-include> when a Policy matches both patterns. Using
201C<-exclude> or C<-include> causes the C<-priority> settings to be
202silently ignored.
203
204=item -exclude PATTERN
205
206Directs perlcritic to load Policy modules from your C<-profile> that
207do not match the regex C</PATTERN/imx>. The idea here is to provide a
208compact interface for selecting Policies at the command-line. You can
209specify multiple C<-exclude> options and you can use it in conjunction
210with the C<-include> option. Note that C<-exclude> takes precedence
211over C<-include> when a Policy matches both patterns. Using
212C<-exclude> or C<-include> causes the C<-priority> settings to be
213silently ignored.
214
215=item -force
216
217Directs perlcritic not to observe the magical C<## no critic>
218pseudo-pragmas in the source code. See L<"BENDING THE RULES"> for more
219information.
220
221=item -verbose N | FORMAT
222
223Sets the verbosity level or format for reporting violations. If given
224a number (N), perlcritic reports violations using one of the
225predefined formats described below. If given a string (FORMAT), it is
226interpreted to be an actual format specification. If the C<-verbose>
227option is not specified, it defaults to either 2 or 3, depending on
228whether multiple files were given as arguments to perlcritic.
229
230 Verbosity Format Specification
231 ----------- -------------------------------------------------
232 1 "%f:%l:%c:%m.\n"
233 2 "%m at line %l, column %c. %e.\n"
234 3 "%f: %m at line %l, column %c. %e.\n"
235 4 "[%p] %m at line %1, column %c. %e.\n"
236 5 "[%p] %m at line %1, column %c. %e.\n %d\n"
237
238Formats are a combination of literal and escape characters similar to
239the way C<sprintf> works. See L<String::Format> for a full
240explanation of the formatting capabilities. Valid escape characters
241are:
242
243 Escape Meaning
244 ------- -----------------------------------------------------
245 %m Brief description of the violation
246 %f Name of the file where the violation occurred.
247 %l Line number where the violation occurred
248 %c Column number where the violation occurred
249 %e Explanation of violation or page numbers in PBP
250 %d Full diagnostic discussion of the violation
251 %p Name of the Policy module that created the violation
252
253The purpose of these formats is to provide some compatibility with
254editors that have an interface for parsing certain kinds of input. See
255L<"EDITOR INTEGRATION"> for more information about that.
256
257=item -safari
258
259Report "Perl Best Practice" citations as section numbers from
260L<http://safari.oreilly.com> instead of page numbers from the actual
261book. NOTE: This feature is not implemented yet.
262
263=item -help
264
265=item -?
266
267Displays a brief summary of options and exits.
268
269=item -man
270
271Displays the complete perlcritic manual and exits.
272
273=item -Version
274
275=item -V
276
277Displays the version number of perlcritic and exits.
278
279=back
280
281=head1 CONFIGURATION
282
283The default configuration file is called F<.perlcriticrc>.
284Perl::Critic will look for this file in the current directory first,
285and then in your home directory. Alternatively, you can set the
286PERLCRITIC environment variable to explicitly point to a different
287configuration file in another location. If none of these files exist,
288And the C<-profile> option is not given at the command-line,
289perlcritic defaults to loading all the Policies that are distributed
290with L<Perl::Critic>.
291
292The format of the configuration file is a series of named sections
293that contain key-value pairs separated by '='. Comments should
294start with '#' and can be placed on a separate line or after the
295name-value pairs if you desire. The general recipe is a series of
296blocks like this:
297
298 [Perl::Critic::Policy::Category::PolicyName]
299 priority = 1
300 arg1 = value1
301 arg2 = value2
302
303C<Perl::Critic::Policy::Category::PolicyName> is the full name of a
304module that implements the policy you want to load into the engine.
305The Policy modules distributed with Perl::Critic have been grouped
306into categories according to the table of contents in Damian Conway's
307book B<Perl Best Practices>. For brevity, you can omit the
308C<'Perl::Critic::Policy'> part of the module name. The module must be
309a subclass of L<Perl::Critic::Policy>.
310
311C<priority> is the level of importance you wish to assign to this
312policy. 1 is the "highest" priority level, and all numbers greater
313than 1 have increasingly "lower" priority. Only those policies with a
314priority less than or equal to the C<-priority> value given on the
315command-line will be loaded. The priority can be an arbitrarily large
316positive integer. If the priority is not defined, it defaults to 1.
317
318The remaining key-value pairs are configuration parameters for that
319specific Policy and will be passed into the constructor of the
320L<Perl::Critic::Policy> subclass. The constructors for most Policy
321modules do not support arguments, and those that do should have
322reasonable defaults. See the documentation in the relevant Policy
323module for more details.
324
325By default, all the policies that are distributed with C<Perl::Critic>
326are loaded. Rather than assign a priority level to a Policy, you can
327simply "turn off" a Policy by prepending a '-' to the name of the
328module in the config file. In this manner, the Policy will never be
329loaded, regardless of the C<-priority> option given at the
330command-line.
331
332
333A sample configuration might look like this:
334
335 #--------------------------------------------------------------
336 # These are really important, so always load them
337
338 [TestingAndDebugging::RequirePackageStricture]
339 priority = 1
340
341 [TestingAndDebugging::RequirePackageWarnings]
342 priority = 1
343
344 #--------------------------------------------------------------
345 # These are less important, so only load when asked
346
347 [Variables::ProhibitPackageVars]
348 priority = 2
349
350 [ControlStructures::ProhibitPostfixControls]
351 priority = 2
352
353 #--------------------------------------------------------------
354 # I don't agree with these, so never load them
355
356 [-NamingConventions::ProhibitMixedCaseVars]
357 [-NamingConventions::ProhibitMixedCaseSubs]
358
359=head1 THE POLICIES
360
361The following Policy modules are distributed with Perl::Critic. The
362Policy modules have been categorized according to the table of
363contents in Damian Conway's book B<Perl Best Practices>. Since most
364coding standards take the form "do this..." or "don't do that...", I
365have adopted the convention of naming each module C<RequireSomething>
366or C<ProhibitSomething>. See the documentation of each module for
367it's specific details.
368
369=head2 L<Perl::Critic::Policy::BuiltinFunctions::ProhibitLvalueSubstr>
370
371Use 4-argument C<substr> instead of writing C<substr($foo, 2, 6) = $bar>
372
373=head2 L<Perl::Critic::Policy::BuiltinFunctions::ProhibitSleepViaSelect>
374
375Use L<Time::HiRes> instead of something like C<select(undef, undef, undef, .05)>
376
377=head2 L<Perl::Critic::Policy::BuiltinFunctions::ProhibitStringyEval>
378
379Write C<eval { my $foo; bar($foo) }> instead of C<eval "my $foo; bar($foo);">
380
381=head2 L<Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep>
382
383Write C<grep { $_ =~ /$pattern/ } @list> instead of C<grep /$pattern/, @list>
384
385=head2 L<Perl::Critic::Policy::BuiltinFunctions::RequireBlockMap>
386
387Write C<map { $_ =~ /$pattern/ } @list> instead of C<map /$pattern/, @list>
388
389=head2 L<Perl::Critic::Policy::BuiltinFunctions::RequireGlobFunction>
390
391Use C<glob q{*}> instead of <*>
392
393=head2 L<Perl::Critic::Policy::ClassHierarchies::ProhibitOneArgBless>
394
395Write C<bless {}, $class;> instead of just C<bless {};>
396
397=head2 L<Perl::Critic::Policy::CodeLayout::ProhibitHardTabs>
398
399Use spaces instead of tabs
400
401=head2 L<Perl::Critic::Policy::CodeLayout::ProhibitParensWithBuiltins>
402
403Write C<open $handle, $path> instead of C<open($handle, $path)>
404
405=head2 L<Perl::Critic::Policy::CodeLayout::ProhibitQuotedWordLists>
406
407Write C< qw(foo bar baz) > instead of C< ('foo', 'bar', 'baz') >
408
409=head2 L<Perl::Critic::Policy::CodeLayout::RequireTidyCode>
410
411Must run code through L<perltidy>
412
413=head2 L<Perl::Critic::Policy::CodeLayout::RequireTrailingCommas>
414
415Put a comma at the end of every multi-line list declaration, including the last one
416
417=head2 L<Perl::Critic::Policy::ControlStructures::ProhibitCascadingIfElse>
418
419Don't write long "if-elsif-elsif-elsif-elsif...else" chains
420
421=head2 L<Perl::Critic::Policy::ControlStructures::ProhibitCStyleForLoops>
422
423Write C<for(0..20)> instead of C<for($i=0; $i<=20; $i++)>
424
425=head2 L<Perl::Critic::Policy::ControlStructures::ProhibitPostfixControls>
426
427Write C<if($condition){ do_something() }> instead of C<do_something() if $condition>
428
429=head2 L<Perl::Critic::Policy::ControlStructures::ProhibitUnlessBlocks>
430
431Write C<if(! $condition)> instead of C<unless($condition)>
432
433=head2 L<Perl::Critic::Policy::ControlStructures::ProhibitUntilBlocks>
434
435Write C<while(! $condition)> instead of C<until($condition)>
436
437=head2 L<Perl::Critic::Policy::InputOutput::ProhibitBacktickOperators>
438
439Discourage stuff like C<@files = `ls $directory`>
440
441=head2 L<Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles>
442
443Write C<open my $fh, q{<}, $filename;> instead of C<open FH, q{<}, $filename;>
444
445=head2 L<Perl::Critic::Policy::InputOutput::ProhibitOneArgSelect>
446
447Never write C<select($fh)>
448
449=head2 L<Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen>
450
451Write C<open $fh, q{<}, $filename;> instead of C<open $fh, "<$filename";>
452
453=head2 L<Perl::Critic::Policy::Miscellanea::RequireRcsKeywords>
454
455Put source-control keywords in every file.
456
457=head2 L<Perl::Critic::Policy::Modules::ProhibitMultiplePackages>
458
459Put packages (especially subclasses) in separate files
460
461=head2 L<Perl::Critic::Policy::Modules::RequireBarewordIncludes>
462
463Write C<require Module> instead of C<require 'Module.pm'>
464
465=head2 L<Perl::Critic::Policy::Modules::ProhibitSpecificModules>
466
467Don't use evil modules
468
469=head2 L<Perl::Critic::Policy::Modules::RequireExplicitPackage>
470
471Always make the C<package> explicit
472
473=head2 L<Perl::Critic::Policy::Modules::RequireVersionVar>
474
475Give every module a C<$VERSION> number
476
477=head2 L<Perl::Critic::Policy::RegularExpressions::RequireLineBoundaryMatching>
478
479Always use the C</m> modifier with regular expressions
480
481=head2 L<Perl::Critic::Policy::RegularExpressions::RequireExtendedFormatting>
482
483Always use the C</x> modifier with regular expressions
484
485=head2 L<Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseSubs>
486
487Write C<sub my_function{}> instead of C<sub MyFunction{}>
488
489=head2 L<Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseVars>
490
491Write C<$my_variable = 42> instead of C<$MyVariable = 42>
492
493=head2 L<Perl::Critic::Policy::Subroutines::ProhibitBuiltinHomonyms>
494
495Don't declare your own C<open> function.
496
497=head2 L<Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef>
498
499Return failure with bare C<return> instead of C<return undef>
500
501=head2 L<Perl::Critic::Policy::Subroutines::ProhibitSubroutinePrototypes>
502
503Don't write C<sub my_function (@@) {}>
504
505=head2 L<Perl::Critic::Policy::TestingAndDebugging::RequirePackageStricture>
506
507Always C<use strict>
508
509=head2 L<Perl::Critic::Policy::TestingAndDebugging::RequirePackageWarnings>
510
511Always C<use warnings>
512
513=head2 L<Perl::Critic::Policy::ValuesAndExpressions::ProhibitConstantPragma>
514
515Don't C< use constant $FOO => 15 >
516
517=head2 L<Perl::Critic::Policy::ValuesAndExpressions::ProhibitEmptyQuotes>
518
519Write C<q{}> instead of C<''>
520
521=head2 L<Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals>
522
523Always use single quotes for literal strings.
524
525=head2 L<Perl::Critic::Policy::ValuesAndExpressions::ProhibitLeadingZeros>
526
527Write C<oct(755)> instead of C<0755>
528
529=head2 L<Perl::Critic::Policy::ValuesAndExpressions::ProhibitNoisyQuotes>
530
531Use C<q{}> or C<qq{}> instead of quotes for awkward-looking strings
532
533=head2 L<Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars>
534
535Warns that you might have used single quotes when you really wanted double-quotes.
536
537=head2 L<Perl::Critic::Policy::ValuesAndExpressions::RequireNumberSeparators>
538
539Write C< 141_234_397.0145 > instead of C< 141234397.0145 >
540
541=head2 L<Perl::Critic::Policy::ValuesAndExpressions::RequireQuotedHeredocTerminator>
542
543Write C< print <<'THE_END' > or C< print <<"THE_END" >
544
545=head2 L<Perl::Critic::Policy::ValuesAndExpressions::RequireUpperCaseHeredocTerminator>
546
547Write C< <<'THE_END'; > instead of C< <<'theEnd'; >
548
549=head2 L<Perl::Critic::Policy::Variables::ProhibitLocalVars>
550
551Use C<my> instead of C<local>, except when you have to.
552
553=head2 L<Perl::Critic::Policy::Variables::ProhibitPackageVars>
554
555Eliminate globals declared with C<our> or C<use vars>
556
557=head2 L<Perl::Critic::Policy::Variables::ProhibitPunctuationVars>
558
559Write C<$EVAL_ERROR> instead of C<$@>
560
561=head1 BENDING THE RULES
562
563B<NOTE:> This feature changed in version 0.09 and is not backward
564compatible with earlier versions.
565
566Perl::Critic takes a hard-line approach to your code: either you
567comply or you don't. In the real world, it is not always practical
568(or even possible) to fully comply with coding standards. In such
569cases, it is wise to show that you are knowingly violating the
570standards and that you have a Damn Good Reason (DGR) for doing so.
571
572To help with those situations, you can direct Perl::Critic to ignore
573certain lines or blocks of code by using pseudo-pragmas:
574
575 require 'LegacyLibaray1.pl'; ## no critic
576 require 'LegacyLibrary2.pl'; ## no critic
577
578 for my $element (@list) {
579
580 ## no critic
581
582 $foo = ""; #Violates 'ProhibitEmptyQuotes'
583 $barf = bar() if $foo; #Violates 'ProhibitPostfixControls'
584 #Some more evil code...
585
586 ## use critic
587
588 #Some good code...
589 do_something($_);
590 }
591
592
593The C<"## no critic"> comments direct Perl::Critic to overlook the
594remaining lines of code until the end of the current block, or until a
595C<"## use critic"> comment is found (whichever comes first). If the
596C<"## no critic"> comment is on the same line as a code statement,
597then only that line of code is overlooked. To direct perlcritic to
598ignore the C<"## no critic"> comments, use the C<-force> option.
599
600Use this feature wisely. C<"## no critic"> should be used in the
601smallest possible scope, or only on individual lines of code. If
602Perl::Critic complains about your code, try and find a compliant
603solution before resorting to this feature.
604
605=head1 EDITOR INTEGRATION
606
607For ease-of-use, perlcritic can be integrated with your favorite text
608editor. The output-formatting capabilities of perlcritic are
609specifically intended for use with the "grep" or "compile" modes
610available in editors like C<emacs> and C<vim>. In these modes, you can
611run an arbitrary command and the editor will parse the output into an
612interactive buffer that you can click on and jump to the relevant line
613of code.
614
615=head2 EMACS
616
617Entering C<'Meta-x compile'> causes emacs to switch to compile-mode.
618Next, enter the following command in the minibuffer:
619
620 perlcritic -verbose 1 path/to/your/file
621
622When the results are displayed, pressing [Enter] on any of the
623Violation messages will move the pointer to the relevant location
624within the file. Type C<'Ctrl-h a compile'> for information about
625compile-mode.
626
627=head2 VIM
628
629Configure the grep format as follows:
630
631 set grepformat=%f:%l:%c:m
632 set grepprg=perlcritic\ -verbose\ 1\ %
633
634Then, you can run perlcritic on the current buffer with:
635
636 :grep
637
638Navigation and display instructions can be found under C<:help grep>.
639Someone with stronger Vim-fu may wish to convert this to a real macro.
640
641=head1 EXIT STATUS
642
643If perlcritic has any errors itself, exits with status == 1. If there
644are no errors, but perlcritic finds Policy violations in your source
645code, exits with status == 2. If there were no errors and no
646violations were found, exits with status == 0.
647
648=head1 BUGS
649
650Scrutinizing Perl code is hard for humans, let alone machines. If you
651find any bugs, particularly false-positives or false-negatives from a
652Perl::Critic::Policy, please submit them to
653L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Perl-Critic>. Thanks.
654
655=head1 CREDITS
656
657Adam Kennedy - For creating L<PPI>, the heart and soul of Perl::Critic.
658
659Damian Conway - For writing B<Perl Best Practices>.
660
661Giuseppe Maxia - For all the great ideas and enhancements.
662
663Chris Dolan - For numerous bug reports and suggestions.
664
665Sharon, my wife - For putting up with my all-night code sessions.
666
667=head1 AUTHOR
668
669Jeffrey Ryan Thalhammer <thaljef@cpan.org>
670
671=head1 COPYRIGHT
672
673Copyright (c) 2005 Jeffrey Ryan Thalhammer. All rights reserved.
674
675This program is free software; you can redistribute it and/or modify
676it under the same terms as Perl itself. The full text of this license
677can be found in the LICENSE file included with this module.
678
679=cut