91 lines
2.8 KiB
Go
91 lines
2.8 KiB
Go
package plugin
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/hcl/v2/hclwrite"
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
rpcv1 "code.icb4dc0.de/buildr/api/generated/common/v1"
|
|
|
|
"code.icb4dc0.de/buildr/buildr/internal/hcl"
|
|
)
|
|
|
|
func (m Module) MarshalHCL(block *hclwrite.Block) error {
|
|
for s, value := range m.modSpec.Values {
|
|
switch value.Kind {
|
|
case rpcv1.ModuleSpec_ValueKindUnknown, rpcv1.ModuleSpec_ValueKindAttribute:
|
|
if mapped, err := mapSpecValueToCty(value); err != nil {
|
|
return err
|
|
} else {
|
|
block.Body().SetAttributeValue(s, mapped)
|
|
}
|
|
case rpcv1.ModuleSpec_ValueKindBlock:
|
|
case rpcv1.ModuleSpec_ValueKindLabel:
|
|
if value.Type != rpcv1.ModuleSpec_ValueTypeSingle {
|
|
return errors.New("only single values are supported as labels")
|
|
}
|
|
|
|
if value.SingleValue == nil {
|
|
return errors.New("single value is nil")
|
|
}
|
|
|
|
if s, ok := value.SingleValue.(*rpcv1.ModuleSpec_Value_StringValue); !ok {
|
|
return errors.New("single value is not a string - only strings are supported as labels")
|
|
} else {
|
|
block.SetLabels(append(block.Labels(), s.StringValue))
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
//nolint:gocyclo // cannot be less complex
|
|
func mapSpecValueToCty(value *rpcv1.ModuleSpec_Value) (cty.Value, error) {
|
|
switch value.Type {
|
|
case rpcv1.ModuleSpec_ValueTypeUnknown:
|
|
return cty.Value{}, errors.New("cannot map unknown value type")
|
|
case rpcv1.ModuleSpec_ValueTypeSingle:
|
|
switch v := value.SingleValue.(type) {
|
|
case *rpcv1.ModuleSpec_Value_BoolValue:
|
|
return cty.BoolVal(v.BoolValue), nil
|
|
case *rpcv1.ModuleSpec_Value_StringValue:
|
|
return cty.StringVal(v.StringValue), nil
|
|
case *rpcv1.ModuleSpec_Value_IntValue:
|
|
return cty.NumberIntVal(v.IntValue), nil
|
|
case *rpcv1.ModuleSpec_Value_DoubleValue:
|
|
return cty.NumberFloatVal(v.DoubleValue), nil
|
|
default:
|
|
return cty.NilVal, fmt.Errorf("unsupported value type %q", value.Type)
|
|
}
|
|
case rpcv1.ModuleSpec_ValueTypeStringSlice:
|
|
return hcl.MapToCtyVal(value.StringValues, hcl.MappingCfg{})
|
|
case rpcv1.ModuleSpec_ValueTypeIntSlice:
|
|
return hcl.MapToCtyVal(value.IntValues, hcl.MappingCfg{})
|
|
case rpcv1.ModuleSpec_ValueTypeDoubleSlice:
|
|
return hcl.MapToCtyVal(value.DoubleValues, hcl.MappingCfg{})
|
|
case rpcv1.ModuleSpec_ValueTypeBoolSlice:
|
|
return hcl.MapToCtyVal(value.BoolValues, hcl.MappingCfg{})
|
|
case rpcv1.ModuleSpec_ValueTypeObject:
|
|
return cty.Value{}, errors.New("object type are right now not supported (yet)")
|
|
case rpcv1.ModuleSpec_ValueTypeMap:
|
|
if len(value.ComplexValue) == 0 {
|
|
return cty.MapValEmpty(cty.String), nil
|
|
}
|
|
mappedVal := make(map[string]cty.Value, len(value.ComplexValue))
|
|
|
|
for k, v := range value.ComplexValue {
|
|
if mapped, err := mapSpecValueToCty(v); err != nil {
|
|
return cty.Value{}, err
|
|
} else {
|
|
mappedVal[k] = mapped
|
|
}
|
|
}
|
|
|
|
return cty.MapVal(mappedVal), nil
|
|
default:
|
|
return cty.NilVal, fmt.Errorf("unsupported value type %q", value.Type)
|
|
}
|
|
}
|