110 lines
4.6 KiB
Go
110 lines
4.6 KiB
Go
package configs
|
|
|
|
import (
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Functions in this file are compatibility shims intended to ease conversion
|
|
// from the old configuration loader. Any use of these functions that makes
|
|
// a change should generate a deprecation warning explaining to the user how
|
|
// to update their code for new patterns.
|
|
//
|
|
// Shims are particularly important for any patterns that have been widely
|
|
// documented in books, tutorials, etc. Users will still be starting from
|
|
// these examples and we want to help them adopt the latest patterns rather
|
|
// than leave them stranded.
|
|
// -------------------------------------------------------------------------
|
|
|
|
// shimTraversalInString takes any arbitrary expression and checks if it is
|
|
// a quoted string in the native syntax. If it _is_, then it is parsed as a
|
|
// traversal and re-wrapped into a synthetic traversal expression and a
|
|
// warning is generated. Otherwise, the given expression is just returned
|
|
// verbatim.
|
|
//
|
|
// This function has no effect on expressions from the JSON syntax, since
|
|
// traversals in strings are the required pattern in that syntax.
|
|
//
|
|
// If wantKeyword is set, the generated warning diagnostic will talk about
|
|
// keywords rather than references. The behavior is otherwise unchanged, and
|
|
// the caller remains responsible for checking that the result is indeed
|
|
// a keyword, e.g. using hcl.ExprAsKeyword.
|
|
func shimTraversalInString(expr hcl.Expression, wantKeyword bool) (hcl.Expression, hcl.Diagnostics) {
|
|
// ObjectConsKeyExpr is a special wrapper type used for keys on object
|
|
// constructors to deal with the fact that naked identifiers are normally
|
|
// handled as "bareword" strings rather than as variable references. Since
|
|
// we know we're interpreting as a traversal anyway (and thus it won't
|
|
// matter whether it's a string or an identifier) we can safely just unwrap
|
|
// here and then process whatever we find inside as normal.
|
|
if ocke, ok := expr.(*hclsyntax.ObjectConsKeyExpr); ok {
|
|
expr = ocke.Wrapped
|
|
}
|
|
|
|
if !exprIsNativeQuotedString(expr) {
|
|
return expr, nil
|
|
}
|
|
|
|
strVal, diags := expr.Value(nil)
|
|
if diags.HasErrors() || strVal.IsNull() || !strVal.IsKnown() {
|
|
// Since we're not even able to attempt a shim here, we'll discard
|
|
// the diagnostics we saw so far and let the caller's own error
|
|
// handling take care of reporting the invalid expression.
|
|
return expr, nil
|
|
}
|
|
|
|
// The position handling here isn't _quite_ right because it won't
|
|
// take into account any escape sequences in the literal string, but
|
|
// it should be close enough for any error reporting to make sense.
|
|
srcRange := expr.Range()
|
|
startPos := srcRange.Start // copy
|
|
startPos.Column++ // skip initial quote
|
|
startPos.Byte++ // skip initial quote
|
|
|
|
traversal, tDiags := hclsyntax.ParseTraversalAbs(
|
|
[]byte(strVal.AsString()),
|
|
srcRange.Filename,
|
|
startPos,
|
|
)
|
|
diags = append(diags, tDiags...)
|
|
|
|
if wantKeyword {
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
Severity: hcl.DiagWarning,
|
|
Summary: "Quoted keywords are deprecated",
|
|
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.",
|
|
Subject: &srcRange,
|
|
})
|
|
} else {
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
Severity: hcl.DiagWarning,
|
|
Summary: "Quoted references are deprecated",
|
|
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.",
|
|
Subject: &srcRange,
|
|
})
|
|
}
|
|
|
|
return &hclsyntax.ScopeTraversalExpr{
|
|
Traversal: traversal,
|
|
SrcRange: srcRange,
|
|
}, diags
|
|
}
|
|
|
|
// shimIsIgnoreChangesStar returns true if the given expression seems to be
|
|
// a string literal whose value is "*". This is used to support a legacy
|
|
// form of ignore_changes = all .
|
|
//
|
|
// This function does not itself emit any diagnostics, so it's the caller's
|
|
// responsibility to emit a warning diagnostic when this function returns true.
|
|
func shimIsIgnoreChangesStar(expr hcl.Expression) bool {
|
|
val, valDiags := expr.Value(nil)
|
|
if valDiags.HasErrors() {
|
|
return false
|
|
}
|
|
if val.Type() != cty.String || val.IsNull() || !val.IsKnown() {
|
|
return false
|
|
}
|
|
return val.AsString() == "*"
|
|
}
|