Skip to content

Commit 2851201

Browse files
authored
Refactor merging + add abstraction for attributes (#51)
* initial refactor * added primitives + collection merge tests * add collection nested attributes * type * add single nested test * add main attributes tests and delete old merge functionality * pointer test * license headers * rename package, structs, and test methods * add data source impl * add tests * add provider implementation * add implementations to oas and tests * remove merge package * add error returns + TODOs for future considerations * update allocations + add error join return
1 parent 87aed70 commit 2851201

Some content is hidden

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

52 files changed

+9575
-4708
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package attrmapper
5+
6+
import (
7+
"errors"
8+
9+
"github.com/hashicorp/terraform-plugin-codegen-spec/datasource"
10+
"github.com/hashicorp/terraform-plugin-codegen-spec/provider"
11+
"github.com/hashicorp/terraform-plugin-codegen-spec/resource"
12+
)
13+
14+
type ResourceAttribute interface {
15+
GetName() string
16+
Merge(ResourceAttribute) (ResourceAttribute, error)
17+
ToSpec() resource.Attribute
18+
}
19+
20+
type ResourceAttributes []ResourceAttribute
21+
22+
func (targetSlice ResourceAttributes) Merge(mergeSlices ...ResourceAttributes) (ResourceAttributes, error) {
23+
for _, mergeSlice := range mergeSlices {
24+
for _, mergeAttribute := range mergeSlice {
25+
// As we compare attributes, if we don't find a match, we should add this attribute to the slice after
26+
isNewAttribute := true
27+
28+
for i, targetAttribute := range targetSlice {
29+
if targetAttribute.GetName() == mergeAttribute.GetName() {
30+
// TODO: determine how to surface this error
31+
targetSlice[i], _ = targetAttribute.Merge(mergeAttribute)
32+
33+
isNewAttribute = false
34+
break
35+
}
36+
}
37+
38+
if isNewAttribute {
39+
// Add this back to the original slice to avoid adding duplicate attributes from different mergeSlices
40+
targetSlice = append(targetSlice, mergeAttribute)
41+
}
42+
}
43+
}
44+
45+
return targetSlice, nil
46+
}
47+
48+
func (attributes ResourceAttributes) ToSpec() []resource.Attribute {
49+
specAttributes := make([]resource.Attribute, 0, len(attributes))
50+
for _, attribute := range attributes {
51+
specAttributes = append(specAttributes, attribute.ToSpec())
52+
}
53+
54+
return specAttributes
55+
}
56+
57+
type DataSourceAttribute interface {
58+
GetName() string
59+
Merge(DataSourceAttribute) (DataSourceAttribute, error)
60+
ToSpec() datasource.Attribute
61+
}
62+
63+
type DataSourceAttributes []DataSourceAttribute
64+
65+
func (targetSlice DataSourceAttributes) Merge(mergeSlices ...DataSourceAttributes) (DataSourceAttributes, error) {
66+
var errResult error
67+
68+
for _, mergeSlice := range mergeSlices {
69+
for _, mergeAttribute := range mergeSlice {
70+
// As we compare attributes, if we don't find a match, we should add this attribute to the slice after
71+
isNewAttribute := true
72+
73+
for i, targetAttribute := range targetSlice {
74+
if targetAttribute.GetName() == mergeAttribute.GetName() {
75+
mergedAttribute, err := targetAttribute.Merge(mergeAttribute)
76+
if err != nil {
77+
// TODO: consider how best to surface this error
78+
// Currently, if the merge fails we should just keep the original target attribute for now
79+
errResult = errors.Join(errResult, err)
80+
} else {
81+
targetSlice[i] = mergedAttribute
82+
}
83+
84+
isNewAttribute = false
85+
break
86+
}
87+
}
88+
89+
if isNewAttribute {
90+
// Add this back to the original slice to avoid adding duplicate attributes from different mergeSlices
91+
targetSlice = append(targetSlice, mergeAttribute)
92+
}
93+
}
94+
}
95+
96+
return targetSlice, errResult
97+
}
98+
99+
func (attributes DataSourceAttributes) ToSpec() []datasource.Attribute {
100+
specAttributes := make([]datasource.Attribute, 0, len(attributes))
101+
for _, attribute := range attributes {
102+
specAttributes = append(specAttributes, attribute.ToSpec())
103+
}
104+
105+
return specAttributes
106+
}
107+
108+
type ProviderAttribute interface {
109+
ToSpec() provider.Attribute
110+
}
111+
112+
type ProviderAttributes []ProviderAttribute
113+
114+
func (attributes ProviderAttributes) ToSpec() []provider.Attribute {
115+
specAttributes := make([]provider.Attribute, 0, len(attributes))
116+
for _, attribute := range attributes {
117+
specAttributes = append(specAttributes, attribute.ToSpec())
118+
}
119+
120+
return specAttributes
121+
}

0 commit comments

Comments
 (0)