opentofu/internal/tfdiags/config_traversals.go
Martin Atkins 05caff2ca3 Move tfdiags/ to internal/tfdiags/
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.

If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
2021-05-17 14:09:07 -07:00

69 lines
1.9 KiB
Go

package tfdiags
import (
"bytes"
"fmt"
"strconv"
"github.com/zclconf/go-cty/cty"
)
// FormatCtyPath is a helper function to produce a user-friendly string
// representation of a cty.Path. The result uses a syntax similar to the
// HCL expression language in the hope of it being familiar to users.
func FormatCtyPath(path cty.Path) string {
var buf bytes.Buffer
for _, step := range path {
switch ts := step.(type) {
case cty.GetAttrStep:
fmt.Fprintf(&buf, ".%s", ts.Name)
case cty.IndexStep:
buf.WriteByte('[')
key := ts.Key
keyTy := key.Type()
switch {
case key.IsNull():
buf.WriteString("null")
case !key.IsKnown():
buf.WriteString("(not yet known)")
case keyTy == cty.Number:
bf := key.AsBigFloat()
buf.WriteString(bf.Text('g', -1))
case keyTy == cty.String:
buf.WriteString(strconv.Quote(key.AsString()))
default:
buf.WriteString("...")
}
buf.WriteByte(']')
}
}
return buf.String()
}
// FormatError is a helper function to produce a user-friendly string
// representation of certain special error types that we might want to
// include in diagnostic messages.
//
// This currently has special behavior only for cty.PathError, where a
// non-empty path is rendered in a HCL-like syntax as context.
func FormatError(err error) string {
perr, ok := err.(cty.PathError)
if !ok || len(perr.Path) == 0 {
return err.Error()
}
return fmt.Sprintf("%s: %s", FormatCtyPath(perr.Path), perr.Error())
}
// FormatErrorPrefixed is like FormatError except that it presents any path
// information after the given prefix string, which is assumed to contain
// an HCL syntax representation of the value that errors are relative to.
func FormatErrorPrefixed(err error, prefix string) string {
perr, ok := err.(cty.PathError)
if !ok || len(perr.Path) == 0 {
return fmt.Sprintf("%s: %s", prefix, err.Error())
}
return fmt.Sprintf("%s%s: %s", prefix, FormatCtyPath(perr.Path), perr.Error())
}