File Coverage

blib/lib/rig.pm
Criterion Covered Total %
statement 29 29 100.0
branch 10 18 55.5
condition 3 9 33.3
subroutine 6 6 100.0
pod n/a
total 48 62 77.4


line stmt bran cond sub pod time code
1             package rig;
2             {
3             $rig::VERSION = '0.04';
4             }
5 6     6   152004 use strict;
  6         15  
  6         199  
6 6     6   35 use Carp;
  6         10  
  6         4827  
7              
8             our %opts = (
9             engine => 'rig::engine::base',
10             parser => 'rig::parser::yaml',
11             );
12              
13             sub import {
14 12     12   312 my $class = shift;
15 12         41 my @args = $class->_process_pragmas(@_);
16 12 50 66     115 return if !@args and !exists $opts{'load'};
17              
18             # engine setup
19 9         29 my $foo = $class->_setup_engine;
20              
21             # parser setup
22 9         52 $class->_setup_parser;
23              
24             # go to the engine's import method
25 9 50       46 return unless @args;
26 9         121 my $instance = $opts{engine}->new(%opts);
27 9         34 @_ = ( $instance, @args );
28 9         59 goto &$foo;
29             }
30              
31             sub _process_pragmas {
32 12     12   20 my $class = shift;
33 12         16 my @args;
34 12         57 while ( local $_ = shift ) {
35 12 100       53 if (/^-(.+)$/) {
36              
37             # process pragma
38 3         7 my $next = shift;
39 3 50 33     77 unshift( @_, $next ), $next = undef
40             if defined $next && $next =~ /^-/;
41 3 50       19 $opts{$1} = defined $next ? $next : 1;
42             }
43             else {
44 9         34 push @args, $_;
45             }
46             }
47 12         34 return @args;
48             }
49              
50             sub _setup_engine {
51 9 50 0 9   50 $opts{engine} = shift || 'rig::engine::' . $opts{engine}
52             unless $opts{engine} =~ /\:\:/;
53 9 50       573 eval "require $opts{engine};" or croak "rig: " . $@;
54 9         67 return $opts{engine} . '::import';
55             }
56              
57             sub _setup_parser {
58 9 50   9   57 $opts{parser} = 'rig::parser::' . $opts{parser}
59             unless $opts{parser} =~ /\:\:/;
60 9 50       557 eval "require $opts{parser};" or croak "rig: " . $@;
61             }
62              
63             1;
64              
65             =head1 NAME
66              
67             rig - import groups of favorite/related modules with a single expression
68              
69             =head1 VERSION
70              
71             version 0.04
72              
73             =head1 SYNOPSIS
74              
75             In your C yaml file:
76              
77             favorite:
78             use:
79             - strict
80             - warnings
81             - List::Util:
82             - first
83             - max
84             - Data::Dumper
85              
86             Back in your code:
87              
88             use rig favorite;
89              
90             # same as:
91             # use strict;
92             # use warnings;
93             # use List::Util qw/first max/;
94             # use Data::Dumper;
95              
96             # now have a ball:
97              
98             print first { $_ > 10 } @ary; # from List::Utils;
99             print Dumper $foo; # from Data::Dumper
100              
101             =head1 DESCRIPTION
102              
103             This module allows you to organize and bundle your favorite modules, thus reducing
104             the recurring task of Cing them in your programs, and implicitly requesting
105             imports by default.
106              
107             You can rig your bundles in 2 places:
108              
109             =over
110              
111             =item *
112              
113             A file called C<.perlrig> in your home or current working directory.
114              
115             =item *
116              
117             Packages undeneath the C>, for better portability.
118              
119             =back
120              
121             =head1 IMPLEMENTATION
122              
123             This module uses lots of internal Cs to trick modules to think they're being
124             loaded by the original caller, and not by C itself. It also hooks into C to keep
125             modules loading after a C.
126              
127             Modules that don't have an C method are instead Cled into the caller's package.
128              
129             This is somewhat hacky, there are probably better ways of achieving the same results.
130             We're open to suggestions on how to make loading modules more generic and effective.
131             Just fork me on Github!
132              
133             =head1 USAGE
134              
135             =head2 Code
136              
137             use rig -file => '/tmp/.rig'; # explicitly use a file
138             use rig -engine => 'base'; # chooses the current engine
139             use rig -path => qw(. /home/me /opt); # not implemented yet
140              
141             use rig moose, strictness, modernity;
142              
143             use rig 'kensho'; # loads a rig called kensho
144             use rig ':kensho'; # skips files, goes straight to rig::task::kensho
145             use rig 'kensho::strictive'; # skips files, uses rig::task::kensho::strictive
146             use rig 'signes';
147              
148             =head2 C<.perlrig> YAML structure
149              
150             :
151             use:
152             - [min_version]
153             - +
154             - :
155             -
156             -
157             - ...
158             also: [, ... ]
159              
160             =head3 use section
161              
162             =over
163              
164             =item *
165              
166             Lists modules to be Cd.
167              
168             =item *
169              
170             Checks module versions (optional).
171              
172             =item *
173              
174             Lists exports (optional).
175              
176             =back
177              
178             By default, modules in your rig are imported by calling C.
179              
180             Alternatively, a plus sign C<+> can be used in front of the module to force
181             it to be loaded using the C method, as such:
182              
183             eval "package ; use ;"
184              
185             This may be useful to workaround issues with using import when
186             none is available and C fails to detect a missing import method,
187             or things are just not working as expected.
188              
189             =head3 also section
190              
191             Used to bundle tasks into each other.
192              
193             =head3 Examples
194              
195             modernity:
196             use:
197             - strict
198             - warnings
199             - feature:
200             - say
201             - switch
202             moose:
203             use:
204             - Moose 1.0
205             - Moose::Autobox
206             - autodie
207             - Method::Signatures
208             - Try::Tiny
209             goo:
210             use:
211             - strict
212             - warnings
213             - Data::Dumper
214             - Data::Alias
215             - autodie
216             also: modernity
217             bam:
218             use:
219             - List::Util:
220             - first
221             - max
222             - min
223             - Scalar::Util:
224             - refaddr
225             - Carp:
226             - cluck
227             - croak
228              
229             =head1 The .perlrig file
230              
231             The .perlrig file is where you keep your favorite rigs.
232              
233             As mentioned earlier, C looks for a C<.perlrig> file in two
234             directories by default:
235              
236             * The current working directory.
237             * Your home directory.
238              
239             Important: only one rig file is loaded per C interpreter
240             instance. This will probably change in the future, as C<.perlrig>
241             file merging should be implemented.
242              
243             =head2 Structure
244              
245             It could have had room to put your funky startup code, but
246             it doesn't. This module is about order and parseability.
247              
248             Having a structured file written in plain yaml makes it easier for worldly parsers
249             to parse the file and understand your configuration.
250              
251             =head2 Global Configuration
252              
253             Use the C<$ENV{PERLRIG_FILE}> variable to tell C where to find your file.
254              
255             $ export PERLRIG_FILE=/etc/myrig
256             $ perl foo_that_rigs.pl
257            
258             =head1 rig::task:: modules
259              
260             A more distribution-friendly way of wiring up module bundles for your application is
261             to ship them as part of the C namespace.
262              
263             package rig::task::myfav;
264              
265             sub rig {
266             return {
267             use => [
268             'strict',
269             { 'warnings'=> [ 'FATAL','all' ] }
270             ],
271             also => 'somethingelse',
272             };
273             }
274              
275             This is the recommended way to ship a rig with your distribution. It
276             makes your distribution portable, no C<.perlrig> file is required.
277              
278             =head2 Out-of-the-box rig tasks
279              
280             This module comes with 2 internal rigs defined:
281              
282             =over
283              
284             =item *
285              
286             Modern L
287              
288             =item *
289              
290             Red L
291              
292             =back
293              
294             =head2 Writing your own parser
295              
296             Although this distribution only comes with a yaml parser for the .perlrig file.
297             you can still write your own parser if you like:
298              
299             package rig::parser::xml;
300             use base 'rig::parser::base';
301              
302             sub parse { return .... }
303              
304             # meanwhile in Gotham City:
305              
306             package main;
307             use rig -parser => 'xml';
308             use rig 'fav-in-xml';
309              
310             =head1 CAVEATS
311              
312             Although short, the api and yaml specs are still unstable and are
313             subject to change. Mild thought has been put into it as to support
314             modifications without major deprecations.
315              
316             =head2 Startup Cost
317              
318             There's an upfront load time (on the first C it finds) while C
319             looks for, parses and processes your C<.perlrig> file. Subsequent calls
320             won't look for any more files, as its structure will remain loaded in memory.
321              
322             =head2 Ordered Load
323              
324             As of right now, module loading order tends to get messed up easily. This
325             will probably be fixed, as the author's intention is to load modules
326             following the order set by the user in the C<.perlrig> and C
327             statements.
328              
329             =head1 ON NAMING THIS PACKAGE
330              
331             The authors feel that C is a short name that is good for one-liners.
332             It's lowercase because we feel it's a pragma-like module that augments
333             the functionality of C.
334             But C is a unique enough name as to avoid
335             clashing with future Perl pragmas.
336              
337             We're sorry if it hurts anyone's lowercase sensibility.
338              
339             =head1 TODO
340              
341             =over
342              
343             =item *
344              
345             Create a class to hold the perlrig definition.
346              
347             =item *
348              
349             Use L or similar for more agnostic and advanced file loading.
350              
351             =item *
352              
353             Straighten out and optimize internals.
354              
355             =item *
356              
357             Test many more modules for edge cases.
358              
359             =item *
360              
361             More verbs besides C and C, such as require, etc.
362              
363             =item *
364              
365             A cookbook of some sort, with everyday examples.
366              
367             =item *
368              
369             More tests.
370              
371             =item *
372              
373             Fix load sequence.
374              
375             =back
376              
377             =head1 SEE ALSO
378              
379             L - uses filters and C to accomplish its import magic.
380              
381             L - employs C and C.
382              
383             =cut