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