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