diff --git a/cmd/cue/cmd/eval.go b/cmd/cue/cmd/eval.go index 2820eedcfc5..e73cf57e644 100644 --- a/cmd/cue/cmd/eval.go +++ b/cmd/cue/cmd/eval.go @@ -93,6 +93,7 @@ func runEval(cmd *Command, args []string) error { cue.Definitions(true), cue.Attributes(flagAttributes.Bool(cmd)), cue.Optional(flagAll.Bool(cmd) || flagOptional.Bool(cmd)), + cue.ErrorsAsValues(flagIgnore.Bool(cmd)), } // Keep for legacy reasons. Note that `cue eval` is to be deprecated by @@ -143,18 +144,21 @@ func runEval(cmd *Command, args []string) error { b, _ := format.Node(b.expressions[i%len(b.expressions)]) id = string(b) } - if err := v.Err(); err != nil { - errHeader() - return v.Validate(syn...) - } - // TODO(#553): this can be removed once v.Syntax() below retains line - // information. - if (e.IsConcrete() || flagConcrete.Bool(cmd)) && !flagIgnore.Bool(cmd) { - if err := v.Validate(cue.Concrete(true)); err != nil { + if !flagIgnore.Bool(cmd) { + if err := v.Err(); err != nil { errHeader() - exitOnErr(cmd, err, false) - continue + return v.Validate(syn...) + } + + // TODO(#553): this can be removed once v.Syntax() below retains line + // information. + if e.IsConcrete() || flagConcrete.Bool(cmd) { + if err := v.Validate(cue.Concrete(true)); err != nil { + errHeader() + exitOnErr(cmd, err, false) + continue + } } } diff --git a/cmd/cue/cmd/testdata/script/eval_ignore.txtar b/cmd/cue/cmd/testdata/script/eval_ignore.txtar new file mode 100644 index 00000000000..702acf9e096 --- /dev/null +++ b/cmd/cue/cmd/testdata/script/eval_ignore.txtar @@ -0,0 +1,20 @@ +exec cue eval -i in.cue +cmp stdout expect/stdout + +# Issue #1981 +# Issue #1786 +-- in.cue -- +a: 4 +a: 5 + +l: [ 1, 2 ] +l: [ 1, 3 ] + +list: [0, 1, 2] +val: list[3] + +-- expect/stdout -- +a: _|_ // a: conflicting values 5 and 4 +l: [1, _|_] +list: [0, 1, 2] +val: _|_ // val: index out of range [3] with length 3 diff --git a/cue/types.go b/cue/types.go index fc0f35b3557..702736bdbd5 100644 --- a/cue/types.go +++ b/cue/types.go @@ -2137,6 +2137,14 @@ func ResolveReferences(resolve bool) Option { } } +// ErrorsAsValues treats errors as a regular value, including them at the +// location in the tree where they occur, instead of interpreting them as a +// configuration-wide failure that is returned instead of root value. +// Used by Syntax. +func ErrorsAsValues(show bool) Option { + return func(p *options) { p.showErrors = show } +} + // Raw tells Syntax to generate the value as is without any simplifications. func Raw() Option { return func(p *options) { p.raw = true }