summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Atkins <mart@degeneration.co.uk>2018-12-14 14:46:44 -0800
committerMartin Atkins <mart@degeneration.co.uk>2018-12-14 14:46:44 -0800
commit4c4fdbdcc016df0562391a71965701efa4a1408c (patch)
treeb39f136955899d288a22616534b21405c5e6ab52
parent002296d7bb6a2f74d3eb2a3915409ae60a6a4ba3 (diff)
hclwrite: Suspend indentation adjustment inside heredocs
Leading whitespace is significant in heredocs, so we'll avoid making any indentation adjustments for lines between OHeredoc and CHeredoc. This fixes #31.
-rw-r--r--hclwrite/format.go47
-rw-r--r--hclwrite/format_test.go80
2 files changed, 124 insertions, 3 deletions
diff --git a/hclwrite/format.go b/hclwrite/format.go
index c699195..ad17121 100644
--- a/hclwrite/format.go
+++ b/hclwrite/format.go
@@ -54,14 +54,22 @@ func formatIndent(lines []formatLine) {
// which should be more than enough for reasonable HCL uses.
indents := make([]int, 0, 10)
+ inHeredoc := false
for i := range lines {
- // TODO: need to track when we're inside a multi-line template and
- // suspend indentation processing.
-
line := &lines[i]
if len(line.lead) == 0 {
continue
}
+
+ if inHeredoc {
+ for _, token := range line.lead {
+ if token.Type == hclsyntax.TokenCHeredoc {
+ inHeredoc = false
+ }
+ }
+ continue // don't touch indentation inside heredocs
+ }
+
if line.lead[0].Type == hclsyntax.TokenNewline {
// Never place spaces before a newline
line.lead[0].SpacesBefore = 0
@@ -74,6 +82,9 @@ func formatIndent(lines []formatLine) {
}
for _, token := range line.assign {
netBrackets += tokenBracketChange(token)
+ if token.Type == hclsyntax.TokenOHeredoc {
+ inHeredoc = true
+ }
}
switch {
@@ -309,6 +320,15 @@ func spaceAfterToken(subject, before, after *Token) bool {
// Never spaces before colons
return false
+ // In the unlikely event that an interpolation expression is just
+ // a single object constructor, we'll put a space between the ${ and
+ // the following { to make this more obvious, and then the same
+ // thing for the two braces at the end.
+ case (subject.Type == hclsyntax.TokenTemplateInterp || subject.Type == hclsyntax.TokenTemplateControl) && after.Type == hclsyntax.TokenOBrace:
+ return true
+ case subject.Type == hclsyntax.TokenCBrace && after.Type == hclsyntax.TokenTemplateSeqEnd:
+ return true
+
case tokenBracketChange(subject) > 0:
// No spaces after open brackets
return false
@@ -371,6 +391,7 @@ func linesForFormat(tokens Tokens) []formatLine {
// Now we'll pick off any trailing comments and attribute assignments
// to shuffle off into the "comment" and "assign" cells.
+ inHeredoc := false
for i := range lines {
line := &lines[i]
if len(line.lead) == 0 {
@@ -380,6 +401,26 @@ func linesForFormat(tokens Tokens) []formatLine {
continue
}
+ if inHeredoc {
+ for _, tok := range line.lead {
+ if tok.Type == hclsyntax.TokenCHeredoc {
+ inHeredoc = false
+ break
+ }
+ }
+ // Inside a heredoc everything is "lead", even if there's a
+ // template interpolation embedded in there that might otherwise
+ // confuse our logic below.
+ continue
+ }
+
+ for _, tok := range line.lead {
+ if tok.Type == hclsyntax.TokenOHeredoc {
+ inHeredoc = true
+ break
+ }
+ }
+
if len(line.lead) > 1 && line.lead[len(line.lead)-1].Type == hclsyntax.TokenComment {
line.comment = line.lead[len(line.lead)-1:]
line.lead = line.lead[:len(line.lead)-1]
diff --git a/hclwrite/format_test.go b/hclwrite/format_test.go
index 1c06682..9106466 100644
--- a/hclwrite/format_test.go
+++ b/hclwrite/format_test.go
@@ -418,6 +418,86 @@ foo {
}
`,
},
+ {
+ `
+foo {
+bar = <<EOT
+Foo bar baz
+EOT
+}
+`,
+ `
+foo {
+ bar = <<EOT
+Foo bar baz
+EOT
+}
+`,
+ },
+ {
+ `
+foo {
+bar = <<-EOT
+Foo bar baz
+EOT
+}
+`,
+ `
+foo {
+ bar = <<-EOT
+Foo bar baz
+EOT
+}
+`,
+ },
+ {
+ `
+foo {
+bar = <<-EOT
+ Foo bar baz
+EOT
+}
+`,
+ `
+foo {
+ bar = <<-EOT
+ Foo bar baz
+EOT
+}
+`,
+ },
+ {
+ `
+foo {
+bar = <<-EOT
+ blahblahblah = x
+EOT
+}
+`,
+ `
+foo {
+ bar = <<-EOT
+ blahblahblah = x
+EOT
+}
+`,
+ },
+ {
+ `
+foo {
+bar = <<-EOT
+ ${{ blahblahblah = x }}
+EOT
+}
+`,
+ `
+foo {
+ bar = <<-EOT
+ ${ { blahblahblah = x } }
+EOT
+}
+`,
+ },
}
for i, test := range tests {