mirror of
https://github.com/wader/fq.git
synced 2024-12-23 13:22:58 +03:00
cli: Implement --arg, --argjson and --rawfile
This commit is contained in:
parent
962d84dc68
commit
f5ffd32096
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -139,4 +139,5 @@
|
||||
"editor.formatOnSave": true,
|
||||
"cSpell.allowCompoundWords": true,
|
||||
"cSpell.enabled": true,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
}
|
@ -7,10 +7,12 @@ Tool, language and decoders for exploring binary data.
|
||||
For more information see https://github.com/wader/fq
|
||||
|
||||
Usage: fq [OPTIONS] [--] [EXPR] [FILE...]
|
||||
--compact,-c Compact output
|
||||
--arg NAME VALUE Set variable $NAME to string VALUE
|
||||
--argjson NAME JSON Set variable $NAME to JSON
|
||||
--compact-output,-c Compact output
|
||||
--decode,-d NAME Decode format (probe)
|
||||
--file,-f PATH Read EXPR from file
|
||||
--formats Show supported formats
|
||||
--from-file,-f PATH Read EXPR from file
|
||||
--help,-h Show help
|
||||
--include-path,-L PATH Include search path
|
||||
--join-output,-j No newline between outputs
|
||||
@ -20,6 +22,7 @@ Usage: fq [OPTIONS] [--] [EXPR] [FILE...]
|
||||
--options Show all options
|
||||
--raw-input,-R Read raw input strings (don't decode)
|
||||
--raw-output,-r Raw string output (without quotes)
|
||||
--rawfile NAME PATH Set variable $NAME to string content of file
|
||||
--repl,-i Interactive REPL
|
||||
--slurp,-s Read (slurp) all inputs into an array
|
||||
--version,-v Show version (dev)
|
||||
|
@ -12,6 +12,8 @@ def args_parse($args; $opts):
|
||||
)
|
||||
elif $opt.array then
|
||||
_parse($new_args; $flagmap; ($r | .parsed[$optname] += [$value]))
|
||||
elif $opt.pairs then
|
||||
_parse($new_args; $flagmap; ($r | .parsed[$optname] += [$value]))
|
||||
else
|
||||
_parse($new_args; $flagmap; ($r | .parsed[$optname] = $value))
|
||||
end;
|
||||
@ -55,6 +57,12 @@ def args_parse($args; $opts):
|
||||
else
|
||||
_parse_with_arg($args[2:]; $optname; $args[1]; $opt)
|
||||
end
|
||||
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
|
||||
else
|
||||
if $assign_i then error("\($arg): takes no argument")
|
||||
else _parse_without_arg($args[1:]; $optname)
|
||||
@ -96,7 +104,7 @@ def args_help_text($opts):
|
||||
, .short
|
||||
] | map(select(strings)) | join(",")
|
||||
) +
|
||||
( .string // .array // .object
|
||||
( .string // .array // .object // .pairs
|
||||
| if . then " \(.)"
|
||||
else ""
|
||||
end
|
||||
|
@ -3,26 +3,13 @@ include "funcs";
|
||||
include "args";
|
||||
include "query";
|
||||
|
||||
# will include all per format specific function etc
|
||||
# generated decode functions per format
|
||||
include "@format/decode";
|
||||
# include per format specific functions
|
||||
include "@format/all";
|
||||
|
||||
# optional user init
|
||||
include "@config/init?";
|
||||
|
||||
|
||||
# def readline: #:: [a]| => string
|
||||
# Read a line.
|
||||
|
||||
# def readline($prompt): #:: [a]|(string) => string
|
||||
# Read a line with prompt.
|
||||
|
||||
# def readline($prompt; $completion): #:: [a]|(string;string) => string
|
||||
# $prompt is prompt to show.
|
||||
# $completion name of completion function [a](string) => [string],
|
||||
# it will be called with same input as readline and a string argument being the
|
||||
# current line from start to current cursor position. Should return possible completions.
|
||||
|
||||
# try to be same exit codes as jq
|
||||
# TODO: jq seems to halt processing inputs on JSON decode error but not IO errors,
|
||||
# seems strange.
|
||||
@ -52,6 +39,8 @@ def _build_default_options:
|
||||
( (null | stdout) as $stdout
|
||||
| {
|
||||
addrbase: 16,
|
||||
arg: [],
|
||||
argjson: [],
|
||||
arraytruncate: 50,
|
||||
bitsformat: "snippet",
|
||||
bytecolors: "0-0xff=brightwhite,0=brightblack,32-126:9-13=white",
|
||||
@ -87,6 +76,7 @@ def _build_default_options:
|
||||
join_string: "\n",
|
||||
linebytes: (if $stdout.is_terminal then [intdiv(intdiv($stdout.width; 8); 2) * 2, 4] | max else 16 end),
|
||||
null_input: false,
|
||||
rawfile: [],
|
||||
raw_output: ($stdout.is_terminal | not),
|
||||
raw_string: false,
|
||||
repl: false,
|
||||
@ -114,18 +104,31 @@ def _tonumber:
|
||||
try tonumber catch null;
|
||||
|
||||
def _tostring:
|
||||
if . != null then "\"\(.)\"" | fromjson end;
|
||||
|
||||
def _toarray:
|
||||
if . != null then
|
||||
( fromjson
|
||||
| if type != "array" then null end
|
||||
( "\"\(.)\""
|
||||
| try
|
||||
( fromjson
|
||||
| if type != "string" then error end
|
||||
)
|
||||
catch null
|
||||
)
|
||||
end;
|
||||
|
||||
def _toarray(f):
|
||||
try
|
||||
( fromjson
|
||||
| if type == "array" and (all(f) | not) then null end
|
||||
)
|
||||
catch null;
|
||||
|
||||
def _is_string_pair:
|
||||
type == "array" and length == 2 and all(type == "string");
|
||||
|
||||
def _to_options:
|
||||
( {
|
||||
addrbase: (.addrbase | _tonumber),
|
||||
arg: (.arg | _toarray(_is_string_pair)),
|
||||
argjson: (.argjson | _toarray(_is_string_pair)),
|
||||
arraytruncate: (.arraytruncate | _tonumber),
|
||||
bitsformat: (.bitsformat | _tostring),
|
||||
bytecolors: (.bytecolors | _tostring),
|
||||
@ -138,11 +141,12 @@ def _to_options:
|
||||
displaybytes: (.displaybytes | _tonumber),
|
||||
expr: (.expr | _tostring),
|
||||
expr_file: (.expr_file | _tostring),
|
||||
filename: (.filenames | _toarray),
|
||||
filename: (.filenames | _toarray(type == "string")),
|
||||
include_path: (.include_path | _tostring),
|
||||
join_string: (.join_string | _tostring),
|
||||
linebytes: (.linebytes | _tonumber),
|
||||
null_input: (.null_input | _toboolean),
|
||||
rawfile: (.rawfile| _toarray(_is_string_pair)),
|
||||
raw_output: (.raw_output | _toboolean),
|
||||
raw_string: (.raw_string | _toboolean),
|
||||
repl: (.repl | _toboolean),
|
||||
@ -458,6 +462,16 @@ def _main:
|
||||
);
|
||||
def _opts($version):
|
||||
{
|
||||
"arg": {
|
||||
long: "--arg",
|
||||
description: "Set variable $NAME to string VALUE",
|
||||
pairs: "NAME VALUE"
|
||||
},
|
||||
"argjson": {
|
||||
long: "--argjson",
|
||||
description: "Set variable $NAME to JSON",
|
||||
pairs: "NAME JSON"
|
||||
},
|
||||
"compact": {
|
||||
short: "-c",
|
||||
long: "--compact-output",
|
||||
@ -531,6 +545,11 @@ def _main:
|
||||
description: "Read raw input strings (don't decode)",
|
||||
bool: true
|
||||
},
|
||||
"rawfile": {
|
||||
long: "--rawfile",
|
||||
description: "Set variable $NAME to string content of file",
|
||||
pairs: "NAME PATH"
|
||||
},
|
||||
"raw_string": {
|
||||
short: "-r",
|
||||
# for jq compat, is called raw string internally, "raw output" is if
|
||||
@ -580,6 +599,18 @@ def _main:
|
||||
| _options_stack(
|
||||
[ $args_opts
|
||||
+ ( {
|
||||
argjson: (
|
||||
( $args_opts.argjson
|
||||
| if . then map(
|
||||
( . as $a
|
||||
| .[1] |=
|
||||
try fromjson
|
||||
catch error("--argjson \($a[0]): \(.)")
|
||||
)
|
||||
)
|
||||
end
|
||||
)
|
||||
),
|
||||
expr: (
|
||||
( $args_opts.expr_file
|
||||
| if . then
|
||||
@ -612,6 +643,17 @@ def _main:
|
||||
end
|
||||
)
|
||||
),
|
||||
rawfile: (
|
||||
( $args_opts.rawfile
|
||||
| if . then
|
||||
( map(.[1] |=
|
||||
try (open | tobytes | tostring)
|
||||
catch halt_error(_exit_code_args_error)
|
||||
)
|
||||
)
|
||||
end
|
||||
)
|
||||
),
|
||||
raw_string: (
|
||||
if $args_opts.raw_string
|
||||
or $args_opts.join_output
|
||||
@ -652,6 +694,14 @@ def _main:
|
||||
_finally(
|
||||
( _include_paths($opts.include_path) as $_
|
||||
| _input_filenames($opts.filenames) as $_ # store inputs
|
||||
| _variables(
|
||||
( $opts.arg +
|
||||
$opts.argjson +
|
||||
$opts.rawfile
|
||||
| map({key: .[0], value: .[1]})
|
||||
| from_entries
|
||||
)
|
||||
)
|
||||
| ( def _inputs:
|
||||
( if $opts.null_input then null
|
||||
# note jq --slurp --raw-string is special, will be just
|
||||
|
6
pkg/interp/testdata/args.fqtest
vendored
6
pkg/interp/testdata/args.fqtest
vendored
@ -9,6 +9,8 @@ Tool, language and decoders for exploring binary data.
|
||||
For more information see https://github.com/wader/fq
|
||||
|
||||
Usage: fq [OPTIONS] [--] [EXPR] [FILE...]
|
||||
--arg NAME VALUE Set variable $NAME to string VALUE
|
||||
--argjson NAME JSON Set variable $NAME to JSON
|
||||
--compact-output,-c Compact output
|
||||
--decode,-d NAME Decode format (probe)
|
||||
--formats Show supported formats
|
||||
@ -22,6 +24,7 @@ Usage: fq [OPTIONS] [--] [EXPR] [FILE...]
|
||||
--options Show all options
|
||||
--raw-input,-R Read raw input strings (don't decode)
|
||||
--raw-output,-r Raw string output (without quotes)
|
||||
--rawfile NAME PATH Set variable $NAME to string content of file
|
||||
--repl,-i Interactive REPL
|
||||
--slurp,-s Read (slurp) all inputs into an array
|
||||
--version,-v Show version (dev)
|
||||
@ -114,6 +117,8 @@ xing Xing header
|
||||
$ fq --options
|
||||
{
|
||||
"addrbase": 16,
|
||||
"arg": [],
|
||||
"argjson": [],
|
||||
"arraytruncate": 50,
|
||||
"bitsformat": "snippet",
|
||||
"bytecolors": "0-0xff=brightwhite,0=brightblack,32-126:9-13=white",
|
||||
@ -136,6 +141,7 @@ $ fq --options
|
||||
"null_input": false,
|
||||
"raw_output": false,
|
||||
"raw_string": false,
|
||||
"rawfile": [],
|
||||
"repl": false,
|
||||
"show_formats": false,
|
||||
"show_help": false,
|
||||
|
3
pkg/interp/testdata/options.fqtest
vendored
3
pkg/interp/testdata/options.fqtest
vendored
@ -1,6 +1,8 @@
|
||||
$ fq -n options
|
||||
{
|
||||
"addrbase": 16,
|
||||
"arg": [],
|
||||
"argjson": [],
|
||||
"arraytruncate": 50,
|
||||
"bitsformat": "snippet",
|
||||
"bytecolors": "0-0xff=brightwhite,0=brightblack,32-126:9-13=white",
|
||||
@ -23,6 +25,7 @@ $ fq -n options
|
||||
"null_input": true,
|
||||
"raw_output": false,
|
||||
"raw_string": false,
|
||||
"rawfile": [],
|
||||
"repl": false,
|
||||
"show_formats": false,
|
||||
"show_help": false,
|
||||
|
Loading…
Reference in New Issue
Block a user