bump version to 1.999_002
[p5sagit/strictures.git] / lib / strictures.pm
CommitLineData
394c3a46 1package strictures;
2
3use strict;
4use warnings FATAL => 'all';
5
500f28df 6BEGIN {
7 *_PERL_LT_5_8_4 = ($] < 5.008004) ? sub(){1} : sub(){0};
24590d98 8 *_CAN_GOTO_VERSION = ($] >= 5.008000) ? sub(){1} : sub(){0};
500f28df 9}
084caaf3 10
415df732 11our $VERSION = '1.999_002';
20b853bb 12$VERSION = eval $VERSION;
07dc8b03 13$VERSION = 2; # a bit of a cheat, but requesting v2 needs to be possible
394c3a46 14
23c0b85d 15our @WARNING_CATEGORIES = grep { exists $warnings::Offsets{$_} } qw(
16 closure
95d54bcb 17 chmod
23c0b85d 18 deprecated
19 exiting
20 experimental
c5b35ddf 21 experimental::autoderef
1e139b49 22 experimental::const_attr
23c0b85d 23 experimental::lexical_subs
24 experimental::lexical_topic
c5b35ddf 25 experimental::postderef
1e139b49 26 experimental::re_strict
27 experimental::refaliasing
23c0b85d 28 experimental::regex_sets
c5b35ddf 29 experimental::signatures
23c0b85d 30 experimental::smartmatch
1e139b49 31 experimental::win32_perlio
23c0b85d 32 glob
33 imprecision
34 io
35 closed
36 exec
37 layer
38 newline
39 pipe
c5b35ddf 40 syscalls
23c0b85d 41 unopened
1e139b49 42 locale
23c0b85d 43 misc
1e139b49 44 missing
23c0b85d 45 numeric
46 once
47 overflow
48 pack
49 portable
50 recursion
51 redefine
1e139b49 52 redundant
23c0b85d 53 regexp
54 severe
55 debugging
56 inplace
57 internal
58 malloc
59 signal
60 substr
61 syntax
62 ambiguous
63 bareword
64 digit
65 illegalproto
66 parenthesis
67 precedence
68 printf
69 prototype
70 qw
71 reserved
72 semicolon
73 taint
74 threads
75 uninitialized
95d54bcb 76 umask
23c0b85d 77 unpack
78 untie
79 utf8
80 non_unicode
81 nonchar
82 surrogate
83 void
1e139b49 84 void_unusual
23c0b85d 85 y2k
86);
87
394c3a46 88sub VERSION {
24590d98 89 {
90 no warnings;
91 local $@;
92 if (defined $_[1] && eval { &UNIVERSAL::VERSION; 1}) {
93 $^H |= 0x20000
94 unless _PERL_LT_5_8_4;
95 $^H{strictures_enable} = int $_[1];
96 }
394c3a46 97 }
24590d98 98 _CAN_GOTO_VERSION ? goto &UNIVERSAL::VERSION : &UNIVERSAL::VERSION;
394c3a46 99}
100
8f0df510 101our %extra_load_states;
ffedb166 102
2da53f4a 103our $Smells_Like_VCS;
12b8f19b 104
394c3a46 105sub import {
92cde693 106 my $class = shift;
107 my %opts = ref $_[0] ? %{$_[0]} : @_;
108 if (!exists $opts{version}) {
109 $opts{version}
110 = exists $^H{strictures_enable} ? delete $^H{strictures_enable}
111 : int $VERSION;
112 }
c5a67be6 113 $opts{file} = (caller)[1];
92cde693 114 $class->_enable(\%opts);
115}
116
117sub _enable {
118 my ($class, $opts) = @_;
119 my $version = $opts->{version};
120 $version = 'undef'
121 if !defined $version;
122 my $method = "_enable_$version";
123 if (!$class->can($method)) {
a97f64c7 124 require Carp;
125 Carp::croak("Major version specified as $version - not supported!");
92cde693 126 }
127 $class->$method($opts);
128}
129
130sub _enable_1 {
c5a67be6 131 my ($class, $opts) = @_;
394c3a46 132 strict->import;
133 warnings->import(FATAL => 'all');
084caaf3 134
c5a67be6 135 if (_want_extra($opts->{file})) {
136 _load_extras(qw(indirect multidimensional bareword::filehandles));
137 indirect->unimport(':fatal')
138 if $extra_load_states{indirect};
139 multidimensional->unimport
140 if $extra_load_states{multidimensional};
141 bareword::filehandles->unimport
142 if $extra_load_states{'bareword::filehandles'};
143 }
8f0df510 144}
145
1931c77d 146our @V2_NONFATAL = grep { exists $warnings::Offsets{$_} } (
147 'exec', # not safe to catch
148 'recursion', # will be caught by other mechanisms
149 'internal', # not safe to catch
150 'malloc', # not safe to catch
151 'newline', # stat on nonexistent file with a newline in it
152 'experimental', # no reason for these to be fatal
153 'deprecated', # unfortunately can't make these fatal
154 'portable', # everything worked fine here, just may not elsewhere
23c0b85d 155);
1931c77d 156our @V2_DISABLE = grep { exists $warnings::Offsets{$_} } (
157 'once' # triggers inconsistently, can't be fatalized
23c0b85d 158);
159
160sub _enable_2 {
161 my ($class, $opts) = @_;
162 strict->import;
163 warnings->import;
164 warnings->import(FATAL => @WARNING_CATEGORIES);
d50343b9 165 warnings->unimport(FATAL => @V2_NONFATAL);
166 warnings->import(@V2_NONFATAL);
23c0b85d 167 warnings->unimport(@V2_DISABLE);
168
169 if (_want_extra($opts->{file})) {
170 _load_extras(qw(indirect multidimensional bareword::filehandles));
171 indirect->unimport(':fatal')
172 if $extra_load_states{indirect};
173 multidimensional->unimport
174 if $extra_load_states{multidimensional};
175 bareword::filehandles->unimport
176 if $extra_load_states{'bareword::filehandles'};
177 }
178}
179
9d763997 180sub _want_extra_env {
c5a67be6 181 if (exists $ENV{PERL_STRICTURES_EXTRA}) {
182 if (_PERL_LT_5_8_4 and $ENV{PERL_STRICTURES_EXTRA}) {
183 die 'PERL_STRICTURES_EXTRA checks are not available on perls older'
184 . "than 5.8.4: please unset \$ENV{PERL_STRICTURES_EXTRA}\n";
394c3a46 185 }
9d763997 186 return $ENV{PERL_STRICTURES_EXTRA} ? 1 : 0;
c5a67be6 187 }
9d763997 188 return undef;
189}
190
191sub _want_extra {
192 my $file = shift;
193 my $want_env = _want_extra_env();
194 return $want_env
195 if defined $want_env;
c5a67be6 196 return (
197 !_PERL_LT_5_8_4
198 and $file =~ /^(?:t|xt|lib|blib)[\\\/]/
199 and defined $Smells_Like_VCS ? $Smells_Like_VCS
200 : ( $Smells_Like_VCS = !!(
201 -e '.git' || -e '.svn' || -e '.hg'
202 || (-e '../../dist.ini'
203 && (-e '../../.git' || -e '../../.svn' || -e '../../.hg' ))
204 ))
205 );
206}
4f219885 207
c5a67be6 208sub _load_extras {
209 my @extras = @_;
8f0df510 210 my @failed;
211 foreach my $mod (@extras) {
212 next
213 if exists $extra_load_states{$mod};
4f219885 214
8f0df510 215 $extra_load_states{$mod} = eval "require $mod; 1;" or do {
216 push @failed, $mod;
488f2966 217
8f0df510 218 #work around 5.8 require bug
219 (my $file = $mod) =~ s|::|/|g;
220 delete $INC{"${file}.pm"};
221 };
222 }
4f219885 223
8f0df510 224 if (@failed) {
225 my $failed = join ' ', @failed;
226 my $extras = join ' ', @extras;
227 print STDERR <<EOE;
ffedb166 228strictures.pm extra testing active but couldn't load all modules. Missing were:
229
230 $failed
231
0925b84b 232Extra testing is auto-enabled in checkouts only, so if you're the author
624cf8bb 233of a strictures-using module you need to run:
653f4377 234
8f0df510 235 cpan $extras
653f4377 236
237but these modules are not required by your users.
084caaf3 238EOE
394c3a46 239 }
240}
241
2421;
243
244__END__
245=head1 NAME
246
247strictures - turn on strict and make all warnings fatal
248
249=head1 SYNOPSIS
250
1c35787c 251 use strictures 2;
394c3a46 252
253is equivalent to
254
255 use strict;
256 use warnings FATAL => 'all';
1c35787c 257 use warnings NONFATAL => qw(
258 exec
259 recursion
260 internal
261 malloc
262 newline
263 experimental
264 deprecated
265 portable
266 );
267 no warnings 'once';
394c3a46 268
5ab06a4d 269except when called from a file which matches:
394c3a46 270
5b2a026b 271 (caller)[1] =~ /^(?:t|xt|lib|blib)[\\\/]/
394c3a46 272
3e14202f 273and when either C<.git>, C<.svn>, or C<.hg> is present in the current directory
274(with the intention of only forcing extra tests on the author side) -- or when
275C<.git>, C<.svn>, or C<.hg> is present two directories up along with
276C<dist.ini> (which would indicate we are in a C<dzil test> operation, via
277L<Dist::Zilla>) -- or when the C<PERL_STRICTURES_EXTRA> environment variable is
40836ccc 278set, in which case it also does the equivalent of
394c3a46 279
394c3a46 280 no indirect 'fatal';
653f4377 281 no multidimensional;
282 no bareword::filehandles;
394c3a46 283
3e14202f 284Note that C<PERL_STRICTURES_EXTRA> may at some point add even more tests, with
285only a minor version increase, but any changes to the effect of C<use
286strictures> in normal mode will involve a major version bump.
394c3a46 287
0eb0d037 288If any of the extra testing modules are not present, L<strictures> will
25877bf2 289complain loudly, once, via C<warn()>, and then shut up. But you really
ffedb166 290should consider installing them, they're all great anti-footgun tools.
17b03f2e 291
394c3a46 292=head1 DESCRIPTION
293
294I've been writing the equivalent of this module at the top of my code for
295about a year now. I figured it was time to make it shorter.
296
25877bf2 297Things like the importer in C<use Moose> don't help me because they turn
d8c1c6b2 298warnings on but don't make them fatal -- which from my point of view is
2288278f 299useless because I want an exception to tell me my code isn't warnings-clean.
394c3a46 300
301Any time I see a warning from my code, that indicates a mistake.
302
d8c1c6b2 303Any time my code encounters a mistake, I want a crash -- not spew to STDERR
394c3a46 304and then unknown (and probably undesired) subsequent behaviour.
305
306I also want to ensure that obvious coding mistakes, like indirect object
307syntax (and not so obvious mistakes that cause things to accidentally compile
308as such) get caught, but not at the cost of an XS dependency and not at the
309cost of blowing things up on another machine.
310
0eb0d037 311Therefore, L<strictures> turns on additional checking, but only when it thinks
2288278f 312it's running in a test file in a VCS checkout -- although if this causes
93ae637e 313undesired behaviour this can be overridden by setting the
25877bf2 314C<PERL_STRICTURES_EXTRA> environment variable.
394c3a46 315
316If additional useful author side checks come to mind, I'll add them to the
3e14202f 317C<PERL_STRICTURES_EXTRA> code path only -- this will result in a minor version
318increase (e.g. 1.000000 to 1.001000 (1.1.0) or similar). Any fixes only to the
319mechanism of this code will result in a sub-version increase (e.g. 1.000000 to
3201.000001 (1.0.1)).
394c3a46 321
d48424bd 322=head1 CATEGORY SELECTIONS
323
324strictures does not enable fatal warnings for all categories.
325
326=over 4
327
328=item exec
329
330Includes a warning that can cause your program to continue running
331unintentionally after an internal fork. Not safe to fatalize.
332
333=item recursion
334
335Infinite recursion will end up overflowing the stack eventually anyway.
336
337=item internal
338
339Triggers deep within perl, in places that are not safe to trap.
340
341=item malloc
342
343Triggers deep within perl, in places that are not safe to trap.
344
345=item newline
346
347Includes a warning for using stat on a valid but suspect filename, ending in a
348newline.
349
350=item experimental
351
352Experimental features are used intentionally.
353
354=item deprecated
355
356Deprecations will inherently be added to in the future in unexpected ways,
357so making them fatal won't be reliable.
358
359=item portable
360
361Doesn't indicate an actual problem with the program, only that it may not
362behave properly if run on a different machine.
363
364=item once
365
366Can't be fatalized. Also triggers very inconsistently, so we just disable it.
367
368=back
369
1c35787c 370=head1 VERSIONS
371
372Depending on the version of strictures requested, different warnings will be
373enabled. If no specific version is requested, the current version's behavior
374will be used. Versions can be requested using perl's standard mechanism:
375
376 use strictures 2;
377
378Or, by passing in a C<version> option:
379
380 use strictures version => 2;
394c3a46 381
1c35787c 382=head2 VERSION 2
394c3a46 383
1c35787c 384Equivalent to:
385
386 use strict;
387 use warnings FATAL => 'all';
d771b3bb 388 use warnings NONFATAL => qw(
389 exec
390 recursion
391 internal
392 malloc
393 newline
394 experimental
395 deprecated
396 portable
397 );
398 no warnings 'once';
399
1c35787c 400 # and if in dev mode:
401 no indirect 'fatal';
402 no multidimensional;
403 no bareword::filehandles;
404
d771b3bb 405Additionally, any warnings created by modules using L<warnings::register> or
406C<warnings::register_categories()> will not be fatalized.
407
1c35787c 408=head2 VERSION 1
409
410Equivalent to:
411
412 use strict;
413 use warnings FATAL => 'all';
414 # and if in dev mode:
415 no indirect 'fatal';
416 no multidimensional;
417 no bareword::filehandles;
eae006ee 418
419=head1 METHODS
420
421=head2 import
422
1c35787c 423This method does the setup work described above in L</DESCRIPTION>. Optionally
424accepts a C<version> option to request a specific version's behavior.
eae006ee 425
426=head2 VERSION
427
25877bf2 428This method traps the C<< strictures->VERSION(1) >> call produced by a use line
eae006ee 429with a version number on it and does the version check.
430
f9df7e2e 431=head1 EXTRA TESTING RATIONALE
432
25877bf2 433Every so often, somebody complains that they're deploying via C<git pull>
d8c1c6b2 434and that they don't want L<strictures> to enable itself in this case -- and that
f9df7e2e 435setting C<PERL_STRICTURES_EXTRA> to 0 isn't acceptable (additional ways to
436disable extra testing would be welcome but the discussion never seems to get
437that far).
438
439In order to allow us to skip a couple of stages and get straight to a
440productive conversation, here's my current rationale for turning the
441extra testing on via a heuristic:
442
443The extra testing is all stuff that only ever blows up at compile time;
2288278f 444this is intentional. So the oft-raised concern that it's different code being
d8c1c6b2 445tested is only sort of the case -- none of the modules involved affect the
f9df7e2e 446final optree to my knowledge, so the author gets some additional compile
447time crashes which he/she then fixes, and the rest of the testing is
448completely valid for all environments.
449
d8c1c6b2 450The point of the extra testing -- especially C<no indirect> -- is to catch
f9df7e2e 451mistakes that newbie users won't even realise are mistakes without
452help. For example,
453
454 foo { ... };
455
d8c1c6b2 456where foo is an & prototyped sub that you forgot to import -- this is
9a363fed 457pernicious to track down since all I<seems> fine until it gets called
f9df7e2e 458and you get a crash. Worse still, you can fail to have imported it due
459to a circular require, at which point you have a load order dependent
9a363fed 460bug which I've seen before now I<only> show up in production due to tiny
f9df7e2e 461differences between the production and the development environment. I wrote
462L<http://shadow.cat/blog/matt-s-trout/indirect-but-still-fatal/> to explain
463this particular problem before L<strictures> itself existed.
464
2288278f 465As such, in my experience so far L<strictures>' extra testing has
9a363fed 466I<avoided> production versus development differences, not caused them.
f9df7e2e 467
0eb0d037 468Additionally, L<strictures>' policy is very much "try and provide as much
d8c1c6b2 469protection as possible for newbies -- who won't think about whether there's
470an option to turn on or not" -- so having only the environment variable
f9df7e2e 471is not sufficient to achieve that (I get to explain that you need to add
d8c1c6b2 472C<use strict> at least once a week on freenode #perl -- newbies sometimes
f9df7e2e 473completely skip steps because they don't understand that that step
474is important).
475
d8c1c6b2 476I make no claims that the heuristic is perfect -- it's already been evolved
f9df7e2e 477significantly over time, especially for 1.004 where we changed things to
0eb0d037 478ensure it only fires on files in your checkout (rather than L<strictures>-using
f9df7e2e 479modules you happened to have installed, which was just silly). However, I
480hope the above clarifies why a heuristic approach is not only necessary but
3e14202f 481desirable from a point of view of providing new users with as much safety as
482possible, and will allow any future discussion on the subject to focus on "how
483do we minimise annoyance to people deploying from checkouts intentionally".
f9df7e2e 484
96c8649b 485=head1 SEE ALSO
486
487=over 4
488
489=item *
490
491L<indirect>
492
493=item *
494
495L<multidimensional>
496
497=item *
498
499L<bareword::filehandles>
500
501=back
502
eae006ee 503=head1 COMMUNITY AND SUPPORT
504
505=head2 IRC channel
506
507irc.perl.org #toolchain
508
509(or bug 'mst' in query on there or freenode)
510
511=head2 Git repository
512
513Gitweb is on http://git.shadowcat.co.uk/ and the clone URL is:
514
515 git clone git://git.shadowcat.co.uk/p5sagit/strictures.git
516
91be28bc 517The web interface to the repository is at:
518
519 http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/strictures.git
520
eae006ee 521=head1 AUTHOR
522
d81f898d 523mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
eae006ee 524
525=head1 CONTRIBUTORS
526
8190ff5b 527Karen Etheridge (cpan:ETHER) <ether@cpan.org>
eae006ee 528
04b4a35d 529Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@gmail.com>
530
a79d1096 531haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
532
eae006ee 533=head1 COPYRIGHT
534
535Copyright (c) 2010 the strictures L</AUTHOR> and L</CONTRIBUTORS>
536as listed above.
537
538=head1 LICENSE
539
540This library is free software and may be distributed under the same terms
541as perl itself.
542
543=cut