From 135cae64def1ebb796b1dc640ac13abd89017f5e Mon Sep 17 00:00:00 2001 From: aq17 Date: Thu, 1 Dec 2022 13:42:28 -0800 Subject: [PATCH] feedback --- ...invalid-enum-values-on-pulumi-convert.yaml | 2 +- pkg/codegen/pcl/binder_schema.go | 55 +++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/changelog/pending/20221201--programgen--improve-error-message-for-invalid-enum-values-on-pulumi-convert.yaml b/changelog/pending/20221201--programgen--improve-error-message-for-invalid-enum-values-on-pulumi-convert.yaml index ec1617a13af5..1b8b163cc48a 100644 --- a/changelog/pending/20221201--programgen--improve-error-message-for-invalid-enum-values-on-pulumi-convert.yaml +++ b/changelog/pending/20221201--programgen--improve-error-message-for-invalid-enum-values-on-pulumi-convert.yaml @@ -1,4 +1,4 @@ changes: -- type: chore +- type: fix scope: programgen description: Improve error message for invalid enum values on `pulumi convert`. diff --git a/pkg/codegen/pcl/binder_schema.go b/pkg/codegen/pcl/binder_schema.go index fd8a5565ee76..bf859b7c3d85 100644 --- a/pkg/codegen/pcl/binder_schema.go +++ b/pkg/codegen/pcl/binder_schema.go @@ -16,6 +16,7 @@ package pcl import ( "fmt" + "strings" "sync" "github.com/blang/semver" @@ -499,11 +500,10 @@ func getDiscriminatedUnionObjectItem(t model.Type) (string, model.Type) { // no member if found, (nil, true) returned. If the query is nonsensical, either // because no schema is associated with the EnumMember or if the type of value // mismatches the type of the schema, (nil, false) is returned. -func EnumMember(t *model.EnumType, value cty.Value) (*schema.Enum, []interface{}, bool) { - validMembers := make([]interface{}, 0) +func EnumMember(t *model.EnumType, value cty.Value) (*schema.Enum, bool) { srcBase, ok := GetSchemaForType(t) if !ok { - return nil, validMembers, false + return nil, false } src := srcBase.(*schema.EnumType) @@ -513,31 +513,28 @@ func EnumMember(t *model.EnumType, value cty.Value) (*schema.Enum, []interface{} for _, el := range src.Elements { v := el.Value.(string) if v == s { - return el, validMembers, true + return el, true } - validMembers = append(validMembers, v) } - return nil, validMembers, true + return nil, true case t.Type.Equals(model.NumberType): f, _ := value.AsBigFloat().Float64() for _, el := range src.Elements { if el.Value.(float64) == f { - return el, validMembers, true + return el, true } - validMembers = append(validMembers, f) } - return nil, validMembers, true + return nil, true case t.Type.Equals(model.IntType): f, _ := value.AsBigFloat().Int64() for _, el := range src.Elements { if el.Value.(int64) == f { - return el, validMembers, true + return el, true } - validMembers = append(validMembers, f) } - return nil, validMembers, true + return nil, true default: - return nil, validMembers, false + return nil, false } } @@ -566,7 +563,7 @@ func GenEnum( if known != cty.NilVal { // If the value is known, but we can't find a member, we should have // indicated a conversion is impossible when type checking. - member, validMembers, ok := EnumMember(t, known) + member, ok := EnumMember(t, known) contract.Assertf(ok, "We have determined %s is a safe enum, which we define as "+ "being able to calculate a member for", t) @@ -574,10 +571,11 @@ func GenEnum( safeEnum(member) } else { unsafeEnum(from) + knownVal := strings.Split(strings.Split(known.GoString(), "(")[1], ")")[0] return &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: fmt.Sprintf("\"%v\" is not a valid value of the enum \"%v\"", known.GoString(), t.Token), - Detail: fmt.Sprintf("Valid members are: %v", validMembers), + Summary: fmt.Sprintf("%v is not a valid value of the enum \"%v\"", knownVal, t.Token), + Detail: fmt.Sprintf("Valid members are %v", listToString(enumMemberValues(t))), } } } else { @@ -585,3 +583,28 @@ func GenEnum( } return nil } + +func enumMemberValues(t *model.EnumType) []interface{} { + srcBase, ok := GetSchemaForType(t) + if !ok { + return nil + } + src := srcBase.(*schema.EnumType) + members := make([]interface{}, len(src.Elements)) + for i, el := range src.Elements { + members[i] = el.Value + } + return members +} + +func listToString(l []interface{}) string { + vals := "" + for i, v := range l { + if i == 0 { + vals = fmt.Sprintf("\"%v\"", v) + } else { + vals = fmt.Sprintf("%s, \"%v\"", vals, v) + } + } + return vals +}