github.com/mineiros-io/terradoc@v0.0.9-0.20220711062319-018bd4ae81f5/internal/parsers/docparser/attributes.go (about) 1 package docparser 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/hcl/v2" 7 "github.com/mineiros-io/terradoc/internal/entities" 8 "github.com/mineiros-io/terradoc/internal/parsers/hclparser" 9 "github.com/mineiros-io/terradoc/internal/schemas/docschema" 10 ) 11 12 func parseVariableAttributes(attributeBlocks hcl.Blocks) (attributes []entities.Attribute, err error) { 13 const variableAttributeLevel = 1 14 15 for _, attrBlk := range attributeBlocks { 16 attribute, err := parseAttribute(attrBlk, variableAttributeLevel) 17 if err != nil { 18 return nil, fmt.Errorf("parsing attributes: %s", err) 19 } 20 21 attributes = append(attributes, attribute) 22 } 23 24 return attributes, nil 25 } 26 27 func parseAttribute(attrBlock *hcl.Block, level int) (entities.Attribute, error) { 28 attrContent, diags := attrBlock.Body.Content(docschema.AttributeSchema()) 29 if diags.HasErrors() { 30 return entities.Attribute{}, fmt.Errorf("parsing attribute block: %v", diags.Errs()) 31 } 32 33 if len(attrBlock.Labels) != 1 { 34 return entities.Attribute{}, fmt.Errorf("expected single 'name' label, got %v", attrBlock.Labels) 35 } 36 37 // variable blocks are required to have a label as defined in the schema 38 name := attrBlock.Labels[0] 39 40 attr, err := createAttributeFromHCLAttributes(attrContent.Attributes, name, level) 41 if err != nil { 42 return entities.Attribute{}, fmt.Errorf("parsing attribute: %s", err) 43 } 44 45 nestedAttributeLevel := level + 1 46 // attribute blocks have only `attribute` blocks 47 for _, blk := range attrContent.Blocks.OfType(attributeBlockName) { 48 nestedAttr, err := parseAttribute(blk, nestedAttributeLevel) 49 if err != nil { 50 return entities.Attribute{}, fmt.Errorf("parsing nested attribute: %s", err) 51 } 52 53 attr.Attributes = append(attr.Attributes, nestedAttr) 54 } 55 56 return attr, nil 57 } 58 59 func createAttributeFromHCLAttributes(attrs hcl.Attributes, name string, level int) (entities.Attribute, error) { 60 var err error 61 62 attr := entities.Attribute{Name: name, Level: level} 63 64 attr.Description, err = hclparser.GetAttribute(attrs, descriptionAttributeName).String() 65 if err != nil { 66 return entities.Attribute{}, err 67 } 68 69 attr.Required, err = hclparser.GetAttribute(attrs, requiredAttributeName).Bool() 70 if err != nil { 71 return entities.Attribute{}, err 72 } 73 74 attr.ForcesRecreation, err = hclparser.GetAttribute(attrs, forcesRecreationAttributeName).Bool() 75 if err != nil { 76 return entities.Attribute{}, err 77 } 78 79 attr.ReadmeExample, err = hclparser.GetAttribute(attrs, readmeExampleAttributeName).String() 80 if err != nil { 81 return entities.Attribute{}, err 82 } 83 84 // type definition 85 readmeType := hclparser.GetAttribute(attrs, readmeTypeAttributeName) 86 if readmeType == nil { 87 attr.Type, err = hclparser.GetAttribute(attrs, typeAttributeName).VarType() 88 } else { 89 attr.Type, err = readmeType.VarTypeFromString() 90 } 91 92 if err != nil { 93 return entities.Attribute{}, err 94 } 95 96 attr.Default, err = hclparser.GetAttribute(attrs, defaultAttributeName).RawJSON() 97 if err != nil { 98 return entities.Attribute{}, err 99 } 100 101 return attr, nil 102 }