github.com/beauknowssoftware/makehcl@v0.0.0-20200322000747-1b9bb1e1c008/internal/parse/parseDynamicCommands.go (about)

     1  package parse
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  
     6  	"github.com/beauknowssoftware/makehcl/internal/definition"
     7  	"github.com/hashicorp/hcl/v2"
     8  	"github.com/zclconf/go-cty/cty"
     9  )
    10  
    11  var (
    12  	dynamicCommandListSchema = hcl.BodySchema{
    13  		Attributes: []hcl.AttributeSchema{
    14  			{
    15  				Name:     "alias",
    16  				Required: false,
    17  			},
    18  			{
    19  				Name:     "for_each",
    20  				Required: true,
    21  			},
    22  			{
    23  				Name:     "as",
    24  				Required: false,
    25  			},
    26  			{
    27  				Name:     "name",
    28  				Required: true,
    29  			},
    30  		},
    31  	}
    32  )
    33  
    34  type dynamicCommand struct {
    35  	alias    string
    36  	commands []*definition.Command
    37  }
    38  
    39  func constructDynamicCommands(blk *hcl.Block, ctx *hcl.EvalContext) (*dynamicCommand, error) {
    40  	con, body, diag := blk.Body.PartialContent(&dynamicCommandListSchema)
    41  	if diag.HasErrors() {
    42  		return nil, diag
    43  	}
    44  
    45  	forEach, err := evaluateValueArray(con.Attributes["for_each"].Expr, ctx)
    46  	if err != nil {
    47  		err = errors.Wrap(err, "failed to evaluate for_each")
    48  		return nil, err
    49  	}
    50  
    51  	var dr dynamicCommand
    52  
    53  	as := "command"
    54  	if asVal, hasAs := con.Attributes["as"]; hasAs {
    55  		as, err = evaluateString(asVal.Expr, ctx)
    56  		if err != nil {
    57  			err = errors.Wrap(err, "failed to evaluate as")
    58  			return nil, err
    59  		}
    60  	}
    61  
    62  	if aliasVal, hasName := con.Attributes["alias"]; hasName {
    63  		dr.alias, err = evaluateString(aliasVal.Expr, ctx)
    64  		if err != nil {
    65  			err = errors.Wrap(err, "failed to evaluate alias")
    66  			return nil, err
    67  		}
    68  	}
    69  
    70  	dr.commands = make([]*definition.Command, 0, len(forEach))
    71  
    72  	for _, each := range forEach {
    73  		ectx := ctx.NewChild()
    74  		ectx.Variables = map[string]cty.Value{
    75  			as: each,
    76  		}
    77  
    78  		name, err := evaluateString(con.Attributes["name"].Expr, ectx)
    79  		if err != nil {
    80  			err = errors.Wrap(err, "failed to evaluate name")
    81  			return nil, err
    82  		}
    83  
    84  		ectx.Variables["name"] = cty.StringVal(name)
    85  
    86  		r, err := fillCommand(name, body, ectx)
    87  		if err != nil {
    88  			return nil, err
    89  		}
    90  
    91  		dr.commands = append(dr.commands, r)
    92  	}
    93  
    94  	return &dr, nil
    95  }