File Coverage

blib/lib/Import/Base.pm
Criterion Covered Total %
statement 118 120 98.3
branch 39 42 92.8
condition 4 5 80.0
subroutine 12 12 100.0
pod 2 2 100.0
total 175 181 96.6


line stmt bran cond sub pod time code
1             package Import::Base;
2             # ABSTRACT: Import a set of modules into the calling module
3             $Import::Base::VERSION = '1.002';
4 8     8   25561 use strict;
  8         10  
  8         182  
5 8     8   25 use warnings;
  8         10  
  8         139  
6 8     8   2549 use mro ();
  8         4020  
  8         148  
7 8     8   2903 use Import::Into;
  8         14088  
  8         203  
8 8     8   33 use Module::Runtime qw( use_module );
  8         10  
  8         23  
9              
10             require Exporter;
11              
12             our @ISA = qw(Exporter);
13              
14             sub modules {
15 46     46 1 2592 my ( $class, $bundles, $args ) = @_;
16 46         54 my @modules = ();
17              
18             # Find all the modules from the static API
19             # Reverse the array to allow more-specific classes to override
20             # less-specific ones
21 46         39 for my $pkg ( reverse @{ mro::get_linear_isa( $class ) } ) {
  46         175  
22 8     8   597 no strict 'refs';
  8         10  
  8         189  
23 8     8   23 no warnings 'once';
  8         8  
  8         6038  
24              
25 151 100       254 if ( !$args->{bundles_only} ) {
26 145         90 push @modules, @{ $pkg . "::IMPORT_MODULES" };
  145         342  
27             }
28              
29 151         94 my %bundles = %{ $pkg . "::IMPORT_BUNDLES" };
  151         375  
30 23         21 push @modules, map { @{ $bundles{ $_ } } }
  23         65  
31 151         167 grep { exists $bundles{ $_ } }
  99         208  
32             @$bundles;
33             }
34              
35 46         139 return @modules;
36             }
37              
38             sub _parse_args {
39 46     46   57 my ( $class, @args ) = @_;
40 46         43 my @bundles;
41 46         114 while ( @args ) {
42 34 100       87 last if $args[0] =~ /^-/;
43 31         76 push @bundles, shift @args;
44             }
45 46         75 my %args = @args;
46 46         94 return ( \@bundles, \%args );
47             }
48              
49             sub import_bundle {
50 2     2 1 3733 my ( $class, @args ) = @_;
51 2         5 my ( $bundles, $args ) = $class->_parse_args( @args );
52              
53             # Add internal Import::Base args
54 2         5 $args->{package} = scalar caller(0);
55 2         3 $args->{bundles_only} = 1;
56              
57 2         4 my @modules = $class->modules( $bundles, $args );
58 2         5 $class->_import_modules( \@modules, $bundles, $args );
59             }
60              
61             sub import {
62 44     44   90752 my ( $class, @args ) = @_;
63 44         130 my ( $bundles, $args ) = $class->_parse_args( @args );
64              
65             # Add internal Import::Base args
66 44         109 $args->{package} = scalar caller(0);
67              
68 44         111 my @modules = $class->modules( $bundles, $args );
69 44         203 $class->_import_modules( \@modules, $bundles, $args );
70             }
71              
72             sub _import_modules {
73 46     46   57 my ( $class, $modules, $bundles, $args ) = @_;
74              
75             die "Argument to -exclude must be arrayref"
76 46 100 100     180 if $args->{-exclude} && ref $args->{-exclude} ne 'ARRAY';
77 45         51 my $exclude = {};
78 45 100       90 if ( $args->{-exclude} ) {
79 2         2 while ( @{ $args->{-exclude} } ) {
  4         10  
80 2         2 my $module = shift @{ $args->{-exclude} };
  2         3  
81 2 100       5 my $subs = ref $args->{-exclude}[0] eq 'ARRAY' ? shift @{ $args->{-exclude} } : undef;
  1         14  
82 2         4 $exclude->{ $module } = $subs;
83             }
84             }
85              
86             # Add internal Import::Base args
87 45   50     78 $args->{package} ||= scalar caller(0);
88              
89 45         74 my @modules = @$modules;
90 45         59 my @cb_args = ( $bundles, $args );
91              
92             # Prepare the modules to load
93             # First pass determines the order to load
94 45         33 my ( @first_load, @last_load );
95 45         109 while ( @modules ) {
96 145 100       201 if ( ref $modules[0] eq 'CODE' ) {
97 15         10 push @first_load, shift @modules;
98 15         30 next;
99             }
100              
101 130         105 my $thing = shift @modules;
102 130         92 my $module;
103             my $version;
104 130 100       157 if ( ref $thing eq 'HASH' ) {
105 4         10 ( $module, $version ) = %$thing;
106             }
107             else {
108 126         133 $module = $thing;
109             }
110 130 100       204 my $imports = ref $modules[0] eq 'ARRAY' ? shift @modules : [];
111              
112             # Determine the module order
113 130 100       242 if ( $module =~ /^</ ) {
    100          
114 10         21 $module =~ s/^<//;
115 10 50       13 if ( defined $version ) {
116 0         0 unshift @first_load, { $module => $version } => $imports;
117             }
118             else {
119 10         26 unshift @first_load, $module => $imports;
120             }
121             }
122             elsif ( $module =~ /^>/ ) {
123 10         16 $module =~ s/^>//;
124 10 50       13 if ( defined $version ) {
125 0         0 push @last_load, { $module => $version } => $imports;
126             }
127             else {
128 10         22 push @last_load, $module => $imports;
129             }
130             }
131             else {
132 110         218 push @first_load, $thing => $imports;
133             }
134             }
135              
136             # Second pass loads the modules
137 45         84 my @loads = ( @first_load, @last_load );
138 45         82 while ( my $load = shift @loads ) {
139 153         13431 my $module;
140             my $version;
141 153 100       294 if ( ref $load eq 'CODE' ) {
    100          
142 15         32 unshift @loads, $load->( @cb_args );
143 12         12926 next;
144             }
145             elsif ( ref $load eq 'HASH' ) {
146 4         8 ( $module, $version ) = %$load;
147             }
148             else {
149 134         113 $module = $load;
150             }
151              
152 138 100       220 my $imports = ref $loads[0] eq 'ARRAY' ? shift @loads : [];
153              
154 138 100       234 if ( exists $exclude->{ $module } ) {
155 2 100       4 if ( defined $exclude->{ $module } ) {
156 1         1 my @left;
157 1         2 for my $import ( @$imports ) {
158             push @left, $import
159 1 50       1 unless grep { $_ eq $import } @{ $exclude->{ $module } };
  1         4  
  1         2  
160             }
161 1         1 $imports = \@left;
162             }
163             else {
164 1         2 next;
165             }
166             }
167              
168 137         109 my $method = 'import::into';
169 137 100       253 if ( $module =~ /^-/ ) {
170 34         29 $method = 'unimport::out_of';
171 34         81 $module =~ s/^-//;
172             }
173              
174 137 100       642 if ($module->isa("Import::Base")) {
175 2         2 $module->export_to_level( 2, $module, @{ $imports } );
  2         114  
176              
177 2         62 next;
178             }
179              
180 135         247 use_module( $module );
181 135 100       5867 if ( defined $version ) {
182 4         9 $module->$method( { level => 2, version => $version }, @{ $imports } );
  4         17  
183             }
184             else {
185 131         115 $module->$method( 2, @{ $imports } );
  131         415  
186             }
187             }
188             }
189              
190             1;
191              
192             __END__
193              
194             =pod
195              
196             =head1 NAME
197              
198             Import::Base - Import a set of modules into the calling module
199              
200             =head1 VERSION
201              
202             version 1.002
203              
204             =head1 SYNOPSIS
205              
206             ### Static API
207             package My::Base;
208             use base 'Import::Base';
209              
210             # Modules that are always imported
211             our @IMPORT_MODULES = (
212             'strict',
213             'warnings',
214             # Import only these subs
215             'My::Exporter' => [ 'foo', 'bar', 'baz' ],
216             # Disable uninitialized warnings
217             '-warnings' => [qw( uninitialized )],
218             # Test for minimum version
219             { 'Getopt::Long' => 2.31 },
220             # Callback to generate modules to import
221             sub {
222             my ( $bundles, $args ) = @_;
223             return "My::MoreModule" => [qw( fuzz )];
224             },
225             );
226              
227             # Optional bundles
228             our %IMPORT_BUNDLES = (
229             with_signatures => [
230             'feature' => [qw( signatures )],
231             # Put this last to make sure nobody else can re-enable this warning
232             '>-warnings' => [qw( experimental::signatures )]
233             ],
234             Test => [qw( Test::More Test::Deep )],
235             Class => [
236             # Put this first so we can override what it enables later
237             '<Moo',
238             ],
239             );
240              
241             ### Consumer classes
242             # Use only the default set of modules
243             use My::Base;
244              
245             # Use one of the optional packages
246             use My::Base 'with_signatures';
247             use My::Base 'Test';
248             use My::Base 'Class';
249              
250             # Exclude some modules and symbols we don't want
251             use My::Base -exclude => [ 'warnings', 'My::Exporter' => [ 'bar' ] ];
252              
253             =head1 DESCRIPTION
254              
255             This module makes it easier to build and manage a base set of imports. Rather
256             than importing a dozen modules in each of your project's modules, you simply
257             import one module and get all the other modules you want. This reduces your
258             module boilerplate from 12 lines to 1.
259              
260             =head1 USAGE
261              
262             =head2 Base Module
263              
264             Creating a base module means extending Import::Base and creating an
265             C<@IMPORT_MODULES> package variable with a list of modules to import,
266             optionally with a arrayref of arguments to be passed to the module's import()
267             method.
268              
269             A common base module should probably include L<strict|strict>,
270             L<warnings|warnings>, and a L<feature|feature> set.
271              
272             package My::Base;
273             use base 'Import::Base';
274              
275             our @IMPORT_MODULES = (
276             'strict',
277             'warnings',
278             feature => [qw( :5.14 )],
279             );
280              
281             Now we can consume our base module by doing:
282              
283             package My::Module;
284             use My::Base;
285              
286             Which is equivalent to:
287              
288             package My::Module;
289             use strict;
290             use warnings;
291             use feature qw( :5.14 );
292              
293             Now when we want to change our feature set, we only need to edit one file!
294              
295             =head2 Import Bundles
296              
297             In addition to a set of modules, we can also create optional bundles with the
298             C<%IMPORT_BUNDLES> package variable.
299              
300             package My::Bundles;
301             use base 'My::Base';
302              
303             # Modules that will always be included
304             our @IMPORT_MODULES
305             experimental => [qw( signatures )],
306             );
307              
308             # Named bundles to include
309             our %IMPORT_BUNDLES = (
310             Class => [qw( Moose MooseX::Types )],
311             Role => [qw( Moose::Role MooseX::Types )],
312             Test => [qw( Test::More Test::Deep )],
313             );
314              
315             Now we can choose one or more bundles to include:
316              
317             # lib/MyClass.pm
318             use My::Base 'Class';
319              
320             # t/mytest.t
321             use My::Base 'Test';
322              
323             # t/lib/MyTest.pm
324             use My::Base 'Test', 'Class';
325              
326             Bundles must always come before options. Bundle names cannot start with "-".
327              
328             =head2 Extended Base Module
329              
330             We can further extend our base module to create more specialized modules for
331             classes and testing.
332              
333             package My::Class;
334             use base 'My::Base';
335             our @IMPORT_MODULES = (
336             'Moo::Lax',
337             'Types::Standard' => [qw( :all )],
338             );
339              
340             package My::Test;
341             use base 'My::Base';
342             our @IMPORT_MODULES = (
343             'Test::More',
344             'Test::Deep',
345             'Test::Exception',
346             'Test::Differences',
347             );
348              
349             Now all our classes just need to C<use My::Class> and all our test scripts just
350             need to C<use My::Test>.
351              
352             B<NOTE:> Be careful when extending base modules from other projects! If the
353             module you are extending changes, your modules may unexpectedly break. It is
354             best to keep your base modules on a per-project scale.
355              
356             =head2 Unimporting
357              
358             Sometimes instead of C<use Module> we need to do C<no Module>, to turn off
359             C<strict> or C<warnings> categories for example.
360              
361             By prefixing the module name with a C<->, Import::Base will act like C<no>
362             instead of C<use>.
363              
364             package My::Base;
365             use base 'Import::Base';
366             our @IMPORT_MODULES = (
367             'strict',
368             'warnings',
369             feature => [qw( :5.20 signatures )],
370             '-warnings' => [qw( experimental::signatures )],
371             );
372              
373             Now the warnings for using the 5.20 subroutine signatures feature will be
374             disabled.
375              
376             =head2 Version Check
377              
378             The standard Perl C<use> function allows for a version check at compile
379             time to ensure that a module is at least a minimum version.
380              
381             # Require Getopt::Long version 2.31 or higher
382             use Getopt::Long 2.31;
383              
384             Generally, you should be declaring your dependency with the correct version,
385             but some modules (like Getopt::Long) change their behavior based on what
386             version you ask for.
387              
388             To ask for a specific version, use a hashref with the key is the module and
389             the value as the required version.
390              
391             our @IMPORT_MODULES = (
392             # Require a minimum version
393             { 'Getopt::Long' => 2.31 },
394             # Version and imports
395             { 'File::Spec::Functions' => 3.47 } => [qw( catfile )],
396             );
397              
398             =head2 -exclude
399              
400             When importing a base module, you can use C<-exclude> to prevent certain
401             modules or symbols from being imported (if, for example, they would
402             conflict with existing symbols).
403              
404             # Prevent the "warnings" module from being imported
405             use My::Base -exclude => [ 'warnings' ];
406              
407             # Prevent the "bar" sub from My::Exporter from being imported
408             use My::Base -exclude => [ 'My::Exporter' => [ 'bar' ] ];
409              
410             NOTE: If you find yourself using C<-exclude> often, you would be better off
411             removing the module or sub and creating a bundle, or only including it in those
412             modules that need it.
413              
414             =head2 Control Ordering
415              
416             The order you import modules can be important!
417              
418             use warnings;
419             no warnings 'uninitialized';
420             # Uninitialized warnings are disabled
421              
422             no warnings 'uninitialized';
423             use warnings;
424             # Uninitialized warnings are enabled!
425              
426             Due to modules enforcing their own strict and warnings, like L<Moose> and
427             L<Moo>, you may not even know it's happening. This can make it hard to disable the
428             experimental warnings:
429              
430             use feature qw( postderef );
431             no warnings 'experimental::postderef';
432             use Moo;
433             # The postderef warnings are back on!
434              
435             To force a module to the front or the back of the list of imports, you can prefix
436             the module name with C<E<lt>> or C<E<gt>>.
437              
438             package My::Base;
439             use base 'Import::Base';
440             our @IMPORT_MODULES = (
441             feature => [qw( postderef )],
442             # Disable this warning last!
443             '>-warnings' => [qw( experimental::postderef )],
444             );
445              
446             our %IMPORT_BUNDLES = (
447             Class => [
448             # Import this module first!
449             '<Moo',
450             ],
451             );
452              
453             package main;
454             use My::Base 'Class';
455             my @foo = [ 1, 2, 3 ]->@*; # postderef!
456              
457             In this case, either putting Moo first or putting C<no warnings
458             'experimental::postderef'> last would solve the problem.
459              
460             B<NOTE:> C<E<lt>> and C<E<gt>> come before C<->.
461              
462             If you need even more control over the order, consider the L</"Dynamic API">.
463              
464             =head2 Subref Callbacks
465              
466             To get a little bit of dynamic support in the otherwise static module lists, you may
467             add sub references to generate module imports.
468              
469             package My::Base;
470             use base 'Import::Base';
471             our @IMPORT_MODULES = (
472             sub {
473             my ( $bundles, $args ) = @_;
474             return (
475             qw( strict warnings ),
476             feature => [qw( :5.20 )],
477             );
478             },
479             );
480              
481             # strict, warnings, and 5.20 features will be imported
482              
483             Plain strings are module names. Array references are arguments to import.
484              
485             B<NOTE:> Subrefs cannot return modules with C<E<lt>> or C<E<gt>> to control
486             ordering. Subrefs are run after the order has already been determined, while
487             the imports are being executed. Subrefs can assume that imports before them
488             have already been completed.
489              
490             =head2 Subref Arguments
491              
492             Sub references get an arrayref of bundles being requested, and a hashref of
493             extra arguments. Arguments from the calling side start with a '-'. Arguments
494             from Import::Base do not. Possible arguments are:
495              
496             package - The package we are exporting to
497             -exclude - The exclusions, see L</"-exclude">.
498              
499             Using C<package>, a subref could check or alter C<@ISA>, work with the object's
500             metaclass (if you're using one), or export additional symbols not set up for
501             export.
502              
503             Here's an example for applying a role (L<Moo::Role>, L<Role::Tiny>,
504             L<Moose::Role>, and anything that uses C<with>) when importing a bundle:
505              
506             package My::Base;
507             use base 'Import::Base';
508             our %IMPORT_BUNDLES = (
509             'Plugin' => [
510             'Moo',
511             # Plugins require the "My::Plugin" role
512             sub {
513             my ( $bundles, $args ) = @_;
514             $args->{package}->can( 'with' )->( 'My::Plugin' );
515             return;
516             },
517             ],
518             );
519              
520             package My::Custom::Plugin;
521             use My::Base 'Plugin';
522              
523             B<NOTE:> This sub is still being called during the compile phase. If you need your
524             role to be applied later, if you get errors when trying to apply it at compile time,
525             use L<the import_bundle method|/import_bundle>, below.
526              
527             =head2 Custom Arguments
528              
529             When using L</"Subref Callbacks">, you can add additional arguments to the
530             C<use> line. The arguments list starts after the first key that starts with a
531             '-'. To avoid conflicting with any future Import::Base feature, prefix all your
532             custom arguments with '--'.
533              
534             use My::Base -exclude => [qw( strict )], --custom => "arguments";
535             # Subrefs will get $args{--custom} set to "arguments"
536              
537             =head2 Dynamic API
538              
539             Instead of providing C<@IMPORT_MODULES> and C<%IMPORT_BUNDLES>, you can override the
540             C<modules()> method to do anything you want.
541              
542             package My::Bundles;
543             use base 'My::Base';
544              
545             sub modules {
546             my ( $class, $bundles, $args ) = @_;
547              
548             # Modules that will always be included
549             my @modules = (
550             experimental => [qw( signatures )],
551             );
552              
553             # Named bundles to include
554             my %bundles = (
555             Class => [qw( Moose MooseX::Types )],
556             Role => [qw( Moose::Role MooseX::Types )],
557             Test => [qw( Test::More Test::Deep )],
558             );
559              
560             # Go to our parent class first
561             return $class->SUPER::modules( $bundles, $args ),
562             # Then the always included modules
563             @modules,
564             # Then the bundles we asked for
565             map { @{ $bundles{ $_ } } } grep { exists $bundles{ $_ } } @$bundles;
566             }
567              
568             Using the above boilerplate will ensure that you start with all the basic functionality.
569              
570             One advantage the dynamic API has is the ability to remove modules from superclasses, or
571             completely control the order that modules are imported, even from superclasses.
572              
573             =head2 Exporting symbols from the base class
574              
575             Import::Base inherits from Exporter and allows for EXPORT_OK usage.
576              
577             package My::Base;
578             use base 'Import::Base';
579              
580             our @EXPORT_OK = qw($joy);
581              
582             our @IMPORT_MODULES = (
583             'strict',
584             'warnings',
585             feature => [qw( :5.10 )],
586             'My::Base' => [qw( $joy )],
587             );
588              
589             our $joy = "Is everywhere";
590              
591             package main;
592              
593             use My::Base;
594              
595             say $joy;
596              
597             Notice how the base class 'My::Base' is in it's own IMPORT_MODULES definition.
598              
599             =head1 METHODS
600              
601             =head2 modules( $bundles, $args )
602              
603             Prepare the list of modules to import. $bundles is an array ref of bundles, if any.
604             $args is a hash ref of generic arguments, if any.
605              
606             Returns a list of MODULE => [ import() args ]. MODULE may appear multiple times.
607              
608             =head2 import_bundle( @bundles, @args )
609              
610             Import a bundle at runtime. This method takes the exact same arguments as in
611             the C<use My::Base ...> compile-time API, but allows it to happen at runtime,
612             so that all of the current package's subs have been made available, and all
613             C<BEGIN> blocks have been executed.
614              
615             This is useful when using bundles to apply roles that have dependencies or
616             other esoteric use-cases. It is not necessary for most things.
617              
618             =head1 DOCUMENTATION BOILERPLATE
619              
620             Here is an example for documenting your own base modules
621              
622             =head1 SYNOPSIS
623              
624             package MyModule;
625             use My::Base;
626              
627             use My::Base 'Class';
628             use My::Base 'Role';
629             use My::Base 'Test';
630              
631             =head1 DESCRIPTION
632              
633             This is the base module that all {{PROJECT}} files should use.
634              
635             This module always imports the following into your namespace:
636              
637             =over
638              
639             =item L<strict>
640              
641             =item L<warnings>
642              
643             =item L<feature>
644              
645             Currently the 5.20 feature bundle
646              
647             =item L<experimental> 'signatures' 'postderef'
648              
649             We are using the 5.20 experimental signatures and postfix deref syntax.
650              
651             =back
652              
653             =head1 BUNDLES
654              
655             The following bundles are available. You may import one or more of these by name.
656              
657             =head2 Class
658              
659             The class bundle makes your package into a class and includes:
660              
661             =over 4
662              
663             =item L<Moo::Lax>
664              
665             =item L<Types::Standard> ':all'
666              
667             =back
668              
669             =head2 Role
670              
671             The role bundle makes your package into a role and includes:
672              
673             =over 4
674              
675             =item L<Moo::Role::Lax>
676              
677             =item L<Types::Standard> ':all'
678              
679             =back
680              
681             =head2 Test
682              
683             The test bundle includes:
684              
685             =over 4
686              
687             =item L<Test::More>
688              
689             =item L<Test::Deep>
690              
691             =item L<Test::Differences>
692              
693             =item L<Test::Exception>
694              
695             =back
696              
697             =head1 SEE ALSO
698              
699             =over
700              
701             =item L<Import::Base>
702              
703             =back
704              
705             =head1 BEST PRACTICES
706              
707             =head2 One Per Project
708              
709             Every project of at least medium size should have its own base module.
710             Consolidating a bunch of common base modules into a single distribution and
711             releasing to CPAN may sound like a good idea, but it opens you up to
712             difficult-to-diagnose problems.
713              
714             If many projects all depend on the same base, any change to the central base
715             module could potentially break one of the consuming modules. In a single,
716             well-tested project, it is easy to track down and address issues due to changes
717             in the base module. If the base module is released to CPAN, breakage may not
718             appear until someone tries to install a module that depends on your base.
719              
720             Version incompatibility, where project Foo depends on version 1 of the base,
721             while project Bar depends on version 2, will create very frustrating situations
722             for your users.
723              
724             Having to track down another project to figure out what modules are active in
725             the current package is a lot of work, creating frustration for contributing
726             authors.
727              
728             =head1 KNOWN ISSUES
729              
730             =over 4
731              
732             =item Moo::Role does not work if base module shares the same file as role package
733              
734             When trying to import L<Moo::Role> using Import::Base, the role will not
735             be applied if it shares the same file as the Import::Base module. For
736             safety and sanity, you should keep your Import::Base module separate
737             from classes and roles.
738              
739             =item Dancer plugins do not work when applied with Import::Base
740              
741             Dancer plugins check, at compile time, to see if they can be imported into
742             the consuming class by looking for the Dancer DSL. Because Import::Base uses
743             Module::Runtime to load the class, Dancer::Plugin thinks Module::Runtime is
744             the calling class, sees there is no DSL to register itself with, and bails.
745              
746             See L<https://github.com/PerlDancer/Dancer2/pull/1136> for more information.
747              
748             =back
749              
750             =head1 SEE ALSO
751              
752             =over
753              
754             =item L<Import::Into|Import::Into>
755              
756             The module that provides the functionality to create this module. If Import::Base
757             doesn't do what you want, look at Import::Into to build your own.
758              
759             =item L<Importer|Importer>
760              
761             This module wraps the C<import> method of other modules, allowing you to rename
762             the symbols you import. If you need to change a name, use this module together
763             with Import::Base.
764              
765             =item L<perl5|perl5>
766              
767             This module is very similar, and has a bunch of built-in bundles and features for
768             quickly importing Perl feature sets. It is also flexible, allowing you to specify
769             your own module bundles.
770              
771             =item L<ToolSet|ToolSet>
772              
773             ToolSet is very similar. Its API just uses package methods instead of package
774             variables. It also allows for exporting symbols directly from the bundle.
775              
776             =item L<sanity|sanity>
777              
778             Sanity is more consise, but not as flexible. If you don't need the wild
779             flexibility of Import::Base or the above solutions, take a look.
780              
781             =item L<Toolkit|Toolkit>
782              
783             This one requires configuration files in a home directory, so is not shippable.
784              
785             =item L<rig|rig>
786              
787             This one also requires configuration files in a home directory, so is not shippable.
788              
789             =back
790              
791             =head1 AUTHOR
792              
793             Doug Bell <preaction@cpan.org>
794              
795             =head1 CONTRIBUTOR
796              
797             =for stopwords Brian Medley
798              
799             Brian Medley <pub-github@bmedley.org>
800              
801             =head1 COPYRIGHT AND LICENSE
802              
803             This software is copyright (c) 2015 by Doug Bell.
804              
805             This is free software; you can redistribute it and/or modify it under
806             the same terms as the Perl 5 programming language system itself.
807              
808             =cut