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