repl: fix formatting of list and map values

The indent function was stripping out newlines, causing multi-element
lists and maps to be rendered incorrectly.

We were also not quoting strings in these nested structures, leading to
weird behavior if any expression punctuation or newlines were present in
these strings.

This part of Terraform will get a more serious overhaul as part of
switching to the new parser/interpreter implementation but this is a
tactical fix to make the results of this command more usable in the
short term.
This commit is contained in:
Martin Atkins 2018-03-28 12:03:29 -07:00
parent 68ff5f767c
commit 5659128126
1 changed files with 20 additions and 11 deletions

View File

@ -13,12 +13,15 @@ import (
// The value must currently be a string, list, map, and any nested values // The value must currently be a string, list, map, and any nested values
// with those same types. // with those same types.
func FormatResult(value interface{}) (string, error) { func FormatResult(value interface{}) (string, error) {
return formatResult(value) return formatResult(value, false)
} }
func formatResult(value interface{}) (string, error) { func formatResult(value interface{}, nested bool) (string, error) {
switch output := value.(type) { switch output := value.(type) {
case string: case string:
if nested {
return fmt.Sprintf("%q", output), nil
}
return output, nil return output, nil
case []interface{}: case []interface{}:
return formatListResult(output) return formatListResult(output)
@ -36,18 +39,14 @@ func formatListResult(value []interface{}) (string, error) {
outputBuf.WriteString("\n") outputBuf.WriteString("\n")
} }
lastIdx := len(value) - 1 for _, v := range value {
for i, v := range value { raw, err := formatResult(v, true)
raw, err := formatResult(v)
if err != nil { if err != nil {
return "", err return "", err
} }
outputBuf.WriteString(indent(raw)) outputBuf.WriteString(indent(raw))
if lastIdx != i { outputBuf.WriteString(",\n")
outputBuf.WriteString(",")
}
outputBuf.WriteString("\n")
} }
outputBuf.WriteString("]") outputBuf.WriteString("]")
@ -69,12 +68,17 @@ func formatMapResult(value map[string]interface{}) (string, error) {
for _, k := range ks { for _, k := range ks {
v := value[k] v := value[k]
raw, err := formatResult(v) rawK, err := formatResult(k, true)
if err != nil {
return "", err
}
rawV, err := formatResult(v, true)
if err != nil { if err != nil {
return "", err return "", err
} }
outputBuf.WriteString(indent(fmt.Sprintf("%s = %v\n", k, raw))) outputBuf.WriteString(indent(fmt.Sprintf("%s = %s", rawK, rawV)))
outputBuf.WriteString("\n")
} }
outputBuf.WriteString("}") outputBuf.WriteString("}")
@ -84,8 +88,13 @@ func formatMapResult(value map[string]interface{}) (string, error) {
func indent(value string) string { func indent(value string) string {
var outputBuf bytes.Buffer var outputBuf bytes.Buffer
s := bufio.NewScanner(strings.NewReader(value)) s := bufio.NewScanner(strings.NewReader(value))
newline := false
for s.Scan() { for s.Scan() {
if newline {
outputBuf.WriteByte('\n')
}
outputBuf.WriteString(" " + s.Text()) outputBuf.WriteString(" " + s.Text())
newline = true
} }
return outputBuf.String() return outputBuf.String()