Skip to content

Commit

Permalink
schema: Convert complex types to relevant expression type constraints (
Browse files Browse the repository at this point in the history
…#68)

* schema: Convert complex types to relevant expression type constraints

* bump hcl-lang to latest rev

* schema: sort targetable module outputs
  • Loading branch information
radeksimko authored Jul 30, 2021
1 parent ade5695 commit e9a4cde
Show file tree
Hide file tree
Showing 6 changed files with 395 additions and 8 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.14
require (
github.com/google/go-cmp v0.5.6
github.com/hashicorp/go-version v1.3.0
github.com/hashicorp/hcl-lang v0.0.0-20210728150846-565e9ca96f5a
github.com/hashicorp/hcl-lang v0.0.0-20210730145509-f403a86a1605
github.com/hashicorp/hcl/v2 v2.10.1
github.com/hashicorp/terraform-json v0.12.0
github.com/hashicorp/terraform-registry-address v0.0.0-20210412075316-9b2996cce896
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl-lang v0.0.0-20210728150846-565e9ca96f5a h1:/4iJtfKKXrHCi99FQgUeHvF6OBNUzJeVO7Tsmfj8F1s=
github.com/hashicorp/hcl-lang v0.0.0-20210728150846-565e9ca96f5a/go.mod h1:xzXU6Fn+TWVaZUFxV8CyAsObi2oMgSEFAmLvCx2ArzM=
github.com/hashicorp/hcl-lang v0.0.0-20210730145509-f403a86a1605 h1:558O3NRU7baTVlQNgui1NeHDORRFEgTsICpHmI+ubA0=
github.com/hashicorp/hcl-lang v0.0.0-20210730145509-f403a86a1605/go.mod h1:xzXU6Fn+TWVaZUFxV8CyAsObi2oMgSEFAmLvCx2ArzM=
github.com/hashicorp/hcl/v2 v2.10.1 h1:h4Xx4fsrRE26ohAk/1iGF/JBqRQbyUqu5Lvj60U54ys=
github.com/hashicorp/hcl/v2 v2.10.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
github.com/hashicorp/terraform-json v0.12.0 h1:8czPgEEWWPROStjkWPUnTQDXmpmZPlkQAwYYLETaTvw=
Expand Down
61 changes: 57 additions & 4 deletions schema/convert_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,7 @@ func convertAttributesFromJson(attributes map[string]*tfjson.SchemaAttribute) ma
func exprConstraintsFromAttribute(attr *tfjson.SchemaAttribute) schema.ExprConstraints {
var expr schema.ExprConstraints
if attr.AttributeType != cty.NilType {
return schema.ExprConstraints{
schema.TraversalExpr{OfType: attr.AttributeType},
schema.LiteralTypeExpr{Type: attr.AttributeType},
}
return convertAttributeTypeToExprConstraints(attr.AttributeType)
}
if attr.AttributeNestedType != nil {
switch attr.AttributeNestedType.NestingMode {
Expand Down Expand Up @@ -165,6 +162,62 @@ func exprConstraintsFromAttribute(attr *tfjson.SchemaAttribute) schema.ExprConst
return expr
}

func convertAttributeTypeToExprConstraints(attrType cty.Type) schema.ExprConstraints {
ec := schema.ExprConstraints{
schema.TraversalExpr{OfType: attrType},
schema.LiteralTypeExpr{Type: attrType},
}

if attrType.IsListType() {
ec = append(ec, schema.ListExpr{
Elem: convertAttributeTypeToExprConstraints(attrType.ElementType()),
})
}
if attrType.IsSetType() {
ec = append(ec, schema.SetExpr{
Elem: convertAttributeTypeToExprConstraints(attrType.ElementType()),
})
}
if attrType.IsTupleType() {
te := schema.TupleExpr{Elems: make([]schema.ExprConstraints, 0)}
for _, elemType := range attrType.TupleElementTypes() {
te.Elems = append(te.Elems, convertAttributeTypeToExprConstraints(elemType))
}
ec = append(ec, te)
}
if attrType.IsMapType() {
ec = append(ec, schema.MapExpr{
Elem: convertAttributeTypeToExprConstraints(attrType.ElementType()),
})
}
if attrType.IsObjectType() {
ec = append(ec, convertCtyObjectToObjectExprAttr(attrType))
}

return ec
}

func convertCtyObjectToObjectExprAttr(obj cty.Type) schema.ObjectExpr {
attrTypes := obj.AttributeTypes()
attributes := make(schema.ObjectExprAttributes, len(attrTypes))
for name, attrType := range attrTypes {
aSchema := &schema.AttributeSchema{
Expr: convertAttributeTypeToExprConstraints(attrType),
}

if obj.AttributeOptional(name) {
aSchema.IsOptional = true
} else {
aSchema.IsRequired = true
}

attributes[name] = aSchema
}
return schema.ObjectExpr{
Attributes: attributes,
}
}

func convertJsonAttributesToObjectExprAttr(attrs map[string]*tfjson.SchemaAttribute) schema.ObjectExpr {
attributes := make(schema.ObjectExprAttributes, len(attrs))
for name, attr := range attrs {
Expand Down
6 changes: 5 additions & 1 deletion schema/module_schema.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package schema

import (
"sort"

"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/schema"
"github.com/hashicorp/terraform-schema/internal/schema/refscope"
Expand All @@ -20,7 +22,7 @@ func SchemaForDependentModuleBlock(localName string, modMeta *module.Meta) (*sch

modOutputTypes := make(map[string]cty.Type, 0)
modOutputVals := make(map[string]cty.Value, 0)
targetableOutputs := make([]*schema.Targetable, 0)
targetableOutputs := make(schema.Targetables, 0)

for name, output := range modMeta.Outputs {
addr := lang.Address{
Expand Down Expand Up @@ -51,6 +53,8 @@ func SchemaForDependentModuleBlock(localName string, modMeta *module.Meta) (*sch
modOutputVals[name] = output.Value
}

sort.Sort(targetableOutputs)

addr := lang.Address{
lang.RootStep{Name: "module"},
lang.AttrStep{Name: localName},
Expand Down
Loading

0 comments on commit e9a4cde

Please sign in to comment.