Login
Update TODO with some clarifications and mental notes for my upcoming work
[gknop/Perl-Critic.git] / lib / Perl / Critic / Policy / CodeLayout / RequireTidyCode.pm
CommitLineData
6036a254 1##############################################################################
dff08b70
JRT
2# $URL$
3# $Date$
4# $Author$
5# $Revision$
6036a254 6##############################################################################
dff08b70 7
59b05e08
JRT
8package Perl::Critic::Policy::CodeLayout::RequireTidyCode;
9
10use strict;
11use warnings;
bf159007 12use English qw(-no_match_vars);
bbf4108c 13use Perl::Critic::Utils qw{ :characters :severities };
59b05e08
JRT
14use base 'Perl::Critic::Policy';
15
e858ba92 16our $VERSION = 1.06;
59b05e08 17
6036a254 18#-----------------------------------------------------------------------------
dff08b70 19
59b05e08 20my $desc = q{Code is not tidy};
5dc3db7a 21my $expl = [ 33 ];
59b05e08 22
6036a254 23#-----------------------------------------------------------------------------
59b05e08 24
e178fe38 25sub supported_parameters { return qw( perltidyrc ) }
fd5bd7b5
JRT
26sub default_severity { return $SEVERITY_LOWEST }
27sub default_themes { return qw(core pbp cosmetic) }
28sub applies_to { return 'PPI::Document' }
dff08b70 29
6036a254 30#-----------------------------------------------------------------------------
02558daa
CD
31
32sub new {
85da2bf2
ES
33 my $class = shift;
34 my $self = $class->SUPER::new(@_);
35
36 my (%config) = @_;
02558daa
CD
37
38 #Set configuration if defined
85da2bf2 39 $self->{_perltidyrc} = $config{perltidyrc};
fd5bd7b5
JRT
40 if (defined $self->{_perltidyrc} && $self->{_perltidyrc} eq $EMPTY) {
41 $self->{_perltidyrc} = \$EMPTY;
02558daa
CD
42 }
43
44 return $self;
45}
46
6036a254 47#-----------------------------------------------------------------------------
59b05e08
JRT
48
49sub violates {
50 my ( $self, $elem, $doc ) = @_;
bf159007
JRT
51
52 # If Perl::Tidy is missing, silently pass this test
53 eval { require Perl::Tidy; };
54 return if $EVAL_ERROR;
59b05e08 55
05bf01cd 56 # Perl::Tidy seems to produce slightly different output, depending
871ec032 57 # on the trailing whitespace in the input. As best I can tell,
fd9d73d0
JRT
58 # Perl::Tidy will truncate any extra trailing newlines, and if the
59 # input has no trailing newline, then it adds one. But when you
60 # re-run it through Perl::Tidy here, that final newline gets lost,
61 # which causes the policy to insist that the code is not tidy.
62 # This only occurs when Perl::Tidy is writing the output to a
63 # scalar, but does not occur when writing to a file. I may
64 # investigate further, but for now, this seems to do the trick.
871ec032 65
02558daa 66 my $source = $doc->serialize();
fd9d73d0 67 $source =~ s{ \s+ \Z}{\n}mx;
871ec032 68
44b74300
CD
69 # Remove the shell fix code from the top of program, if applicable
70 my $shebang_re = qr/\#![^\015\012]+[\015\012]+/xms;
71 my $shell_re = qr/eval [ ] 'exec [ ] [^\015\012]* [ ] \$0 [ ] \${1\+"\$@"}'
72 [ \t]*[\012\015]+ [ \t]*if[^\015\012]+[\015\012]+/xms;
73 $source =~ s/\A ($shebang_re) $shell_re /$1/xms;
74
59b05e08 75 my $dest = $EMPTY;
59b05e08
JRT
76 my $stderr = $EMPTY;
77
871ec032 78
6bf9b465
JRT
79 # Perl::Tidy gets confused if @ARGV has arguments from
80 # another program. Also, we need to override the
81 # stdout and stderr redirects that the user may have
82 # configured in their .perltidyrc file.
83 local @ARGV = qw(-nst -nse); ## no critic
ee99f507 84
d5fc0818
JRT
85 # Trap Perl::Tidy errors, just in case it dies
86 eval {
0a6f07d0
AL
87 Perl::Tidy::perltidy(
88 source => \$source,
89 destination => \$dest,
90 stderr => \$stderr,
02558daa 91 defined $self->{_perltidyrc} ? (perltidyrc => $self->{_perltidyrc}) : (),
d5fc0818
JRT
92 );
93 };
94
95 if ($stderr || $EVAL_ERROR) {
59b05e08
JRT
96
97 # Looks like perltidy had problems
44b74300 98 return $self->violation( 'perltidy had errors!!', $expl, $elem );
59b05e08
JRT
99 }
100
47639f94 101 if ( $source ne $dest ) {
2c6df011 102 return $self->violation( $desc, $expl, $elem );
59b05e08
JRT
103 }
104
105 return; #ok!
106}
107
1081;
109
6036a254 110#-----------------------------------------------------------------------------
6bf9b465 111
59b05e08
JRT
112__END__
113
114=pod
115
116=head1 NAME
117
118Perl::Critic::Policy::CodeLayout::RequireTidyCode
119
120=head1 DESCRIPTION
121
122Conway does make specific recommendations for whitespace and
123curly-braces in your code, but the most important thing is to adopt a
124consistent layout, regardless of the specifics. And the easiest way
125to do that is to use L<Perl::Tidy>. This policy will complain if
126you're code hasn't been run through Perl::Tidy.
127
6c893fc9 128=head1 CONFIGURATION
02558daa 129
6c893fc9
ES
130This policy can be configured to tell Perl::Tidy to use a particular
131F<perltidyrc> file or no configuration at all. By default, Perl::Tidy is told
132to look in its default location for configuration. Perl::Critic can be told to
133tell Perl::Tidy to use a specific configuration file by putting an entry in a
134F<.perlcriticrc> file like this:
02558daa
CD
135
136 [CodeLayout::RequireTidyCode]
137 perltidyrc = /usr/share/perltidy.conf
138
139As a special case, setting C<perltidyrc> to the empty string tells
140Perl::Tidy not to load any configuration file at all and just use
141Perl::Tidy's own default style.
142
143 [CodeLayout::RequireTidyCode]
8e2aefdb 144 perltidyrc =
02558daa 145
59b05e08
JRT
146=head1 NOTES
147
df249cc5
JRT
148L<Perl::Tidy> is not included in the Perl::Critic distribution. The
149latest version of Perl::Tidy can be downloaded from CPAN. If
150Perl::Tidy is not installed, this policy is silently ignored.
59b05e08
JRT
151
152=head1 SEE ALSO
153
154L<Perl::Tidy>
155
59b05e08
JRT
156=head1 AUTHOR
157
158Jeffrey Ryan Thalhammer <thaljef@cpan.org>
159
160=head1 COPYRIGHT
161
0d5b2dca 162Copyright (c) 2005-2007 Jeffrey Ryan Thalhammer. All rights reserved.
59b05e08
JRT
163
164This program is free software; you can redistribute it and/or modify
165it under the same terms as Perl itself. The full text of this license
166can be found in the LICENSE file included with this module.
167
168=cut
737d3b65
CD
169
170# Local Variables:
171# mode: cperl
172# cperl-indent-level: 4
173# fill-column: 78
174# indent-tabs-mode: nil
175# c-indentation-style: bsd
176# End:
345c7562 177# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab :