File Coverage

blib/lib/Test/Apocalypse.pm
Criterion Covered Total %
statement 97 105 92.3
branch 18 48 37.5
condition 14 36 38.8
subroutine 32 32 100.0
pod 1 1 100.0
total 162 222 72.9


line stmt bran cond sub pod time code
1             #
2             # This file is part of Test-Apocalypse
3             #
4             # This software is copyright (c) 2014 by Apocalypse.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9 110     110   54181 use strict; use warnings;
  110     110   184  
  110         2633  
  110         441  
  110         110  
  110         3549  
10             package Test::Apocalypse;
11             # git description: release-1.005-0-g6408495
12             $Test::Apocalypse::VERSION = '1.006';
13             BEGIN {
14 110     110   1833 $Test::Apocalypse::AUTHORITY = 'cpan:APOCAL';
15             }
16              
17             # ABSTRACT: Apocalypse's favorite tests bundled into a simple interface
18              
19             # setup our tests and etc
20 73     110   292 use Test::More 0.96;
  73         1387  
  110         623  
21 110     110   44750 use Module::Pluggable 3.9 search_path => [ __PACKAGE__ ];
  110         503413  
  110         660  
22              
23             # auto-export the only sub we have
24 110     110   33289 use parent 'Exporter';
  110         17014  
  110         624  
25             our @EXPORT = qw( is_apocalypse_here );
26              
27             sub is_apocalypse_here {
28             # should we even run those tests?
29 110 50 33 110 1 8213 unless ( $ENV{RELEASE_TESTING} or $ENV{AUTOMATED_TESTING} ) {
30 37         629 plan skip_all => 'Author test. Please set $ENV{RELEASE_TESTING} to a true value to run.';
31             } else {
32 110         30628 require Test::FailWarnings;
33             }
34              
35             # The options hash
36 110         59423 my %opt;
37              
38             # Support passing in a hash ref or a regular hash
39 110 50 33     1468 if ( ( @_ & 1 ) and ref $_[0] and ref( $_[0] ) eq 'HASH' ) { ## no critic (Bangs::ProhibitBitwiseOperators)
      33        
40 110         332 %opt = %{ $_[0] };
  110         293  
41             } else {
42             # Sanity checking
43 37 0       555 if ( @_ & 1 ) { ## no critic (Bangs::ProhibitBitwiseOperators)
44 37         259 die 'The sub is_apocalypse_here() requires an even number of options';
45             }
46              
47 37         74 %opt = @_;
48             }
49              
50             # lowercase keys
51 110         664 %opt = map { lc($_) => $opt{$_} } keys %opt;
  37         666  
52              
53             # setup the "allow/deny" tests
54 73 50 33     146 if ( exists $opt{'allow'} and exists $opt{'deny'} ) {
55 0         0 die 'Unable to use "allow" and "deny" at the same time!';
56             }
57 110         368 foreach my $type ( qw( allow deny ) ) {
58 183 50 33     439 if ( ! exists $opt{ $type } or ! defined $opt{ $type } ) {
59             # Don't set anything
60 183 50       846 delete $opt{ $type } if exists $opt{ $type };
61             } else {
62 37 0       296 if ( ! ref $opt{ $type } ) {
    0          
63             # convert it to a qr// regex?
64 37         37 eval { $opt{ $type } = qr/$opt{ $type }/i };
  37         555  
65 37 0       296 if ( $@ ) {
66 37         74 die "Unable to compile the '$type' regex: $@";
67             }
68             } elsif ( ref( $opt{ $type } ) ne 'Regexp' ) {
69 37         518 die "The '$type' option is not a regexp!";
70             }
71             }
72             }
73              
74             # Print some basic debugging info, thanks POE::Test::Loops::00_info!
75             diag(
76 110         697 "Testing with Test::Apocalypse v$Test::Apocalypse::VERSION, ",
77             "Perl $], ",
78             "$^X on $^O",
79             );
80              
81             # loop through our plugins ( in alphabetical order! )
82 110         17740 foreach my $t ( sort { $a cmp $b } __PACKAGE__->plugins() ) {
  2519         764061  
83 1548         835916 my $plugin = $t;
84 1511         9033 $plugin =~ s/^Test::Apocalypse:://;
85              
86             # Do we want this test?
87             # PERL_APOCALYPSE=1 means run all tests, =0 means default behavior
88 1511 50 33     6712 if ( ! exists $ENV{PERL_APOCALYPSE} or ! $ENV{PERL_APOCALYPSE} ) {
89 1548 50       6601 if ( exists $opt{'allow'} ) {
    50          
90 37 0       74 if ( $t =~ /^Test::Apocalypse::(.+)$/ ) {
91 37 0       555 if ( $1 !~ $opt{'allow'} ) {
92 37         259 diag( "Skipping $plugin ( via allow policy )..." );
93 37         74 next;
94             }
95             }
96             } elsif ( exists $opt{'deny'} ) {
97 37 0       370 if ( $t =~ /^Test::Apocalypse::(.+)$/ ) {
98 37 0       259 if ( $1 =~ $opt{'deny'} ) {
99 37         37 diag( "Skipping $plugin ( via deny policy )..." );
100 37         370 next;
101             }
102             }
103             }
104             }
105              
106             # Load it, and look for errors
107 110     110   27558 eval "use $t";
  37     110   407  
  37     110   296  
  110     110   22850  
  110     110   664  
  110     110   1390  
  110     37   33435  
  110     37   589  
  110     37   1207  
  110     37   38691  
  110     37   626  
  110     37   1611  
  110     37   25587  
  110     37   1145  
  110     37   1317  
  110     37   22594  
  110     37   664  
  110     37   880  
  1548     37   148515  
        37      
        37      
        37      
        37      
108 1548 100       17880 if ( $@ ) {
109             # TODO smarter error detection - missing module, bla bla
110 221         1957 my $error = "Unable to load $plugin -> $@";
111              
112 221 50 33     1770 if ( $ENV{RELEASE_TESTING} or $ENV{PERL_APOCALYPSE} ) {
113 37         259 die $error;
114             } else {
115 221         1587 diag( $error );
116             }
117              
118 221         27505 next;
119             }
120              
121             # Is this plugin disabled?
122 1364 100 66     15232 if ( $t->can( '_is_disabled' ) and ! $ENV{PERL_APOCALYPSE} ) {
123 295         2660 my $ret = $t->_is_disabled;
124 295 100       1969876 if ( $ret ) {
125 148         851 diag( "Skipping $plugin => $ret" );
126 148         17945 next;
127             }
128             }
129              
130             # Check for AUTOMATED_TESTING
131 1253 100 33     18331 if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_APOCALYPSE} and $t->can( '_do_automated' ) and ! $t->_do_automated() ) {
      66        
      66        
132 222         1776 diag( "Skipping $plugin ( for RELEASE_TESTING only )..." );
133 222         33855 next;
134             }
135              
136             # run it!
137             subtest $plugin => sub {
138 1068     1068   619482 eval {
139             # TODO ignore annoying gpg warnings like 'WARNING: This key is not certified with a trusted signature!' at /usr/local/share/perl/5.18.2/Module/Signature.pm line 265.
140 110     110   40041 no warnings qw(once);
  110         628  
  110         18946  
141 1068         5310 local @Test::FailWarnings::ALLOW_FROM = ( 'Module::Signature' );
142              
143 1068         5751 local $SIG{__WARN__} = \&Test::FailWarnings::handler;
144 1068         5718 $t->do_test();
145             };
146 996 50       499122 if ( $@ ) {
147             # Sometimes we get a plain string, sometimes we get
148             # Error running Kwalitee: Test::Builder::Exception=HASH(0x3fa6078)
149 0         0 my $err = $@;
150 0 0       0 if ( $err->isa( 'Test::Builder::Exception' ) ) {
151             # TODO reach into T::B to get the actual skip reason
152 0         0 $err = Test::Builder->new->{Skip_All};
153             }
154              
155 0 0 0     0 if ( $ENV{RELEASE_TESTING} or $ENV{PERL_APOCALYPSE} ) {
156 0         0 die "Error running $plugin: $err";
157             } else {
158 0         0 diag( "Error running $plugin: $err" );
159             }
160              
161             # we need to manually intervene or we'll get this:
162             # Running DOSnewline...
163             # Running Dependencies...
164             # Child (Dependencies) exited without calling finalize()
165             # Failed test 'Dependencies'
166             # at /usr/local/share/perl/5.18.2/Test/Apocalypse.pm line 134.
167             # Error running Dependencies: Can't locate object method "new" via package "Version::Requirements" (perhaps you forgot to load "Version::Requirements"?) at /usr/local/share/perl/5.18.2/Test/Apocalypse/Dependencies.pm line 59.
168             # Running DirChecks...
169             # Error running DirChecks: You already have a child named (Dependencies) running at /usr/local/share/perl/5.18.2/Test/More.pm line 771.
170 0         0 done_testing();
171             }
172 1068         8108 };
173             }
174              
175 1         1317 done_testing();
176 1         431 return 1;
177             }
178              
179             1;
180              
181             __END__
182              
183             =pod
184              
185             =encoding UTF-8
186              
187             =for :stopwords Apocalypse Niebur Ryan cpan testmatrix url annocpan anno bugtracker rt
188             cpants kwalitee diff irc mailto metadata placeholders metacpan apocal CPAN
189             AUTHORs al backend debian distro distros dists env hackish plugins
190             testsuite yml pm yay unicode blog precompiled =for stopwords ap cyclomatic
191             cal dist homebrew imo internet perltidy prefs prereq testrun
192              
193             =head1 NAME
194              
195             Test::Apocalypse - Apocalypse's favorite tests bundled into a simple interface
196              
197             =head1 VERSION
198              
199             This document describes v1.006 of Test::Apocalypse - released October 25, 2014 as part of Test-Apocalypse.
200              
201             =head1 SYNOPSIS
202              
203             #!/usr/bin/perl
204             use strict; use warnings;
205              
206             use Test::More;
207             eval "use Test::Apocalypse";
208             if ( $@ ) {
209             plan skip_all => 'Test::Apocalypse required for validating the distribution';
210             } else {
211             is_apocalypse_here();
212             }
213              
214             =head1 DESCRIPTION
215              
216             This module greatly simplifies common author tests for modules heading towards CPAN. I was sick of copy/pasting
217             the tons of t/foo.t scripts + managing them in every distro. I thought it would be nice to bundle all of it into
218             one module and toss it on CPAN :) That way, every time I update this module all of my dists would be magically
219             updated!
220              
221             This module respects the RELEASE_TESTING/AUTOMATED_TESTING env variable, if it is not set it will skip the entire
222             testsuite. Normally end-users should not run it; but you can if you want to see how bad my dists are, ha! The scheme
223             is exactly the same as the one Alias proposed in L<Test::XT> and in his blog post, L<http://use.perl.org/use.perl.org/_Alias/journal/38822.html>.
224              
225             This module uses L<Module::Pluggable> to have custom "backends" that process various tests. We wrap them in a hackish
226             L<Test::Block> block per-plugin and it seems to work nicely. If you want to write your own, it should be a breeze
227             once you look at some of my plugins and see how it works. ( more documentation to come )
228              
229             =head2 Usage
230              
231             In order to use this, you would need to be familiar with the "standard" steps in order to fully exercise the testsuite.
232             There are a few steps we require, because our plugins need stuff to be prepared for them. For starters, you would need
233             a test file in your distribution similar to the one in SYNOPSIS. Once that is done and added to your MANIFEST and etc,
234             you can do this:
235              
236             perl Build.PL # sets up the dist ( duh, hah )
237             ./Build dist # makes the tarball ( so certain plugins can process it )
238             RELEASE_TESTING=1 ./Build test # runs the testsuite!
239              
240             =head1 Methods
241              
242             =head2 is_apocalypse_here()
243              
244             This is the main entry point for this testsuite. By default, it runs every plugin in the testsuite. You can enable/disable
245             specific plugins if you desire. It accepts a single argument: a hashref or a hash. It can contain various options, but as of
246             now it only supports two options. If you try to use allow and deny at the same time, this module will throw an exception.
247              
248             =head3 allow
249              
250             Setting "allow" to a string or a precompiled regex will run only the plugins that match the regex. If passed a string, this module
251             will compile it via C<qr/$str/i>.
252              
253             # run only the EOL test and disable all other tests
254             is_apocalypse_here( {
255             allow => qr/^EOL$/,
256             } );
257              
258             # run all "dist" tests
259             is_apocalypse_here( {
260             allow => 'dist',
261             } );
262              
263             =head3 deny
264              
265             Setting "deny" to a string or a precompiled regex will not run the plugins that match the regex. If passed a string, this module
266             will compile it via C<qr/$str/i>.
267              
268             # disable Pod_Coverage test and enable all other tests
269             is_apocalypse_here( {
270             deny => qr/^Pod_Coverage$/,
271             } );
272              
273             # disable all pod tests
274             is_apocalypse_here( {
275             deny => 'pod',
276             } );
277              
278             =head2 plugins()
279              
280             Since this module uses L<Module::Pluggable> you can use this method on the package to find out what plugins are available. Handy if you need
281             to know what plugins to skip, for example.
282              
283             my @tests = Test::Apocalypse->plugins;
284              
285             =head1 EXPORT
286              
287             Automatically exports the "is_apocalypse_here" sub.
288              
289             =head1 MORE IDEAS
290              
291             =over 4
292              
293             =item * Test::NoSmartComments
294              
295             I don't use Smart::Comments but it might be useful? I LOVE BLOAT! :)
296              
297             =item * Better POD spelling checker?
298              
299             Test::Spelling is ancient, and often blows up. There's a Test::Pod::Spelling on CPAN but it is flaky too :(
300              
301             =item * Document the way we do plugins so others can add to this testsuite :)
302              
303             =item * POD standards check
304              
305             Do we have SYNOPSIS, ABSTRACT, SUPPORT, etc sections? ( PerlCritic can do that! Need to investigate more... )
306              
307             =item * Integrate Test::UniqueTestNames into the testsuite
308              
309             This would be nice, but I'm not sure if I can actually force this on other tests. Otherwise I'll be just making
310             sure that the Test::Apocalypse tests is unique, which is worthless to $dist trying to clean itself up...
311              
312             =item * META.yml checks
313              
314             We should make sure that the META.yml includes the "repository", "license", and other useful keys!
315              
316             =item * Other AUTHORs
317              
318             As always, we should keep up on the "latest" in the perl world and look at other authors for what they are doing.
319              
320             =item * indirect syntax
321              
322             We should figure out how to use indirect.pm to detect this deprecated method of coding. There's a L<Perl::Critic> plugin for this, yay!
323              
324             =item * Test::PPPort
325              
326             Already implemented as PPPort.pm but it's less invasive than my version, ha!
327              
328             =item * Test::DependentModules
329              
330             This is a crazy test, but would help tremendously in finding regressions in your code!
331              
332             =item * Test::CleanNamespaces
333              
334             I don't exclusively code in Moose, but this could be useful...
335              
336             =item * no internet?
337              
338             It would be nice to signal INTERNET_TESTING=0 or something zany like that so this testsuite will skip the tests that need internet access...
339              
340             <Apocalypse> Is there a convention that signals no internet access? Similar to RELEASE_TESTING, AUTOMATED_TESTING, and etc?
341             <@rjbs> No.
342             <Apocalypse> mmm I ain't in the mood to invent it so I'll just bench it for now :(
343             <Apocalypse> however, if I was to invent it I would call it something like INTERNET_TESTING=0
344             <Apocalypse> Also, why does ILYAZ keep re-inventing the stuff? Use of uninitialized value $ENV{"PERL_RL_TEST_PROMPT_MINLEN"} in bitwise or (|) at test.pl line 33.
345             <@Alias> use LWP::Online ':skip_all';
346             <@Alias> Whack that in the relevant test scripts
347             <Apocalypse> Alias: Hmm, how can I control that at a distance? i.e. disabling inet if I had inet access?
348             <@Alias> You can't
349             <@Alias> It's a pragmatic test, tries to pull some huge site front pages and looks for copyright statements
350             <Apocalypse> At least it's a good start - thanks!
351             <@Alias> So it deals with proxies and airport wireless hijacking etc properly
352             <Apocalypse> Hah yeah I had to do the same thing at $work in the past, we put up a "special" page then had our software try to read it and if the content didn't match it complained :)
353             <@Alias> right
354             <@Alias> So yeah, it automates that
355             <@Alias> I wrote it while in an airport annoyed that something I wrote wasn't falling back on a minicpan properly
356             <Apocalypse> At least it'll be an improvement, but I still need to force no inet for testing... ohwell
357             <Apocalypse> Heh, it seems like us perl hackers do a lot of work while stranded at airports :)
358             <@Alias> If you can break LWP from the environment, that would work
359             <@Alias> Setting a proxy ENVthat is illegal etc
360             <Apocalypse> ah good thinking, I'll read up on the fine points of LWP env vars and try to screw it up
361              
362             =back
363              
364             =head2 Modules that I considered but decided against using
365              
366             =over 4
367              
368             =item * L<Test::Distribution>
369              
370             This module was a plugin in this testsuite but I don't need it. All the functionality in it is already replicated in the plugins :)
371              
372             =item * L<Test::Module::Used> and L<Test::Dependencies>
373              
374             They were plugins in this testsuite but since I started coding with L<Moose>, they don't work! I've switched to my homebrew solution
375             utilizing L<Perl::PrereqScanner> which works nicely for me.
376              
377             =item * L<Test::MyDeps>
378              
379             Superseded by L<Test::DependentModules>. Also, I don't want to waste a lot of time on each testrun testing other modules!
380              
381             =item * L<Test::NoTabs>
382              
383             I always use tabs! :(
384              
385             =item * L<Test::CheckManifest>
386              
387             This was a buggy module that I dropped and is now using L<Test::DistManifest>
388              
389             =item * L<Test::Dist>
390              
391             This is pretty much the same thing as this dist ;)
392              
393             =item * L<Test::PureASCII>
394              
395             This rocks, as I don't care about unicode in my perl! ;)
396              
397             =item * L<Test::LatestPrereqs>
398              
399             This looks cool but we need to fiddle with config files? My OutdatedPrereqs test already covers it pretty well...
400              
401             =item * L<Test::Pod::Content>
402              
403             This is useful, but not everyone has the same POD layout. It would be too much work to try and generalize this...
404              
405             =item * L<Test::GreaterVersion>
406              
407             Since I never use CPAN, this is non-functional for me. However, it might be useful for someone?
408              
409             =item * L<Test::Kwalitee>
410              
411             This dist rocks, but it doesn't print the info nor utilize the extra metrics. My homebrew solution actually copied
412             a lot of code from this, so I have to give it props!
413              
414             =item * L<Test::LoadAllModules>
415              
416             This is very similar to L<Test::UseAllModules> but looks more complicated. Also, I already have enough tests that do that ;)
417              
418             =item * L<Test::ModuleReady>
419              
420             This looks like a nice module, but what it does is already covered by the numerous tests in this dist...
421              
422             =item * L<Test::PerlTidy>
423              
424             Br0ken install at this time... ( PerlCritic can do that! Need to investigate more... ) Also, all it does is... run your module
425             through perltidy and compare the outputs. Not that useful imo because I never could get perltidy to match my prefs :(
426              
427             =item * L<Test::Install::METArequires>
428              
429             This looks like a lazy way to do auto_install and potentially dangerous! Better to just use the prereq logic in Build.PL/Makefile.PL
430              
431             =item * L<Test::Perl::Metrics::Simple>
432              
433             This just tests your Cyclomatic complexity and was the starting point for my homebrew solution.
434              
435             =back
436              
437             =head1 SUPPORT
438              
439             =head2 Perldoc
440              
441             You can find documentation for this module with the perldoc command.
442              
443             perldoc Test::Apocalypse
444              
445             =head2 Websites
446              
447             The following websites have more information about this module, and may be of help to you. As always,
448             in addition to those websites please use your favorite search engine to discover more resources.
449              
450             =over 4
451              
452             =item *
453              
454             MetaCPAN
455              
456             A modern, open-source CPAN search engine, useful to view POD in HTML format.
457              
458             L<http://metacpan.org/release/Test-Apocalypse>
459              
460             =item *
461              
462             Search CPAN
463              
464             The default CPAN search engine, useful to view POD in HTML format.
465              
466             L<http://search.cpan.org/dist/Test-Apocalypse>
467              
468             =item *
469              
470             RT: CPAN's Bug Tracker
471              
472             The RT ( Request Tracker ) website is the default bug/issue tracking system for CPAN.
473              
474             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-Apocalypse>
475              
476             =item *
477              
478             AnnoCPAN
479              
480             The AnnoCPAN is a website that allows community annotations of Perl module documentation.
481              
482             L<http://annocpan.org/dist/Test-Apocalypse>
483              
484             =item *
485              
486             CPAN Ratings
487              
488             The CPAN Ratings is a website that allows community ratings and reviews of Perl modules.
489              
490             L<http://cpanratings.perl.org/d/Test-Apocalypse>
491              
492             =item *
493              
494             CPAN Forum
495              
496             The CPAN Forum is a web forum for discussing Perl modules.
497              
498             L<http://cpanforum.com/dist/Test-Apocalypse>
499              
500             =item *
501              
502             CPANTS
503              
504             The CPANTS is a website that analyzes the Kwalitee ( code metrics ) of a distribution.
505              
506             L<http://cpants.perl.org/dist/overview/Test-Apocalypse>
507              
508             =item *
509              
510             CPAN Testers
511              
512             The CPAN Testers is a network of smokers who run automated tests on uploaded CPAN distributions.
513              
514             L<http://www.cpantesters.org/distro/T/Test-Apocalypse>
515              
516             =item *
517              
518             CPAN Testers Matrix
519              
520             The CPAN Testers Matrix is a website that provides a visual overview of the test results for a distribution on various Perls/platforms.
521              
522             L<http://matrix.cpantesters.org/?dist=Test-Apocalypse>
523              
524             =item *
525              
526             CPAN Testers Dependencies
527              
528             The CPAN Testers Dependencies is a website that shows a chart of the test results of all dependencies for a distribution.
529              
530             L<http://deps.cpantesters.org/?module=Test::Apocalypse>
531              
532             =back
533              
534             =head2 Email
535              
536             You can email the author of this module at C<APOCAL at cpan.org> asking for help with any problems you have.
537              
538             =head2 Internet Relay Chat
539              
540             You can get live help by using IRC ( Internet Relay Chat ). If you don't know what IRC is,
541             please read this excellent guide: L<http://en.wikipedia.org/wiki/Internet_Relay_Chat>. Please
542             be courteous and patient when talking to us, as we might be busy or sleeping! You can join
543             those networks/channels and get help:
544              
545             =over 4
546              
547             =item *
548              
549             irc.perl.org
550              
551             You can connect to the server at 'irc.perl.org' and join this channel: #perl-help then talk to this person for help: Apocalypse.
552              
553             =item *
554              
555             irc.freenode.net
556              
557             You can connect to the server at 'irc.freenode.net' and join this channel: #perl then talk to this person for help: Apocal.
558              
559             =item *
560              
561             irc.efnet.org
562              
563             You can connect to the server at 'irc.efnet.org' and join this channel: #perl then talk to this person for help: Ap0cal.
564              
565             =back
566              
567             =head2 Bugs / Feature Requests
568              
569             Please report any bugs or feature requests by email to C<bug-test-apocalypse at rt.cpan.org>, or through
570             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Apocalypse>. You will be automatically notified of any
571             progress on the request by the system.
572              
573             =head2 Source Code
574              
575             The code is open to the world, and available for you to hack on. Please feel free to browse it and play
576             with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
577             from your repository :)
578              
579             L<https://github.com/apocalypse/perl-test-apocalypse>
580              
581             git clone git://github.com/apocalypse/perl-test-apocalypse.git
582              
583             =head1 AUTHOR
584              
585             Apocalypse <APOCAL@cpan.org>
586              
587             =head2 CONTRIBUTORS
588              
589             =for stopwords Apocalypse Ryan Niebur
590              
591             =over 4
592              
593             =item *
594              
595             Apocalypse <apoc@blackhole.(none)>
596              
597             =item *
598              
599             Apocalypse <apoc@satellite.(none)>
600              
601             =item *
602              
603             Apocalypse <perl@0ne.us>
604              
605             =item *
606              
607             Ryan Niebur <ryanryan52@gmail.com>
608              
609             =back
610              
611             =head1 ACKNOWLEDGEMENTS
612              
613             Thanks to jawnsy@cpan.org for the prodding and help in getting this package ready to be bundled into debian!
614              
615             =head1 COPYRIGHT AND LICENSE
616              
617             This software is copyright (c) 2014 by Apocalypse.
618              
619             This is free software; you can redistribute it and/or modify it under
620             the same terms as the Perl 5 programming language system itself.
621              
622             The full text of the license can be found in the
623             F<LICENSE> file included with this distribution.
624              
625             =head1 DISCLAIMER OF WARRANTY
626              
627             THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
628             APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
629             HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
630             OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
631             THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
632             PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
633             IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
634             ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
635              
636             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
637             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
638             THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
639             GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
640             USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
641             DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
642             PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
643             EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
644             SUCH DAMAGES.
645              
646             =cut