github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/configs/backend.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package configs 5 6 import ( 7 "github.com/hashicorp/hcl/v2" 8 "github.com/hashicorp/hcl/v2/hcldec" 9 "github.com/terramate-io/tf/configs/configschema" 10 "github.com/zclconf/go-cty/cty" 11 ) 12 13 // Backend represents a "backend" block inside a "terraform" block in a module 14 // or file. 15 type Backend struct { 16 Type string 17 Config hcl.Body 18 19 TypeRange hcl.Range 20 DeclRange hcl.Range 21 } 22 23 func decodeBackendBlock(block *hcl.Block) (*Backend, hcl.Diagnostics) { 24 return &Backend{ 25 Type: block.Labels[0], 26 TypeRange: block.LabelRanges[0], 27 Config: block.Body, 28 DeclRange: block.DefRange, 29 }, nil 30 } 31 32 // Hash produces a hash value for the reciever that covers the type and the 33 // portions of the config that conform to the given schema. 34 // 35 // If the config does not conform to the schema then the result is not 36 // meaningful for comparison since it will be based on an incomplete result. 37 // 38 // As an exception, required attributes in the schema are treated as optional 39 // for the purpose of hashing, so that an incomplete configuration can still 40 // be hashed. Other errors, such as extraneous attributes, have no such special 41 // case. 42 func (b *Backend) Hash(schema *configschema.Block) int { 43 // Don't fail if required attributes are not set. Instead, we'll just 44 // hash them as nulls. 45 schema = schema.NoneRequired() 46 spec := schema.DecoderSpec() 47 val, _ := hcldec.Decode(b.Config, spec, nil) 48 if val == cty.NilVal { 49 val = cty.UnknownVal(schema.ImpliedType()) 50 } 51 52 toHash := cty.TupleVal([]cty.Value{ 53 cty.StringVal(b.Type), 54 val, 55 }) 56 57 return toHash.Hash() 58 }