diff --git a/tfdiags/contextual.go b/tfdiags/contextual.go index de392c54b..f53a4d1e2 100644 --- a/tfdiags/contextual.go +++ b/tfdiags/contextual.go @@ -80,6 +80,19 @@ func AttributeValue(severity Severity, summary, detail string, attrPath cty.Path } } +// GetAttribute extracts an attribute cty.Path from a diagnostic if it contains +// one. Normally this is not accessed directly, and instead the config body is +// added to the Diagnostic to create a more complete message for the user. In +// some cases however, we may want to know just the name of the attribute that +// generated the Diagnostic message. +// This returns a nil cty.Path if it does not exist in the Diagnostic. +func GetAttribute(d Diagnostic) cty.Path { + if d, ok := d.(*attributeDiagnostic); ok { + return d.attrPath + } + return nil +} + type attributeDiagnostic struct { diagnosticBase attrPath cty.Path diff --git a/tfdiags/contextual_test.go b/tfdiags/contextual_test.go index 4171c7c84..45c678cb1 100644 --- a/tfdiags/contextual_test.go +++ b/tfdiags/contextual_test.go @@ -1,6 +1,7 @@ package tfdiags import ( + "reflect" "testing" "github.com/go-test/deep" @@ -137,3 +138,23 @@ baz "b" { t.Error(problem) } } + +func TestGetAttribute(t *testing.T) { + path := cty.Path{ + cty.GetAttrStep{Name: "foo"}, + cty.IndexStep{Key: cty.NumberIntVal(0)}, + cty.GetAttrStep{Name: "bar"}, + } + + d := AttributeValue( + Error, + "foo[0].bar", + "detail", + path, + ) + + p := GetAttribute(d) + if !reflect.DeepEqual(path, p) { + t.Fatalf("paths don't match:\nexpected: %#v\ngot: %#v", path, p) + } +}