diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/tfdiags/config_traversals.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/tfdiags/config_traversals.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/tfdiags/config_traversals.go b/vendor/github.com/hashicorp/terraform/tfdiags/config_traversals.go new file mode 100644 index 0000000..8e41f46 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/tfdiags/config_traversals.go | |||
@@ -0,0 +1,68 @@ | |||
1 | package tfdiags | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "fmt" | ||
6 | "strconv" | ||
7 | |||
8 | "github.com/zclconf/go-cty/cty" | ||
9 | ) | ||
10 | |||
11 | // FormatCtyPath is a helper function to produce a user-friendly string | ||
12 | // representation of a cty.Path. The result uses a syntax similar to the | ||
13 | // HCL expression language in the hope of it being familiar to users. | ||
14 | func FormatCtyPath(path cty.Path) string { | ||
15 | var buf bytes.Buffer | ||
16 | for _, step := range path { | ||
17 | switch ts := step.(type) { | ||
18 | case cty.GetAttrStep: | ||
19 | fmt.Fprintf(&buf, ".%s", ts.Name) | ||
20 | case cty.IndexStep: | ||
21 | buf.WriteByte('[') | ||
22 | key := ts.Key | ||
23 | keyTy := key.Type() | ||
24 | switch { | ||
25 | case key.IsNull(): | ||
26 | buf.WriteString("null") | ||
27 | case !key.IsKnown(): | ||
28 | buf.WriteString("(not yet known)") | ||
29 | case keyTy == cty.Number: | ||
30 | bf := key.AsBigFloat() | ||
31 | buf.WriteString(bf.Text('g', -1)) | ||
32 | case keyTy == cty.String: | ||
33 | buf.WriteString(strconv.Quote(key.AsString())) | ||
34 | default: | ||
35 | buf.WriteString("...") | ||
36 | } | ||
37 | buf.WriteByte(']') | ||
38 | } | ||
39 | } | ||
40 | return buf.String() | ||
41 | } | ||
42 | |||
43 | // FormatError is a helper function to produce a user-friendly string | ||
44 | // representation of certain special error types that we might want to | ||
45 | // include in diagnostic messages. | ||
46 | // | ||
47 | // This currently has special behavior only for cty.PathError, where a | ||
48 | // non-empty path is rendered in a HCL-like syntax as context. | ||
49 | func FormatError(err error) string { | ||
50 | perr, ok := err.(cty.PathError) | ||
51 | if !ok || len(perr.Path) == 0 { | ||
52 | return err.Error() | ||
53 | } | ||
54 | |||
55 | return fmt.Sprintf("%s: %s", FormatCtyPath(perr.Path), perr.Error()) | ||
56 | } | ||
57 | |||
58 | // FormatErrorPrefixed is like FormatError except that it presents any path | ||
59 | // information after the given prefix string, which is assumed to contain | ||
60 | // an HCL syntax representation of the value that errors are relative to. | ||
61 | func FormatErrorPrefixed(err error, prefix string) string { | ||
62 | perr, ok := err.(cty.PathError) | ||
63 | if !ok || len(perr.Path) == 0 { | ||
64 | return fmt.Sprintf("%s: %s", prefix, err.Error()) | ||
65 | } | ||
66 | |||
67 | return fmt.Sprintf("%s%s: %s", prefix, FormatCtyPath(perr.Path), perr.Error()) | ||
68 | } | ||