File Coverage

blib/lib/Perl/ToPerl6.pm
Criterion Covered Total %
statement 100 113 88.5
branch 20 34 58.8
condition 8 18 44.4
subroutine 24 25 96.0
pod 6 6 100.0
total 158 196 80.6


line stmt bran cond sub pod time code
1             package Perl::ToPerl6;
2              
3 12     12   1300 use 5.006001;
  12         35  
4 12     12   53 use strict;
  12         19  
  12         275  
5 12     12   53 use warnings;
  12         16  
  12         399  
6              
7 12     12   55 use English qw(-no_match_vars);
  12         17  
  12         86  
8 12     12   4549 use Readonly;
  12         79  
  12         614  
9              
10 12     12   58 use Exporter 'import';
  12         16  
  12         322  
11              
12 12     12   49 use File::Spec;
  12         17  
  12         315  
13 12     12   48 use List::MoreUtils qw< firstidx >;
  12         20  
  12         127  
14 12     12   5124 use Scalar::Util qw< blessed >;
  12         21  
  12         620  
15              
16 12     12   3892 use Perl::ToPerl6::Exception::Configuration::Generic;
  12         26  
  12         595  
17 12     12   6303 use Perl::ToPerl6::Config;
  12         30  
  12         453  
18 12     12   77 use Perl::ToPerl6::Transformation;
  12         19  
  12         286  
19 12     12   6162 use Perl::ToPerl6::Document;
  12         34  
  12         476  
20 12     12   5712 use Perl::ToPerl6::Statistics;
  12         29  
  12         669  
21 12     12   82 use Perl::ToPerl6::Utils qw< :characters hashify shebang_line >;
  12         18  
  12         809  
22              
23             #-----------------------------------------------------------------------------
24              
25             our $VERSION = '0.031';
26              
27             Readonly::Array our @EXPORT_OK => qw(transform);
28              
29             #=============================================================================
30             # PUBLIC methods
31              
32             sub new {
33 7     7 1 14428 my ( $class, %args ) = @_;
34 7         17 my $self = bless {}, $class;
35 7   66     78 $self->{_config} = $args{-config} || Perl::ToPerl6::Config->new( %args );
36 6         52 $self->{_stats} = Perl::ToPerl6::Statistics->new();
37 6         22 return $self;
38             }
39              
40             #-----------------------------------------------------------------------------
41              
42             sub config {
43 20     20 1 49 my $self = shift;
44 20         77 return $self->{_config};
45             }
46              
47             #-----------------------------------------------------------------------------
48              
49             sub apply_transform {
50 0     0 1 0 my ( $self, @args ) = @_;
51             #Delegate to Perl::ToPerl6::Config
52 0         0 return $self->config()->apply_transform( @args );
53             }
54              
55             #-----------------------------------------------------------------------------
56              
57             sub transformers {
58 4     4 1 7 my $self = shift;
59              
60             #Delegate to Perl::ToPerl6::Config
61 4         11 return $self->config()->transformers();
62             }
63              
64             #-----------------------------------------------------------------------------
65              
66             sub statistics {
67 5     5 1 397 my $self = shift;
68 5         29 return $self->{_stats};
69             }
70              
71             #-----------------------------------------------------------------------------
72              
73             sub transform {
74              
75             #-------------------------------------------------------------------
76             # This subroutine can be called as an object method or as a static
77             # function. In the latter case, the first argument can be a
78             # hashref of configuration parameters that shall be used to create
79             # an object behind the scenes. Note that this object does not
80             # persist. In other words, it is not a singleton.
81             #
82             # In addition, if it is called with a trailing 'doc => \$ref'
83             # named argument, the reference is populated with the serialized document.
84             # This is only really needed for test suites.
85             #
86             # Here are some of the ways this subroutine might get called:
87             #
88             # #Object style...
89             # $mogrify->transform( $code );
90             # $mogrify->transform( $code, doc => \$my_doc );
91             #
92             # #Functional style...
93             # transform( $code );
94             # transform( {}, $code );
95             # transform( {-foo => bar}, $code );
96             # transform( {-foo => bar}, $code, doc => \$my_doc );
97             #------------------------------------------------------------------
98              
99 6 100   6 1 3029 my ( $self, $source_code ) = @_ >= 2 ? @_ : ( {}, $_[0] );
100 6 100       20 $self = ref $self eq 'HASH' ? __PACKAGE__->new(%{ $self }) : $self;
  4         19  
101 6 100       91 return if not defined $source_code; # If no code, then nothing to do.
102              
103 4         15 my $config = $self->config();
104 4 50 33     33 my $doc =
105             blessed($source_code) && $source_code->isa('Perl::ToPerl6::Document')
106             ? $source_code
107             : Perl::ToPerl6::Document->new(
108             '-source' => $source_code,
109             '-program-extensions' => [$config->program_extensions_as_regexes()],
110             );
111              
112 4 50       16 if ( 0 == $self->transformers() ) {
113 0         0 Perl::ToPerl6::Exception::Configuration::Generic->throw(
114             message => 'There are no enabled transformers.',
115             )
116             }
117              
118 4         14 my @transformations = $self->_gather_transformations($doc);
119              
120             # Never thought I'd be smuggling myself in one of these.
121             #
122 4 50 66     29 if ( $_[-2] and $_[-2] eq 'doc' ) {
123 0         0 ${$_[-1]} = $doc->serialize;
  0         0  
124             }
125 4 50       17 unless( ref $source_code ) {
126 0 0       0 open my $fh, '>', $source_code . '.pl6'
127             or die "Could not write to '$source_code.pl6': $!";
128 0         0 print $fh $doc->serialize;
129 0         0 close $fh;
130             }
131 4         81 return @transformations;
132             }
133              
134             #=============================================================================
135             # PRIVATE methods
136              
137             sub _gather_transformations {
138 4     4   7 my ($self, $doc) = @_;
139              
140             # Disable exempt code lines, if desired
141 4 50       8 if ( not $self->config->force() ) {
142 4         13 $doc->process_annotations();
143             }
144              
145             # Evaluate each transformer
146 4         106 my @transformers = $self->config->transformers();
147 4         18 my @ordered_transformers = _futz_with_transformer_order(@transformers);
148 4         10 my @transformations = map { _transform($_, $doc) } @ordered_transformers;
  151         240  
149              
150             # Accumulate statistics
151 4         16 $self->statistics->accumulate( $doc, \@transformations );
152              
153             # If requested, rank transformations by their severity and return the top N.
154 4 50 33     50 if ( @transformations && (my $top = $self->config->top()) ) {
155 0 0       0 my $limit = @transformations < $top ? $#transformations : $top-1;
156 0         0 @transformations = Perl::ToPerl6::Transformation::sort_by_severity(@transformations);
157 0         0 @transformations = ( reverse @transformations )[ 0 .. $limit ]; #Slicing...
158             }
159              
160             # Always return transformations sorted by location
161 4         20 return Perl::ToPerl6::Transformation->sort_by_location(@transformations);
162             }
163              
164             #=============================================================================
165             # PRIVATE functions
166              
167             sub _transform {
168 151     151   165 my ($transformer, $doc) = @_;
169              
170 151 50       766 return if not $transformer->prepare_to_scan_document($doc);
171              
172 151         511 my $maximum_transformations = $transformer->get_maximum_transformations_per_document();
173 151 50 33     367 return if defined $maximum_transformations && $maximum_transformations == 0;
174              
175 151         155 my @transformations = ();
176              
177             TYPE:
178 151         585 for my $type ( $transformer->applies_to() ) {
179 159         138 my @elements;
180 159 100       282 if ($type eq 'PPI::Document') {
181 4         9 @elements = ($doc);
182             }
183             else {
184 155 100       123 @elements = @{ $doc->find($type) || [] };
  155         369  
185             }
186              
187             ELEMENT:
188 159         1584 for my $element (@elements) {
189              
190             # Evaluate the transformer on this $element. A transformer may
191             # return zero or more transformations. We only want the
192             # transformations that occur on lines that have not been
193             # disabled.
194              
195             VIOLATION:
196 26         92 for my $transformation ( $transformer->transform( $element, $doc ) ) {
197              
198 19         65 my $line = $transformation->location()->[0];
199 19 50       77 if ( $doc->line_is_disabled_for_transformer($line, $transformer) ) {
200 0         0 $doc->add_suppressed_transformation($transformation);
201 0         0 next VIOLATION;
202             }
203              
204 19         207 push @transformations, $transformation;
205 19 50 33     80 last TYPE if defined $maximum_transformations and @transformations >= $maximum_transformations;
206             }
207             }
208             }
209              
210 151         513 return @transformations;
211             }
212              
213             #-----------------------------------------------------------------------------
214              
215             sub _futz_with_transformer_order {
216             # The ProhibitUselessNoCritic transformer is another special transformer. It
217             # deals with the transformations that *other* Transformers produce. Therefore
218             # it needs to be run *after* all the other Transformers. TODO: find
219             # a way for Transformers to express an ordering preference somehow.
220              
221 4     4   14 my @transformer_objects = @_;
222 4         8 my $magical_transformer_name = 'Perl::ToPerl6::Transformer::Miscellanea::ProhibitUselessNoCritic';
223 4     151   37 my $idx = firstidx {ref $_ eq $magical_transformer_name} @transformer_objects;
  151         187  
224 4         22 push @transformer_objects, splice @transformer_objects, $idx, 1;
225 4         27 return @transformer_objects;
226             }
227              
228             #-----------------------------------------------------------------------------
229              
230             1;
231              
232              
233              
234             __END__
235              
236             =pod
237              
238             =for stopwords DGR INI-style API -params refactored ActivePerl ben Jore
239             Dolan's Twitter Alexandr Ciornii Ciornii's downloadable
240              
241             =head1 NAME
242              
243             Perl::ToPerl6 - Critique Perl source code for best-practices.
244              
245              
246             =head1 SYNOPSIS
247              
248             use Perl::ToPerl6;
249             my $file = shift;
250             my $mogrify = Perl::ToPerl6->new();
251             my @transformations = $mogrify->transform($file);
252             print @transformations;
253              
254              
255             =head1 DESCRIPTION
256              
257             Perl::ToPerl6 is an extensible framework for creating and applying coding
258             standards to Perl source code. Essentially, it is a static source code
259             analysis engine. Perl::ToPerl6 is distributed with a number of
260             L<Perl::ToPerl6::Transformer> modules that attempt to enforce various coding
261             guidelines. Most Transformer modules are based on Damian Conway's book B<Perl Best
262             Practices>. However, Perl::ToPerl6 is B<not> limited to PBP and will even
263             support Transformers that contradict Conway. You can enable, disable, and
264             customize those Polices through the Perl::ToPerl6 interface. You can also
265             create new Transformer modules that suit your own tastes.
266              
267             For a command-line interface to Perl::ToPerl6, see the documentation for
268             L<perlmogrify>. If you want to integrate Perl::ToPerl6 with your build process,
269             L<Test::Perl::ToPerl6> provides an interface that is suitable for test
270             programs. Also, L<Test::Perl::ToPerl6::Progressive> is useful for gradually
271             applying coding standards to legacy code. For the ultimate convenience (at
272             the expense of some flexibility) see the L<mogrification> pragma.
273              
274             If you'd like to try L<Perl::ToPerl6> without installing anything, there is a
275             web-service available at L<http://perlmogrify.com>. The web-service does not
276             yet support all the configuration features that are available in the native
277             Perl::ToPerl6 API, but it should give you a good idea of what it does.
278              
279             Also, ActivePerl includes a very slick graphical interface to Perl-ToPerl6
280             called C<perlmogrify-gui>. You can get a free community edition of ActivePerl
281             from L<http://www.activestate.com>.
282              
283              
284             =head1 INTERFACE SUPPORT
285              
286             This is considered to be a public class. Any changes to its interface will go
287             through a deprecation cycle.
288              
289              
290             =head1 CONSTRUCTOR
291              
292             =over
293              
294             =item C<< new( [ -profile => $FILE, -severity => $N, -theme => $string, -include => \@PATTERNS, -exclude => \@PATTERNS, -top => $N, -only => $B, -profile-strictness => $PROFILE_STRICTNESS_{WARN|FATAL|QUIET}, -force => $B, -verbose => $N ], -color => $B, -pager => $string, -allow-unsafe => $B, -mogrification-fatal => $B) >>
295              
296             =item C<< new() >>
297              
298             Returns a reference to a new Perl::ToPerl6 object. Most arguments are just
299             passed directly into L<Perl::ToPerl6::Config>, but I have described them here
300             as well. The default value for all arguments can be defined in your
301             F<.perlmogrifyrc> file. See the L<"CONFIGURATION"> section for more
302             information about that. All arguments are optional key-value pairs as
303             follows:
304              
305             B<-profile> is a path to a configuration file. If C<$FILE> is not defined,
306             Perl::ToPerl6::Config attempts to find a F<.perlmogrifyrc> configuration file in
307             the current directory, and then in your home directory. Alternatively, you
308             can set the C<PERLMOGRIFY> environment variable to point to a file in another
309             location. If a configuration file can't be found, or if C<$FILE> is an empty
310             string, then all Transformers will be loaded with their default configuration.
311             See L<"CONFIGURATION"> for more information.
312              
313             B<-severity> is the minimum severity level. Only Transformer modules that have a
314             severity greater than C<$N> will be applied. Severity values are integers
315             ranging from 1 (least severe transformations) to 5 (most severe transformations). The
316             default is 5. For a given C<-profile>, decreasing the C<-severity> will
317             usually reveal more Transformer transformations. You can set the default value for this
318             option in your F<.perlmogrifyrc> file. Users can redefine the severity level
319             for any Transformer in their F<.perlmogrifyrc> file. See L<"CONFIGURATION"> for
320             more information.
321              
322             If it is difficult for you to remember whether severity "5" is the most or
323             least restrictive level, then you can use one of these named values:
324              
325             SEVERITY NAME ...is equivalent to... SEVERITY NUMBER
326             --------------------------------------------------------
327             -severity => 'gentle' -severity => 5
328             -severity => 'stern' -severity => 4
329             -severity => 'harsh' -severity => 3
330             -severity => 'cruel' -severity => 2
331             -severity => 'brutal' -severity => 1
332              
333             The names reflect how severely the code is mogrified: a C<gentle>
334             mogrification reports only the most severe transformations, and so on down to a
335             C<brutal> mogrification which reports even the most minor transformations.
336              
337             B<-theme> is special expression that determines which Transformers to apply
338             based on their respective themes. For example, the following would load only
339             Transformers that have a 'bugs' AND 'core' theme:
340              
341             my $mogrify = Perl::ToPerl6->new( -theme => 'bugs && core' );
342              
343             Unless the C<-severity> option is explicitly given, setting C<-theme> silently
344             causes the C<-severity> to be set to 1. You can set the default value for
345             this option in your F<.perlmogrifyrc> file. See the L<"POLICY THEMES"> section
346             for more information about themes.
347              
348              
349             B<-include> is a reference to a list of string C<@PATTERNS>. Transformer modules
350             that match at least one C<m/$PATTERN/ixms> will always be loaded, irrespective
351             of all other settings. For example:
352              
353             my $mogrify = Perl::ToPerl6->new(-include => ['layout'] -severity => 4);
354              
355             This would cause Perl::ToPerl6 to apply all the C<CodeLayout::*> Transformer modules
356             even though they have a severity level that is less than 4. You can set the
357             default value for this option in your F<.perlmogrifyrc> file. You can also use
358             C<-include> in conjunction with the C<-exclude> option. Note that C<-exclude>
359             takes precedence over C<-include> when a Transformer matches both patterns.
360              
361             B<-exclude> is a reference to a list of string C<@PATTERNS>. Transformer modules
362             that match at least one C<m/$PATTERN/ixms> will not be loaded, irrespective of
363             all other settings. For example:
364              
365             my $mogrify = Perl::ToPerl6->new(-exclude => ['strict'] -severity => 1);
366              
367             This would cause Perl::ToPerl6 to not apply the C<RequireUseStrict> and
368             C<ProhibitNoStrict> Transformer modules even though they have a severity level that
369             is greater than 1. You can set the default value for this option in your
370             F<.perlmogrifyrc> file. You can also use C<-exclude> in conjunction with the
371             C<-include> option. Note that C<-exclude> takes precedence over C<-include>
372             when a Transformer matches both patterns.
373              
374             B<-single-transformer> is a string C<PATTERN>. Only one transformer that matches
375             C<m/$PATTERN/ixms> will be used. Transformers that do not match will be
376             excluded. This option has precedence over the C<-severity>, C<-theme>,
377             C<-include>, C<-exclude>, and C<-only> options. You can set the default value
378             for this option in your F<.perlmogrifyrc> file.
379              
380             B<-top> is the maximum number of Transformations to return when ranked by their
381             severity levels. This must be a positive integer. Transformations are still
382             returned in the order that they occur within the file. Unless the C<-severity>
383             option is explicitly given, setting C<-top> silently causes the C<-severity>
384             to be set to 1. You can set the default value for this option in your
385             F<.perlmogrifyrc> file.
386              
387             B<-only> is a boolean value. If set to a true value, Perl::ToPerl6 will only
388             choose from Transformers that are mentioned in the user's profile. If set to a
389             false value (which is the default), then Perl::ToPerl6 chooses from all the
390             Transformers that it finds at your site. You can set the default value for this
391             option in your F<.perlmogrifyrc> file.
392              
393             B<-profile-strictness> is an enumerated value, one of
394             L<Perl::ToPerl6::Utils::Constants/"$PROFILE_STRICTNESS_WARN"> (the default),
395             L<Perl::ToPerl6::Utils::Constants/"$PROFILE_STRICTNESS_FATAL">, and
396             L<Perl::ToPerl6::Utils::Constants/"$PROFILE_STRICTNESS_QUIET">. If set to
397             L<Perl::ToPerl6::Utils::Constants/"$PROFILE_STRICTNESS_FATAL">, Perl::ToPerl6
398             will make certain warnings about problems found in a F<.perlmogrifyrc> or file
399             specified via the B<-profile> option fatal. For example, Perl::ToPerl6 normally
400             only C<warn>s about profiles referring to non-existent Transformers, but this
401             value makes this situation fatal. Correspondingly,
402             L<Perl::ToPerl6::Utils::Constants/"$PROFILE_STRICTNESS_QUIET"> makes
403             Perl::ToPerl6 shut up about these things.
404              
405             B<-force> is a boolean value that controls whether Perl::ToPerl6 observes the
406             magical C<"## no mogrify"> annotations in your code. If set to a true value,
407             Perl::ToPerl6 will analyze all code. If set to a false value (which is the
408             default) Perl::ToPerl6 will ignore code that is tagged with these annotations.
409             See L<"BENDING THE RULES"> for more information. You can set the default
410             value for this option in your F<.perlmogrifyrc> file.
411              
412             B<-verbose> can be a positive integer (from 1 to 11), or a literal format
413             specification. See L<Perl::ToPerl6::Transformation|Perl::ToPerl6::Transformation> for an
414             explanation of format specifications. You can set the default value for this
415             option in your F<.perlmogrifyrc> file.
416              
417             B<-unsafe> directs Perl::ToPerl6 to allow the use of Transformers that are
418             marked as "unsafe" by the author. Such transformers may compile untrusted code
419             or do other nefarious things.
420              
421             B<-color> and B<-pager> are not used by Perl::ToPerl6 but is provided for the
422             benefit of L<perlmogrify|perlmogrify>.
423              
424             B<-mogrification-fatal> is not used by Perl::ToPerl6 but is provided for the
425             benefit of L<mogrification|mogrification>.
426              
427             B<-color-severity-highest>, B<-color-severity-high>, B<-color-severity-
428             medium>, B<-color-severity-low>, and B<-color-severity-lowest> are not used by
429             Perl::ToPerl6, but are provided for the benefit of L<perlmogrify|perlmogrify>.
430             Each is set to the Term::ANSIColor color specification to be used to display
431             transformations of the corresponding severity.
432              
433             B<-files-with-transformations> and B<-files-without-transformations> are not used by
434             Perl::ToPerl6, but are provided for the benefit of L<perlmogrify|perlmogrify>, to
435             cause only the relevant filenames to be displayed.
436              
437             =back
438              
439              
440             =head1 METHODS
441              
442             =over
443              
444             =item C<transform( $source_code )>
445              
446             Runs the C<$source_code> through the Perl::ToPerl6 engine using all the
447             Transformers that have been loaded into this engine. If C<$source_code> is a
448             scalar reference, then it is treated as a string of actual Perl code. If
449             C<$source_code> is a reference to an instance of L<PPI::Document>, then that
450             instance is used directly. Otherwise, it is treated as a path to a local file
451             containing Perl code. This method returns a list of
452             L<Perl::ToPerl6::Transformation> objects for each transformation of the loaded
453             Transformers.
454             The list is sorted in the order that the Transformations appear in the code. If
455             there are no transformations, this method returns an empty list.
456              
457             =item C<< apply_transform( -transformer => $transformer_name, -params => \%param_hash ) >>
458              
459             Creates a Transformer object and loads it into this ToPerl6. If the object cannot
460             be instantiated, it will throw a fatal exception. Otherwise, it returns a
461             reference to this ToPerl6.
462              
463             B<-transformer> is the name of a L<Perl::ToPerl6::Transformer> subclass module. The
464             C<'Perl::ToPerl6::Transformer'> portion of the name can be omitted for brevity.
465             This argument is required.
466              
467             B<-params> is an optional reference to a hash of Transformer parameters. The
468             contents of this hash reference will be passed into to the constructor of the
469             Transformer module. See the documentation in the relevant Transformer module for a
470             description of the arguments it supports.
471              
472             =item C< transformers() >
473              
474             Returns a list containing references to all the Transformer objects that have been
475             loaded into this engine. Objects will be in the order that they were loaded.
476              
477             =item C< config() >
478              
479             Returns the L<Perl::ToPerl6::Config> object that was created for or given to
480             this ToPerl6.
481              
482             =item C< statistics() >
483              
484             Returns the L<Perl::ToPerl6::Statistics> object that was created for this
485             ToPerl6. The Statistics object accumulates data for all files that are
486             analyzed by this ToPerl6.
487              
488             =back
489              
490              
491             =head1 FUNCTIONAL INTERFACE
492              
493             For those folks who prefer to have a functional interface, The C<transform>
494             method can be exported on request and called as a static function. If the
495             first argument is a hashref, its contents are used to construct a new
496             Perl::ToPerl6 object internally. The keys of that hash should be the same as
497             those supported by the C<Perl::ToPerl6::new()> method. Here are some examples:
498              
499             use Perl::ToPerl6 qw(transform);
500              
501             # Use default parameters...
502             @transformations = transform( $some_file );
503              
504             # Use custom parameters...
505             @transformations = transform( {-severity => 2}, $some_file );
506              
507             # As a one-liner
508             %> perl -MPerl::ToPerl6=transform -e 'print transform(shift)' some_file.pm
509              
510             None of the other object-methods are currently supported as static
511             functions. Sorry.
512              
513              
514             =head1 CONFIGURATION
515              
516             Most of the settings for Perl::ToPerl6 and each of the Transformer modules can be
517             controlled by a configuration file. The default configuration file is called
518             F<.perlmogrifyrc>. Perl::ToPerl6 will look for this file in the current
519             directory first, and then in your home directory. Alternatively, you can set
520             the C<PERLMOGRIFY> environment variable to explicitly point to a different file
521             in another location. If none of these files exist, and the C<-profile> option
522             is not given to the constructor, then all the modules that are found in the
523             Perl::ToPerl6::Transformer namespace will be loaded with their default
524             configuration.
525              
526             The format of the configuration file is a series of INI-style blocks that
527             contain key-value pairs separated by '='. Comments should start with '#' and
528             can be placed on a separate line or after the name-value pairs if you desire.
529              
530             Default settings for Perl::ToPerl6 itself can be set B<before the first named
531             block.> For example, putting any or all of these at the top of your
532             configuration file will set the default value for the corresponding
533             constructor argument.
534              
535             severity = 3 #Integer or named level
536             only = 1 #Zero or One
537             force = 0 #Zero or One
538             verbose = 4 #Integer or format spec
539             top = 50 #A positive integer
540             theme = (pbp || security) && bugs #A theme expression
541             include = NamingConventions ClassHierarchies #Space-delimited list
542             exclude = Variables Modules::RequirePackage #Space-delimited list
543             mogrification-fatal = 1 #Zero or One
544             color = 1 #Zero or One
545             allow-unsafe = 1 #Zero or One
546             pager = less #pager to pipe output to
547              
548             The remainder of the configuration file is a series of blocks like this:
549              
550             [Perl::ToPerl6::Transformer::Category::TransformerName]
551             severity = 1
552             set_themes = foo bar
553             add_themes = baz
554             maximum_transformations_per_document = 57
555             arg1 = value1
556             arg2 = value2
557              
558             C<Perl::ToPerl6::Transformer::Category::TransformerName> is the full name of a module
559             that implements the transformer. The Transformer modules distributed with Perl::ToPerl6
560             have been grouped into categories according to the table of contents in Damian
561             Conway's book B<Perl Best Practices>. For brevity, you can omit the
562             C<'Perl::ToPerl6::Transformer'> part of the module name.
563              
564             C<severity> is the level of importance you wish to assign to the Transformer. All
565             Transformer modules are defined with a default severity value ranging from 1 (least
566             severe) to 5 (most severe). However, you may disagree with the default
567             severity and choose to give it a higher or lower severity, based on your own
568             coding philosophy. You can set the C<severity> to an integer from 1 to 5, or
569             use one of the equivalent names:
570              
571             SEVERITY NAME ...is equivalent to... SEVERITY NUMBER
572             ----------------------------------------------------
573             gentle 5
574             stern 4
575             harsh 3
576             cruel 2
577             brutal 1
578              
579             The names reflect how severely the code is mogrified: a C<gentle>
580             mogrification reports only the most severe transformations, and so on down to a
581             C<brutal> mogrification which reports even the most minor transformations.
582              
583             C<set_themes> sets the theme for the Transformer and overrides its default theme.
584             The argument is a string of one or more whitespace-delimited alphanumeric
585             words. Themes are case-insensitive. See L<"POLICY THEMES"> for more
586             information.
587              
588             C<add_themes> appends to the default themes for this Transformer. The argument is
589             a string of one or more whitespace-delimited words. Themes are case-
590             insensitive. See L<"POLICY THEMES"> for more information.
591              
592             C<maximum_transformations_per_document> limits the number of Transformations the Transformer
593             will return for a given document. Some Transformers have a default limit; see
594             the documentation for the individual Transformers to see whether there is one.
595             To force a Transformer to not have a limit, specify "no_limit" or the empty string for
596             the value of this parameter.
597              
598             The remaining key-value pairs are configuration parameters that will be passed
599             into the constructor for that Transformer. The constructors for most Transformer
600             objects do not support arguments, and those that do should have reasonable
601             defaults. See the documentation on the appropriate Transformer module for more
602             details.
603              
604             Instead of redefining the severity for a given Transformer, you can completely
605             disable a Transformer by prepending a '-' to the name of the module in your
606             configuration file. In this manner, the Transformer will never be loaded,
607             regardless of the C<-severity> given to the Perl::ToPerl6 constructor.
608              
609             A simple configuration might look like this:
610              
611             #--------------------------------------------------------------
612             # I think these are really important, so always load them
613              
614             [TestingAndDebugging::RequireUseStrict]
615             severity = 5
616              
617             [TestingAndDebugging::RequireUseWarnings]
618             severity = 5
619              
620             #--------------------------------------------------------------
621             # I think these are less important, so only load when asked
622              
623             [Variables::ProhibitPackageVars]
624             severity = 2
625              
626             [ControlStructures::ProhibitPostfixControls]
627             allow = if unless # My custom configuration
628             severity = cruel # Same as "severity = 2"
629              
630             #--------------------------------------------------------------
631             # Give these transformers a custom theme. I can activate just
632             # these transformers by saying `perlmogrify -theme larry`
633              
634             [Modules::RequireFilenameMatchesPackage]
635             add_themes = larry
636              
637             [TestingAndDebugging::RequireTestLables]
638             add_themes = larry curly moe
639              
640             #--------------------------------------------------------------
641             # I do not agree with these at all, so never load them
642              
643             [-NamingConventions::Capitalization]
644             [-ValuesAndExpressions::ProhibitMagicNumbers]
645              
646             #--------------------------------------------------------------
647             # For all other Transformers, I accept the default severity,
648             # so no additional configuration is required for them.
649              
650             For additional configuration examples, see the F<perlmogrifyrc> file that is
651             included in this F<examples> directory of this distribution.
652              
653             Damian Conway's own Perl::ToPerl6 configuration is also included in this
654             distribution as F<examples/perlmogrifyrc-conway>.
655              
656              
657             =head1 THE POLICIES
658              
659             A large number of Transformer modules are distributed with Perl::ToPerl6. They are
660             described briefly in the companion document L<Perl::ToPerl6::TransformerSummary> and
661             in more detail in the individual modules themselves. Say C<"perlmogrify -doc
662             PATTERN"> to see the perldoc for all Transformer modules that match the regex
663             C<m/PATTERN/ixms>
664              
665             There are a number of distributions of additional transformers on CPAN. If
666             L<Perl::ToPerl6> doesn't contain a transformer that you want, some one may have
667             already written it. See the L</"SEE ALSO"> section below for a list of some
668             of these distributions.
669              
670              
671             =head1 POLICY THEMES
672              
673             Each Transformer is defined with one or more "themes". Themes can be used to
674             create arbitrary groups of Transformers. They are intended to provide an
675             alternative mechanism for selecting your preferred set of Transformers. For
676             example, you may wish disable a certain subset of Transformers when analyzing
677             test programs. Conversely, you may wish to enable only a specific subset of
678             Transformers when analyzing modules.
679              
680             The Transformers that ship with Perl::ToPerl6 have been broken into the
681             following themes. This is just our attempt to provide some basic logical
682             groupings. You are free to invent new themes that suit your needs.
683              
684             THEME DESCRIPTION
685             --------------------------------------------------------------------------
686             core All transformers that ship with Perl::ToPerl6
687             pbp Transformers that come directly from "Perl Best Practices"
688             bugs Transformers that that prevent or reveal bugs
689             maintenance Transformers that affect the long-term health of the code
690             cosmetic Transformers that only have a superficial effect
691             complexity Transformers that specificaly relate to code complexity
692             security Transformers that relate to security issues
693             tests Transformers that are specific to test programs
694              
695              
696             Any Transformer may fit into multiple themes. Say C<"perlmogrify -list"> to get a
697             listing of all available Transformers and the themes that are associated with each
698             one. You can also change the theme for any Transformer in your F<.perlmogrifyrc>
699             file. See the L<"CONFIGURATION"> section for more information about that.
700              
701             Using the C<-theme> option, you can create an arbitrarily complex rule that
702             determines which Transformers will be loaded. Precedence is the same as regular
703             Perl code, and you can use parentheses to enforce precedence as well.
704             Supported operators are:
705              
706             Operator Alternative Example
707             -----------------------------------------------------------------
708             && and 'pbp && core'
709             || or 'pbp || (bugs && security)'
710             ! not 'pbp && ! (portability || complexity)'
711              
712             Theme names are case-insensitive. If the C<-theme> is set to an empty string,
713             then it evaluates as true all Transformers.
714              
715              
716             =head1 BENDING THE RULES
717              
718             Perl::ToPerl6 takes a hard-line approach to your code: either you comply or you
719             don't. In the real world, it is not always practical (nor even possible) to
720             fully comply with coding standards. In such cases, it is wise to show that
721             you are knowingly violating the standards and that you have a Damn Good Reason
722             (DGR) for doing so.
723              
724             To help with those situations, you can direct Perl::ToPerl6 to ignore certain
725             lines or blocks of code by using annotations:
726              
727             require 'LegacyLibaray1.pl'; ## no mogrify
728             require 'LegacyLibrary2.pl'; ## no mogrify
729              
730             for my $element (@list) {
731              
732             ## no mogrify
733              
734             $foo = ""; #Violates 'ProhibitEmptyQuotes'
735             $barf = bar() if $foo; #Violates 'ProhibitPostfixControls'
736             #Some more evil code...
737              
738             ## use mogrify
739              
740             #Some good code...
741             do_something($_);
742             }
743              
744             The C<"## no mogrify"> annotations direct Perl::ToPerl6 to ignore the remaining
745             lines of code until a C<"## use mogrify"> annotation is found. If the C<"## no
746             mogrify"> annotation is on the same line as a code statement, then only that
747             line of code is overlooked. To direct perlmogrify to ignore the C<"## no
748             mogrify"> annotations, use the C<--force> option.
749              
750             A bare C<"## no mogrify"> annotation disables all the active Transformers.
751             If you wish to disable only specific Transformers, add a list of Transformer
752             names as arguments, just as you would for the C<"no strict"> or C<"no warnings">
753             pragmas. For example, this would disable the C<ProhibitEmptyQuotes> and
754             C<ProhibitPostfixControls> transformers until the end of the block or until the
755             next C<"## use mogrify"> annotation (whichever comes first):
756              
757             ## no mogrify (EmptyQuotes, PostfixControls)
758              
759             # Now exempt from ValuesAndExpressions::ProhibitEmptyQuotes
760             $foo = "";
761              
762             # Now exempt ControlStructures::ProhibitPostfixControls
763             $barf = bar() if $foo;
764              
765             # Still subjected to ValuesAndExpression::RequireNumberSeparators
766             $long_int = 10000000000;
767              
768             Since the Transformer names are matched against the C<"## no mogrify"> arguments as
769             regular expressions, you can abbreviate the Transformer names or disable an entire
770             family of Transformers in one shot like this:
771              
772             ## no mogrify (NamingConventions)
773              
774             # Now exempt from NamingConventions::Capitalization
775             my $camelHumpVar = 'foo';
776              
777             # Now exempt from NamingConventions::Capitalization
778             sub camelHumpSub {}
779              
780             The argument list must be enclosed in parentheses and must contain one or more
781             comma-separated barewords (e.g. don't use quotes). The C<"## no mogrify">
782             annotations can be nested, and Transformers named by an inner annotation will be
783             disabled along with those already disabled an outer annotation.
784              
785             Some Transformers like C<Subroutines::ProhibitExcessComplexity> apply to an
786             entire block of code. In those cases, the C<"## no mogrify"> annotation must
787             appear on the line where the transformation is reported. For example:
788              
789             sub complicated_function { ## no mogrify (ProhibitExcessComplexity)
790             # Your code here...
791             }
792              
793             Transformers such as C<Documentation::RequirePodSections> apply to the entire
794             document, in which case transformations are reported at line 1.
795              
796             Use this feature wisely. C<"## no mogrify"> annotations should be used in the
797             smallest possible scope, or only on individual lines of code. And you should
798             always be as specific as possible about which Transformers you want to disable
799             (i.e. never use a bare C<"## no mogrify">). If Perl::ToPerl6 complains about
800             your code, try and find a compliant solution before resorting to this feature.
801              
802              
803             =head1 THE L<Perl::ToPerl6> PHILOSOPHY
804              
805             Coding standards are deeply personal and highly subjective. The goal of
806             Perl::ToPerl6 is to help you write code that conforms with a set of best
807             practices. Our primary goal is not to dictate what those practices are, but
808             rather, to implement the practices discovered by others. Ultimately, you make
809             the rules -- Perl::ToPerl6 is merely a tool for encouraging consistency. If
810             there is a transformer that you think is important or that we have overlooked, we
811             would be very grateful for contributions, or you can simply load your own
812             private set of transformers into Perl::ToPerl6.
813              
814              
815             =head1 EXTENDING THE MOGRIFIER
816              
817             The modular design of Perl::ToPerl6 is intended to facilitate the addition of
818             new Transformers. You'll need to have some understanding of L<PPI>, but most
819             Transformer modules are pretty straightforward and only require about 20 lines of
820             code. Please see the L<Perl::ToPerl6::DEVELOPER> file included in this
821             distribution for a step-by-step demonstration of how to create new Transformer
822             modules.
823              
824             If you develop any Transformer modules, feel free to add a pull request on
825             GitHub, L<http://github.com/drforr/Perl-Mogrify.git>.
826              
827              
828             =head1 PREREQUISITES
829              
830             Perl::ToPerl6 requires the following modules:
831              
832             L<B::Keywords>
833              
834             L<Config::Tiny>
835              
836             L<Exception::Class>
837              
838             L<File::HomeDir>
839              
840             L<File::Spec>
841              
842             L<File::Spec::Unix>
843              
844             L<File::Which>
845              
846             L<IO::String>
847              
848             L<List::MoreUtils>
849              
850             L<List::Util>
851              
852             L<Module::Pluggable>
853              
854             L<PPI|PPI>
855              
856             L<Pod::PlainText>
857              
858             L<Pod::Select>
859              
860             L<Pod::Usage>
861              
862             L<Readonly>
863              
864             L<Scalar::Util>
865              
866             L<String::Format>
867              
868             L<Task::Weaken>
869              
870             L<Term::ANSIColor>
871              
872             L<Text::ParseWords>
873              
874             L<version|version>
875              
876              
877             =head1 CONTACTING THE DEVELOPMENT TEAM
878              
879             You are encouraged to subscribe to the mailing list; send a message to
880             L<mailto:users-subscribe@perlmogrify.tigris.org>. To prevent spam, you may be
881             required to register for a user account with Tigris.org before being allowed
882             to post messages to the mailing list. See also the mailing list archives at
883             L<http://perlmogrify.tigris.org/servlets/SummarizeList?listName=users>. At
884             least one member of the development team is usually hanging around in
885             L<irc://irc.perl.org/#perlmogrify> and you can follow Perl::ToPerl6 on Twitter,
886             at L<https://twitter.com/perlmogrify>.
887              
888             =head1 BUGS
889              
890             Scrutinizing Perl code is hard for humans, let alone machines. If you find
891             any bugs, particularly false-positives or false-negatives from a
892             Perl::ToPerl6::Transformer, please submit them at L<https://github.com/Perl-ToPerl6
893             /Perl-ToPerl6/issues>. Thanks.
894              
895             =head1 CREDITS
896              
897             Adam Kennedy - For creating L<PPI>, the heart and soul of L<Perl::ToPerl6>.
898              
899             Damian Conway - For writing B<Perl Best Practices>, finally :)
900              
901             Chris Dolan - For contributing the best features and Transformer modules.
902              
903             Andy Lester - Wise sage and master of all-things-testing.
904              
905             Elliot Shank - The self-proclaimed quality freak.
906              
907             Giuseppe Maxia - For all the great ideas and positive encouragement.
908              
909             and Sharon, my wife - For putting up with my all-night code sessions.
910              
911             Thanks also to the Perl Foundation for providing a grant to support Chris
912             Dolan's project to implement twenty PBP transformers.
913             L<http://www.perlfoundation.org/april_1_2007_new_grant_awards>
914              
915             =head1 AUTHOR
916              
917             Jeffrey Goff <drforr@pobox.com>
918              
919             =head1 AUTHOR Emeritus
920              
921             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
922              
923              
924             =head1 COPYRIGHT
925              
926             Copyright (c) 2015 Jeffrey Goff. All rights reserved.
927              
928             This program is free software; you can redistribute it and/or modify it under
929             the same terms as Perl itself. The full text of this license can be found in
930             the LICENSE file included with this module.
931              
932             =cut
933              
934             ##############################################################################
935             # Local Variables:
936             # mode: cperl
937             # cperl-indent-level: 4
938             # fill-column: 78
939             # indent-tabs-mode: nil
940             # c-indentation-style: bsd
941             # End:
942             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :