Skip to content

Commit b45af68

Browse files
committed
[hcledit/read] return error if fallback occurred
1 parent 9104984 commit b45af68

File tree

4 files changed

+74
-46
lines changed

4 files changed

+74
-46
lines changed

hcledit.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@ func (h *HCLEditor) Read(queryStr string, opts ...Option) (map[string]interface{
8787
if err != nil {
8888
return nil, err
8989
}
90-
90+
91+
fallback := opt.readFallbackToRawString
9192
results := make(map[string]cty.Value)
92-
hdlr, err := handler.NewReadHandler(results, opt.readFallbackToRawString)
93+
hdlr, err := handler.NewReadHandler(results, fallback)
9394
if err != nil {
9495
return nil, err
9596
}
@@ -99,11 +100,17 @@ func (h *HCLEditor) Read(queryStr string, opts ...Option) (map[string]interface{
99100
Mode: walker.Read,
100101
}
101102

102-
if err := w.Walk(h.writeFile.Body(), queries, 0, []string{}); err != nil {
103+
err = w.Walk(h.writeFile.Body(), queries, 0, []string{})
104+
if err != nil && !fallback {
103105
return nil, err
104106
}
105107

106-
return convert(results)
108+
ret, convertErr := convert(results)
109+
if convertErr != nil {
110+
return ret, convertErr
111+
}
112+
113+
return ret, err
107114
}
108115

109116
// Update replaces attributes and blocks which matched with its key

hcledit_test.go

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -205,17 +205,19 @@ object1 = {
205205

206206
func TestRead(t *testing.T) {
207207
cases := map[string]struct {
208-
input string
209-
query string
210-
options []hcledit.Option
211-
want map[string]interface{}
208+
input string
209+
query string
210+
options []hcledit.Option
211+
expectErr bool
212+
want map[string]interface{}
212213
}{
213214
"Attribute": {
214215
input: `
215216
attribute = "R"
216217
`,
217-
query: "attribute",
218-
options: make([]hcledit.Option, 0),
218+
query: "attribute",
219+
options: make([]hcledit.Option, 0),
220+
expectErr: false,
219221
want: map[string]interface{}{
220222
"attribute": "R",
221223
},
@@ -228,9 +230,10 @@ block "label1" "label2" {
228230
attribute = "str"
229231
}
230232
`,
231-
options: make([]hcledit.Option, 0),
232-
query: "block",
233-
want: map[string]interface{}{},
233+
options: make([]hcledit.Option, 0),
234+
expectErr: false,
235+
query: "block",
236+
want: map[string]interface{}{},
234237
},
235238

236239
"AttributeInBlock1": {
@@ -239,8 +242,9 @@ block "label1" "label2" {
239242
attribute = "R"
240243
}
241244
`,
242-
options: make([]hcledit.Option, 0),
243-
query: "block.label1.label2.attribute",
245+
options: make([]hcledit.Option, 0),
246+
expectErr: false,
247+
query: "block.label1.label2.attribute",
244248
want: map[string]interface{}{
245249
"block.label1.label2.attribute": "R",
246250
},
@@ -254,8 +258,9 @@ block1 "label1" "label2" {
254258
}
255259
}
256260
`,
257-
options: make([]hcledit.Option, 0),
258-
query: "block1.label1.label2.block2.label3.label4.attribute",
261+
options: make([]hcledit.Option, 0),
262+
expectErr: false,
263+
query: "block1.label1.label2.block2.label3.label4.attribute",
259264
want: map[string]interface{}{
260265
"block1.label1.label2.block2.label3.label4.attribute": "R",
261266
},
@@ -272,8 +277,9 @@ block "label" "label2" {
272277
}
273278
274279
`,
275-
options: make([]hcledit.Option, 0),
276-
query: "block.label.*.attribute",
280+
options: make([]hcledit.Option, 0),
281+
expectErr: false,
282+
query: "block.label.*.attribute",
277283
want: map[string]interface{}{
278284
"block.label.label1.attribute": "R",
279285
"block.label.label2.attribute": "R",
@@ -286,8 +292,9 @@ object = {
286292
attribute = "R"
287293
}
288294
`,
289-
options: make([]hcledit.Option, 0),
290-
query: "object.attribute",
295+
options: make([]hcledit.Option, 0),
296+
expectErr: false,
297+
query: "object.attribute",
291298
want: map[string]interface{}{
292299
"object.attribute": "R",
293300
},
@@ -300,8 +307,9 @@ object1 = {
300307
}
301308
}
302309
`,
303-
options: make([]hcledit.Option, 0),
304-
query: "object1.object2.attribute",
310+
options: make([]hcledit.Option, 0),
311+
expectErr: false,
312+
query: "object1.object2.attribute",
305313
want: map[string]interface{}{
306314
"object1.object2.attribute": "R",
307315
},
@@ -311,8 +319,9 @@ object1 = {
311319
input: `
312320
attribute = 1
313321
`,
314-
options: make([]hcledit.Option, 0),
315-
query: "attribute",
322+
options: make([]hcledit.Option, 0),
323+
expectErr: false,
324+
query: "attribute",
316325
want: map[string]interface{}{
317326
"attribute": 1,
318327
},
@@ -322,8 +331,9 @@ attribute = 1
322331
input: `
323332
attribute = "str"
324333
`,
325-
options: make([]hcledit.Option, 0),
326-
query: "attribute",
334+
options: make([]hcledit.Option, 0),
335+
expectErr: false,
336+
query: "attribute",
327337
want: map[string]interface{}{
328338
"attribute": "str",
329339
},
@@ -333,8 +343,9 @@ attribute = "str"
333343
input: `
334344
attribute = true
335345
`,
336-
options: make([]hcledit.Option, 0),
337-
query: "attribute",
346+
options: make([]hcledit.Option, 0),
347+
expectErr: false,
348+
query: "attribute",
338349
want: map[string]interface{}{
339350
"attribute": true,
340351
},
@@ -344,8 +355,9 @@ attribute = true
344355
input: `
345356
attribute = false
346357
`,
347-
options: make([]hcledit.Option, 0),
348-
query: "attribute",
358+
options: make([]hcledit.Option, 0),
359+
expectErr: false,
360+
query: "attribute",
349361
want: map[string]interface{}{
350362
"attribute": false,
351363
},
@@ -355,8 +367,9 @@ attribute = false
355367
input: `
356368
attribute = ["str1", "str2", "str3"]
357369
`,
358-
options: make([]hcledit.Option, 0),
359-
query: "attribute",
370+
options: make([]hcledit.Option, 0),
371+
expectErr: false,
372+
query: "attribute",
360373
want: map[string]interface{}{
361374
"attribute": []string{"str1", "str2", "str3"},
362375
},
@@ -366,8 +379,9 @@ attribute = ["str1", "str2", "str3"]
366379
input: `
367380
attribute = [1, 2, 3]
368381
`,
369-
options: make([]hcledit.Option, 0),
370-
query: "attribute",
382+
options: make([]hcledit.Option, 0),
383+
expectErr: false,
384+
query: "attribute",
371385
want: map[string]interface{}{
372386
"attribute": []int{1, 2, 3},
373387
},
@@ -377,8 +391,9 @@ attribute = [1, 2, 3]
377391
input: `
378392
attribute = [true, false, true]
379393
`,
380-
options: make([]hcledit.Option, 0),
381-
query: "attribute",
394+
options: make([]hcledit.Option, 0),
395+
expectErr: false,
396+
query: "attribute",
382397
want: map[string]interface{}{
383398
"attribute": []bool{true, false, true},
384399
},
@@ -388,8 +403,9 @@ attribute = [true, false, true]
388403
input: `
389404
attribute = local.var
390405
`,
391-
options: []hcledit.Option{hcledit.WithReadFallbackToRawString()},
392-
query: "attribute",
406+
options: []hcledit.Option{hcledit.WithReadFallbackToRawString()},
407+
expectErr: true,
408+
query: "attribute",
393409
want: map[string]interface{}{
394410
"attribute": "local.var",
395411
},
@@ -399,8 +415,9 @@ attribute = local.var
399415
input: `
400416
attribute = "some-${local.var}"
401417
`,
402-
options: []hcledit.Option{hcledit.WithReadFallbackToRawString()},
403-
query: "attribute",
418+
options: []hcledit.Option{hcledit.WithReadFallbackToRawString()},
419+
expectErr: true,
420+
query: "attribute",
404421
want: map[string]interface{}{
405422
"attribute": `"some-${local.var}"`,
406423
},
@@ -416,7 +433,7 @@ attribute = "some-${local.var}"
416433
}
417434

418435
got, err := editor.Read(tc.query, tc.options...)
419-
if err != nil {
436+
if !tc.expectErr && err != nil {
420437
t.Fatal(err)
421438
}
422439

internal/handler/read.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ func NewReadHandler(results map[string]cty.Value, fallbackToRawString bool) (Han
2525

2626
func (h *readHandler) HandleBody(body *hclwrite.Body, name string, keyTrail []string) error {
2727
buf := body.GetAttribute(name).BuildTokens(nil).Bytes()
28-
value, err := parse(buf, name, h.fallbackToRawString)
29-
if err != nil {
28+
fallback := h.fallbackToRawString
29+
value, err := parse(buf, name, fallback)
30+
if err != nil && !fallback {
3031
return err
3132
}
3233
h.results[strings.Join(keyTrail, ".")] = value
33-
return nil
34+
return err
3435
}
3536

3637
func (h *readHandler) HandleObject(object *ast.Object, name string, keyTrail []string) error {
@@ -59,7 +60,7 @@ func parse(buf []byte, name string, fallback bool) (cty.Value, error) {
5960

6061
// Could not parse the value with a nil EvalContext, so this is likely an
6162
// interpolated string. Instead, attempt to parse the raw string value.
62-
return cty.StringVal(string(expr.Range().SliceBytes(buf))), nil
63+
return cty.StringVal(string(expr.Range().SliceBytes(buf))), diags
6364
}
6465
return v, nil
6566
}

option.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ func WithNewLine() Option {
3232
}
3333
}
3434

35+
// This provides a fallback to return the raw string of the value if we could
36+
// not parse it. If this option is provided to HCLEditor.Read(), the error
37+
// return value will signal fallback occurred.
3538
func WithReadFallbackToRawString() Option {
3639
return func(opt *option) {
3740
opt.readFallbackToRawString = true

0 commit comments

Comments
 (0)