hclwrite: Generate multi-line objects and maps

The previous syntax for object and map values was a single line of
key-value pairs. For example:

  object = { bar = 5, baz = true, foo = "foo" }

This is very compact, but in practice for many HCL values, less readable
and less common than a multi-line object format. This commit changes the
generated output from hclwrite to one line per attribute.

Examples of the new format:

  // Empty object/map is a single line
  a = {}

  // Single-value object/map has the attribute on a separate line
  b = {
    bar = 5
  }

  // Multi-value object/map has one line per attribute
  c = {
    bar = 5
    baz = true
  }
This commit is contained in:
Alisdair McDiarmid 2020-05-06 09:45:13 -04:00
parent 7098edec61
commit 926e53e338
3 changed files with 53 additions and 24 deletions

View File

@ -48,9 +48,13 @@ func Example_generateFromScratch() {
// Output: // Output:
// string = "foo" // string = "foo"
// //
// object = { bar = 5, baz = true, foo = "foo" } // object = {
// bool = false // bar = 5
// path = env.PATH // baz = true
// foo = "foo"
// }
// bool = false
// path = env.PATH
// //
// foo { // foo {
// hello = "world" // hello = "world"

View File

@ -119,15 +119,15 @@ func appendTokensForValue(val cty.Value, toks Tokens) Tokens {
Type: hclsyntax.TokenOBrace, Type: hclsyntax.TokenOBrace,
Bytes: []byte{'{'}, Bytes: []byte{'{'},
}) })
if val.LengthInt() > 0 {
toks = append(toks, &Token{
Type: hclsyntax.TokenNewline,
Bytes: []byte{'\n'},
})
}
i := 0 i := 0
for it := val.ElementIterator(); it.Next(); { for it := val.ElementIterator(); it.Next(); {
if i > 0 {
toks = append(toks, &Token{
Type: hclsyntax.TokenComma,
Bytes: []byte{','},
})
}
eKey, eVal := it.Element() eKey, eVal := it.Element()
if hclsyntax.ValidIdentifier(eKey.AsString()) { if hclsyntax.ValidIdentifier(eKey.AsString()) {
toks = append(toks, &Token{ toks = append(toks, &Token{
@ -142,6 +142,10 @@ func appendTokensForValue(val cty.Value, toks Tokens) Tokens {
Bytes: []byte{'='}, Bytes: []byte{'='},
}) })
toks = appendTokensForValue(eVal, toks) toks = appendTokensForValue(eVal, toks)
toks = append(toks, &Token{
Type: hclsyntax.TokenNewline,
Bytes: []byte{'\n'},
})
i++ i++
} }

View File

@ -340,10 +340,14 @@ func TestTokensForValue(t *testing.T) {
Type: hclsyntax.TokenOBrace, Type: hclsyntax.TokenOBrace,
Bytes: []byte(`{`), Bytes: []byte(`{`),
}, },
{
Type: hclsyntax.TokenNewline,
Bytes: []byte("\n"),
},
{ {
Type: hclsyntax.TokenIdent, Type: hclsyntax.TokenIdent,
Bytes: []byte(`foo`), Bytes: []byte(`foo`),
SpacesBefore: 1, SpacesBefore: 2,
}, },
{ {
Type: hclsyntax.TokenEqual, Type: hclsyntax.TokenEqual,
@ -356,9 +360,12 @@ func TestTokensForValue(t *testing.T) {
SpacesBefore: 1, SpacesBefore: 1,
}, },
{ {
Type: hclsyntax.TokenCBrace, Type: hclsyntax.TokenNewline,
Bytes: []byte(`}`), Bytes: []byte("\n"),
SpacesBefore: 1, },
{
Type: hclsyntax.TokenCBrace,
Bytes: []byte(`}`),
}, },
}, },
}, },
@ -372,10 +379,14 @@ func TestTokensForValue(t *testing.T) {
Type: hclsyntax.TokenOBrace, Type: hclsyntax.TokenOBrace,
Bytes: []byte(`{`), Bytes: []byte(`{`),
}, },
{
Type: hclsyntax.TokenNewline,
Bytes: []byte("\n"),
},
{ {
Type: hclsyntax.TokenIdent, Type: hclsyntax.TokenIdent,
Bytes: []byte(`bar`), Bytes: []byte(`bar`),
SpacesBefore: 1, SpacesBefore: 2,
}, },
{ {
Type: hclsyntax.TokenEqual, Type: hclsyntax.TokenEqual,
@ -388,13 +399,13 @@ func TestTokensForValue(t *testing.T) {
SpacesBefore: 1, SpacesBefore: 1,
}, },
{ {
Type: hclsyntax.TokenComma, Type: hclsyntax.TokenNewline,
Bytes: []byte(`,`), Bytes: []byte("\n"),
}, },
{ {
Type: hclsyntax.TokenIdent, Type: hclsyntax.TokenIdent,
Bytes: []byte(`foo`), Bytes: []byte(`foo`),
SpacesBefore: 1, SpacesBefore: 2,
}, },
{ {
Type: hclsyntax.TokenEqual, Type: hclsyntax.TokenEqual,
@ -407,9 +418,12 @@ func TestTokensForValue(t *testing.T) {
SpacesBefore: 1, SpacesBefore: 1,
}, },
{ {
Type: hclsyntax.TokenCBrace, Type: hclsyntax.TokenNewline,
Bytes: []byte(`}`), Bytes: []byte("\n"),
SpacesBefore: 1, },
{
Type: hclsyntax.TokenCBrace,
Bytes: []byte(`}`),
}, },
}, },
}, },
@ -422,10 +436,14 @@ func TestTokensForValue(t *testing.T) {
Type: hclsyntax.TokenOBrace, Type: hclsyntax.TokenOBrace,
Bytes: []byte(`{`), Bytes: []byte(`{`),
}, },
{
Type: hclsyntax.TokenNewline,
Bytes: []byte("\n"),
},
{ {
Type: hclsyntax.TokenOQuote, Type: hclsyntax.TokenOQuote,
Bytes: []byte(`"`), Bytes: []byte(`"`),
SpacesBefore: 1, SpacesBefore: 2,
}, },
{ {
Type: hclsyntax.TokenQuotedLit, Type: hclsyntax.TokenQuotedLit,
@ -446,9 +464,12 @@ func TestTokensForValue(t *testing.T) {
SpacesBefore: 1, SpacesBefore: 1,
}, },
{ {
Type: hclsyntax.TokenCBrace, Type: hclsyntax.TokenNewline,
Bytes: []byte(`}`), Bytes: []byte("\n"),
SpacesBefore: 1, },
{
Type: hclsyntax.TokenCBrace,
Bytes: []byte(`}`),
}, },
}, },
}, },