line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Perinci::Sub::ConvertArgs::Argv; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $DATE = '2016-12-12'; # DATE |
4
|
|
|
|
|
|
|
our $VERSION = '0.10'; # VERSION |
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
23847
|
use 5.010001; |
|
1
|
|
|
|
|
4
|
|
7
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
36
|
|
8
|
1
|
|
|
1
|
|
8
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
64
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
851
|
use Data::Sah::Util::Type qw(is_simple); |
|
1
|
|
|
|
|
1380
|
|
|
1
|
|
|
|
|
91
|
|
11
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
8
|
use Exporter; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1216
|
|
13
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
14
|
|
|
|
|
|
|
our @EXPORT_OK = qw(convert_args_to_argv); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our %SPEC; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub _json { |
19
|
2
|
|
|
2
|
|
21
|
require JSON; |
20
|
2
|
|
|
|
|
40
|
state $json = JSON->new->allow_nonref; |
21
|
2
|
|
|
|
|
31
|
$json->encode($_[0]); |
22
|
|
|
|
|
|
|
} |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub _encode { |
25
|
3
|
100
|
|
3
|
|
16
|
ref($_[0]) ? _json($_[0]) : $_[0]; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
$SPEC{convert_args_to_argv} = { |
29
|
|
|
|
|
|
|
v => 1.1, |
30
|
|
|
|
|
|
|
summary => 'Convert hash arguments to command-line options (and arguments)', |
31
|
|
|
|
|
|
|
description => <<'_', |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
Convert hash arguments to command-line arguments. This is the reverse of |
34
|
|
|
|
|
|
|
`Perinci::Sub::GetArgs::Argv::get_args_from_argv`. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
Note: currently the function expects schemas in metadata to be normalized |
37
|
|
|
|
|
|
|
already. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
_ |
40
|
|
|
|
|
|
|
args => { |
41
|
|
|
|
|
|
|
args => {req=>1, schema=>'hash*', pos=>0}, |
42
|
|
|
|
|
|
|
meta => {req=>0, schema=>'hash*', pos=>1}, |
43
|
|
|
|
|
|
|
use_pos => { |
44
|
|
|
|
|
|
|
summary => 'Whether to use positional arguments', |
45
|
|
|
|
|
|
|
schema => 'bool', |
46
|
|
|
|
|
|
|
description => <<'_', |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
For example, given this metadata: |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
{ |
51
|
|
|
|
|
|
|
v => 1.1, |
52
|
|
|
|
|
|
|
args => { |
53
|
|
|
|
|
|
|
arg1 => {pos=>0, req=>1}, |
54
|
|
|
|
|
|
|
arg2 => {pos=>1}, |
55
|
|
|
|
|
|
|
arg3 => {}, |
56
|
|
|
|
|
|
|
}, |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
then under `use_pos=0` the hash `{arg1=>1, arg2=>2, arg3=>'a b'}` will be |
60
|
|
|
|
|
|
|
converted to `['--arg1', 1, '--arg2', 2, '--arg3', 'a b']`. Meanwhile if |
61
|
|
|
|
|
|
|
`use_pos=1` the same hash will be converted to `[1, 2, '--arg3', 'a b']`. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
_ |
64
|
|
|
|
|
|
|
}, |
65
|
|
|
|
|
|
|
}, |
66
|
|
|
|
|
|
|
}; |
67
|
|
|
|
|
|
|
sub convert_args_to_argv { |
68
|
7
|
|
|
7
|
1
|
29721
|
my %fargs = @_; |
69
|
|
|
|
|
|
|
|
70
|
7
|
50
|
|
|
|
36
|
my $iargs = $fargs{args} or return [400, "Please specify args"]; |
71
|
7
|
|
100
|
|
|
43
|
my $meta = $fargs{meta} // {v=>1.1}; |
72
|
7
|
|
100
|
|
|
28
|
my $args_prop = $meta->{args} // {}; |
73
|
|
|
|
|
|
|
|
74
|
7
|
|
50
|
|
|
19
|
my $v = $meta->{v} // 1.0; |
75
|
7
|
50
|
|
|
|
24
|
return [412, "Sorry, only metadata version 1.1 is supported (yours: $v)"] |
76
|
|
|
|
|
|
|
unless $v == 1.1; |
77
|
|
|
|
|
|
|
|
78
|
7
|
|
|
|
|
7
|
my @argv; |
79
|
7
|
|
|
|
|
32
|
my %iargs = %$iargs; # copy 'coz we will delete them one by one as we fill |
80
|
|
|
|
|
|
|
|
81
|
7
|
100
|
|
|
|
32
|
if ($fargs{use_pos}) { |
82
|
2
|
|
|
|
|
7
|
for my $arg (sort {$args_prop->{$a}{pos} <=> $args_prop->{$b}{pos}} |
|
1
|
|
|
|
|
6
|
|
83
|
5
|
|
|
|
|
18
|
grep {defined $args_prop->{$_}{pos}} keys %iargs) { |
84
|
3
|
|
|
|
|
7
|
my $pos = $args_prop->{$arg}{pos}; |
85
|
3
|
100
|
|
|
|
10
|
if ($args_prop->{$arg}{greedy}) { |
86
|
1
|
|
|
|
|
28
|
my $sch = $args_prop->{$arg}{schema}; |
87
|
|
|
|
|
|
|
my $is_array_of_simple = $sch && $sch->[0] eq 'array' && |
88
|
1
|
|
33
|
|
|
21
|
is_simple($sch->[1]{of} // $sch->[1]{each_elem}); |
89
|
1
|
|
|
|
|
33
|
for my $el (@{ $iargs{$arg} }) { |
|
1
|
|
|
|
|
4
|
|
90
|
2
|
50
|
|
|
|
7
|
$argv[$pos] = $is_array_of_simple ? $el : _encode($el); |
91
|
2
|
|
|
|
|
4
|
$pos++; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
} else { |
94
|
2
|
|
|
|
|
7
|
$argv[$pos] = _encode($iargs{$arg}); |
95
|
|
|
|
|
|
|
} |
96
|
3
|
|
|
|
|
22
|
delete $iargs{$arg}; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
7
|
|
|
|
|
35
|
for (sort keys %iargs) { |
101
|
9
|
|
|
|
|
20
|
my $sch = $args_prop->{$_}{schema}; |
102
|
9
|
|
66
|
|
|
53
|
my $is_bool = $sch && $sch->[0] eq 'bool'; |
103
|
|
|
|
|
|
|
my $is_array_of_simple = $sch && $sch->[0] eq 'array' && |
104
|
9
|
|
33
|
|
|
64
|
$sch->[1]{of} && is_simple($sch->[1]{of}); |
105
|
|
|
|
|
|
|
my $is_hash_of_simple = $sch && $sch->[0] eq 'hash' && |
106
|
9
|
|
66
|
|
|
118
|
is_simple($sch->[1]{of} // $sch->[1]{each_value} // $sch->[1]{each_elem}); |
107
|
|
|
|
|
|
|
my $can_be_comma_separated = $is_array_of_simple && |
108
|
9
|
|
100
|
|
|
63
|
$sch->[1]{of}[0] =~ /\A(int|float)\z/; # XXX as well as other simple types that cannot contain commas |
109
|
9
|
|
|
|
|
13
|
my $opt = $_; $opt =~ s/_/-/g; |
|
9
|
|
|
|
|
18
|
|
110
|
9
|
100
|
|
|
|
31
|
my $dashopt = length($opt) > 1 ? "--$opt" : "-$opt"; |
111
|
9
|
100
|
|
|
|
35
|
if ($is_bool) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
112
|
2
|
100
|
|
|
|
6
|
if ($iargs{$_}) { |
113
|
1
|
|
|
|
|
5
|
push @argv, $dashopt; |
114
|
|
|
|
|
|
|
} else { |
115
|
1
|
|
|
|
|
6
|
push @argv, "--no$opt"; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
} elsif ($can_be_comma_separated) { |
118
|
1
|
|
|
|
|
4
|
push @argv, "$dashopt", join(",", @{ $iargs{$_} }); |
|
1
|
|
|
|
|
9
|
|
119
|
|
|
|
|
|
|
} elsif ($is_array_of_simple) { |
120
|
1
|
|
|
|
|
3
|
for (@{ $iargs{$_} }) { |
|
1
|
|
|
|
|
6
|
|
121
|
2
|
|
|
|
|
9
|
push @argv, "$dashopt", $_; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
} elsif ($is_hash_of_simple) { |
124
|
1
|
|
|
|
|
3
|
my $arg = $iargs{$_}; |
125
|
1
|
|
|
|
|
8
|
for (sort keys %$arg) { |
126
|
2
|
|
|
|
|
14
|
push @argv, "$dashopt", "$_=$arg->{$_}"; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
} else { |
129
|
4
|
100
|
|
|
|
11
|
if (ref $iargs{$_}) { |
130
|
1
|
|
|
|
|
7
|
push @argv, "$dashopt-json", _encode($iargs{$_}); |
131
|
|
|
|
|
|
|
} else { |
132
|
3
|
|
|
|
|
15
|
push @argv, $dashopt, "$iargs{$_}"; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
} |
136
|
7
|
|
|
|
|
61
|
[200, "OK", \@argv]; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
1; |
140
|
|
|
|
|
|
|
# ABSTRACT: Convert hash arguments to command-line options (and arguments) |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
__END__ |