Skip to content

Commit 8149041

Browse files
committed
migrate: unify raw TF state parsing into rawTFState struct
- Introduce rawTFState that captures lineage/serial alongside resources in one unmarshal, eliminating the separate meta struct parse. - parseTFStateAttrsFromBytes and parseTFStateAttrsFromRaw now share the same struct instead of defining an anonymous one. - Move Lineage/Serial after Attrs/IDs in TFState struct. Co-authored-by: Isaac
1 parent 396ba4e commit 8149041

1 file changed

Lines changed: 40 additions & 33 deletions

File tree

bundle/migrate/tf_state.go

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type TFState struct {
5151
Attrs TFStateAttrs
5252
// IDs maps bundle resource key → {ID, ETag} (same as terraform.ParseResourcesState).
5353
IDs terraform.ExportedResourcesMap
54+
5455
// Lineage and Serial are the top-level state metadata used to seed the direct state.
5556
Lineage string
5657
Serial int
@@ -67,23 +68,49 @@ func ParseTFStateFull(ctx context.Context, path string) (*TFState, error) {
6768
return nil, err
6869
}
6970

70-
var meta struct {
71-
Lineage string `json:"lineage"`
72-
Serial int `json:"serial"`
73-
}
74-
if err := json.Unmarshal(raw, &meta); err != nil {
71+
// Parse once: lineage/serial live at the top level alongside the resources array,
72+
// so a single unmarshal captures everything needed for both attrs and IDs.
73+
var parsed rawTFState
74+
if err := json.Unmarshal(raw, &parsed); err != nil {
7575
return nil, err
7676
}
7777

78-
attrs, err := parseTFStateAttrsFromBytes(raw)
79-
if err != nil {
80-
return nil, err
81-
}
78+
attrs := parseTFStateAttrsFromRaw(&parsed)
79+
8280
ids, err := terraform.ParseResourcesStateFromBytes(ctx, raw)
8381
if err != nil {
8482
return nil, err
8583
}
86-
return &TFState{Attrs: attrs, IDs: ids, Lineage: meta.Lineage, Serial: meta.Serial}, nil
84+
return &TFState{Attrs: attrs, IDs: ids, Lineage: parsed.Lineage, Serial: parsed.Serial}, nil
85+
}
86+
87+
// rawTFState is the on-disk terraform state format; it captures everything we need in one parse.
88+
type rawTFState struct {
89+
Version int `json:"version"`
90+
Lineage string `json:"lineage"`
91+
Serial int `json:"serial"`
92+
Resources []struct {
93+
Type string `json:"type"`
94+
Name string `json:"name"`
95+
Mode tfjson.ResourceMode `json:"mode"`
96+
Instances []struct {
97+
Attributes json.RawMessage `json:"attributes"`
98+
} `json:"instances"`
99+
} `json:"resources"`
100+
}
101+
102+
func parseTFStateAttrsFromRaw(s *rawTFState) TFStateAttrs {
103+
result := make(TFStateAttrs)
104+
for _, r := range s.Resources {
105+
if r.Mode != tfjson.ManagedResourceMode || len(r.Instances) == 0 {
106+
continue
107+
}
108+
if result[r.Type] == nil {
109+
result[r.Type] = make(map[string]json.RawMessage)
110+
}
111+
result[r.Type][r.Name] = r.Instances[0].Attributes
112+
}
113+
return result
87114
}
88115

89116
// ParseTFStateAttrs parses the terraform state file returning full attribute JSON per resource.
@@ -98,31 +125,11 @@ func ParseTFStateAttrs(path string) (TFStateAttrs, error) {
98125
}
99126

100127
func parseTFStateAttrsFromBytes(raw []byte) (TFStateAttrs, error) {
101-
var state struct {
102-
Version int `json:"version"`
103-
Resources []struct {
104-
Type string `json:"type"`
105-
Name string `json:"name"`
106-
Mode tfjson.ResourceMode `json:"mode"`
107-
Instances []struct {
108-
Attributes json.RawMessage `json:"attributes"`
109-
} `json:"instances"`
110-
} `json:"resources"`
111-
}
112-
if err := json.Unmarshal(raw, &state); err != nil {
128+
var s rawTFState
129+
if err := json.Unmarshal(raw, &s); err != nil {
113130
return nil, err
114131
}
115-
result := make(TFStateAttrs)
116-
for _, r := range state.Resources {
117-
if r.Mode != tfjson.ManagedResourceMode || len(r.Instances) == 0 {
118-
continue
119-
}
120-
if result[r.Type] == nil {
121-
result[r.Type] = make(map[string]json.RawMessage)
122-
}
123-
result[r.Type][r.Name] = r.Instances[0].Attributes
124-
}
125-
return result, nil
132+
return parseTFStateAttrsFromRaw(&s), nil
126133
}
127134

128135
// LookupTFField looks up a field from TF state attributes for a bundle resource.

0 commit comments

Comments
 (0)