mirror of
https://github.com/wader/fq.git
synced 2024-12-23 13:22:58 +03:00
cli: Better filenames in errors
This commit is contained in:
parent
394e2b3837
commit
0dd848de6c
@ -38,7 +38,7 @@ func (i *Interp) makeFunctions(registry *registry.Registry) []Function {
|
|||||||
{[]string{"tty"}, 0, 0, i.tty, nil},
|
{[]string{"tty"}, 0, 0, i.tty, nil},
|
||||||
|
|
||||||
{[]string{"readline"}, 0, 2, i.readline, nil},
|
{[]string{"readline"}, 0, 2, i.readline, nil},
|
||||||
{[]string{"eval"}, 1, 1, nil, i.eval},
|
{[]string{"eval"}, 1, 2, nil, i.eval},
|
||||||
{[]string{"stdout"}, 0, 0, nil, i.stdout},
|
{[]string{"stdout"}, 0, 0, nil, i.stdout},
|
||||||
{[]string{"stderr"}, 0, 0, nil, i.stderr},
|
{[]string{"stderr"}, 0, 0, nil, i.stderr},
|
||||||
|
|
||||||
@ -246,12 +246,20 @@ func (i *Interp) readline(c interface{}, a []interface{}) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) eval(c interface{}, a []interface{}) gojq.Iter {
|
func (i *Interp) eval(c interface{}, a []interface{}) gojq.Iter {
|
||||||
|
var err error
|
||||||
src, err := toString(a[0])
|
src, err := toString(a[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gojq.NewIter(fmt.Errorf("src: %w", err))
|
return gojq.NewIter(fmt.Errorf("src: %w", err))
|
||||||
}
|
}
|
||||||
|
var filenameHint string
|
||||||
|
if len(a) >= 2 {
|
||||||
|
filenameHint, err = toString(a[1])
|
||||||
|
if err != nil {
|
||||||
|
return gojq.NewIter(fmt.Errorf("filename hint: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iter, err := i.Eval(i.evalContext.ctx, ScriptMode, c, src, i.evalContext.stdout)
|
iter, err := i.Eval(i.evalContext.ctx, ScriptMode, c, src, filenameHint, i.evalContext.stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gojq.NewIter(err)
|
return gojq.NewIter(err)
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,11 @@ type compileError struct {
|
|||||||
|
|
||||||
func (ce compileError) Value() interface{} {
|
func (ce compileError) Value() interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"error": ce.err.Error(),
|
"error": ce.err.Error(),
|
||||||
"what": ce.what,
|
"what": ce.what,
|
||||||
"line": ce.pos.Line,
|
"filename": ce.filename,
|
||||||
"column": ce.pos.Column,
|
"line": ce.pos.Line,
|
||||||
|
"column": ce.pos.Column,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (ee compileError) Error() string {
|
func (ee compileError) Error() string {
|
||||||
@ -540,7 +541,7 @@ func (i *Interp) Main(ctx context.Context, stdout io.Writer, version string) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src string, stdout Output) (gojq.Iter, error) {
|
func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src string, filename string, stdout Output) (gojq.Iter, error) {
|
||||||
var err error
|
var err error
|
||||||
// TODO: did not work
|
// TODO: did not work
|
||||||
// nq := &(*q)
|
// nq := &(*q)
|
||||||
@ -549,9 +550,10 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
p := queryErrorPosition(err)
|
p := queryErrorPosition(err)
|
||||||
return nil, compileError{
|
return nil, compileError{
|
||||||
err: err,
|
err: err,
|
||||||
what: "parse",
|
what: "parse",
|
||||||
pos: p,
|
filename: filename,
|
||||||
|
pos: p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,7 +694,7 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
|||||||
return nil, compileError{
|
return nil, compileError{
|
||||||
err: err,
|
err: err,
|
||||||
what: "parse",
|
what: "parse",
|
||||||
filename: filename,
|
filename: filenamePart,
|
||||||
pos: p,
|
pos: p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -712,9 +714,10 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
p := queryErrorPosition(err)
|
p := queryErrorPosition(err)
|
||||||
return nil, compileError{
|
return nil, compileError{
|
||||||
err: err,
|
err: err,
|
||||||
what: "compile",
|
what: "compile",
|
||||||
pos: p,
|
filename: filename,
|
||||||
|
pos: p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,7 +755,7 @@ func (i *Interp) EvalFunc(ctx context.Context, mode RunMode, c interface{}, name
|
|||||||
/// _args to mark variable as internal and hide it from completion
|
/// _args to mark variable as internal and hide it from completion
|
||||||
// {input: ..., args: [...]} | .args as {args: $_args} | .input | name[($_args[0]; ...)]
|
// {input: ..., args: [...]} | .args as {args: $_args} | .input | name[($_args[0]; ...)]
|
||||||
trampolineExpr := fmt.Sprintf(". as {args: $_args} | .input | %s%s", name, argExpr)
|
trampolineExpr := fmt.Sprintf(". as {args: $_args} | .input | %s%s", name, argExpr)
|
||||||
iter, err := i.Eval(ctx, mode, trampolineInput, trampolineExpr, stdout)
|
iter, err := i.Eval(ctx, mode, trampolineInput, trampolineExpr, "", stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -169,9 +169,9 @@ def _eval_is_compile_error: type == "object" and .error != null and .what != nul
|
|||||||
def _eval_compile_error_tostring:
|
def _eval_compile_error_tostring:
|
||||||
"\(.filename // "src"):\(.line):\(.column): \(.error)";
|
"\(.filename // "src"):\(.line):\(.column): \(.error)";
|
||||||
|
|
||||||
def _eval($e; f; on_error; on_compile_error):
|
def _eval($e; $filename; f; on_error; on_compile_error):
|
||||||
( _default_options(_build_default_options) as $_
|
( _default_options(_build_default_options) as $_
|
||||||
| try eval($e) | f
|
| try eval($e; $filename) | f
|
||||||
catch
|
catch
|
||||||
if _eval_is_compile_error then on_compile_error
|
if _eval_is_compile_error then on_compile_error
|
||||||
else on_error
|
else on_error
|
||||||
@ -184,7 +184,7 @@ def _repl_on_error:
|
|||||||
| (_error_str | println)
|
| (_error_str | println)
|
||||||
);
|
);
|
||||||
def _repl_on_compile_error: _repl_on_error;
|
def _repl_on_compile_error: _repl_on_error;
|
||||||
def _repl_eval($e): _eval($e; _repl_display; _repl_on_error; _repl_on_compile_error);
|
def _repl_eval($e): _eval($e; "repl"; _repl_display; _repl_on_error; _repl_on_compile_error);
|
||||||
|
|
||||||
# run read-eval-print-loop
|
# run read-eval-print-loop
|
||||||
def repl($opts; iter): #:: a|(Opts) => @
|
def repl($opts; iter): #:: a|(Opts) => @
|
||||||
@ -231,8 +231,8 @@ def _cli_expr_on_compile_error:
|
|||||||
| halt_error(_exit_code_compile_error)
|
| halt_error(_exit_code_compile_error)
|
||||||
);
|
);
|
||||||
# _cli_expr_eval halts on compile errors
|
# _cli_expr_eval halts on compile errors
|
||||||
def _cli_expr_eval($e; f): _eval($e; f; _cli_expr_on_error; _cli_expr_on_compile_error);
|
def _cli_expr_eval($e; $filename; f): _eval($e; $filename; f; _cli_expr_on_error; _cli_expr_on_compile_error);
|
||||||
def _cli_expr_eval($e): _eval($e; .; _cli_expr_on_error; _cli_expr_on_compile_error);
|
def _cli_expr_eval($e; $filename): _eval($e; $filename; .; _cli_expr_on_error; _cli_expr_on_compile_error);
|
||||||
|
|
||||||
# next valid input
|
# next valid input
|
||||||
def input:
|
def input:
|
||||||
@ -450,10 +450,12 @@ def _main:
|
|||||||
( { null_input: ($parsed_args.null_input == true) }
|
( { null_input: ($parsed_args.null_input == true) }
|
||||||
| if $parsed_args.file then
|
| if $parsed_args.file then
|
||||||
( .expr = ($parsed_args.file | open | string)
|
( .expr = ($parsed_args.file | open | string)
|
||||||
|
| .expr_filename = $parsed_args.file
|
||||||
| .filenames = $rest
|
| .filenames = $rest
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
( .expr = ($rest[0] // ".")
|
( .expr = ($rest[0] // ".")
|
||||||
|
| .expr_filename = "arg"
|
||||||
| .filenames = $rest[1:]
|
| .filenames = $rest[1:]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -462,7 +464,7 @@ def _main:
|
|||||||
elif .filenames == [] then
|
elif .filenames == [] then
|
||||||
.filenames = ["-"]
|
.filenames = ["-"]
|
||||||
end
|
end
|
||||||
| . as {$expr, $filenames, $null_input}
|
| . as {$expr, $expr_filename, $filenames, $null_input}
|
||||||
| _include_paths([
|
| _include_paths([
|
||||||
$parsed_args.include_path // empty
|
$parsed_args.include_path // empty
|
||||||
]) as $_
|
]) as $_
|
||||||
@ -472,10 +474,10 @@ def _main:
|
|||||||
else inputs
|
else inputs
|
||||||
end
|
end
|
||||||
# will iterate zero or more inputs
|
# will iterate zero or more inputs
|
||||||
| if $parsed_args.repl then [_cli_expr_eval($expr)] | repl({}; .[])
|
| if $parsed_args.repl then [_cli_expr_eval($expr; $expr_filename)] | repl({}; .[])
|
||||||
else
|
else
|
||||||
( _cli_last_expr_error(null) as $_
|
( _cli_last_expr_error(null) as $_
|
||||||
| _cli_expr_eval($expr; _repl_display)
|
| _cli_expr_eval($expr; $expr_filename; _repl_display)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
4
pkg/interp/testdata/exitcode.fqtest
vendored
4
pkg/interp/testdata/exitcode.fqtest
vendored
@ -15,11 +15,11 @@ exitcode: 123
|
|||||||
$ fq -n invalid
|
$ fq -n invalid
|
||||||
exitcode: 3
|
exitcode: 3
|
||||||
stderr:
|
stderr:
|
||||||
error: src:1:0: function not defined: invalid/0
|
error: arg:1:0: function not defined: invalid/0
|
||||||
$ fq -n "("
|
$ fq -n "("
|
||||||
exitcode: 3
|
exitcode: 3
|
||||||
stderr:
|
stderr:
|
||||||
error: src:1:2: unexpected token <EOF>
|
error: arg:1:2: unexpected token <EOF>
|
||||||
$ fq . non-existing
|
$ fq . non-existing
|
||||||
exitcode: 2
|
exitcode: 2
|
||||||
stderr:
|
stderr:
|
||||||
|
2
pkg/interp/testdata/incudepath.fqtest
vendored
2
pkg/interp/testdata/incudepath.fqtest
vendored
@ -5,4 +5,4 @@ $ fq -L /library -n 'include "a"; a'
|
|||||||
$ fq -L /wrong -n 'include "a"; a'
|
$ fq -L /wrong -n 'include "a"; a'
|
||||||
exitcode: 3
|
exitcode: 3
|
||||||
stderr:
|
stderr:
|
||||||
error: src:1:0: open a.jq: file does not exist
|
error: arg:1:0: open a.jq: file does not exist
|
||||||
|
4
pkg/interp/testdata/inputs.fqtest
vendored
4
pkg/interp/testdata/inputs.fqtest
vendored
@ -54,11 +54,11 @@ error: /non-existing: file not found
|
|||||||
$ fq -d raw '(' /a /b /c
|
$ fq -d raw '(' /a /b /c
|
||||||
exitcode: 3
|
exitcode: 3
|
||||||
stderr:
|
stderr:
|
||||||
error: src:1:2: unexpected token <EOF>
|
error: arg:1:2: unexpected token <EOF>
|
||||||
$ fq -d raw bla /a /b /c
|
$ fq -d raw bla /a /b /c
|
||||||
exitcode: 3
|
exitcode: 3
|
||||||
stderr:
|
stderr:
|
||||||
error: src:1:0: function not defined: bla/0
|
error: arg:1:0: function not defined: bla/0
|
||||||
$ fq -d raw '1+"a"' /a /b /c
|
$ fq -d raw '1+"a"' /a /b /c
|
||||||
exitcode: 5
|
exitcode: 5
|
||||||
stderr:
|
stderr:
|
||||||
|
4
pkg/interp/testdata/repl.fqtest
vendored
4
pkg/interp/testdata/repl.fqtest
vendored
@ -2,9 +2,9 @@ $ fq -i
|
|||||||
null> 1+1
|
null> 1+1
|
||||||
2
|
2
|
||||||
null> (
|
null> (
|
||||||
error: src:1:2: unexpected token <EOF>
|
error: repl:1:2: unexpected token <EOF>
|
||||||
null> abc
|
null> abc
|
||||||
error: src:1:0: function not defined: abc/0
|
error: repl:1:0: function not defined: abc/0
|
||||||
null> 1+"a"
|
null> 1+"a"
|
||||||
error: cannot add: number (1) and string ("a")
|
error: cannot add: number (1) and string ("a")
|
||||||
null> 1 | repl
|
null> 1 | repl
|
||||||
|
2
pkg/interp/testdata/var.fqtest
vendored
2
pkg/interp/testdata/var.fqtest
vendored
@ -19,7 +19,7 @@ null> $a
|
|||||||
"aa"
|
"aa"
|
||||||
null> var("a"; empty)
|
null> var("a"; empty)
|
||||||
null> $a
|
null> $a
|
||||||
error: src:1:0: variable not defined: $a
|
error: repl:1:0: variable not defined: $a
|
||||||
null> var
|
null> var
|
||||||
{
|
{
|
||||||
"bb": "bb"
|
"bb": "bb"
|
||||||
|
Loading…
Reference in New Issue
Block a user