cue: support multierror return from Unify
Also fixes:
- file naming issue in Marshalling, which was not
relative to the module root, if available.
- gocode generated output was not checked
against golden (which was only used in gen_test.go)
Change-Id: I6a5f5363e2d0656ef3935fc46f84444ccbdd9a3e
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2942
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/builtin.go b/cue/builtin.go
index c6fc328..f7dbefa 100644
--- a/cue/builtin.go
+++ b/cue/builtin.go
@@ -359,10 +359,7 @@
}
func (c *callCtxt) errf(src source, underlying error, format string, args ...interface{}) {
- a := make([]interface{}, 0, 2+len(args))
- if underlying != nil {
- a = append(a, underlying)
- }
+ a := make([]interface{}, 0, 1+len(args))
a = append(a, format)
a = append(a, args...)
err := c.ctx.mkErr(src, a...)
diff --git a/cue/errors.go b/cue/errors.go
index b8f8436..5335733 100644
--- a/cue/errors.go
+++ b/cue/errors.go
@@ -51,6 +51,9 @@
}
func (v Value) toErr(b *bottom) errors.Error {
+ if b.err != nil {
+ return b.err
+ }
return &valueError{
v: v,
err: b,
@@ -127,12 +130,9 @@
format string
args []interface{}
- // Debugging info
+ err errors.Error // pass-through from higher-level API
value value
wrapped *bottom
-
- // TODO: file at which the error was generated in the code.
- // File positions of where the error occurred.
}
func (x *bottom) kind() kind { return bottomKind }
@@ -209,6 +209,8 @@
e.code = x
case *bottom:
e.wrapped = x
+ case errors.Error:
+ e.err = x
case value:
case string:
e.format = x
diff --git a/cue/lit.go b/cue/lit.go
index 5fecf92..6252781 100644
--- a/cue/lit.go
+++ b/cue/lit.go
@@ -181,7 +181,7 @@
src := newExpr(node)
str, err := q.Unquote(s)
if err != nil {
- return ctx.mkErr(src, err, "invalid string: %v", err)
+ return ctx.mkErr(src, "invalid string: %v", err)
}
if q.IsDouble() {
return &stringLit{src, str, nil}
diff --git a/cue/marshal.go b/cue/marshal.go
index 0feb4dd..843f018 100644
--- a/cue/marshal.go
+++ b/cue/marshal.go
@@ -159,8 +159,13 @@
filename := "unmarshal"
if i.inst != nil && len(i.inst.Files) == 1 {
filename = i.inst.Files[0].Filename
- if i.Dir != "" {
- filename, _ = filepath.Rel(i.Dir, filename)
+
+ dir := i.Dir
+ if i.inst != nil && i.inst.Root != "" {
+ dir = i.inst.Root
+ }
+ if dir != "" {
+ filename, _ = filepath.Rel(dir, filename)
}
}
diff --git a/cue/types.go b/cue/types.go
index c656759..c31a2d2 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -1242,17 +1242,7 @@
val := mkBin(ctx, src.Pos(), opUnify, a, b)
u := newValueRoot(ctx, val)
if err := u.Validate(); err != nil {
- // TODO: record all errors in a Value.
- switch x := errors.Errors(err)[0].(type) {
- case *valueError:
- p := *x.v.path
- p.v = x.err
- p.cache = x.err
- u = Value{x.v.idx, &p}
-
- default:
- u = newValueRoot(ctx, ctx.mkErr(src, err))
- }
+ u = newValueRoot(ctx, ctx.mkErr(src, err))
}
return u
}
diff --git a/encoding/gocode/gen_test.go b/encoding/gocode/gen_test.go
index 6f01c2b..d1bb8c2 100644
--- a/encoding/gocode/gen_test.go
+++ b/encoding/gocode/gen_test.go
@@ -42,7 +42,7 @@
v := &pkg1.OtherStruct{A: "car"}
return v.Validate()
}(),
- want: "A: invalid value \"car\" (does not satisfy strings.ContainsAny(\"X\")):\n pkg1/instance.cue:x:x",
+ want: "A: invalid value \"car\" (does not satisfy strings.ContainsAny(\"X\")):\n pkg1/instance.cue:x:x\nP: invalid value 0 (out of bound >5):\n pkg2/instance.cue:x:x",
}, {
name: "failing field of type int",
got: func() error {
@@ -53,7 +53,7 @@
}, {
name: "failing nested struct ",
got: func() error {
- v := &pkg1.MyStruct{A: 5, B: "dog", O: &pkg1.OtherStruct{A: "car"}}
+ v := &pkg1.MyStruct{A: 5, B: "dog", O: &pkg1.OtherStruct{A: "car", P: 6}}
return v.Validate()
}(),
want: "O.A: invalid value \"car\" (does not satisfy strings.ContainsAny(\"X\")):\n pkg1/instance.cue:x:x",
diff --git a/encoding/gocode/generator_test.go b/encoding/gocode/generator_test.go
index 70e0aa8..a4ad90a 100644
--- a/encoding/gocode/generator_test.go
+++ b/encoding/gocode/generator_test.go
@@ -26,6 +26,7 @@
"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/load"
+ "github.com/kylelemons/godebug/diff"
)
var update = flag.Bool("update", false, "update test files")
@@ -62,13 +63,21 @@
if err != nil {
t.Fatal(errStr(err))
}
- // t.Log(string(b))
goFile := filepath.Join("testdata", d.Name(), "cue_gen.go")
if *update {
_ = ioutil.WriteFile(goFile, b, 0644)
return
}
+
+ want, err := ioutil.ReadFile(goFile)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if d := diff.Diff(string(want), string(b)); d != "" {
+ t.Errorf("files differ:\n%v", d)
+ }
})
}
}