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{"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{"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 {
|
||||
var err error
|
||||
src, err := toString(a[0])
|
||||
if err != nil {
|
||||
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 {
|
||||
return gojq.NewIter(err)
|
||||
}
|
||||
|
@ -54,10 +54,11 @@ type compileError struct {
|
||||
|
||||
func (ce compileError) Value() interface{} {
|
||||
return map[string]interface{}{
|
||||
"error": ce.err.Error(),
|
||||
"what": ce.what,
|
||||
"line": ce.pos.Line,
|
||||
"column": ce.pos.Column,
|
||||
"error": ce.err.Error(),
|
||||
"what": ce.what,
|
||||
"filename": ce.filename,
|
||||
"line": ce.pos.Line,
|
||||
"column": ce.pos.Column,
|
||||
}
|
||||
}
|
||||
func (ee compileError) Error() string {
|
||||
@ -540,7 +541,7 @@ func (i *Interp) Main(ctx context.Context, stdout io.Writer, version string) err
|
||||
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
|
||||
// TODO: did not work
|
||||
// nq := &(*q)
|
||||
@ -549,9 +550,10 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
||||
if err != nil {
|
||||
p := queryErrorPosition(err)
|
||||
return nil, compileError{
|
||||
err: err,
|
||||
what: "parse",
|
||||
pos: p,
|
||||
err: err,
|
||||
what: "parse",
|
||||
filename: filename,
|
||||
pos: p,
|
||||
}
|
||||
}
|
||||
|
||||
@ -692,7 +694,7 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
||||
return nil, compileError{
|
||||
err: err,
|
||||
what: "parse",
|
||||
filename: filename,
|
||||
filename: filenamePart,
|
||||
pos: p,
|
||||
}
|
||||
}
|
||||
@ -712,9 +714,10 @@ func (i *Interp) Eval(ctx context.Context, mode RunMode, c interface{}, src stri
|
||||
if err != nil {
|
||||
p := queryErrorPosition(err)
|
||||
return nil, compileError{
|
||||
err: err,
|
||||
what: "compile",
|
||||
pos: p,
|
||||
err: err,
|
||||
what: "compile",
|
||||
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
|
||||
// {input: ..., args: [...]} | .args as {args: $_args} | .input | name[($_args[0]; ...)]
|
||||
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 {
|
||||
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:
|
||||
"\(.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 $_
|
||||
| try eval($e) | f
|
||||
| try eval($e; $filename) | f
|
||||
catch
|
||||
if _eval_is_compile_error then on_compile_error
|
||||
else on_error
|
||||
@ -184,7 +184,7 @@ def _repl_on_error:
|
||||
| (_error_str | println)
|
||||
);
|
||||
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
|
||||
def repl($opts; iter): #:: a|(Opts) => @
|
||||
@ -231,8 +231,8 @@ def _cli_expr_on_compile_error:
|
||||
| halt_error(_exit_code_compile_error)
|
||||
);
|
||||
# _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): _eval($e; .; _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; $filename): _eval($e; $filename; .; _cli_expr_on_error; _cli_expr_on_compile_error);
|
||||
|
||||
# next valid input
|
||||
def input:
|
||||
@ -450,10 +450,12 @@ def _main:
|
||||
( { null_input: ($parsed_args.null_input == true) }
|
||||
| if $parsed_args.file then
|
||||
( .expr = ($parsed_args.file | open | string)
|
||||
| .expr_filename = $parsed_args.file
|
||||
| .filenames = $rest
|
||||
)
|
||||
else
|
||||
( .expr = ($rest[0] // ".")
|
||||
| .expr_filename = "arg"
|
||||
| .filenames = $rest[1:]
|
||||
)
|
||||
end
|
||||
@ -462,7 +464,7 @@ def _main:
|
||||
elif .filenames == [] then
|
||||
.filenames = ["-"]
|
||||
end
|
||||
| . as {$expr, $filenames, $null_input}
|
||||
| . as {$expr, $expr_filename, $filenames, $null_input}
|
||||
| _include_paths([
|
||||
$parsed_args.include_path // empty
|
||||
]) as $_
|
||||
@ -472,10 +474,10 @@ def _main:
|
||||
else inputs
|
||||
end
|
||||
# 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
|
||||
( _cli_last_expr_error(null) as $_
|
||||
| _cli_expr_eval($expr; _repl_display)
|
||||
| _cli_expr_eval($expr; $expr_filename; _repl_display)
|
||||
)
|
||||
end
|
||||
)
|
||||
|
4
pkg/interp/testdata/exitcode.fqtest
vendored
4
pkg/interp/testdata/exitcode.fqtest
vendored
@ -15,11 +15,11 @@ exitcode: 123
|
||||
$ fq -n invalid
|
||||
exitcode: 3
|
||||
stderr:
|
||||
error: src:1:0: function not defined: invalid/0
|
||||
error: arg:1:0: function not defined: invalid/0
|
||||
$ fq -n "("
|
||||
exitcode: 3
|
||||
stderr:
|
||||
error: src:1:2: unexpected token <EOF>
|
||||
error: arg:1:2: unexpected token <EOF>
|
||||
$ fq . non-existing
|
||||
exitcode: 2
|
||||
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'
|
||||
exitcode: 3
|
||||
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
|
||||
exitcode: 3
|
||||
stderr:
|
||||
error: src:1:2: unexpected token <EOF>
|
||||
error: arg:1:2: unexpected token <EOF>
|
||||
$ fq -d raw bla /a /b /c
|
||||
exitcode: 3
|
||||
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
|
||||
exitcode: 5
|
||||
stderr:
|
||||
|
4
pkg/interp/testdata/repl.fqtest
vendored
4
pkg/interp/testdata/repl.fqtest
vendored
@ -2,9 +2,9 @@ $ fq -i
|
||||
null> 1+1
|
||||
2
|
||||
null> (
|
||||
error: src:1:2: unexpected token <EOF>
|
||||
error: repl:1:2: unexpected token <EOF>
|
||||
null> abc
|
||||
error: src:1:0: function not defined: abc/0
|
||||
error: repl:1:0: function not defined: abc/0
|
||||
null> 1+"a"
|
||||
error: cannot add: number (1) and string ("a")
|
||||
null> 1 | repl
|
||||
|
2
pkg/interp/testdata/var.fqtest
vendored
2
pkg/interp/testdata/var.fqtest
vendored
@ -19,7 +19,7 @@ null> $a
|
||||
"aa"
|
||||
null> var("a"; empty)
|
||||
null> $a
|
||||
error: src:1:0: variable not defined: $a
|
||||
error: repl:1:0: variable not defined: $a
|
||||
null> var
|
||||
{
|
||||
"bb": "bb"
|
||||
|
Loading…
Reference in New Issue
Block a user