66 "github.com/aquasecurity/trivy/pkg/iac/terraform"
77 "github.com/hashicorp/hcl/v2"
88 "github.com/zclconf/go-cty/cty"
9+ "github.com/zclconf/go-cty/cty/json"
910
1011 "github.com/coder/preview/types"
1112)
@@ -47,21 +48,6 @@ func workspaceTags(modules terraform.Modules, files map[string]*hcl.File) (types
4748 continue
4849 }
4950
50- // tagsObj, ok := tagsAttr.HCLAttribute().Expr.(*hclsyntax.ObjectConsExpr)
51- // if !ok {
52- // diags = diags.Append(&hcl.Diagnostic{
53- // Severity: hcl.DiagError,
54- // Summary: "Incorrect type for \"tags\" attribute",
55- // // TODO: better error message for types
56- // Detail: fmt.Sprintf(`"tags" attribute must be an 'ObjectConsExpr', but got %T`, tagsAttr.HCLAttribute().Expr),
57- // Subject: &tagsAttr.HCLAttribute().NameRange,
58- // Context: &tagsAttr.HCLAttribute().Range,
59- // Expression: tagsAttr.HCLAttribute().Expr,
60- // EvalContext: block.Context().Inner(),
61- // })
62- // continue
63- //}
64-
6551 var tags []types.Tag
6652 tagsValue .ForEachElement (func (key cty.Value , val cty.Value ) (stop bool ) {
6753 r := tagsAttr .HCLAttribute ().Expr .Range ()
@@ -75,15 +61,7 @@ func workspaceTags(modules terraform.Modules, files map[string]*hcl.File) (types
7561
7662 return false
7763 })
78- // for _, item := range tagsObj.Items {
79- // tag, tagDiag := newTag(tagsObj, files, item, evCtx)
80- // if tagDiag != nil {
81- // diags = diags.Append(tagDiag)
82- // continue
83- // }
84- //
85- // tags = append(tags, tag)
86- //}
64+
8765 tagBlocks = append (tagBlocks , types.TagBlock {
8866 Tags : tags ,
8967 Block : block ,
@@ -96,73 +74,47 @@ func workspaceTags(modules terraform.Modules, files map[string]*hcl.File) (types
9674
9775// newTag creates a workspace tag from its hcl expression.
9876func newTag (srcRange * hcl.Range , _ map [string ]* hcl.File , key , val cty.Value ) (types.Tag , * hcl.Diagnostic ) {
99- // key, kdiags := expr.KeyExpr.Value(evCtx)
100- // val, vdiags := expr.ValueExpr.Value(evCtx)
101-
102- // TODO: ???
103-
104- // if kdiags.HasErrors() {
105- // key = cty.UnknownVal(cty.String)
106- //}
107- // if vdiags.HasErrors() {
108- // val = cty.UnknownVal(cty.String)
109- //}
110-
11177 if key .IsKnown () && key .Type () != cty .String {
11278 return types.Tag {}, & hcl.Diagnostic {
11379 Severity : hcl .DiagError ,
11480 Summary : "Invalid key type for tags" ,
11581 Detail : fmt .Sprintf ("Key must be a string, but got %s" , key .Type ().FriendlyName ()),
116- //Subject: &r,
117- Context : srcRange ,
118- //Expression: expr.KeyExpr,
119- //EvalContext: evCtx,
82+ Context : srcRange ,
12083 }
12184 }
12285
12386 tag := types.Tag {
12487 Key : types.HCLString {
12588 Value : key ,
126- //ValueDiags: kdiags,
127- //ValueExpr: expr.KeyExpr,
12889 },
12990 Value : types.HCLString {
13091 Value : val ,
131- //ValueDiags: vdiags,
132- //ValueExpr: expr.ValueExpr,
13392 },
13493 }
13594
136- // If the value is known, but the type is not a string, bool, or number.
137- // Then throw an error. Only the supported types can safely be converted to a string.
138- if ! (val .Type () == cty .String || val .Type () == cty .Bool || val .Type () == cty .Number ) {
95+ switch val .Type () {
96+ case cty .String , cty .Bool , cty .Number :
97+ // These types are supported and can be safely converted to a string.
98+ default :
13999 fr := "<nil>"
140100 if ! val .Type ().Equals (cty .NilType ) {
141101 fr = val .Type ().FriendlyName ()
142102 }
143103
144- tag .Value .ValueDiags = tag .Value .ValueDiags .Append (& hcl.Diagnostic {
145- Severity : hcl .DiagError ,
146- Summary : fmt .Sprintf ("Invalid value type for tag %q" , tag .KeyString ()),
147- Detail : fmt .Sprintf ("Value must be a string, but got %s" , fr ),
148- //Subject: &r,
149- Context : srcRange ,
150- //Expression: expr.ValueExpr,
151- //EvalContext: evCtx,
152- })
104+ // Unsupported types will be converted to a JSON string representation.
105+ jsonData , err := json .Marshal (val , val .Type ())
106+ if err != nil {
107+ tag .Value .ValueDiags = tag .Value .ValueDiags .Append (& hcl.Diagnostic {
108+ Severity : hcl .DiagError ,
109+ Summary : fmt .Sprintf ("Invalid value type for tag %q" , tag .KeyString ()),
110+ Detail : fmt .Sprintf ("Value must be a string, but got %s. Attempt to marshal to json: %s" , fr , err .Error ()),
111+ Context : srcRange ,
112+ })
113+ } else {
114+ // Value successfully marshaled to JSON, we can store it as a string.
115+ tag .Value .Value = cty .StringVal (string (jsonData ))
116+ }
153117 }
154118
155- // ks, err := source(expr.KeyExpr.Range(), files)
156- // if err == nil {
157- // src := string(ks)
158- // tag.Key.Source = &src
159- //}
160- //
161- // vs, err := source(expr.ValueExpr.Range(), files)
162- // if err == nil {
163- // src := string(vs)
164- // tag.Value.Source = &src
165- //}
166-
167119 return tag , nil
168120}
0 commit comments