cue/errors: change API to accept localization hooks
prepare for localizable errors
Issue #52
Change-Id: I6f5b4a7d1151b041bb1a73bd4ed32f2a79acd27a
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2211
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cmd/cue/cmd/cmd_test.go b/cmd/cue/cmd/cmd_test.go
index 5defa9f..e892730 100644
--- a/cmd/cue/cmd/cmd_test.go
+++ b/cmd/cue/cmd/cmd_test.go
@@ -48,7 +48,7 @@
}
err = executeTasks("command", name, tools)
if err != nil {
- errors.Print(stdout, err)
+ errors.Print(stdout, err, nil)
}
return nil
}
diff --git a/cmd/cue/cmd/common.go b/cmd/cue/cmd/common.go
index 7d23861..3ed7383 100644
--- a/cmd/cue/cmd/common.go
+++ b/cmd/cue/cmd/common.go
@@ -16,6 +16,7 @@
import (
"bytes"
+ "io"
"os"
"cuelang.org/go/cue"
@@ -23,7 +24,10 @@
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/load"
"cuelang.org/go/cue/parser"
+ "github.com/cloudfoundry-attic/jibber_jabber"
"github.com/spf13/cobra"
+ "golang.org/x/text/language"
+ "golang.org/x/text/message"
)
var runtime = &cue.Runtime{}
@@ -41,8 +45,15 @@
cwd = p
}
+ // Link x/text as our localizer.
+ lang, _ := jibber_jabber.DetectIETF()
+ p := message.NewPrinter(language.Make(lang))
+ format := func(w io.Writer, format string, args ...interface{}) {
+ p.Fprintf(w, format, args...)
+ }
+
w := &bytes.Buffer{}
- errors.Print(w, err)
+ errors.Print(w, err, &errors.Config{Format: format})
// TODO: do something more principled than this.
b := w.Bytes()
diff --git a/cmd/cue/cmd/common_test.go b/cmd/cue/cmd/common_test.go
index 2920aec..6a44a37 100644
--- a/cmd/cue/cmd/common_test.go
+++ b/cmd/cue/cmd/common_test.go
@@ -72,9 +72,9 @@
switch err := recover().(type) {
case nil:
case panicError:
- errors.Print(wOut, err.Err)
+ errors.Print(wOut, err.Err, nil)
case error:
- errors.Print(wOut, err)
+ errors.Print(wOut, err, nil)
default:
fmt.Fprintln(wOut, err)
}
diff --git a/cue/ast_test.go b/cue/ast_test.go
index c46f4e7..95b96ca 100644
--- a/cue/ast_test.go
+++ b/cue/ast_test.go
@@ -253,7 +253,7 @@
ctx, root, errs := compileFileWithErrors(t, tc.in)
buf := &bytes.Buffer{}
if len(errs) > 0 {
- errors.Print(buf, errs)
+ errors.Print(buf, errs, nil)
}
buf.WriteString(debugStr(ctx, root))
got := buf.String()
diff --git a/cue/errors/errors.go b/cue/errors/errors.go
index 652c0cd..32b3770 100644
--- a/cue/errors/errors.go
+++ b/cue/errors/errors.go
@@ -324,24 +324,42 @@
return p
}
+// A Config defines parameters for printing.
+type Config struct {
+ // Format formats the given string and arguments and writes it to w.
+ // It is used for all printing.
+ Format func(w io.Writer, format string, args ...interface{})
+}
+
// Print is a utility function that prints a list of errors to w,
// one error per line, if the err parameter is an List. Otherwise
// it prints the err string.
//
-func Print(w io.Writer, err error) {
+func Print(w io.Writer, err error, cfg *Config) {
+ if cfg == nil {
+ cfg = &Config{}
+ }
if list, ok := err.(List); ok {
for _, e := range list {
- printError(w, e)
+ printError(w, e, cfg)
}
} else if err != nil {
- printError(w, err)
+ printError(w, err, cfg)
}
}
-func printError(w io.Writer, err error) {
+func defaultFprintf(w io.Writer, format string, args ...interface{}) {
+ fmt.Fprintf(w, format, args...)
+}
+
+func printError(w io.Writer, err error, cfg *Config) {
if err == nil {
return
}
+ fprintf := cfg.Format
+ if fprintf == nil {
+ fprintf = defaultFprintf
+ }
positions := []string{}
@@ -361,19 +379,19 @@
}
}
- if p := Path(err); p != nil {
- fmt.Fprintf(w, "%v:", strings.Join(p, "."))
+ if path := Path(err); path != nil {
+ fprintf(w, "%s:", strings.Join(path, "."))
}
if len(positions) == 0 {
- fmt.Fprintln(w, err)
+ fprintf(w, "%v\n", err)
return
}
unique.Strings(&positions)
- fmt.Fprintf(w, "%v:\n", err)
+ fprintf(w, "%v:\n", err)
for _, pos := range positions {
- fmt.Fprintf(w, " %v\n", pos)
+ fprintf(w, " %s\n", pos)
}
}
diff --git a/cue/errors/errors_test.go b/cue/errors/errors_test.go
index 2f124a4..f670cd8 100644
--- a/cue/errors/errors_test.go
+++ b/cue/errors/errors_test.go
@@ -184,7 +184,7 @@
}
for _, tt := range tests {
w := &bytes.Buffer{}
- Print(w, tt.args.err)
+ Print(w, tt.args.err, nil)
if gotW := w.String(); gotW != tt.wantW {
t.Errorf("%q. PrintError() = %v, want %v", tt.name, gotW, tt.wantW)
}
diff --git a/cue/scanner/scanner_test.go b/cue/scanner/scanner_test.go
index 0e0ad45..9fc91d0 100644
--- a/cue/scanner/scanner_test.go
+++ b/cue/scanner/scanner_test.go
@@ -662,19 +662,19 @@
if len(list) != 9 {
t.Errorf("found %d raw errors, expected 9", len(list))
- errors.Print(os.Stderr, list)
+ errors.Print(os.Stderr, list, nil)
}
list.Sort()
if len(list) != 9 {
t.Errorf("found %d sorted errors, expected 9", len(list))
- errors.Print(os.Stderr, list)
+ errors.Print(os.Stderr, list, nil)
}
list.RemoveMultiples()
if len(list) != 4 {
t.Errorf("found %d one-per-line errors, expected 4", len(list))
- errors.Print(os.Stderr, list)
+ errors.Print(os.Stderr, list, nil)
}
}
diff --git a/go.mod b/go.mod
index 51bfbf7..f1868aa 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,7 @@
module cuelang.org/go
require (
+ github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
github.com/cockroachdb/apd v1.1.0
github.com/emicklei/proto v1.6.11
github.com/ghodss/yaml v1.0.0
@@ -15,6 +16,7 @@
github.com/spf13/pflag v1.0.3
golang.org/x/exp/errors v0.0.0-20181221233300-b68661188fbf
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f
+ golang.org/x/text v0.3.2
golang.org/x/tools v0.0.0-20181210225255-6a3e9aa2ab77
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373
gopkg.in/yaml.v2 v2.2.2 // indirect
diff --git a/go.sum b/go.sum
index d768393..cd33d74 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:Yg2hDs4b13Evkpj42FU2idX2cVXVFqQSheXYKM86Qsk=
+github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:MgJyK38wkzZbiZSKeIeFankxxSA8gayko/nr5x5bgBA=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -43,6 +45,9 @@
golang.org/x/lint v0.0.0-20181011164241-5906bd5c48cd/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181018182439-def26773749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181210225255-6a3e9aa2ab77 h1:s+6psEFi3o1QryeA/qyvUoVaHMCQkYVvZ0i2ZolwSJc=
golang.org/x/tools v0.0.0-20181210225255-6a3e9aa2ab77/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=