Initial import of Config::Any (refactored from Catalyst::Plugin::ConfigLoader), and...
Joel Bernstein [Wed, 9 Aug 2006 16:57:11 +0000 (16:57 +0000)]
15 files changed:
Build.PL [new file with mode: 0644]
Changes [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
README [new file with mode: 0644]
lib/Config/Any.pm [new file with mode: 0644]
lib/Config/Any/General.pm [new file with mode: 0644]
lib/Config/Any/INI.pm [new file with mode: 0644]
lib/Config/Any/JSON.pm [new file with mode: 0644]
lib/Config/Any/Perl.pm [new file with mode: 0644]
lib/Config/Any/XML.pm [new file with mode: 0644]
lib/Config/Any/YAML.pm [new file with mode: 0644]
t/00.load.t [new file with mode: 0644]
t/perlcritic.t [new file with mode: 0644]
t/pod-coverage.t [new file with mode: 0644]
t/pod.t [new file with mode: 0644]

diff --git a/Build.PL b/Build.PL
new file mode 100644 (file)
index 0000000..02a5026
--- /dev/null
+++ b/Build.PL
@@ -0,0 +1,18 @@
+use strict;
+use warnings;
+use Module::Build;
+
+my $builder = Module::Build->new(
+    module_name         => 'Config::Any',
+    license             => 'perl',
+    dist_author         => 'Joel Bernstein <rataxis@cpan.org>',
+    dist_version_from   => 'lib/Config/Any.pm',
+    requires => {
+        'Test::More' => 0,
+        'version'    => 0,
+               'Module::Pluggable' => '3.01'
+    },
+    add_to_cleanup      => [ 'Config-Any-*' ],
+);
+
+$builder->create_build_script();
diff --git a/Changes b/Changes
new file mode 100644 (file)
index 0000000..95f6dc4
--- /dev/null
+++ b/Changes
@@ -0,0 +1,5 @@
+Revision history for Config-Any
+
+0.0.1  Mon Aug  7 15:15:15 2006
+       Initial release.
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..b412a1b
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,17 @@
+Build.PL
+Changes
+lib/Config/Any.pm
+lib/Config/Any/General.pm
+lib/Config/Any/INI.pm
+lib/Config/Any/JSON.pm
+lib/Config/Any/Perl.pm
+lib/Config/Any/XML.pm
+lib/Config/Any/YAML.pm
+Makefile.PL
+MANIFEST
+META.yml                       # Will be created by "make dist"
+README
+t/00.load.t
+t/perlcritic.t
+t/pod-coverage.t
+t/pod.t
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..3d80d7e
--- /dev/null
+++ b/README
@@ -0,0 +1,26 @@
+Config-Any version 0.0.4
+
+This module generalises loading class configuration data from a number of different
+file formats.
+
+INSTALLATION
+
+To install this module, run the following commands:
+    perl Build.PL
+    ./Build
+    ./Build test
+    ./Build install
+
+
+DEPENDENCIES
+
+Module::Pluggable >= 3.01
+
+COPYRIGHT AND LICENCE
+
+The development of this module was sponsored by SAPO, a division of Portugal Telecom.
+
+Copyright (C) 2006, Portugal Telecom
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
diff --git a/lib/Config/Any.pm b/lib/Config/Any.pm
new file mode 100644 (file)
index 0000000..c6a30e2
--- /dev/null
@@ -0,0 +1,227 @@
+package Config::Any;
+# $Id: $
+use warnings;
+use strict;
+use Carp;
+use Module::Pluggable::Object ();
+our $VERSION = (qw$Rev: $)[-1];
+
+sub load_files {
+    my ($class, $args) = @_;
+    croak "load_files requires a hashref argument" unless defined $args;
+    croak "no files specified!" unless defined $args->{files};
+    my $files = [ grep { -f $_ } @{$args->{files}} ];
+    my $filter_cb = delete $args->{filter};
+    return $class->_load($files, $filter_cb);
+}
+
+sub load_stems {
+    my ($class, $args) = @_;
+    croak "load_stems requires a hashref argument" unless defined $args;
+    croak "no stems specified!" unless defined $args->{stems};
+    my $filter_cb = delete $args->{filter};
+    my $stems = $args->{stems};
+    my @files;
+    STEM:
+    for my $s (@$stems) {
+        EXT:
+        for my $ext ($class->extensions) {
+            my $file = "$s.$ext";
+            next EXT unless -f $file;
+            push @files, $file;
+            last EXT;
+        }
+    }
+    return $class->_load(\@files, $filter_cb);
+}
+
+sub _load {
+    my ($class, $files_ref, $filter_cb) = @_;
+    croak "_load requires a arrayref of file paths" unless defined $files_ref;
+
+    my $final_configs = [];
+
+    for my $loader ( $class->plugins ) {
+        for my $filename (@$files_ref) {
+            my $config = $loader->load( $filename );
+            next if !$config;
+            $filter_cb->( $config ) if defined $filter_cb;
+            push @$final_configs, { $filename => $config };
+        }
+    }
+    $final_configs;
+}
+
+sub finder {
+    my $class = shift;
+    my $finder = Module::Pluggable::Object->new(
+        search_path => [ __PACKAGE__ ],
+        require     => 1
+    );
+    $finder;
+}
+
+sub plugins {
+    my $class = shift;
+    return $class->finder->plugins;
+}
+
+sub extensions {
+    my $class = shift;
+    return [ map { $_->extensions } $class->plugins ];
+}
+
+1; # Magic true value required at end of module
+__END__
+
+=head1 NAME
+
+Config::Any - [One line description of module's purpose here]
+
+
+=head1 VERSION
+
+This document describes Config::Any version 0.0.4
+
+
+=head1 SYNOPSIS
+
+    use Config::Any;
+
+       my $cfg = Config::Any->load_stems({stems => \@filepath_stems, ... });
+       # or
+       my $cfg = Config::Any->load_files({files => \@filepaths, ... });
+
+       for (@$cfg) {
+               my ($filename, $config) = each %$_;
+               $class->config($config);
+               warn "loaded config from file: $filename";
+       }
+
+=head1 DESCRIPTION
+
+=for author to fill in:
+    Write a full description of the module and its features here.
+    Use subsections (=head2, =head3) as appropriate.
+
+
+=head1 INTERFACE 
+
+=for author to fill in:
+    Write a separate section listing the public components of the modules
+    interface. These normally consist of either subroutines that may be
+    exported, or methods that may be called on objects belonging to the
+    classes provided by the module.
+
+
+=head1 DIAGNOSTICS
+
+=for author to fill in:
+    List every single error and warning message that the module can
+    generate (even the ones that will "never happen"), with a full
+    explanation of each problem, one or more likely causes, and any
+    suggested remedies.
+
+=over
+
+=item C<< Error message here, perhaps with %s placeholders >>
+
+[Description of error here]
+
+=item C<< Another error message here >>
+
+[Description of error here]
+
+[Et cetera, et cetera]
+
+=back
+
+
+=head1 CONFIGURATION AND ENVIRONMENT
+
+=for author to fill in:
+    A full explanation of any configuration system(s) used by the
+    module, including the names and locations of any configuration
+    files, and the meaning of any environment variables or properties
+    that can be set. These descriptions must also include details of any
+    configuration language used.
+  
+Config::Any requires no configuration files or environment variables.
+
+
+=head1 DEPENDENCIES
+
+=for author to fill in:
+    A list of all the other modules that this module relies upon,
+    including any restrictions on versions, and an indication whether
+    the module is part of the standard Perl distribution, part of the
+    module's distribution, or must be installed separately. ]
+
+None.
+
+
+=head1 INCOMPATIBILITIES
+
+=for author to fill in:
+    A list of any modules that this module cannot be used in conjunction
+    with. This may be due to name conflicts in the interface, or
+    competition for system or program resources, or due to internal
+    limitations of Perl (for example, many modules that use source code
+    filters are mutually incompatible).
+
+None reported.
+
+
+=head1 BUGS AND LIMITATIONS
+
+=for author to fill in:
+    A list of known problems with the module, together with some
+    indication Whether they are likely to be fixed in an upcoming
+    release. Also a list of restrictions on the features the module
+    does provide: data types that cannot be handled, performance issues
+    and the circumstances in which they may arise, practical
+    limitations on the size of data sets, special cases that are not
+    (yet) handled, etc.
+
+No bugs have been reported.
+
+Please report any bugs or feature requests to
+C<bug-config-any@rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org>.
+
+
+=head1 AUTHOR
+
+Joel Bernstein  C<< <rataxis@cpan.org> >>
+
+
+=head1 LICENCE AND COPYRIGHT
+
+Copyright (c) 2006, Portugal Telecom C<< http://www.sapo.pt/ >>. All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself. See L<perlartistic>.
+
+
+=head1 DISCLAIMER OF WARRANTY
+
+BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
+YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR, OR CORRECTION.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
+OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
diff --git a/lib/Config/Any/General.pm b/lib/Config/Any/General.pm
new file mode 100644 (file)
index 0000000..c91bd4d
--- /dev/null
@@ -0,0 +1,80 @@
+package Config::Any::General;\r
+\r
+use strict;\r
+use warnings;\r
+\r
+=head1 NAME\r
+\r
+Config::Any::General - Load Config::General files\r
+\r
+=head1 DESCRIPTION\r
+\r
+Loads Config::General files. Example:\r
+\r
+    name = TestApp\r
+    <Component Controller::Foo>\r
+        foo bar\r
+    </Component>\r
+    <Model Baz>\r
+        qux xyzzy\r
+    </Model>\r
+\r
+=head1 METHODS\r
+\r
+=head2 extensions( )\r
+\r
+return an array of valid extensions (C<cnf>, C<conf>).\r
+\r
+=cut\r
+\r
+sub extensions {\r
+    return qw( cnf conf );\r
+}\r
+\r
+=head2 load( $file )\r
+\r
+Attempts to load C<$file> via Config::General.\r
+\r
+=cut\r
+\r
+sub load {\r
+    my $class = shift;\r
+    my $file  = shift;\r
+\r
+    require Config::General;\r
+    my $configfile = Config::General->new( $file );\r
+    my $config     = { $configfile->getall };\r
+    \r
+    return $config;\r
+}\r
+\r
+=head1 AUTHOR\r
+\r
+=over 4 \r
+\r
+=item * Brian Cassidy E<lt>bricas@cpan.orgE<gt>\r
+\r
+=back\r
+\r
+=head1 COPYRIGHT AND LICENSE\r
+\r
+Copyright 2006 by Brian Cassidy\r
+\r
+This library is free software; you can redistribute it and/or modify\r
+it under the same terms as Perl itself. \r
+\r
+=head1 SEE ALSO\r
+\r
+=over 4 \r
+\r
+=item * L<Catalyst>\r
+\r
+=item * L<Config::Any>\r
+\r
+=item * L<Config::General>\r
+\r
+=back\r
+\r
+=cut\r
+\r
+1;
\ No newline at end of file
diff --git a/lib/Config/Any/INI.pm b/lib/Config/Any/INI.pm
new file mode 100644 (file)
index 0000000..092362d
--- /dev/null
@@ -0,0 +1,82 @@
+package Config::Any::INI;\r
+\r
+use strict;\r
+use warnings;\r
+\r
+=head1 NAME\r
+\r
+Config::Any::INI - Load INI config files\r
+\r
+=head1 DESCRIPTION\r
+\r
+Loads INI files. Example:\r
+\r
+    name=TestApp\r
+    \r
+    [Controller::Foo]\r
+    foo=bar\r
+    \r
+    [Model::Baz]\r
+    qux=xyzzy\r
+\r
+=head1 METHODS\r
+\r
+=head2 extensions( )\r
+\r
+return an array of valid extensions (C<ini>).\r
+\r
+=cut\r
+\r
+sub extensions {\r
+    return qw( ini );\r
+}\r
+\r
+=head2 load( $file )\r
+\r
+Attempts to load C<$file> as an INI file.\r
+\r
+=cut\r
+\r
+sub load {\r
+    my $class = shift;\r
+    my $file  = shift;\r
+\r
+    require Config::Tiny;\r
+    my $config = Config::Tiny->read( $file );\r
+    my $main   = delete $config->{ _ };\r
+    \r
+    $config->{ $_ } = $main->{ $_ } for keys %$main;\r
+\r
+    return $config;\r
+}\r
+\r
+=head1 AUTHOR\r
+\r
+=over 4 \r
+\r
+=item * Brian Cassidy E<lt>bricas@cpan.orgE<gt>\r
+\r
+=back\r
+\r
+=head1 COPYRIGHT AND LICENSE\r
+\r
+Copyright 2006 by Brian Cassidy\r
+\r
+This library is free software; you can redistribute it and/or modify\r
+it under the same terms as Perl itself. \r
+\r
+=head1 SEE ALSO\r
+\r
+=over 4 \r
+\r
+=item * L<Catalyst>\r
+\r
+=item * L<Config::Any>\r
+\r
+=item * L<Config::Tiny>\r
+\r
+=back\r
+\r
+=cut\r
+\r
+1;
\ No newline at end of file
diff --git a/lib/Config/Any/JSON.pm b/lib/Config/Any/JSON.pm
new file mode 100644 (file)
index 0000000..faa041d
--- /dev/null
@@ -0,0 +1,92 @@
+package Config::Any::JSON;\r
+\r
+use strict;\r
+use warnings;\r
+\r
+=head1 NAME\r
+\r
+Config::Any::JSON - Load JSON config files\r
+\r
+=head1 DESCRIPTION\r
+\r
+Loads JSON files. Example:\r
+\r
+    {\r
+        "name": "TestApp",\r
+        "Controller::Foo": {\r
+            "foo": "bar"\r
+        },\r
+        "Model::Baz": {\r
+            "qux": "xyzzy"\r
+        }\r
+    }\r
+\r
+=head1 METHODS\r
+\r
+=head2 extensions( )\r
+\r
+return an array of valid extensions (C<json>, C<jsn>).\r
+\r
+=cut\r
+\r
+sub extensions {\r
+    return qw( json jsn );\r
+}\r
+\r
+=head2 load( $file )\r
+\r
+Attempts to load C<$file> as a JSON file.\r
+\r
+=cut\r
+\r
+sub load {\r
+    my $class = shift;\r
+    my $file  = shift;\r
+\r
+    open( my $fh, $file ) or die $!;\r
+    my $content = do { local $/; <$fh> };\r
+    close $fh;\r
+\r
+    eval { require JSON::Syck; };\r
+    if( $@ ) {\r
+        require JSON;\r
+        JSON->import;\r
+        return jsonToObj( $content );\r
+    }\r
+    else {\r
+        return JSON::Syck::Load( $content );\r
+    }\r
+}\r
+\r
+=head1 AUTHOR\r
+\r
+=over 4 \r
+\r
+=item * Brian Cassidy E<lt>bricas@cpan.orgE<gt>\r
+\r
+=back\r
+\r
+=head1 COPYRIGHT AND LICENSE\r
+\r
+Copyright 2006 by Brian Cassidy\r
+\r
+This library is free software; you can redistribute it and/or modify\r
+it under the same terms as Perl itself. \r
+\r
+=head1 SEE ALSO\r
+\r
+=over 4 \r
+\r
+=item * L<Catalyst>\r
+\r
+=item * L<Config::Any>\r
+\r
+=item * L<JSON>\r
+\r
+=item * L<JSON::Syck>\r
+\r
+=back\r
+\r
+=cut\r
+\r
+1;
\ No newline at end of file
diff --git a/lib/Config/Any/Perl.pm b/lib/Config/Any/Perl.pm
new file mode 100644 (file)
index 0000000..6c179f5
--- /dev/null
@@ -0,0 +1,76 @@
+package Config::Any::Perl;\r
+\r
+use strict;\r
+use warnings;\r
+\r
+=head1 NAME\r
+\r
+Config::Any::Perl - Load Perl config files\r
+\r
+=head1 DESCRIPTION\r
+\r
+Loads Perl files. Example:\r
+\r
+    {\r
+        name => 'TestApp',\r
+        'Controller::Foo' => {\r
+            foo => 'bar'\r
+        },\r
+        'Model::Baz' => {\r
+            qux => 'xyzzy'\r
+        }\r
+    }\r
+\r
+=head1 METHODS\r
+\r
+=head2 extensions( )\r
+\r
+return an array of valid extensions (C<pl>, C<perl>).\r
+\r
+=cut\r
+\r
+sub extensions {\r
+    return qw( pl perl );\r
+}\r
+\r
+=head2 load( $file )\r
+\r
+Attempts to load C<$file> as a Perl file.\r
+\r
+=cut\r
+\r
+sub load {\r
+    my $class = shift;\r
+    my $file  = shift;\r
+\r
+    return eval { require $file };\r
+}\r
+\r
+=head1 AUTHOR\r
+\r
+=over 4 \r
+\r
+=item * Brian Cassidy E<lt>bricas@cpan.orgE<gt>\r
+\r
+=back\r
+\r
+=head1 COPYRIGHT AND LICENSE\r
+\r
+Copyright 2006 by Brian Cassidy\r
+\r
+This library is free software; you can redistribute it and/or modify\r
+it under the same terms as Perl itself. \r
+\r
+=head1 SEE ALSO\r
+\r
+=over 4 \r
+\r
+=item * L<Catalyst>\r
+\r
+=item * L<Config::Any>\r
+\r
+=back\r
+\r
+=cut\r
+\r
+1;
\ No newline at end of file
diff --git a/lib/Config/Any/XML.pm b/lib/Config/Any/XML.pm
new file mode 100644 (file)
index 0000000..a37a2f2
--- /dev/null
@@ -0,0 +1,82 @@
+package Config::Any::XML;\r
+\r
+use strict;\r
+use warnings;\r
+\r
+=head1 NAME\r
+\r
+Config::Any::XML - Load XML config files\r
+\r
+=head1 DESCRIPTION\r
+\r
+Loads XML files. Example:\r
+\r
+    <config>\r
+        <name>TestApp</name>\r
+        <component name="Controller::Foo">\r
+            <foo>bar</foo>\r
+        </component>\r
+        <model name="Baz">\r
+            <qux>xyzzy</qux>\r
+        </model>\r
+    </config>\r
+\r
+=head1 METHODS\r
+\r
+=head2 extensions( )\r
+\r
+return an array of valid extensions (C<xml>).\r
+\r
+=cut\r
+\r
+sub extensions {\r
+    return qw( xml );\r
+}\r
+\r
+=head2 load( $file )\r
+\r
+Attempts to load C<$file> as an XML file.\r
+\r
+=cut\r
+\r
+sub load {\r
+    my $class = shift;\r
+    my $file  = shift;\r
+\r
+    require XML::Simple;\r
+    XML::Simple->import;\r
+    my $config = XMLin( $file, ForceArray => [ qw( component model view controller ) ] );\r
+\r
+    return $config;\r
+}\r
+\r
+=head1 AUTHOR\r
+\r
+=over 4 \r
+\r
+=item * Brian Cassidy E<lt>bricas@cpan.orgE<gt>\r
+\r
+=back\r
+\r
+=head1 COPYRIGHT AND LICENSE\r
+\r
+Copyright 2006 by Brian Cassidy\r
+\r
+This library is free software; you can redistribute it and/or modify\r
+it under the same terms as Perl itself. \r
+\r
+=head1 SEE ALSO\r
+\r
+=over 4 \r
+\r
+=item * L<Catalyst>\r
+\r
+=item * L<Config::Any>\r
+\r
+=item * L<XML::Simple>\r
+\r
+=back\r
+\r
+=cut\r
+\r
+1;
\ No newline at end of file
diff --git a/lib/Config/Any/YAML.pm b/lib/Config/Any/YAML.pm
new file mode 100644 (file)
index 0000000..564fc52
--- /dev/null
@@ -0,0 +1,88 @@
+package Config::Any::YAML;\r
+\r
+use strict;\r
+use warnings;\r
+\r
+=head1 NAME\r
+\r
+Config::Any::YAML - Load YAML config files\r
+\r
+=head1 DESCRIPTION\r
+\r
+Loads YAML files. Example:\r
+\r
+    ---\r
+    name: TestApp\r
+    Controller::Foo:\r
+        foo: bar\r
+    Model::Baz:\r
+        qux: xyzzy\r
+    \r
+\r
+=head1 METHODS\r
+\r
+=head2 extensions( )\r
+\r
+return an array of valid extensions (C<yml>, C<yaml>).\r
+\r
+=cut\r
+\r
+sub extensions {\r
+    return qw( yml yaml );\r
+}\r
+\r
+=head2 load( $file )\r
+\r
+Attempts to load C<$file> as a YAML file.\r
+\r
+=cut\r
+\r
+sub load {\r
+    my $class = shift;\r
+    my $file  = shift;\r
+\r
+    eval { require YAML::Syck; };\r
+    if( $@ ) {\r
+        require YAML;\r
+        return YAML::LoadFile( $file );\r
+    }\r
+    else {\r
+        open( my $fh, $file ) or die $!;\r
+        my $content = do { local $/; <$fh> };\r
+        close $fh;\r
+        return YAML::Syck::Load( $content );\r
+    }\r
+}\r
+\r
+=head1 AUTHOR\r
+\r
+=over 4 \r
+\r
+=item * Brian Cassidy E<lt>bricas@cpan.orgE<gt>\r
+\r
+=back\r
+\r
+=head1 COPYRIGHT AND LICENSE\r
+\r
+Copyright 2006 by Brian Cassidy\r
+\r
+This library is free software; you can redistribute it and/or modify\r
+it under the same terms as Perl itself. \r
+\r
+=head1 SEE ALSO\r
+\r
+=over 4 \r
+\r
+=item * L<Catalyst>\r
+\r
+=item * L<Config::Any>\r
+\r
+=item * L<YAML>\r
+\r
+=item * L<YAML::Syck>\r
+\r
+=back\r
+\r
+=cut\r
+\r
+1;
\ No newline at end of file
diff --git a/t/00.load.t b/t/00.load.t
new file mode 100644 (file)
index 0000000..459cbb3
--- /dev/null
@@ -0,0 +1,7 @@
+use Test::More tests => 1;
+
+BEGIN {
+use_ok( 'Config::Any' );
+}
+
+diag( "Testing Config::Any $Config::Any::VERSION" );
diff --git a/t/perlcritic.t b/t/perlcritic.t
new file mode 100644 (file)
index 0000000..7e7b210
--- /dev/null
@@ -0,0 +1,9 @@
+#!perl
+
+if (!require Test::Perl::Critic) {
+    Test::More::plan(
+        skip_all => "Test::Perl::Critic required for testing PBP compliance"
+    );
+}
+
+Test::Perl::Critic::all_critic_ok();
diff --git a/t/pod-coverage.t b/t/pod-coverage.t
new file mode 100644 (file)
index 0000000..703f91d
--- /dev/null
@@ -0,0 +1,6 @@
+#!perl -T
+
+use Test::More;
+eval "use Test::Pod::Coverage 1.04";
+plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@;
+all_pod_coverage_ok();
diff --git a/t/pod.t b/t/pod.t
new file mode 100644 (file)
index 0000000..976d7cd
--- /dev/null
+++ b/t/pod.t
@@ -0,0 +1,6 @@
+#!perl -T
+
+use Test::More;
+eval "use Test::Pod 1.14";
+plan skip_all => "Test::Pod 1.14 required for testing POD" if $@;
+all_pod_files_ok();