github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/configs/compat_shim.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/hclsyntax" 9 "github.com/zclconf/go-cty/cty" 10 ) 11 12 // ------------------------------------------------------------------------- 13 // Functions in this file are compatibility shims intended to ease conversion 14 // from the old configuration loader. Any use of these functions that makes 15 // a change should generate a deprecation warning explaining to the user how 16 // to update their code for new patterns. 17 // 18 // Shims are particularly important for any patterns that have been widely 19 // documented in books, tutorials, etc. Users will still be starting from 20 // these examples and we want to help them adopt the latest patterns rather 21 // than leave them stranded. 22 // ------------------------------------------------------------------------- 23 24 // shimTraversalInString takes any arbitrary expression and checks if it is 25 // a quoted string in the native syntax. If it _is_, then it is parsed as a 26 // traversal and re-wrapped into a synthetic traversal expression and a 27 // warning is generated. Otherwise, the given expression is just returned 28 // verbatim. 29 // 30 // This function has no effect on expressions from the JSON syntax, since 31 // traversals in strings are the required pattern in that syntax. 32 // 33 // If wantKeyword is set, the generated warning diagnostic will talk about 34 // keywords rather than references. The behavior is otherwise unchanged, and 35 // the caller remains responsible for checking that the result is indeed 36 // a keyword, e.g. using hcl.ExprAsKeyword. 37 func shimTraversalInString(expr hcl.Expression, wantKeyword bool) (hcl.Expression, hcl.Diagnostics) { 38 // ObjectConsKeyExpr is a special wrapper type used for keys on object 39 // constructors to deal with the fact that naked identifiers are normally 40 // handled as "bareword" strings rather than as variable references. Since 41 // we know we're interpreting as a traversal anyway (and thus it won't 42 // matter whether it's a string or an identifier) we can safely just unwrap 43 // here and then process whatever we find inside as normal. 44 if ocke, ok := expr.(*hclsyntax.ObjectConsKeyExpr); ok { 45 expr = ocke.Wrapped 46 } 47 48 if !exprIsNativeQuotedString(expr) { 49 return expr, nil 50 } 51 52 strVal, diags := expr.Value(nil) 53 if diags.HasErrors() || strVal.IsNull() || !strVal.IsKnown() { 54 // Since we're not even able to attempt a shim here, we'll discard 55 // the diagnostics we saw so far and let the caller's own error 56 // handling take care of reporting the invalid expression. 57 return expr, nil 58 } 59 60 // The position handling here isn't _quite_ right because it won't 61 // take into account any escape sequences in the literal string, but 62 // it should be close enough for any error reporting to make sense. 63 srcRange := expr.Range() 64 startPos := srcRange.Start // copy 65 startPos.Column++ // skip initial quote 66 startPos.Byte++ // skip initial quote 67 68 traversal, tDiags := hclsyntax.ParseTraversalAbs( 69 []byte(strVal.AsString()), 70 srcRange.Filename, 71 startPos, 72 ) 73 diags = append(diags, tDiags...) 74 75 if wantKeyword { 76 diags = append(diags, &hcl.Diagnostic{ 77 Severity: hcl.DiagWarning, 78 Summary: "Quoted keywords are deprecated", 79 Detail: "In this context, keywords are expected literally rather than in quotes. Terraform 0.11 and earlier required quotes, but quoted keywords are now deprecated and will be removed in a future version of Terraform. Remove the quotes surrounding this keyword to silence this warning.", 80 Subject: &srcRange, 81 }) 82 } else { 83 diags = append(diags, &hcl.Diagnostic{ 84 Severity: hcl.DiagWarning, 85 Summary: "Quoted references are deprecated", 86 Detail: "In this context, references are expected literally rather than in quotes. Terraform 0.11 and earlier required quotes, but quoted references are now deprecated and will be removed in a future version of Terraform. Remove the quotes surrounding this reference to silence this warning.", 87 Subject: &srcRange, 88 }) 89 } 90 91 return &hclsyntax.ScopeTraversalExpr{ 92 Traversal: traversal, 93 SrcRange: srcRange, 94 }, diags 95 } 96 97 // shimIsIgnoreChangesStar returns true if the given expression seems to be 98 // a string literal whose value is "*". This is used to support a legacy 99 // form of ignore_changes = all . 100 // 101 // This function does not itself emit any diagnostics, so it's the caller's 102 // responsibility to emit a warning diagnostic when this function returns true. 103 func shimIsIgnoreChangesStar(expr hcl.Expression) bool { 104 val, valDiags := expr.Value(nil) 105 if valDiags.HasErrors() { 106 return false 107 } 108 if val.Type() != cty.String || val.IsNull() || !val.IsKnown() { 109 return false 110 } 111 return val.AsString() == "*" 112 }