@@ -16,6 +16,7 @@ import (
16
16
"github.com/hashicorp/hcl/v2/hclsyntax"
17
17
"github.com/hashicorp/hcl/v2/json"
18
18
"github.com/zclconf/go-cty/cty"
19
+ "github.com/zclconf/go-cty/cty/function"
19
20
)
20
21
21
22
// TestTerraformLike parses both a native syntax and a JSON representation
@@ -53,10 +54,14 @@ func TestTerraformLike(t *testing.T) {
53
54
Name string `hcl:"name,label"`
54
55
Providers hcl.Expression `hcl:"providers"`
55
56
}
57
+ type Locals struct {
58
+ Config hcl.Body `hcl:",remain"`
59
+ }
56
60
type Root struct {
57
61
Variables []* Variable `hcl:"variable,block"`
58
62
Resources []* Resource `hcl:"resource,block"`
59
63
Modules []* Module `hcl:"module,block"`
64
+ Locals []* Locals `hcl:"locals,block"`
60
65
}
61
66
instanceDecode := & hcldec.ObjectSpec {
62
67
"image_id" : & hcldec.AttrSpec {
@@ -343,6 +348,57 @@ func TestTerraformLike(t *testing.T) {
343
348
t .Errorf ("wrong value traversal [1] type %T; want hcl.TraverseAttr" , vt [1 ])
344
349
}
345
350
})
351
+
352
+ t .Run ("locals" , func (t * testing.T ) {
353
+ locals := root .Locals [0 ]
354
+ attrs , diags := locals .Config .JustAttributes ()
355
+ if diags .HasErrors () {
356
+ t .Fatal (diags )
357
+ }
358
+
359
+ ctx := & hcl.EvalContext {
360
+ Functions : map [string ]function.Function {
361
+ "func" : function .New (& function.Spec {
362
+ Params : []function.Parameter {{Type : cty .String }},
363
+ Type : function .StaticReturnType (cty .String ),
364
+ Impl : func ([]cty.Value , cty.Type ) (cty.Value , error ) {
365
+ return cty .StringVal ("func_result" ), nil
366
+ },
367
+ }),
368
+ "scoped::func" : function .New (& function.Spec {
369
+ Params : []function.Parameter {{Type : cty .String }},
370
+ Type : function .StaticReturnType (cty .String ),
371
+ Impl : func ([]cty.Value , cty.Type ) (cty.Value , error ) {
372
+ return cty .StringVal ("scoped::func_result" ), nil
373
+ },
374
+ }),
375
+ },
376
+ }
377
+
378
+ res := attrs ["func_result" ]
379
+ funcVal , diags := res .Expr .Value (ctx )
380
+ if diags .HasErrors () {
381
+ t .Fatal (diags )
382
+ }
383
+
384
+ wantVal := cty .StringVal ("func_result" )
385
+
386
+ if ! funcVal .RawEquals (wantVal ) {
387
+ t .Errorf ("expected %#v, got %#v" , wantVal , funcVal )
388
+ }
389
+
390
+ res = attrs ["scoped_func_result" ]
391
+ funcVal , diags = res .Expr .Value (ctx )
392
+ if diags .HasErrors () {
393
+ t .Fatal (diags )
394
+ }
395
+
396
+ wantVal = cty .StringVal ("scoped::func_result" )
397
+
398
+ if ! funcVal .RawEquals (wantVal ) {
399
+ t .Errorf ("expected %#v, got %#v" , wantVal , funcVal )
400
+ }
401
+ })
346
402
})
347
403
}
348
404
}
@@ -352,6 +408,11 @@ const terraformLikeNativeSyntax = `
352
408
variable "image_id" {
353
409
}
354
410
411
+ locals {
412
+ func_result = func("arg")
413
+ scoped_func_result = scoped::func("arg")
414
+ }
415
+
355
416
resource "happycloud_instance" "test" {
356
417
instance_type = "z3.weedy"
357
418
image_id = var.image_id
@@ -400,6 +461,10 @@ const terraformLikeJSON = `
400
461
"variable": {
401
462
"image_id": {}
402
463
},
464
+ "locals": {
465
+ "func_result": "${func(\"arg\")}",
466
+ "scoped_func_result": "${scoped::func(\"arg\")}"
467
+ },
403
468
"resource": {
404
469
"happycloud_instance": {
405
470
"test": {
0 commit comments