2022-02-16 19:10:41 +03:00
|
|
|
include "funcs";
|
|
|
|
|
2020-06-08 03:29:51 +03:00
|
|
|
# TODO: refactor this mess
|
2021-09-07 02:38:52 +03:00
|
|
|
def _args_parse($args; $opts):
|
2020-06-08 03:29:51 +03:00
|
|
|
def _parse($args; $flagmap; $r):
|
|
|
|
def _parse_with_arg($new_args; $optname; $value; $opt):
|
|
|
|
if $opt.object then
|
|
|
|
( ( $value
|
|
|
|
| capture("^(?<key>.*?)=(?<value>.*)$")
|
|
|
|
// error("\($value): should be key=value")
|
|
|
|
) as {$key, $value}
|
|
|
|
# TODO: validate option name key
|
|
|
|
| _parse($new_args; $flagmap; ($r | .parsed[$optname][$key] |= $value))
|
|
|
|
)
|
|
|
|
elif $opt.array then
|
|
|
|
_parse($new_args; $flagmap; ($r | .parsed[$optname] += [$value]))
|
2021-09-07 00:42:05 +03:00
|
|
|
elif $opt.pairs then
|
|
|
|
_parse($new_args; $flagmap; ($r | .parsed[$optname] += [$value]))
|
2020-06-08 03:29:51 +03:00
|
|
|
else
|
|
|
|
_parse($new_args; $flagmap; ($r | .parsed[$optname] = $value))
|
|
|
|
end;
|
|
|
|
def _parse_without_arg($new_args; $optname):
|
|
|
|
_parse($new_args; $flagmap; ($r | .parsed[$optname] = true));
|
2021-09-06 02:08:03 +03:00
|
|
|
# this is to support --arg=VALUE
|
2020-06-08 03:29:51 +03:00
|
|
|
( ($args[0] | index("=")) as $assign_i
|
|
|
|
| ( if $assign_i then $args[0][0:$assign_i]
|
|
|
|
else $args[0]
|
|
|
|
end
|
|
|
|
) as $arg
|
|
|
|
| if $arg == null then
|
|
|
|
$r
|
|
|
|
else
|
|
|
|
if $arg == "--" then
|
|
|
|
$r | .rest += $args[1:]
|
2023-08-08 17:03:32 +03:00
|
|
|
# \d to not see -0, -123 etc as an argument
|
|
|
|
elif $arg | test("^--?[^-\\d]") then
|
2020-06-08 03:29:51 +03:00
|
|
|
( $flagmap[$arg] as $optname
|
|
|
|
| ($opts[$optname]? // null) as $opt
|
|
|
|
| if $opt == null then
|
|
|
|
if $arg | test("^-[^-]") then
|
|
|
|
( $arg[0:2] as $arg
|
|
|
|
| $flagmap[$arg] as $optname
|
|
|
|
| ($opts[$optname]? // null) as $opt
|
2021-08-09 13:37:48 +03:00
|
|
|
| if $opt == null then
|
|
|
|
error("\($arg): no such argument")
|
|
|
|
elif $opt.bool then
|
2020-06-08 03:29:51 +03:00
|
|
|
_parse_without_arg((["-"+$args[0][2:]]+$args[1:]); $optname)
|
|
|
|
else
|
|
|
|
error("\($arg): needs an argument")
|
|
|
|
end
|
|
|
|
)
|
|
|
|
else
|
|
|
|
error("\($arg): no such argument")
|
|
|
|
end
|
|
|
|
elif $opt.string or $opt.array or $opt.object then
|
|
|
|
if $assign_i then
|
|
|
|
_parse_with_arg($args[1:]; $optname; $args[0][$assign_i+1:]; $opt)
|
|
|
|
elif ($args | length) < 2 then
|
2022-03-03 15:37:35 +03:00
|
|
|
if $opt.optional then
|
|
|
|
_parse_without_arg($args[1:]; $optname)
|
|
|
|
else
|
|
|
|
error("\($arg): needs an argument")
|
|
|
|
end
|
2020-06-08 03:29:51 +03:00
|
|
|
else
|
|
|
|
_parse_with_arg($args[2:]; $optname; $args[1]; $opt)
|
|
|
|
end
|
2021-09-07 00:42:05 +03:00
|
|
|
elif $opt.pairs then
|
|
|
|
if ($args | length) > 2 then
|
|
|
|
_parse_with_arg($args[3:]; $optname; [$args[1], $args[2]]; $opt)
|
|
|
|
else
|
|
|
|
error("\($arg): needs two argument")
|
|
|
|
end
|
2020-06-08 03:29:51 +03:00
|
|
|
else
|
|
|
|
if $assign_i then error("\($arg): takes no argument")
|
|
|
|
else _parse_without_arg($args[1:]; $optname)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
)
|
|
|
|
else
|
|
|
|
_parse($args[1:]; $flagmap; ($r | .rest += [$args[0]]))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
);
|
|
|
|
# build {"-s": "name", "--long": "name", ...}
|
|
|
|
def _flagmap:
|
|
|
|
( $opts
|
|
|
|
| to_entries
|
|
|
|
| map(
|
2021-09-05 13:46:21 +03:00
|
|
|
( . as $opt
|
|
|
|
| [.value.short // empty] +
|
|
|
|
[.value.long // empty] +
|
|
|
|
(.value.aliases // [])
|
|
|
|
| map({key: ., value: $opt.key})
|
|
|
|
| from_entries
|
2020-06-08 03:29:51 +03:00
|
|
|
)
|
|
|
|
)
|
|
|
|
| add
|
|
|
|
);
|
|
|
|
def _defaults:
|
|
|
|
( $opts
|
|
|
|
| to_entries
|
|
|
|
| map(select(.value.default))
|
|
|
|
| map({(.key): .value.default})
|
|
|
|
| add
|
|
|
|
);
|
|
|
|
_parse($args; _flagmap; {parsed: _defaults, rest: []});
|
|
|
|
|
|
|
|
def args_help_text($opts):
|
|
|
|
def _opthelp:
|
|
|
|
( [ .long
|
|
|
|
, .short
|
|
|
|
] | map(select(strings)) | join(",")
|
|
|
|
) +
|
2021-09-07 00:42:05 +03:00
|
|
|
( .string // .array // .object // .pairs
|
2021-08-26 16:38:49 +03:00
|
|
|
| if . then " \(.)"
|
2020-06-08 03:29:51 +03:00
|
|
|
else ""
|
|
|
|
end
|
|
|
|
);
|
|
|
|
def _maxoptlen:
|
|
|
|
[ $opts[]
|
|
|
|
| (_opthelp | length)
|
|
|
|
] | max;
|
2021-08-26 16:38:49 +03:00
|
|
|
def _obj_value:
|
|
|
|
if . == null then ""
|
|
|
|
elif (. | type) == "string" then tojson | .[1:-1]
|
|
|
|
else .
|
|
|
|
end;
|
2020-06-08 03:29:51 +03:00
|
|
|
( _maxoptlen as $l
|
|
|
|
| $opts
|
2021-09-01 20:53:12 +03:00
|
|
|
| to_entries
|
|
|
|
| sort_by(.value.long)
|
|
|
|
| .[]
|
2020-06-08 03:29:51 +03:00
|
|
|
| (.value | .help_default // .default) as $default
|
|
|
|
| [ "\(.value | _opthelp | rpad(" "; $l)) \(.value.description)"
|
|
|
|
, if $default then
|
|
|
|
if .value.object then
|
|
|
|
[ "\n"
|
2021-08-26 16:38:49 +03:00
|
|
|
, ( [$default | to_entries[] | "\(" "*$l) \(.key)=\(.value | _obj_value)"]
|
2020-06-08 03:29:51 +03:00
|
|
|
| join("\n")
|
|
|
|
)
|
|
|
|
]
|
|
|
|
else
|
|
|
|
" (\($default))"
|
|
|
|
end
|
|
|
|
else
|
|
|
|
empty
|
|
|
|
end
|
|
|
|
]
|
|
|
|
| flatten
|
|
|
|
| join("")
|
|
|
|
);
|