=head1 NAME Module::Build::Kwalitee - Module::Build subclass with prepackaged tests =cut package Module::Build::Kwalitee; use strict; use warnings; use base qw( Module::Build ); use File::Spec::Functions qw( splitpath catfile catdir ); use File::Find::Rule; use File::Copy; use File::Path; our $VERSION = '0.24'; # slightly cheeky trick: Module::Build::Kwalitee::Stub is # actually a tiny Module::Build::Kwalitee package, overriding the # build_requires() method of Module::Build to add our test # dependencies. We don't have to duplicate these deps. use Module::Build::Kwalitee::Stub; =head1 SYNOPSIS This module requires this bit of magic in your Build.PL: use lib 'mbk'; use Module::Build::Kwalitee; Module::Build::Kwalitee->new( module_name => 'Foo::Bar', ..., }, )->create_build_script(); =head1 DESCRIPTION Module::Build::Kwalitee subclasses Module::Build to provide boilerplate tests for your project. It does this by overriding C and copying tests to your F directory when you run 'perl Build.PL'. Module::Build::Kwalitee gets over the bootstrapping problem by overriding Module::Build's C target, adding a "mbk" directory to your distribution containing a small stub Module::Build::Kwalitee which just overrides Module::Build's build_requires() method to add the dependencies of its tests. Module::Build::Kwalitee tests are not automatically added to F so if you want them shipped with your distribution you will have to do this manually. =head2 Tests Several boilerplate tests are added to t/: =over =item compile test =item C test =item C tests =item POD syntax & coverage tests =item 'use lib' test =back =cut sub new { my $class = shift; my $self = $class->SUPER::new(@_); unless (-d "t") { warn "Creating t/ dir for tests...\n"; mkdir "t" or die "Can't create dir: $!"; } my $path = $INC{"Module/Build/Kwalitee.pm"}; $path =~ s/\.pm$//; map { my (undef, undef, $filename) = splitpath( $_ ); copy($_, catfile('t', $filename)) or die "Can't copy file: $!"; } File::Find::Rule->file()->name( '*.t' )->in( $path ); return $self; } # ACTION_distdir is documented sub ACTION_distdir { my $self = shift; $self->SUPER::ACTION_distdir; # where's the distribution directory? my $dist_dir = $self->dist_dir; die "No _build dir '$dist_dir'" unless -d $dist_dir; # create the mbk folder in the dist dir mkpath([catdir($dist_dir, qw(mbk Module Build Kwalitee))]) or die "Cannot create directory"; # copy in the module stub my $stub = $INC{"Module/Build/Kwalitee/Stub.pm"}; my $dest = catfile($dist_dir, qw(mbk Module Build Kwalitee.pm)); copy($stub, $dest) or die "Can't copy file ($stub -> $dest) $!"; # munge the manifest so it contains an entry for the shipped # stub if there exists a manifest in the distribution my $manifest = catfile($dist_dir, "MANIFEST"); if (-e $manifest) { chmod 0644, $manifest; open MANIFEST, ">>$manifest" or die "can't open manifest '$manifest' for writing: $!"; print MANIFEST catfile(qw(mbk Module Build Kwalitee.pm)), "\n"; chmod 0444, $manifest; close MANIFEST; } } 1; # these are mixed in from ./Stub.pm, and confuse the pod parser for # some versions of the pod parser. # new is documented # build_requires is documented # recommends is documented __END__ =head1 ADDITIONAL FEATURES You can get the C to report which functions are not documented by using the C enviromental variable bash$ SHOW_NAKED=1 perl -Ilib t/003compile.t =head1 SEE ALSO L =head1 AUTHOR Stig Brautaset , Mark Fowler , Norman Nunley , Chia-liang Kao , et al. =cut