github.com/Yunsang-Jeong/terraforge@v0.0.0-20231003081416-fe4fad2c57e3/internal/configs/generate.go (about)

     1  package configs
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/hashicorp/hcl/v2"
     7  	"github.com/hashicorp/hcl/v2/hclsyntax"
     8  	"github.com/zclconf/go-cty/cty"
     9  )
    10  
    11  type Generate struct {
    12  	Labels  []string
    13  	When    bool
    14  	ForEach map[string]cty.Value
    15  	Config  *hclsyntax.Body
    16  }
    17  
    18  func decodeGenerateBlock(block *hclsyntax.Block, ctx *hcl.EvalContext) (*Generate, error) {
    19  	g := &Generate{
    20  		Labels: block.Labels,
    21  		When:   true,
    22  	}
    23  
    24  	if attr, ok := block.Body.Attributes["when"]; ok {
    25  		value, diags := attr.Expr.Value(ctx)
    26  		if diags.HasErrors() {
    27  			g.When = true
    28  		} else if !value.IsNull() && value.False() {
    29  			g.When = false
    30  		}
    31  	}
    32  
    33  	if attr, ok := block.Body.Attributes["for_each"]; ok {
    34  		forEach, diags := attr.Expr.Value(ctx)
    35  		if diags.HasErrors() {
    36  			return nil, errors.Join(diags.Errs()...)
    37  		}
    38  
    39  		g.ForEach = map[string]cty.Value{}
    40  
    41  		switch t := forEach.Type(); {
    42  		case t.IsObjectType():
    43  			for key, value := range forEach.AsValueMap() {
    44  				g.ForEach[key] = value
    45  			}
    46  		case t.IsListType() || t.IsSetType():
    47  			for _, value := range forEach.AsValueSlice() {
    48  				g.ForEach[value.AsString()] = value
    49  			}
    50  		default:
    51  			return nil, errors.New("for_each type must be object or set(string)")
    52  		}
    53  	}
    54  
    55  	for _, blockInBlock := range block.Body.Blocks {
    56  		if blockInBlock.Type == "config" {
    57  			g.Config = blockInBlock.Body
    58  			break
    59  		}
    60  	}
    61  
    62  	return g, nil
    63  }