diff --git a/command/fmt.go b/command/fmt.go index 09c7ea740..d133e307b 100644 --- a/command/fmt.go +++ b/command/fmt.go @@ -366,7 +366,41 @@ func (c *FmtCommand) formatValueExpr(tokens hclwrite.Tokens) hclwrite.Tokens { // "${ // foo // }" - return c.trimNewlines(inside) + trimmed := c.trimNewlines(inside) + + // Finally, we check if the unwrapped expression is on multiple lines. If + // so, we ensure that it is surrounded by parenthesis to make sure that it + // parses correctly after unwrapping. This may be redundant in some cases, + // but is required for at least multi-line ternary expressions. + isMultiLine := false + hasLeadingParen := false + hasTrailingParen := false + for i, token := range trimmed { + switch { + case i == 0 && token.Type == hclsyntax.TokenOParen: + hasLeadingParen = true + case token.Type == hclsyntax.TokenNewline: + isMultiLine = true + case i == len(trimmed)-1 && token.Type == hclsyntax.TokenCParen: + hasTrailingParen = true + } + } + if isMultiLine && !(hasLeadingParen && hasTrailingParen) { + wrapped := make(hclwrite.Tokens, 0, len(trimmed)+2) + wrapped = append(wrapped, &hclwrite.Token{ + Type: hclsyntax.TokenOParen, + Bytes: []byte("("), + }) + wrapped = append(wrapped, trimmed...) + wrapped = append(wrapped, &hclwrite.Token{ + Type: hclsyntax.TokenCParen, + Bytes: []byte(")"), + }) + + return wrapped + } + + return trimmed } func (c *FmtCommand) formatTypeExpr(tokens hclwrite.Tokens) hclwrite.Tokens { diff --git a/command/testdata/fmt/general_in.tf b/command/testdata/fmt/general_in.tf index 0ee143731..94db1893f 100644 --- a/command/testdata/fmt/general_in.tf +++ b/command/testdata/fmt/general_in.tf @@ -42,3 +42,12 @@ resource "foo_instance" /* ... */ "baz" { provider "" { } + +locals { + name = "${contains(["foo"], var.my_var) ? "${var.my_var}-bar" : + contains(["baz"], var.my_var) ? "baz-${var.my_var}" : + file("ERROR: unsupported type ${var.my_var}")}" + wrapped = "${(var.my_var == null ? 1 : + var.your_var == null ? 2 : + 3)}" +} diff --git a/command/testdata/fmt/general_out.tf b/command/testdata/fmt/general_out.tf index 974646ebd..1fe6b5b3c 100644 --- a/command/testdata/fmt/general_out.tf +++ b/command/testdata/fmt/general_out.tf @@ -42,3 +42,12 @@ resource "foo_instance" "baz" { provider "" { } + +locals { + name = (contains(["foo"], var.my_var) ? "${var.my_var}-bar" : + contains(["baz"], var.my_var) ? "baz-${var.my_var}" : + file("ERROR: unsupported type ${var.my_var}")) + wrapped = (var.my_var == null ? 1 : + var.your_var == null ? 2 : + 3) +}