File Coverage

bin/af
Criterion Covered Total %
statement 210 252 83.3
branch 45 64 70.3
condition 6 11 54.5
subroutine 39 41 95.1
pod 0 5 0.0
total 300 373 80.4


line stmt bran cond sub pod time code
1             #!perl
2              
3 6     6   2998 use strict;
  6         10  
  6         186  
4 6     6   29 use warnings;
  6         10  
  6         145  
5 6     6   104 use 5.014;
  6         18  
6             #use lib::findbin '../lib'; # dev-only
7 6     6   32 use App::af;
  6         19  
  6         135  
8 6     6   970 use File::chdir;
  6         6215  
  6         835  
9              
10             # PODNAME: af
11             # ABSTRACT: Command line tool for alienfile
12             # VERSION
13              
14              
15             package App::af::download 0.17 {
16 6     6   49 use Moose;
  6         12  
  6         57  
17 6     6   46593 use namespace::autoclean;
  6         14  
  6         57  
18 6     6   523 use MooseX::Types::Path::Tiny qw( AbsPath );
  6         12  
  6         109  
19 6     6   17763 use Path::Tiny qw( path );
  6         14  
  6         3041  
20              
21             with 'App::af';
22             with 'App::af::role::alienfile';
23              
24              
25             has local => (
26             is => 'ro',
27             isa => AbsPath,
28             traits => ['App::af::opt'],
29             short => 'l',
30             coerce => 1,
31             opt_type => 's',
32             default => '.',
33             );
34              
35             sub main
36             {
37 4     4 0 10 my($self) = @_;
38            
39 4 50       67 unless(-d $self->local)
40             {
41 0         0 say STDERR "no such directory: @{[ $self->local ]}";
  0         0  
42 0         0 return 2;
43             }
44              
45 4         126 local $ENV{ALIEN_INSTALL_TYPE} = 'share';
46 4         21 my $build = $self->build;
47 4         121 $build->load_requires('configure');
48 4         134 $build->load_requires('share');
49 4         108 eval { $build->download };
  4         20  
50 4 100       9132 warn $@ if $@;
51              
52 4 100 66     228 unless(defined $build->install_prop->{download} &&
53             length $build->install_prop->{download})
54             {
55 1         19 say STDERR "Recipe did not seem to download a file or directory";
56 1         36 return 2;
57             }
58            
59 3         41 my $download = path($build->install_prop->{download});
60            
61 3 100       89 if(-f $download)
    50          
62             {
63 2         99 my $to = $self->local->child($download->basename);
64 2 50       154 $download->copy($to) || die "unable to copy $download => $to $!";
65 2         3909 say "Wrote archive to $to";
66             }
67             elsif(-d $download)
68             {
69 1         682 require File::Copy::Recursive;
70 1         4331 my $to = $self->local->child($download->basename);
71 1 50       74 File::Copy::Recursive::dircopy("$download", "$to") || die "unable to copy $download => $to $!";
72 1         1802 say "Wrote directory to $to";
73             }
74             else
75             {
76 0         0 say STDERR "Recipe did not seem to download a file or directory";
77 0         0 return 2;
78             }
79            
80 3         128 0;
81             }
82              
83             __PACKAGE__->meta->make_immutable;
84             }
85              
86             package App::af::probe 0.17 {
87 6     6   10434 use Moose;
  6         13  
  6         30  
88 6     6   39583 use namespace::autoclean;
  6         14  
  6         35  
89 6     6   518 use MooseX::Types::Path::Tiny qw( AbsPath );
  6         13  
  6         36  
90 6     6   16258 use File::Temp qw( tempdir );
  6         13  
  6         2009  
91            
92             with 'App::af';
93             with 'App::af::role::alienfile';
94             with 'App::af::role::libandblib';
95              
96              
97             has root => (
98             is => 'ro',
99             isa => AbsPath,
100             traits => ['App::af::opt'],
101             opt_type => 's',
102             coerce => 1,
103             lazy => 1,
104             default => sub {
105             shift->_tmp->child('root');
106             },
107             );
108            
109             has _tmp => (
110             is => 'ro',
111             isa => AbsPath,
112             lazy => 1,
113             default => sub {
114             my $dir = Path::Tiny->new(tempdir( CLEANUP => 1));
115             $dir->child($_)->mkpath for qw( root stage prefix );
116             $dir;
117             },
118             );
119            
120             sub main
121             {
122             my($self) = @_;
123            
124             my $build = $self->build( root => $self->root->stringify );
125              
126             $build->set_stage($self->_tmp->child('stage')->stringify);
127             $build->set_prefix($self->_tmp->child('prefix')->stringify);
128             $build->load_requires('configure');
129             my $type = $build->install_type;
130            
131             say "install type: $type";
132              
133             0;
134             }
135             }
136              
137             package App::af::install 0.17 {
138 6     6   9628 use Moose;
  6         13  
  6         27  
139 6     6   39882 use namespace::autoclean;
  6         11  
  6         36  
140 6     6   437 use File::Temp qw( tempdir );
  6         13  
  6         336  
141 6     6   39 use MooseX::Types::Path::Tiny qw( AbsPath );
  6         10  
  6         50  
142 6     6   18951 use YAML qw( Dump );
  6         28967  
  6         391  
143 6     6   47 use Path::Tiny qw( path );
  6         12  
  6         3029  
144            
145             with 'App::af';
146             with 'App::af::role::alienfile';
147             with 'App::af::role::libandblib';
148            
149            
150             has stage => (
151             is => 'ro',
152             isa => AbsPath,
153             traits => ['App::af::opt'],
154             coerce => 1,
155             lazy => 1,
156             opt_type => 's',
157             default => sub {
158             tempdir( CLEANUP => 1);
159             },
160             );
161            
162             has prefix => (
163             is => 'rw',
164             isa => AbsPath,
165             traits => ['App::af::opt'],
166             opt_type => 's',
167             coerce => 1,
168             );
169            
170             has type => (
171             is => 'ro',
172             isa => 'Str',
173             traits => ['App::af::opt'],
174             opt_type => 's',
175             );
176            
177             has dry_run => (
178             is => 'ro',
179             isa => 'Int',
180             traits => ['App::af::opt'],
181             );
182            
183             has root => (
184             is => 'ro',
185             isa => AbsPath,
186             traits => ['App::af::opt'],
187             opt_type => 's',
188             coerce => 1,
189             lazy => 1,
190             default => sub {
191             tempdir( CLEANUP => 1);
192             },
193             );
194            
195             has before => (
196             is => 'ro',
197             isa => 'ArrayRef[Str]',
198             traits => ['App::af::opt'],
199             opt_type => 's{2}',
200             );
201              
202             has after => (
203             is => 'ro',
204             isa => 'ArrayRef[Str]',
205             traits => ['App::af::opt'],
206             opt_type => 's{2}',
207             );
208            
209             sub main
210             {
211             my($self) = @_;
212            
213             local $ENV{ALIEN_INSTALL_TYPE} = $ENV{ALIEN_INSTALL_TYPE};
214            
215             if(defined $self->type)
216             {
217             unless($self->type =~ /^(share|system)$/)
218             {
219             say STDERR "unknown install type: @{[ $self->type ]}";
220             return 2;
221             }
222             $ENV{ALIEN_INSTALL_TYPE} = $self->type;
223             }
224            
225             if(-d $self->stage && $self->stage->children)
226             {
227             say "stage directory is not empty";
228             exit 2;
229             }
230            
231             my($build, $prefix) = $self->build( root => $self->root->stringify );
232             $self->prefix($prefix) if defined($prefix) && ! $self->prefix;
233            
234             my @all_hooks = qw(
235             probe download fetch decode prefer extract patch
236             build stage gather_share gather_system
237             );
238            
239             my $repl = sub {
240 6     6   48 no warnings 'once';
  6         14  
  6         5683  
241             require Shell::Perl;
242             my $pirl = Shell::Perl->new(on_quit => 'return');
243             $pirl->set_package("App::af::pirl");
244             $App::af::pirl::build = $build;
245             $App::af::pirl::meta = $build->meta;
246             eval { $pirl->run };
247             warn $@ if $@;
248             };
249            
250             while(@{ $self->before })
251             {
252             my $hook = shift @{ $self->before };
253             my $command = shift @{ $self->before };
254            
255             my @hook = $hook =~ /^(\%|\*)$/
256             ? @all_hooks
257             : ($hook);
258            
259             $build->meta->before_hook(
260             $_ => sub {
261             my($build) = @_;
262             $build->log(" [ before @{[ $build->hook_prop->{name} ]} ] + $command");
263             $build->checkpoint;
264             $command eq ':repl'
265             ? $repl->()
266             : $build->system($command);
267             }
268             ) for @hook;
269             }
270            
271             while(@{ $self->after })
272             {
273             my $hook = shift @{ $self->after };
274             my $command = shift @{ $self->after };
275              
276             my @hook = $hook =~ /^(\%|\*)$/
277             ? @all_hooks
278             : ($hook);
279            
280             $build->meta->around_hook(
281             $_ => sub {
282             my $orig = shift;
283             my $ret = eval { $orig->(@_) };
284             my $error = $@;
285             $build->log(" [ after @{[ $build->hook_prop->{name} ]} ] + $command");
286             $build->checkpoint;
287             $command eq ':repl'
288             ? $repl->()
289             : $build->system($command);
290             die $error if $error;
291             $ret;
292             },
293             ) for @hook
294             }
295            
296            
297             if($self->dry_run && ! defined $self->prefix)
298             {
299             $self->prefix(tempdir( CLEANUP => 1 ));
300             }
301            
302             unless(defined $self->prefix)
303             {
304             say STDERR "You must specify a prefix with --prefix or use --dry-run";
305             return 2;
306             }
307            
308             if(-d $self->prefix->child('_alien'))
309             {
310             my $test = $self->prefix->child('_alien/test');
311             eval { $test->touch };
312             if($@)
313             {
314             say STDERR "prefix is not writable. You may need to use su or sudo";
315             return 2;
316             }
317             $test->remove;
318             }
319            
320             $build->set_stage($self->stage->stringify);
321             $build->set_prefix($self->prefix->stringify);
322             $build->load_requires('configure');
323             $build->load_requires($build->install_type);
324             $build->download;
325             $build->build;
326            
327             unless($self->dry_run)
328             {
329             require File::Copy::Recursive;
330            
331             if(-d $self->prefix)
332             {
333             # this is slightly dangerous.
334             foreach my $child ($self->prefix->children)
335             {
336             say "rm -rf $child";
337             $_->remove_tree({ safe => 0 }) for $self->prefix->children;
338             }
339             }
340            
341             File::Copy::Recursive::dircopy($self->stage, $self->prefix) || die "unable to copy @{[ $self->stage ]} => @{[ $self->prefix ]} $!";
342             say "copied staged install into @{[ $self->prefix ]}";
343             };
344            
345             print Dump($build->runtime_prop);
346            
347             0;
348             }
349             __PACKAGE__->meta->make_immutable;
350             }
351              
352             package App::af::requires 0.17 {
353 6     6   10947 use Moose;
  6         11  
  6         112  
354 6     6   40962 use namespace::autoclean;
  6         13  
  6         43  
355 6     6   553 use YAML qw( Dump );
  6         12  
  6         1544  
356              
357              
358             with 'App::af';
359             with 'App::af::role::alienfile';
360             with 'App::af::role::phase';
361            
362             sub main
363             {
364 5     5 0 12 my($self) = @_;
365            
366 5         26 $self->check_phase;
367            
368 5         17 my $build = $self->build;
369            
370 5 100       181 if($self->phase eq 'all')
371             {
372             print Dump({
373 1         3 map { $_ => $build->requires($_) } qw( configure any share system )
  4         80  
374             });
375             }
376             else
377             {
378 4         99 print Dump($build->requires($self->phase));
379             }
380            
381 5         20577 0;
382             }
383            
384             __PACKAGE__->meta->make_immutable;
385             }
386              
387             package App::af::missing 0.17 {
388 6     6   8330 use Moose;
  6         23  
  6         279  
389 6     6   39664 use namespace::autoclean;
  6         13  
  6         34  
390 6     6   460 use Capture::Tiny qw( capture );
  6         12  
  6         5484  
391            
392             with 'App::af';
393             with 'App::af::role::alienfile';
394             with 'App::af::role::phase';
395            
396            
397             has plugin => (
398             is => 'ro',
399             isa => 'Int',
400             traits => ['App::af::opt'],
401             );
402            
403             has precompile => (
404             is => 'ro',
405             isa => 'Int',
406             traits => ['App::af::opt'],
407             );
408              
409             sub main
410             {
411 5     5 0 16 my($self) = @_;
412            
413 5         29 $self->check_phase;
414              
415 5 50       89 if($self->plugin)
416             {
417 0         0 require Alien::Build;
418 0         0 require Test2::Mock;
419            
420 0         0 my %need;
421            
422 0         0 my $mock = Test2::Mock->new(class => 'Alien::Build::Meta');
423             $mock->around('apply_plugin' => sub {
424 0     0   0 my($orig, $self, @args) = @_;
425 0         0 local @INC = @INC;
426             push @INC, sub {
427 0         0 my(undef, $filename) = @_;
428 0         0 my $mod = $filename;
429 0         0 $mod =~ s{/}{::}g;
430 0         0 $mod =~ s{\.pm$}{};
431 0         0 $need{$mod}++;
432 0         0 };
433 0         0 eval { $orig->($self, @args) };
  0         0  
434 0         0 });
435 0     0   0 my(undef, undef, $build) = capture { $self->build };
  0         0  
436 0         0 print "$_\n" for sort keys %need;
437 0         0 return 0;
438             }
439            
440 5 50       178 if($self->precompile)
441             {
442 0         0 my %need;
443            
444 0         0 foreach my $line ($self->file->lines)
445             {
446 0         0 chomp $line;
447 0 0       0 if($line =~ /^\s*use\s+([A-Za-z_0-9]+(::[A-Za-z_0-9]+)*)/)
448             {
449 0         0 my $mod = $1;
450 0         0 eval qq{ use $mod () };
451 0 0       0 if($@) { $need{$mod}++ };
  0         0  
452             }
453             }
454 0         0 print "$_\n" for sort keys %need;
455 0         0 exit 0;
456             }
457            
458 5     5   134 my(undef,undef, $build) = capture { $self->build };
  5         7134  
459            
460 5         5163 my @reqs;
461             my %need;
462            
463 5 100       259 if($self->phase eq 'all')
464             {
465 1         10 $build->load_requires('configure');
466 1     1   63 capture { $build->probe };
  1         1306  
467 1         3102 @reqs = map { $build->requires($_) } qw( configure any share system );
  4         83  
468 1         34 @reqs = (
469             $build->requires('configure'),
470             $build->requires($build->install_type),
471             );
472             }
473             else
474             {
475 4         99 @reqs = ( $build->requires($self->phase) );
476             }
477            
478 5         203 foreach my $reqs (@reqs)
479             {
480 6         42 foreach my $module (sort keys %$reqs)
481             {
482 7         18 my $version = $reqs->{$module};
483 7         10 eval {
484 7         18 my $pm = $module . '.pm';
485 7         27 $pm =~ s/::/\//g;
486 7         1436 require $pm;
487 0 0       0 !$version || $module->VERSION($version);
488             };
489 7 50       53 $need{$module} = 1 if $@
490             }
491             }
492            
493 5         242 say $_ for sort keys %need;
494            
495 5         109 0;
496             }
497            
498             __PACKAGE__->meta->make_immutable;
499             }
500              
501             package App::af::prop 0.17 {
502 6     6   8580 use Moose;
  6         200  
  6         45  
503 6     6   40042 use namespace::autoclean;
  6         11  
  6         33  
504              
505            
506             with 'App::af';
507              
508             has class => (
509             is => 'ro',
510             isa => 'Str',
511             traits => ['App::af::opt'],
512             short => 'c',
513             opt_type => 's',
514             );
515            
516             has $_ => (
517             is => 'ro',
518             isa => 'Int',
519             traits => ['App::af::opt'],
520             ) for qw( static cflags libs modversion bin_dir );
521              
522             sub main {
523 8     8 0 18 my($self) = @_;
524            
525 8 50       144 unless($self->class)
526             {
527 0         0 say STDERR "You must specify a class.\n";
528 0         0 return 2;
529             }
530            
531 8 50       104 my $class = $self->class =~ /::/ ? $self->class : 'Alien::' . $self->class;
532              
533             {
534 8         11 my $pm = $class . '.pm';
  8         16  
535 8         27 $pm =~ s/::/\//g;
536 8         482 require $pm;
537             }
538 8 50       69 unless($class->can('runtime_prop'))
539             {
540 0         0 say STDERR "$class was not installed with Alien::Build";
541 0         0 return 2;
542             }
543            
544 8         28 my $prop = $class->runtime_prop;
545            
546 8 50       19644 unless($prop)
547             {
548 0         0 say STDERR "$class was not installed with Alien::Build";
549 0         0 return 2;
550             }
551            
552 8         15 my $found = 0;
553            
554 8 100       134 if($self->cflags)
555             {
556 2 100       30 if($self->static)
557             {
558 1         9 say $class->cflags_static;
559             }
560             else
561             {
562 1         11 say $class->cflags;
563             }
564 2         477 $found = 1;
565             }
566            
567 8 100       147 if($self->libs)
568             {
569 2 100       28 if($self->static)
570             {
571 1         9 say $class->libs_static;
572             }
573             else
574             {
575 1         9 say $class->libs;
576             }
577 2         337 $found = 1;
578             }
579            
580 8 100       136 if($self->bin_dir)
581             {
582 1         11 say $_ for $class->bin_dir;
583 1         441 $found = 1;
584             }
585            
586 8 100       129 if($self->modversion)
587             {
588 1   50     11 say $class->version // 'undef';
589 1         56 $found = 1;
590             }
591            
592 8 100       21 unless($found)
593             {
594 2         12 require YAML;
595 2         12 print YAML::Dump($prop);
596             }
597            
598 8         21838 0;
599             }
600             __PACKAGE__->meta->make_immutable;
601             }
602              
603             package App::af::list 0.17 {
604 6     6   11260 use Moose;
  6         17  
  6         26  
605 6     6   38482 use namespace::autoclean;
  6         11  
  6         39  
606 6     6   443 use Path::Tiny qw( path );
  6         10  
  6         433  
607 6     6   5212 use Text::Table;
  6         108800  
  6         1974  
608            
609            
610             with 'App::af';
611              
612             has long => (
613             is => 'ro',
614             isa => 'Int',
615             traits => ['App::af::opt'],
616             short => 'l',
617             );
618            
619             sub main
620             {
621 2     2 0 5 my($self) = @_;
622            
623 2         2 my $table;
624 2 100       42 $table = Text::Table->new('name', 'install type', 'alien version', 'package version')
625             if $self->long;
626            
627 2         1363 foreach my $inc (map { path($_)->absolute } @INC)
  22         1287  
628             {
629 22         806 my $dist_root = $inc->child('auto/share/dist');
630 22 100       798 next unless -d $dist_root;
631            
632 2         75 foreach my $dist_dir ($dist_root->children)
633             {
634 2 50       322 next unless -f $dist_dir->child('_alien/alien.json');
635 2         126 my $dist = $dist_dir->basename;
636 2         56 my $class = $dist;
637 2         10 $class =~ s/-/::/g;
638            
639 2 100       9 unless($table)
640             {
641 1         72 say $class;
642 1         8 next;
643             }
644            
645 1         7 eval {
646 1         3 my $pm = $class . '.pm';
647 1         4 $pm =~ s/::/\//g;
648 1         520 require $pm;
649             };
650 1 50       5 if($@)
651             {
652 0         0 $table->add($class, '---', '---');
653             }
654             else
655             {
656 1   50     2 my $install_type = eval { $class->install_type } // '---';
  1         11  
657 1   50     19310 my $perl_version = eval { $class->VERSION } // '---';
  1         25  
658 1   50     2 my $pkg_version = eval { $class->version } // '---';
  1         10  
659 1         29 $table->add($class, $install_type, $perl_version, $pkg_version);
660             }
661             }
662              
663             }
664            
665 2 100       67 print $table if defined $table;
666 2         5580 0;
667             }
668            
669             __PACKAGE__->meta->make_immutable;
670             }
671              
672             # for testing, allow us to do this file
673             # without running.
674             unless(caller)
675             {
676             my $class = App::af->compute_class;
677             unless(eval { $class->does('App::af') })
678             {
679             say STDERR "unknown subcommand";
680             exit 2;
681             }
682             my $app = $class->new(@ARGV);
683             exit($app->main // 0);
684             }
685              
686             __END__
687              
688             =pod
689              
690             =encoding UTF-8
691              
692             =head1 NAME
693              
694             af - Command line tool for alienfile
695              
696             =head1 VERSION
697              
698             version 0.17
699              
700             =head1 SYNOPSIS
701              
702             af download --help
703             af probe --help
704             af install --help
705             af requires --help
706             af missing --help
707             af prop --help
708             af list --help
709              
710             =head1 DESCRIPTION
711              
712             The C<af> command is a command line interface to L<alienfile> and
713             L<Alien::Build>.
714              
715             =head3 options
716              
717             These options are available for all subcommands.
718              
719             =head4 --help
720              
721             Print the help for either C<af> as a whole, or the specific subcommand.
722              
723             =head4 --version
724              
725             Print the version of C<af> and exit.
726              
727             =head1 SUBCOMMANDS
728              
729             =head2 download
730              
731             =head3 Usage
732              
733             af download
734             [ ( -f | --file ) alienfile | ( -c | --class ) class ]
735             [ ( -l | --local ) directory ]
736              
737             =head3 description
738              
739             Download the external resource using the usual L<alienfile> logic. File
740             will be deposited in the directory indicated by the C<--local> (or C<-l>)
741             option, or the current working directory if not specified.
742              
743             =head3 options
744              
745             =head4 -f | --file
746              
747             The L<alienfile>. If neither this option, nor C<-c> is specified, then
748             C<alienfile> in the current directory will be assumed.
749              
750             =head4 -c | --class
751              
752             Get the L<alienfile> from the already installed Alien module. You may
753             omit the C<Alien::> prefix, so for example L<Alien::curl> may be specified
754             as simply C<curl>.
755              
756             =head4 -l | --local
757              
758             The location to store the downloaded resource. The current directory
759             if not specified.
760              
761             =head2 probe
762              
763             =head3 Usage
764              
765             af probe
766             [ ( -f | --file ) alienfile | ( -c | --class ) class ]
767             [ --root directory ]
768             [ --before hook command ] [ --after hook command ]
769             [ -I lib ] [ --blib ]
770              
771             =head3 description
772              
773             Probe system for existing library or tool using the given L<alienfile>.
774              
775             =head4 -f | --file
776              
777             The L<alienfile>. If neither this option, nor C<-c> is specified, then
778             C<alienfile> in the current directory will be assumed.
779              
780             =head4 -c | --class
781              
782             Get the L<alienfile> from the already installed Alien module. You may
783             omit the C<Alien::> prefix, so for example L<Alien::curl> may be specified
784             as simply C<curl>. If you do not specify the C<--prefix> option, the
785             package will replace the already installed one.
786              
787             =head4 --root
788              
789             Build in root
790              
791             =head4 -I
792              
793             Add directory to the Perl search lib (like -I on L<perl>).
794              
795             =head4 --blib
796              
797             Use the blib from the current directory.
798              
799             =head2 install
800              
801             =head3 Usage
802              
803             af install
804             [ ( -f | --file ) alienfile | ( -c | --class ) class ]
805             [ --prefix directory | --dry-run ] [ --stage directory ]
806             [ --type ( share | system ) ] [ --root directory ]
807             [ --before hook command ] [ --after hook command ]
808             [ -I lib ] [ --blib ]
809              
810             =head3 description
811              
812             Install or reinstall using the given L<alienfile> or already installed
813             L<Alien>.
814              
815             =head3 options
816              
817             =head4 -f | --file
818              
819             The L<alienfile>. If neither this option, nor C<-c> is specified, then
820             C<alienfile> in the current directory will be assumed.
821              
822             =head4 -c | --class
823              
824             Get the L<alienfile> from the already installed Alien module. You may
825             omit the C<Alien::> prefix, so for example L<Alien::curl> may be specified
826             as simply C<curl>. If you do not specify the C<--prefix> option, the
827             package will replace the already installed one.
828              
829             =head4 --stage
830              
831             The stage directory. By default this is a temporary directory that will
832             automatically be removed.
833              
834             =head4 --prefix
835              
836             The final install location to use. Required when using the C<-f> option,
837             but optional when using the C<-c> option.
838              
839             =head4 --type
840              
841             Override the install type. May be either C<share> or C<system>.
842              
843             =head4 --dry-run
844              
845             Do not install into the final location.
846              
847             =head4 --root
848              
849             Build in root
850              
851             =head4 --before
852              
853             Execute the given command before the given hook. Note that the same
854             hook my execute several times for a given recipe. Example, to open up
855             an interactive shell before the build has started, right after the
856             extraction:
857              
858             % af install --before build bash
859              
860             The build configuration is check pointed, so you can read the install
861             and runtime properties in the C<state.json> file in the build root.
862             Use * or % as the hook to run the command before all hooks. You can
863             use C<:repl> as the command to open up a Perl REPL (Read-Eval-Print-Loop)
864             to inspect the C<$build> and C<$meta> objects.
865              
866             =head4 --after
867              
868             Execute the given command after the given hook. Note that the same hook
869             my execute several times for a given recipe. Example, to open up an
870             interactive shell after the build has completed:
871              
872             % af install --after build bash
873              
874             The build configuration is check pointed, so you can read the install
875             and runtime properties in the C<state.json> file in the build root.
876             Use * or % as the hook to run the command before all hooks. You can
877             use C<:repl> as the command to open up a Perl REPL (Read-Eval-Print-Loop)
878             to inspect the C<$build> and C<$meta> objects.
879              
880             =head4 -I
881              
882             Add directory to the Perl search lib (like -I on L<perl>).
883              
884             =head4 --blib
885              
886             Use the blib from the current directory.
887              
888             =head2 requires
889              
890             =head3 Usage
891              
892             af requires
893             [ ( -f | --file ) alienfile | ( -c | --class ) class ]
894             [ ( -p | --phase ) ( configure | any | share | system ) ]
895              
896             =head3 description
897              
898             Print the requirements for the given phase in L<YAML> format. If the phase
899             is not provided, then requirements for all phases will be printed separately
900             in L<YAML> format.
901              
902             =head3 options
903              
904             =head4 -f | --file
905              
906             The L<alienfile>. If neither this option, nor C<-c> is specified, then
907             C<alienfile> in the current directory will be assumed.
908              
909             =head4 -c | --class
910              
911             Get the L<alienfile> from the already installed Alien module. You may
912             omit the C<Alien::> prefix, so for example L<Alien::curl> may be specified
913             as simply C<curl>.
914              
915             =head4 -p | --phase
916              
917             The phase of the requirement. Please refer to the L<Alien::Build> documentation
918             for the meaning of the various phases.
919              
920             =head2 missing
921              
922             =head3 Usage
923              
924             af missing
925             [ ( -f | --file ) alienfile | ( -c | --class ) class ]
926             [ ( -p | --phase ) ( configure | any | share | system ) ]
927             [ --plugin | --precompile ]
928              
929             =head3 description
930              
931             Print the requirements for the given phase in list format that are not
932             currently fulfilled. This output can be piped into L<cpanm> in order
933             to install any missing requirements:
934              
935             % af missing -p configure | cpanm
936             % af missing | cpanm
937              
938             If no phase is specified, then missing prereqs for configure, and either
939             share or system will be printed depending on what type of install is
940             detected (for this to work you may need to install the configure
941             prereqs, since the probe may use configure required modules).
942              
943             =head3 options
944              
945             =head4 -f | --file
946              
947             The L<alienfile>. If neither this option, nor C<-c> is specified, then
948             C<alienfile> in the current directory will be assumed.
949              
950             =head4 -c | --class
951              
952             Get the L<alienfile> from the already installed Alien module. You may
953             omit the C<Alien::> prefix, so for example L<Alien::curl> may be specified
954             as simply C<curl>.
955              
956             =head4 -p | --phase
957              
958             The phase of the requirement. Please refer to the L<Alien::Build>
959             documentation for the meaning of the various phases.
960              
961             =head4 --plugin
962              
963             Print out missing plugins. Caveat: to do this, C<af> mocks part of
964             L<Alien::Build::Meta>, which may or may not break in the future.
965              
966             =head2 --precompile
967              
968             Print out missing modules that are needed before the L<alienfile> is even
969             compiled. These are usually C<configure> time prereqs, but if they are
970             C<use>d in the L<alienfile> instead of being declared as a C<requires>, then
971             there is no way for L<Alien::Build> to query for them. Caveat: since
972             L<alienfile> is arbitrary Perl code, there may be corner cases not covered
973             by this option.
974              
975             =head2 prop
976              
977             =head3 Usage
978              
979             af prop
980             ( -c | --class ) class [ --cflags ] [ --libs ] [ --static ]
981             [ --modversion ] [ --bin-dir ]
982              
983             =head3 prop
984              
985             Print the runtime properties for the given L<Alien> class. You may
986             omit the C<Alien::> prefix, so for example L<Alien::curl> may be queried
987             as simply C<curl>. If no specific properties are requested then the
988             entire runtime property hash will be printed in L<YAML> format.
989              
990             =head3 options
991              
992             =head4 -c | --class
993              
994             The class to query for runtime properties. This option is required.
995              
996             =head4 --cflags
997              
998             Print the compiler flags
999              
1000             =head4 --libs
1001              
1002             Print the linker flags
1003              
1004             =head4 --static
1005              
1006             For either the C<--cflags> or C<--libs> option print the static versions.
1007              
1008             =head4 --modversion
1009              
1010             Print the version of the Alienized package. This is not the version of
1011             the L<Alien> module itself.
1012              
1013             =head4 --bin-dir
1014              
1015             Print the list of directories bundled with a C<share> install.
1016              
1017             =head2 list
1018              
1019             =head3 Usage
1020              
1021             af list [ -l | --long ]
1022              
1023             =head3 prop
1024              
1025             Print list of L<Alien> modules already installed that used L<Alien::Build>
1026             as their installer.
1027              
1028             =head3 options
1029              
1030             =head4 -l | --long
1031              
1032             Also print the version number of the L<Alien> module, and the version of the
1033             alienized package.
1034              
1035             =head1 AUTHOR
1036              
1037             Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
1038              
1039             Contributors:
1040              
1041             Diab Jerius (DJERIUS)
1042              
1043             =head1 COPYRIGHT AND LICENSE
1044              
1045             This software is copyright (c) 2017 by Graham Ollis.
1046              
1047             This is free software; you can redistribute it and/or modify it under
1048             the same terms as the Perl 5 programming language system itself.
1049              
1050             =cut