File Coverage

blib/lib/YA/CLI.pm
Criterion Covered Total %
statement 61 66 92.4
branch 22 30 73.3
condition 17 20 85.0
subroutine 13 14 92.8
pod 4 5 80.0
total 117 135 86.6


line stmt bran cond sub pod time code
1             package YA::CLI;
2             our $VERSION = '0.007';
3 4     4   673347 use Moo;
  4         20878  
  4         28  
4              
5             # ABSTRACT: Yet another CLI framework
6              
7 4     4   4790 use Carp qw(croak);
  4         8  
  4         277  
8 4     4   3187 use Getopt::Long;
  4         61412  
  4         19  
9 4     4   808 use List::Util qw(first);
  4         13  
  4         319  
10 4     4   2476 use Module::Pluggable::Object;
  4         40504  
  4         3367  
11              
12             with 'YA::CLI::PodRole';
13              
14             sub BUILD_ARGS {
15 0     0 0 0 croak "Please use run()";
16             }
17              
18             sub default_handler {
19 5     5 1 16 return 'main';
20             }
21              
22             sub default_search_path {
23 15     15 1 175 return shift;
24             }
25              
26             sub cli_options {
27 15     15 1 33 return;
28             }
29              
30             sub _init {
31 15     15   29 my ($class, $args) = @_;
32              
33 15   50     42 $args //= \@ARGV;
34              
35 15         52 my %cli_args = $class->_get_opts($args);
36              
37 15         28 my ($action, $subaction);
38 15 100 100     103 if (@$args && $args->[0] !~ /^--/) {
39 10         24 $action = shift @$args;
40             }
41 15 100 100     79 if ($action && @$args && $args->[0] !~ /^--/) {
      100        
42 4         12 $subaction = shift @$args;
43             }
44              
45 15   66     54 $action //= $class->default_handler;
46 15 50       34 if (!defined $action) {
47 0 0       0 return $class->as_manpage() if $cli_args{man};
48 0 0       0 return $class->as_help() if $cli_args{help};
49 0         0 return $class->as_help(1);
50             }
51 15 50       30 return $class->as_help() if !defined $action;
52              
53 15         55 my $handler = $class->_get_action_handler($action, $subaction);
54              
55 15 100       37 if (!$handler) {
56 2         438 require YA::CLI::ErrorHandler;
57 2         22 $handler = 'YA::CLI::ErrorHandler';
58 2 50       6 if (!defined $subaction) {
59 2         7 return $handler->as_help(1, "$action command does not exist!");
60             }
61             else {
62 0         0 return $handler->as_help(1, "$action $subaction command does not exist!");
63             }
64             }
65              
66 13 100 66     74 if ($handler && defined $subaction && !$handler->can('subaction')) {
      100        
67 1         3 unshift(@$args, $subaction);
68             }
69              
70 13 100       41 return $handler->as_manpage() if $cli_args{man};
71 11 100       33 return $handler->as_help() if $cli_args{help};
72              
73 8         36 return $handler->new_from_args($args);
74             }
75              
76             sub run {
77 15     15 1 542701 my ($class, $args) = @_;
78 15         54 my $handler = $class->_init($args);
79 15         2108 return $handler->run();
80             }
81              
82             sub _get_opts {
83 15     15   23 my ($class, $args) = @_;
84              
85 15         38 my @cli_options = qw(
86             help|h
87             man|m
88             );
89              
90 15         43 push(@cli_options, $class->cli_options);
91              
92 15         93 my $p = Getopt::Long::Parser->new(
93             config => [
94             qw(
95             pass_through
96             no_auto_abbrev
97             )
98             ]
99             );
100              
101 15         4438 my %cli_args;
102 15         66 $p->getoptionsfromarray($args, \%cli_args, @cli_options);
103 15         6410 return %cli_args;
104             }
105              
106             my @PLUGINS;
107              
108             sub _get_action_handler {
109 15     15   24 my $class = shift;
110 15         26 my $action = shift;
111 15         21 my $subaction = shift;
112              
113 15 50       45 my $finder = Module::Pluggable::Object->new(
114             search_path => $class->default_search_path,
115             require => 1,
116             $class->can('exclude_search_path') ? (
117             except => $class->exclude_search_path,
118             ) : (),
119             );
120              
121 15 100       147 @PLUGINS = $finder->plugins if !@PLUGINS;
122 15         23410 my @found = grep { $_->has_action($action, $subaction) } @PLUGINS;
  45         157  
123 15 100       36 return unless @found;
124              
125 13 100       68 return $found[0] if @found == 1;
126 3     6   16 return first { $_->has_subaction($subaction) == 1 } @found;
  6         18  
127              
128             }
129              
130             __PACKAGE__->meta->make_immutable;
131              
132             __END__