Skip to content

Commit

Permalink
Merge pull request #635 from hashicorp/jbardin/WithoutOptionalAttribu…
Browse files Browse the repository at this point in the history
…tesDeep

hcldec must use WithoutOptionalAttributesDeep
  • Loading branch information
jbardin authored Oct 18, 2023
2 parents 925bfe8 + 9847e90 commit 341ffa4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
28 changes: 28 additions & 0 deletions hcldec/public_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,20 @@ func TestDecode(t *testing.T) {
cty.NullVal(cty.Number),
1, // attribute "a" is required
},
{
``,
&AttrSpec{
Name: "a",
Type: cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"attr": cty.String,
}, []string{"attr"}),
},
nil,
cty.NullVal(cty.Object(map[string]cty.Type{
"attr": cty.String,
})),
0,
},

{
`
Expand Down Expand Up @@ -328,6 +342,20 @@ b {
cty.NullVal(cty.Map(cty.String)),
1, // missing b block
},
{
``,
&BlockAttrsSpec{
TypeName: "b",
ElementType: cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"attr": cty.String,
}, []string{"attr"}),
},
nil,
cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{
"attr": cty.String,
}))),
0,
},
{
`
b {
Expand Down
31 changes: 15 additions & 16 deletions hcldec/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,13 @@ func (s *AttrSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel, ct
if !exists {
// We don't need to check required and emit a diagnostic here, because
// that would already have happened when building "content".
return cty.NullVal(s.Type), nil
return cty.NullVal(s.Type.WithoutOptionalAttributesDeep()), nil
}

if decodeFn := customdecode.CustomExpressionDecoderForType(s.Type); decodeFn != nil {
v, diags := decodeFn(attr.Expr, ctx)
if v == cty.NilVal {
v = cty.UnknownVal(s.Type)
v = cty.UnknownVal(s.Type.WithoutOptionalAttributesDeep())
}
return v, diags
}
Expand All @@ -229,7 +229,7 @@ func (s *AttrSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel, ct
})
// We'll return an unknown value of the _correct_ type so that the
// incomplete result can still be used for some analysis use-cases.
val = cty.UnknownVal(s.Type)
val = cty.UnknownVal(s.Type.WithoutOptionalAttributesDeep())
} else {
val = convVal
}
Expand Down Expand Up @@ -381,7 +381,7 @@ func (s *BlockSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel, c
Subject: &content.MissingItemRange,
})
}
return cty.NullVal(s.Nested.impliedType()), diags
return cty.NullVal(s.Nested.impliedType().WithoutOptionalAttributesDeep()), diags
}

if s.Nested == nil {
Expand Down Expand Up @@ -478,7 +478,7 @@ func (s *BlockListSpec) decode(content *hcl.BodyContent, blockLabels []blockLabe
if u.Unknown() {
// If any block Body is unknown, then the entire block value
// must be unknown
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}
}

Expand Down Expand Up @@ -640,7 +640,7 @@ func (s *BlockTupleSpec) decode(content *hcl.BodyContent, blockLabels []blockLab
if u.Unknown() {
// If any block Body is unknown, then the entire block value
// must be unknown
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}
}

Expand Down Expand Up @@ -763,7 +763,7 @@ func (s *BlockSetSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel
if u.Unknown() {
// If any block Body is unknown, then the entire block value
// must be unknown
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}
}

Expand Down Expand Up @@ -922,7 +922,7 @@ func (s *BlockMapSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel
if u.Unknown() {
// If any block Body is unknown, then the entire block value
// must be unknown
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}
}

Expand Down Expand Up @@ -1076,7 +1076,7 @@ func (s *BlockObjectSpec) decode(content *hcl.BodyContent, blockLabels []blockLa
if u.Unknown() {
// If any block Body is unknown, then the entire block value
// must be unknown
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}
}

Expand Down Expand Up @@ -1250,7 +1250,7 @@ func (s *BlockAttrsSpec) decode(content *hcl.BodyContent, blockLabels []blockLab
Subject: &content.MissingItemRange,
})
}
return cty.NullVal(cty.Map(s.ElementType)), diags
return cty.NullVal(cty.Map(s.ElementType).WithoutOptionalAttributesDeep()), diags
}
if other != nil {
diags = append(diags, &hcl.Diagnostic{
Expand Down Expand Up @@ -1513,7 +1513,7 @@ func (s *TransformExprSpec) decode(content *hcl.BodyContent, blockLabels []block
// We won't try to run our function in this case, because it'll probably
// generate confusing additional errors that will distract from the
// root cause.
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}

chiCtx := s.TransformCtx.NewChild()
Expand Down Expand Up @@ -1569,7 +1569,7 @@ func (s *TransformFuncSpec) decode(content *hcl.BodyContent, blockLabels []block
// We won't try to run our function in this case, because it'll probably
// generate confusing additional errors that will distract from the
// root cause.
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}

resultVal, err := s.Func.Call([]cty.Value{wrappedVal})
Expand All @@ -1583,7 +1583,7 @@ func (s *TransformFuncSpec) decode(content *hcl.BodyContent, blockLabels []block
Detail: fmt.Sprintf("Decoder transform returned an error: %s", err),
Subject: s.sourceRange(content, blockLabels).Ptr(),
})
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}

return resultVal, diags
Expand Down Expand Up @@ -1637,7 +1637,7 @@ func (s *RefineValueSpec) decode(content *hcl.BodyContent, blockLabels []blockLa
// We won't try to run our function in this case, because it'll probably
// generate confusing additional errors that will distract from the
// root cause.
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}

return wrappedVal.RefineWith(s.Refine), diags
Expand All @@ -1658,7 +1658,6 @@ func (s *RefineValueSpec) sourceRange(content *hcl.BodyContent, blockLabels []bl
// The Subject field of the returned Diagnostic is optional. If not
// specified, it is automatically populated with the range covered by
// the wrapped spec.
//
type ValidateSpec struct {
Wrapped Spec
Func func(value cty.Value) hcl.Diagnostics
Expand All @@ -1674,7 +1673,7 @@ func (s *ValidateSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel
// We won't try to run our function in this case, because it'll probably
// generate confusing additional errors that will distract from the
// root cause.
return cty.UnknownVal(s.impliedType()), diags
return cty.UnknownVal(s.impliedType().WithoutOptionalAttributesDeep()), diags
}

validateDiags := s.Func(wrappedVal)
Expand Down

0 comments on commit 341ffa4

Please sign in to comment.