Skip to content

Commit b13d310

Browse files
authored
Add code generation for collection and object attributes with associated external type (#75)
* Adding generation of custom type and value type with to/from methods for data source list attribute (#74) * Adding tests for list attribute imports, schema, and model field (#74) * Adding generation of custom type and value type, and to/from methods for set attribute for data source, and list, and set attribute for provider and resource (#74) * Adding generation of custom type and value type, and to/from methods for map attribute for data source, provider and resource (#74) * Refactoring import, schema, and model field methods on object attribute to use associated external type (#74) * Refactoring to use nested object as reference to object within list, map, set, single nested attribute, or list, set, single nested block (#74) * Add custom type and value type, and to/from method generation for object attribute for data source, provider, and resource (#74) * Removing hardcoded attribute names (#74) * Adding changelog entry (#74) * Fixing value types (#74) * Return unknown if error diagnostic is raised during From() method (#74) * Bumping to latest version of codegen-spec (#74) * Fixing handling of generated To() method for object attribute (#74)
1 parent 027727c commit b13d310

File tree

168 files changed

+9163
-1413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

168 files changed

+9163
-1413
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: ENHANCEMENTS
2+
body: Adds code generation for List, Map, Object, and Set attributes that have an
3+
associated external type
4+
time: 2023-10-23T18:00:06.752758+01:00
5+
custom:
6+
Issue: "75"

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ go 1.20
44

55
require (
66
github.com/google/go-cmp v0.6.0
7-
github.com/hashicorp/terraform-plugin-codegen-spec v0.1.1-0.20231019064449-867ccf6fb279
7+
github.com/hashicorp/terraform-plugin-codegen-spec v0.1.1-0.20231024091233-c659ac8a54fc
88
github.com/hashicorp/terraform-plugin-framework v1.4.0
9+
github.com/hashicorp/terraform-plugin-go v0.19.0
910
github.com/mattn/go-colorable v0.1.12
1011
github.com/mitchellh/cli v1.1.5
1112
)
@@ -21,7 +22,6 @@ require (
2122
github.com/hashicorp/errwrap v1.0.0 // indirect
2223
github.com/hashicorp/go-hclog v1.5.0 // indirect
2324
github.com/hashicorp/go-multierror v1.0.0 // indirect
24-
github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect
2525
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
2626
github.com/huandu/xstrings v1.3.2 // indirect
2727
github.com/imdario/mergo v0.3.11 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+
2525
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
2626
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
2727
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
28-
github.com/hashicorp/terraform-plugin-codegen-spec v0.1.1-0.20231019064449-867ccf6fb279 h1:9D8ydY5s8Fw76pqCFtwlm9X7wVJdFLMK2FAqyQoOZT0=
29-
github.com/hashicorp/terraform-plugin-codegen-spec v0.1.1-0.20231019064449-867ccf6fb279/go.mod h1:PQn6bDD8UWoAVJoHXqFk2i/RmLbeQBjbiP38i+E+YIw=
28+
github.com/hashicorp/terraform-plugin-codegen-spec v0.1.1-0.20231024091233-c659ac8a54fc h1:VmMk5vOSJgpWOuBsI4ZBZkcsrkLq0fKoyKvKFnbBuxk=
29+
github.com/hashicorp/terraform-plugin-codegen-spec v0.1.1-0.20231024091233-c659ac8a54fc/go.mod h1:PQn6bDD8UWoAVJoHXqFk2i/RmLbeQBjbiP38i+E+YIw=
3030
github.com/hashicorp/terraform-plugin-framework v1.4.0 h1:WKbtCRtNrjsh10eA7NZvC/Qyr7zp77j+D21aDO5th9c=
3131
github.com/hashicorp/terraform-plugin-framework v1.4.0/go.mod h1:XC0hPcQbBvlbxwmjxuV/8sn8SbZRg4XwGMs22f+kqV0=
3232
github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU=

internal/datasource_convert/list_attribute.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
1111

1212
"github.com/hashicorp/terraform-plugin-codegen-framework/internal/datasource_generate"
13+
generatorschema "github.com/hashicorp/terraform-plugin-codegen-framework/internal/schema"
1314
)
1415

1516
func convertListAttribute(a *datasource.ListAttribute) (datasource_generate.GeneratorListAttribute, error) {
@@ -28,8 +29,9 @@ func convertListAttribute(a *datasource.ListAttribute) (datasource_generate.Gene
2829
DeprecationMessage: deprecationMessage(a.DeprecationMessage),
2930
},
3031

31-
CustomType: a.CustomType,
32-
ElementType: a.ElementType,
33-
Validators: a.Validators,
32+
AssociatedExternalType: generatorschema.NewAssocExtType(a.AssociatedExternalType),
33+
CustomType: a.CustomType,
34+
ElementType: a.ElementType,
35+
Validators: a.Validators,
3436
}, nil
3537
}

internal/datasource_convert/map_attribute.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
1111

1212
"github.com/hashicorp/terraform-plugin-codegen-framework/internal/datasource_generate"
13+
generatorschema "github.com/hashicorp/terraform-plugin-codegen-framework/internal/schema"
1314
)
1415

1516
func convertMapAttribute(a *datasource.MapAttribute) (datasource_generate.GeneratorMapAttribute, error) {
@@ -28,8 +29,9 @@ func convertMapAttribute(a *datasource.MapAttribute) (datasource_generate.Genera
2829
DeprecationMessage: deprecationMessage(a.DeprecationMessage),
2930
},
3031

31-
CustomType: a.CustomType,
32-
ElementType: a.ElementType,
33-
Validators: a.Validators,
32+
AssociatedExternalType: generatorschema.NewAssocExtType(a.AssociatedExternalType),
33+
CustomType: a.CustomType,
34+
ElementType: a.ElementType,
35+
Validators: a.Validators,
3436
}, nil
3537
}

internal/datasource_convert/object_attribute.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,28 @@ import (
1010
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
1111

1212
"github.com/hashicorp/terraform-plugin-codegen-framework/internal/datasource_generate"
13+
generatorschema "github.com/hashicorp/terraform-plugin-codegen-framework/internal/schema"
1314
)
1415

15-
func convertObjectAttribute(o *datasource.ObjectAttribute) (datasource_generate.GeneratorObjectAttribute, error) {
16-
if o == nil {
16+
func convertObjectAttribute(a *datasource.ObjectAttribute) (datasource_generate.GeneratorObjectAttribute, error) {
17+
if a == nil {
1718
return datasource_generate.GeneratorObjectAttribute{}, fmt.Errorf("*datasource.ObjectAttribute is nil")
1819
}
1920

2021
return datasource_generate.GeneratorObjectAttribute{
2122
ObjectAttribute: schema.ObjectAttribute{
22-
Required: isRequired(o.ComputedOptionalRequired),
23-
Optional: isOptional(o.ComputedOptionalRequired),
24-
Computed: isComputed(o.ComputedOptionalRequired),
25-
Sensitive: isSensitive(o.Sensitive),
26-
Description: description(o.Description),
27-
MarkdownDescription: description(o.Description),
28-
DeprecationMessage: deprecationMessage(o.DeprecationMessage),
23+
Required: isRequired(a.ComputedOptionalRequired),
24+
Optional: isOptional(a.ComputedOptionalRequired),
25+
Computed: isComputed(a.ComputedOptionalRequired),
26+
Sensitive: isSensitive(a.Sensitive),
27+
Description: description(a.Description),
28+
MarkdownDescription: description(a.Description),
29+
DeprecationMessage: deprecationMessage(a.DeprecationMessage),
2930
},
3031

31-
AttributeTypes: o.AttributeTypes,
32-
CustomType: o.CustomType,
33-
Validators: o.Validators,
32+
AssociatedExternalType: generatorschema.NewAssocExtType(a.AssociatedExternalType),
33+
AttributeTypes: a.AttributeTypes,
34+
CustomType: a.CustomType,
35+
Validators: a.Validators,
3436
}, nil
3537
}

internal/datasource_convert/set_attribute.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
1111

1212
"github.com/hashicorp/terraform-plugin-codegen-framework/internal/datasource_generate"
13+
generatorschema "github.com/hashicorp/terraform-plugin-codegen-framework/internal/schema"
1314
)
1415

1516
func convertSetAttribute(a *datasource.SetAttribute) (datasource_generate.GeneratorSetAttribute, error) {
@@ -28,8 +29,9 @@ func convertSetAttribute(a *datasource.SetAttribute) (datasource_generate.Genera
2829
DeprecationMessage: deprecationMessage(a.DeprecationMessage),
2930
},
3031

31-
CustomType: a.CustomType,
32-
ElementType: a.ElementType,
33-
Validators: a.Validators,
32+
AssociatedExternalType: generatorschema.NewAssocExtType(a.AssociatedExternalType),
33+
CustomType: a.CustomType,
34+
ElementType: a.ElementType,
35+
Validators: a.Validators,
3436
}, nil
3537
}

internal/datasource_generate/embed.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ var float64AttributeTemplate string
1919
var int64AttributeTemplate string
2020

2121
//go:embed templates/list_attribute.gotmpl
22-
var listAttributeGoTemplate string
22+
var listAttributeTemplate string
2323

2424
//go:embed templates/list_nested_attribute.gotmpl
2525
var listNestedAttributeGoTemplate string
2626

2727
//go:embed templates/map_attribute.gotmpl
28-
var mapAttributeGoTemplate string
28+
var mapAttributeTemplate string
2929

3030
//go:embed templates/map_nested_attribute.gotmpl
3131
var mapNestedAttributeGoTemplate string
@@ -34,10 +34,10 @@ var mapNestedAttributeGoTemplate string
3434
var numberAttributeTemplate string
3535

3636
//go:embed templates/object_attribute.gotmpl
37-
var objectAttributeGoTemplate string
37+
var objectAttributeTemplate string
3838

3939
//go:embed templates/set_attribute.gotmpl
40-
var setAttributeGoTemplate string
40+
var setAttributeTemplate string
4141

4242
//go:embed templates/set_nested_attribute.gotmpl
4343
var setNestedAttributeGoTemplate string

internal/datasource_generate/list_attribute.go

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package datasource_generate
55

66
import (
7+
"bytes"
8+
"fmt"
79
"strings"
810
"text/template"
911

@@ -17,6 +19,7 @@ import (
1719
type GeneratorListAttribute struct {
1820
schema.ListAttribute
1921

22+
AssociatedExternalType *generatorschema.AssocExtType
2023
// The "specschema" types are used instead of the types within the attribute
2124
// because support for extracting custom import information is required.
2225
CustomType *specschema.CustomType
@@ -46,6 +49,12 @@ func (g GeneratorListAttribute) Imports() *generatorschema.Imports {
4649
imports.Append(customValidatorImports)
4750
}
4851

52+
if g.AssociatedExternalType != nil {
53+
imports.Append(generatorschema.AssociatedExternalTypeImports())
54+
}
55+
56+
imports.Append(g.AssociatedExternalType.Imports())
57+
4958
return imports
5059
}
5160

@@ -103,6 +112,7 @@ func (g GeneratorListAttribute) Equal(ga generatorschema.GeneratorAttribute) boo
103112
func (g GeneratorListAttribute) Schema(name generatorschema.FrameworkIdentifier) (string, error) {
104113
type attribute struct {
105114
Name string
115+
CustomType string
106116
ElementType string
107117
GeneratorListAttribute GeneratorListAttribute
108118
}
@@ -113,12 +123,19 @@ func (g GeneratorListAttribute) Schema(name generatorschema.FrameworkIdentifier)
113123
GeneratorListAttribute: g,
114124
}
115125

116-
t, err := template.New("list_attribute").Parse(listAttributeGoTemplate)
126+
switch {
127+
case g.CustomType != nil:
128+
a.CustomType = g.CustomType.Type
129+
case g.AssociatedExternalType != nil:
130+
a.CustomType = fmt.Sprintf("%sType{\ntypes.ListType{\nElemType: %s,\n},\n}", name.ToPascalCase(), generatorschema.GetElementType(g.ElementType))
131+
}
132+
133+
t, err := template.New("list_attribute").Parse(listAttributeTemplate)
117134
if err != nil {
118135
return "", err
119136
}
120137

121-
if _, err = addCommonAttributeTemplate(t); err != nil {
138+
if _, err = addAttributeTemplate(t); err != nil {
122139
return "", err
123140
}
124141

@@ -139,9 +156,64 @@ func (g GeneratorListAttribute) ModelField(name generatorschema.FrameworkIdentif
139156
ValueType: model.ListValueType,
140157
}
141158

142-
if g.CustomType != nil {
159+
switch {
160+
case g.CustomType != nil:
143161
field.ValueType = g.CustomType.ValueType
162+
case g.AssociatedExternalType != nil:
163+
field.ValueType = fmt.Sprintf("%sValue", name.ToPascalCase())
144164
}
145165

146166
return field, nil
147167
}
168+
169+
func (g GeneratorListAttribute) CustomTypeAndValue(name string) ([]byte, error) {
170+
if g.AssociatedExternalType == nil {
171+
return nil, nil
172+
}
173+
174+
var buf bytes.Buffer
175+
176+
listType := generatorschema.NewCustomListType(name)
177+
178+
b, err := listType.Render()
179+
180+
if err != nil {
181+
return nil, err
182+
}
183+
184+
buf.Write(b)
185+
186+
elemType := generatorschema.GetElementType(g.ElementType)
187+
188+
listValue := generatorschema.NewCustomListValue(name, elemType)
189+
190+
b, err = listValue.Render()
191+
192+
if err != nil {
193+
return nil, err
194+
}
195+
196+
buf.Write(b)
197+
198+
return buf.Bytes(), nil
199+
}
200+
201+
func (g GeneratorListAttribute) ToFromFunctions(name string) ([]byte, error) {
202+
if g.AssociatedExternalType == nil {
203+
return nil, nil
204+
}
205+
206+
elementTypeType := generatorschema.GetElementType(g.ElementType)
207+
elementTypeValue := generatorschema.GetElementValueType(g.ElementType)
208+
elementFrom := generatorschema.GetElementFromFunc(g.ElementType)
209+
210+
toFrom := generatorschema.NewToFromList(name, g.AssociatedExternalType, elementTypeType, elementTypeValue, elementFrom)
211+
212+
b, err := toFrom.Render()
213+
214+
if err != nil {
215+
return nil, err
216+
}
217+
218+
return b, nil
219+
}

0 commit comments

Comments
 (0)