File Coverage

blib/lib/oCLI/Request.pm
Criterion Covered Total %
statement 47 59 79.6
branch 20 28 71.4
condition 13 15 86.6
subroutine 3 5 60.0
pod 0 1 0.0
total 83 108 76.8


line stmt bran cond sub pod time code
1             package oCLI::Request;
2 2     2   77661 use Moo;
  2         25815  
  2         13  
3 2     2   3237 use Scalar::Util qw( looks_like_number );
  2         5  
  2         2084  
4              
5             has [qw( overrides command stdin )] => (
6             is => 'ro',
7             );
8              
9             has args => (
10             is => 'ro',
11             default => sub { return [] },
12             );
13              
14             has settings => (
15             is => 'ro',
16             default => sub { return +{} },
17             );
18              
19             has command_class => (
20             is => 'ro',
21             lazy => 1,
22             builder => sub {
23 0     0   0 my ( $self ) = @_;
24              
25 0 0       0 return "" unless index($self->command, ':') >= 0;
26              
27 0         0 my @parts = split /:/, $self->command;
28 0         0 delete $parts[-1];
29              
30 0         0 return join "::", map { ucfirst(lc($_)) } @parts;
  0         0  
31             },
32             );
33              
34             has command_name => (
35             is => 'ro',
36             lazy => 1,
37             builder => sub {
38 0     0   0 my ( $self ) = @_;
39              
40 0         0 return lc( (split( /:/, $self->command ))[-1] );
41             }
42             );
43              
44             sub new_from_command_line {
45 16     16 0 42499 my ( $class, @command_line ) = @_;
46              
47 16         38 my $data;
48              
49 16         41 my ( $overrides, $command, @arguments, $switches );
50              
51             # Process over rides
52 16   100     146 while ( @command_line && substr($command_line[0],0,1) eq '/' ) {
53 38         67 my $command = shift @command_line;
54              
55 38 100       202 if ( $command =~ /^\/([^= ]+)=(.+)$/ ) { # /key=value
    50          
56 28         136 $data->{overrides}->{$1} = $2;
57             } elsif ( $command =~ /^\/([^ ]+)$/ ) {
58 10         78 $data->{overrides}->{$1} = 1;
59             } else {
60 0         0 die "Could not parse command line argument: $command\n";
61             }
62             }
63              
64             # Process command if one exists.
65 16 100 66     99 $data->{command} = shift @command_line if @command_line and $command_line[0] !~ /^--/;
66              
67 16   100     83 while ( @command_line && substr($command_line[0],0,2) ne '--' ) {
68 9         19 my $command = shift @command_line;
69              
70             # Expand filenames into their content in arguments prefixed with @.
71 9 100       27 if ( substr($command,0,1) eq '@' ) {
72 1 50       75 open my $lf, "<", substr($command,1)
73             or die "Failed to read $command: $!";
74 1         4 $command = do { local $/; <$lf> };
  1         5  
  1         41  
75 1         17 close $lf;
76             }
77 9         16 push @{$data->{args}}, $command;
  9         48  
78             }
79              
80             # Process arguments
81             #
82             # --foo { foo => 1 }
83             # --no-foo { foo => 0 }
84             # --foo bar { foo => 'bar' }
85             # --foo bar --foo blee { foo => [ 'bar', 'blee' ] }
86             # --foo=bar { foo => 'bar' }
87             # --foo=bar --foo=blee { foo => [ 'bar', 'blee' ] }
88             # --foo @path { foo => contents_of_file() }
89 16         55 while ( defined( my $command = shift @command_line )) {
90              
91              
92 32 100 100     207 if ( $command =~ /^--no-([^ ]+)$/ ) {
    100 66        
93 5         64 $data->{settings}->{$1} = 0;
94             } elsif ( ( ! @command_line or $command_line[0] =~ /^--/ ) && $command =~ /^--([^ =]+)$/ ) {
95 10         54 $data->{settings}->{$1} = 1;
96             } else {
97 17         50 $command =~ s/^--//;
98              
99 17         33 my $argument;
100 17 50       35 if ( $command =~ /^([^=]+)=(.+?)$/ ) {
101 0         0 ( $command, $argument ) = ( $1, $2 );
102             } else {
103 17         45 $argument = shift @command_line;
104             }
105              
106 17 100       40 if ( substr($argument,0,1) eq '@' ) {
107 2 50       107 open my $lf, "<", substr($argument,1)
108             or die "Failed to read $argument: $!";
109 2         9 $data->{settings}->{$command} = do { local $/; <$lf> };
  2         11  
  2         57  
110 2         36 close $lf;
111             } else {
112             # If we have nothing, this becomes a string...
113 15 100       58 if ( ! $data->{settings}->{$command} ) {
    50          
114 9         32 $data->{settings}->{$command} = $argument;
115             # If we have an array ref there already...
116             } elsif ( ref($data->{settings}->{$command}) eq 'ARRAY' ) {
117 0         0 push @{$data->{settings}->{$command}}, $argument;
  0         0  
118             # Otherwise we promote to an array ref
119             } else {
120 6         24 $data->{settings}->{$command} = [ $data->{settings}->{$command}, $argument ];
121             }
122             }
123             }
124             }
125              
126             # Process STDIN
127 16 50       163 if ( ! -t STDIN ) {
128 16         35 $data->{stdin} = do { local $/; };
  16         79  
  16         334  
129             }
130              
131 16         505 return $class->new($data);
132             }
133              
134             1;