mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-20 11:48:24 -06:00
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.
102 lines
2.0 KiB
Go
102 lines
2.0 KiB
Go
package repl
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// FormatResult formats the given result value for human-readable output.
|
|
//
|
|
// The value must currently be a string, list, map, and any nested values
|
|
// with those same types.
|
|
func FormatResult(value interface{}) (string, error) {
|
|
return formatResult(value, false)
|
|
}
|
|
|
|
func formatResult(value interface{}, nested bool) (string, error) {
|
|
switch output := value.(type) {
|
|
case string:
|
|
if nested {
|
|
return fmt.Sprintf("%q", output), nil
|
|
}
|
|
return output, nil
|
|
case []interface{}:
|
|
return formatListResult(output)
|
|
case map[string]interface{}:
|
|
return formatMapResult(output)
|
|
default:
|
|
return "", fmt.Errorf("unknown value type: %T", value)
|
|
}
|
|
}
|
|
|
|
func formatListResult(value []interface{}) (string, error) {
|
|
var outputBuf bytes.Buffer
|
|
outputBuf.WriteString("[")
|
|
if len(value) > 0 {
|
|
outputBuf.WriteString("\n")
|
|
}
|
|
|
|
for _, v := range value {
|
|
raw, err := formatResult(v, true)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
outputBuf.WriteString(indent(raw))
|
|
outputBuf.WriteString(",\n")
|
|
}
|
|
|
|
outputBuf.WriteString("]")
|
|
return outputBuf.String(), nil
|
|
}
|
|
|
|
func formatMapResult(value map[string]interface{}) (string, error) {
|
|
ks := make([]string, 0, len(value))
|
|
for k, _ := range value {
|
|
ks = append(ks, k)
|
|
}
|
|
sort.Strings(ks)
|
|
|
|
var outputBuf bytes.Buffer
|
|
outputBuf.WriteString("{")
|
|
if len(value) > 0 {
|
|
outputBuf.WriteString("\n")
|
|
}
|
|
|
|
for _, k := range ks {
|
|
v := value[k]
|
|
rawK, err := formatResult(k, true)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
rawV, err := formatResult(v, true)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
outputBuf.WriteString(indent(fmt.Sprintf("%s = %s", rawK, rawV)))
|
|
outputBuf.WriteString("\n")
|
|
}
|
|
|
|
outputBuf.WriteString("}")
|
|
return outputBuf.String(), nil
|
|
}
|
|
|
|
func indent(value string) string {
|
|
var outputBuf bytes.Buffer
|
|
s := bufio.NewScanner(strings.NewReader(value))
|
|
newline := false
|
|
for s.Scan() {
|
|
if newline {
|
|
outputBuf.WriteByte('\n')
|
|
}
|
|
outputBuf.WriteString(" " + s.Text())
|
|
newline = true
|
|
}
|
|
|
|
return outputBuf.String()
|
|
}
|