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