File Coverage

blib/lib/alienfile.pm
Criterion Covered Total %
statement 172 174 98.8
branch 26 28 92.8
condition 12 13 92.3
subroutine 35 36 97.2
pod 24 24 100.0
total 269 275 97.8


line stmt bran cond sub pod time code
1             package alienfile;
2              
3 47     47   1504 use strict;
  47         137  
  47         1405  
4 47     47   220 use warnings;
  47         133  
  47         1228  
5 47     47   888 use 5.008004;
  47         174  
6 47     47   19099 use Alien::Build;
  47         146  
  47         1384  
7 47     47   266 use Exporter ();
  47         88  
  47         628  
8 47     47   215 use Path::Tiny ();
  47         98  
  47         508  
9 47     47   201 use Carp ();
  47         120  
  47         84257  
10              
11 0     0   0 sub _path { Path::Tiny::path(@_) }
12              
13             # ABSTRACT: Specification for defining an external dependency for CPAN
14             our $VERSION = '2.47'; # VERSION
15              
16              
17             our @EXPORT = qw( requires on plugin probe configure share sys download fetch decode prefer extract patch patch_ffi build build_ffi gather gather_ffi meta_prop ffi log test start_url before after );
18              
19              
20             sub requires
21             {
22 32     32 1 102 my($module, $version) = @_;
23 32   100     108 $version ||= 0;
24 32         49 my $caller = caller;
25 32         72 my $meta = $caller->meta;
26 32         123 $meta->add_requires($meta->{phase}, $module, $version);
27 32         51 ();
28             }
29              
30              
31             sub plugin
32             {
33 101     101 1 1233 my($name, @args) = @_;
34              
35 101         226 my $caller = caller;
36 101         401 $caller->meta->apply_plugin($name, @args);
37 101         519 return;
38             }
39              
40              
41             sub probe
42             {
43 117     117 1 9514 my($instr) = @_;
44 117         280 my $caller = caller;
45 117 50       471 if(my $phase = $caller->meta->{phase})
46             {
47 117 100       524 Carp::croak "probe must not be in a $phase block" if $phase ne 'any';
48             }
49 116         300 $caller->meta->register_hook(probe => $instr);
50 116         597 return;
51             }
52              
53              
54             sub _phase
55             {
56 126     126   306 my($code, $phase) = @_;
57 126         240 my $caller = caller(1);
58 126         359 my $meta = $caller->meta;
59 126         333 local $meta->{phase} = $phase;
60 126         345 $code->();
61 116         830 return;
62             }
63              
64             sub configure (&)
65             {
66 10     10 1 85 _phase($_[0], 'configure');
67             }
68              
69              
70             sub sys (&)
71             {
72 22     22 1 160 _phase($_[0], 'system');
73             }
74              
75              
76              
77             sub share (&)
78             {
79 94     94 1 1057 _phase($_[0], 'share');
80             }
81              
82              
83             sub _in_phase
84             {
85 165     165   342 my($phase) = @_;
86 165         272 my $caller = caller(1);
87 165         842 my(undef, undef, undef, $sub) = caller(1);
88 165         428 my $meta = $caller->meta;
89 165         791 $sub =~ s/^.*:://;
90             Carp::croak "$sub must be in a $phase block"
91 165 100       597 unless $meta->{phase} eq $phase;
92             }
93              
94             sub start_url
95             {
96 13     13 1 39 my($url) = @_;
97 13         26 _in_phase 'share';
98 13         24 my $caller = caller;
99 13         28 my $meta = $caller->meta;
100 13         34 $meta->prop->{start_url} = $url;
101 13         42 $meta->add_requires('configure' => 'Alien::Build' => '1.19');
102 13         22 return;
103             }
104              
105              
106             sub download
107             {
108 41     41 1 280 my($instr) = @_;
109 41         239 _in_phase 'share';
110 40         73 my $caller = caller;
111 40         170 $caller->meta->register_hook(download => $instr);
112 40         74 return;
113             }
114              
115              
116             sub fetch
117             {
118 1     1 1 7 my($instr) = @_;
119 1         3 _in_phase 'share';
120 1         3 my $caller = caller;
121 1         3 $caller->meta->register_hook(fetch => $instr);
122 1         2 return;
123             }
124              
125              
126             sub decode
127             {
128 1     1 1 8 my($instr) = @_;
129 1         5 _in_phase 'share';
130 1         4 my $caller = caller;
131 1         7 $caller->meta->register_hook(decode => $instr);
132 1         3 return;
133             }
134              
135              
136             sub prefer
137             {
138 1     1 1 6 my($instr) = @_;
139 1         3 _in_phase 'share';
140 1         2 my $caller = caller;
141 1         2 $caller->meta->register_hook(prefer => $instr);
142 1         2 return;
143             }
144              
145              
146             sub extract
147             {
148 34     34 1 196 my($instr) = @_;
149 34         100 _in_phase 'share';
150 34         56 my $caller = caller;
151 34         104 $caller->meta->register_hook(extract => $instr);
152 34         55 return;
153             }
154              
155              
156             sub patch
157             {
158 3     3 1 17 my($instr) = @_;
159 3         8 _in_phase 'share';
160 3         5 my $caller = caller;
161 3         10 my $suffix = $caller->meta->{build_suffix};
162 3         18 $caller->meta->register_hook("patch$suffix" => $instr);
163 3         7 return;
164             }
165              
166              
167             sub patch_ffi
168             {
169 2     2 1 14 my($instr) = @_;
170 2         426 Carp::carp("patch_ffi is deprecated, use ffi { patch ... } } instead");
171 2         129 _in_phase 'share';
172 2         6 my $caller = caller;
173 2         8 $caller->meta->register_hook(patch_ffi => $instr);
174 2         5 return;
175             }
176              
177              
178             sub build
179             {
180 51     51 1 281 my($instr) = @_;
181 51         129 _in_phase 'share';
182 51         84 my $caller = caller;
183 51         130 my $suffix = $caller->meta->{build_suffix};
184 51         131 $caller->meta->register_hook("build$suffix" => $instr);
185 51         105 return;
186             }
187              
188              
189             sub build_ffi
190             {
191 2     2 1 14 my($instr) = @_;
192 2         158 Carp::carp("build_ffi is deprecated, use ffi { build ... } } instead");
193 2         96 _in_phase 'share';
194 2         3 my $caller = caller;
195 2         8 $caller->meta->register_hook(build_ffi => $instr);
196 2         4 return;
197             }
198              
199              
200             sub gather
201             {
202 22     22 1 187 my($instr) = @_;
203 22         41 my $caller = caller;
204 22         59 my $meta = $caller->meta;
205 22         39 my $phase = $meta->{phase};
206 22 100       121 Carp::croak "gather is not allowed in configure block"
207             if $phase eq 'configure';
208 21         43 my $suffix = $caller->meta->{build_suffix};
209 21 100       61 if($suffix eq '_ffi')
210             {
211 4         15 $meta->register_hook(gather_ffi => $instr)
212             }
213             else
214             {
215 17 100       130 $meta->register_hook(gather_system => $instr) if $phase =~ /^(any|system)$/;
216 17 100       112 $meta->register_hook(gather_share => $instr) if $phase =~ /^(any|share)$/;
217             }
218 21         78 return;
219             }
220              
221              
222             sub gather_ffi
223             {
224 2     2 1 13 my($instr) = @_;
225 2         148 Carp::carp("gather_ffi is deprecated, use ffi { gather ... } } instead");
226 2         95 _in_phase 'share';
227 2         4 my $caller = caller;
228 2         8 $caller->meta->register_hook(gather_ffi => $instr);
229 2         2 return;
230             }
231              
232              
233             sub ffi (&)
234             {
235 14     14 1 85 my($code) = @_;
236 14         36 _in_phase 'share';
237 14         38 my $caller = caller;
238 14         43 local $caller->meta->{build_suffix} = '_ffi';
239 14         39 $code->();
240 14         40 return;
241             }
242              
243              
244             sub meta_prop
245             {
246 10     10 1 373 my $caller = caller;
247 10         143 my $meta = $caller->meta;
248 10         41 $meta->prop;
249             }
250              
251              
252             sub log
253             {
254 10     10 1 365 unshift @_, 'Alien::Build';
255 10         53 goto &Alien::Build::log;
256             }
257              
258              
259             sub test
260             {
261 23     23 1 112 my($instr) = @_;
262 23         32 my $caller = caller;
263 23         69 my $meta = $caller->meta;
264 23         39 my $phase = $meta->{phase};
265 23 100 100     349 Carp::croak "test is not allowed in $phase block"
266             if $phase eq 'any' || $phase eq 'configure';
267              
268 21         60 $meta->add_requires('configure' => 'Alien::Build' => '1.14');
269              
270 21 100       53 if($phase eq 'share')
    50          
271             {
272 14   100     29 my $suffix = $caller->meta->{build_suffix} || '_share';
273 14         41 $meta->register_hook(
274             "test$suffix" => $instr,
275             );
276             }
277             elsif($phase eq 'system')
278             {
279 7         18 $meta->register_hook(
280             "test_system" => $instr,
281             );
282             }
283             else
284             {
285 0         0 die "unknown phase: $phase";
286             }
287             }
288              
289              
290             my %modifiers = (
291             probe => { any => 'probe' },
292             download => { share => 'download' },
293             fetch => { share => 'fetch' },
294             decode => { share => 'fetch' },
295             prefer => { share => 'prefer' },
296             extract => { share => 'extract' },
297             patch => { share => 'patch$' },
298             build => { share => 'build$' },
299             test => { share => 'test$' },
300             # Note: below special case gather_ffi for the ffi block :P
301             gather => { share => 'gather_share', system => 'gather_system', any => 'gather_share,gather_system' },
302             );
303              
304             sub _add_modifier
305             {
306 20     20   48 my($type, $stage, $sub) = @_;
307              
308 20         39 my $method = "${type}_hook";
309              
310 20 100       216 Carp::croak "No such stage $stage" unless defined $modifiers{$stage};
311 18 100 66     256 Carp::croak "$type $stage argument must be a code reference" unless defined $sub && ref($sub) eq 'CODE';
312              
313 16         27 my $caller = caller;
314 16         36 my $meta = $caller->meta;
315 16 100       435 Carp::croak "$type $stage is not allowed in sys block" unless defined $modifiers{$stage}->{$meta->{phase}};
316              
317 14         39 $meta->add_requires('configure' => 'Alien::Build' => '1.40');
318              
319 14         25 my $suffix = $meta->{build_suffix};
320 14 100 100     62 if($suffix eq '_ffi' && $stage eq 'gather')
321             {
322 2         9 $meta->$method('gather_ffi' => $sub);
323             }
324              
325 14         35 foreach my $hook (
326 14         48 map { split /,/, $_ } # split on , for when multiple hooks must be attachewd (gather in any)
327 14         23 map { my $x = $_ ; $x =~ s/\$/$suffix/; $x } # substitute $ at the end for a suffix (_ffi) if any
  14         29  
  14         35  
328             $modifiers{$stage}->{$meta->{phase}}) # get the list of modifiers
329             {
330 16         66 $meta->$method($hook => $sub);
331             }
332              
333 14         37 return;
334             }
335              
336             sub before
337             {
338 10     10 1 61 my($stage, $sub) = @_;
339 10         31 @_ = ('before', @_);
340 10         36 goto &alienfile::_add_modifier;
341             }
342              
343              
344             sub after
345             {
346 10     10 1 59 my($stage, $sub) = @_;
347 10         24 @_ = ('after', @_);
348 10         34 goto &alienfile::_add_modifier;
349             }
350              
351             sub import
352             {
353 277     277   5080 strict->import;
354 277         3379 warnings->import;
355 277         43097 goto &Exporter::import;
356             }
357              
358             1;
359              
360             __END__