Skip to content

Commit

Permalink
core: Correctly format nested outputs
Browse files Browse the repository at this point in the history
This commit pretty prints outputs which consist of nested complex
structures (e.g. lists of lists, lists of maps).

Fixes #7143.
  • Loading branch information
jen20 committed Jul 12, 2016
1 parent 6aa9243 commit e1ce2ab
Showing 1 changed file with 77 additions and 5 deletions.
82 changes: 77 additions & 5 deletions command/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,16 @@ func (c *OutputCommand) Run(args []string) int {
break
}

c.Ui.Output(fmt.Sprintf("%s", output[indexInt]))
outputVal := output[indexInt]
switch typedOutputVal := outputVal.(type) {
case string:
c.Ui.Output(fmt.Sprintf("%s", typedOutputVal))
case []interface{}:
c.Ui.Output(fmt.Sprintf("%s", formatNestedList("", typedOutputVal)))
case map[string]interface{}:
c.Ui.Output(fmt.Sprintf("%s", formatNestedMap("", typedOutputVal)))
}

return 0
case map[string]interface{}:
if index == "" {
Expand All @@ -131,7 +140,14 @@ func (c *OutputCommand) Run(args []string) int {
}

if value, ok := output[index]; ok {
c.Ui.Output(fmt.Sprintf("%s", value))
switch typedOutputVal := value.(type) {
case string:
c.Ui.Output(fmt.Sprintf("%s", typedOutputVal))
case []interface{}:
c.Ui.Output(fmt.Sprintf("%s", formatNestedList("", typedOutputVal)))
case map[string]interface{}:
c.Ui.Output(fmt.Sprintf("%s", formatNestedMap("", typedOutputVal)))
}
return 0
} else {
return 1
Expand All @@ -144,18 +160,50 @@ func (c *OutputCommand) Run(args []string) int {
return 0
}

func formatNestedList(indent string, outputList []interface{}) string {
outputBuf := new(bytes.Buffer)
outputBuf.WriteString(fmt.Sprintf("%s[", indent))

lastIdx := len(outputList) - 1

for i, value := range outputList {
outputBuf.WriteString(fmt.Sprintf("\n%s%s%s", indent, " ", value))
if i != lastIdx {
outputBuf.WriteString(",")
}
}

outputBuf.WriteString(fmt.Sprintf("\n%s]", indent))
return strings.TrimPrefix(outputBuf.String(), "\n")
}

func formatListOutput(indent, outputName string, outputList []interface{}) string {
keyIndent := ""

outputBuf := new(bytes.Buffer)

if outputName != "" {
outputBuf.WriteString(fmt.Sprintf("%s%s = [", indent, outputName))
keyIndent = " "
keyIndent = " "
}

for _, value := range outputList {
outputBuf.WriteString(fmt.Sprintf("\n%s%s%s", indent, keyIndent, value))
lastIdx := len(outputList) - 1

for i, value := range outputList {
switch typedValue := value.(type) {
case string:
outputBuf.WriteString(fmt.Sprintf("\n%s%s%s", indent, keyIndent, value))
case []interface{}:
outputBuf.WriteString(fmt.Sprintf("\n%s%s", indent,
formatNestedList(indent+keyIndent, typedValue)))
case map[string]interface{}:
outputBuf.WriteString(fmt.Sprintf("\n%s%s", indent,
formatNestedMap(indent+keyIndent, typedValue)))
}

if lastIdx != i {
outputBuf.WriteString(",")
}
}

if outputName != "" {
Expand All @@ -169,6 +217,30 @@ func formatListOutput(indent, outputName string, outputList []interface{}) strin
return strings.TrimPrefix(outputBuf.String(), "\n")
}

func formatNestedMap(indent string, outputMap map[string]interface{}) string {
ks := make([]string, 0, len(outputMap))
for k, _ := range outputMap {
ks = append(ks, k)
}
sort.Strings(ks)

outputBuf := new(bytes.Buffer)
outputBuf.WriteString(fmt.Sprintf("%s{", indent))

lastIdx := len(outputMap) - 1
for i, k := range ks {
v := outputMap[k]
outputBuf.WriteString(fmt.Sprintf("\n%s%s = %v", indent+" ", k, v))

if lastIdx != i {
outputBuf.WriteString(",")
}
}

outputBuf.WriteString(fmt.Sprintf("\n%s}", indent))

return strings.TrimPrefix(outputBuf.String(), "\n")
}
func formatMapOutput(indent, outputName string, outputMap map[string]interface{}) string {
ks := make([]string, 0, len(outputMap))
for k, _ := range outputMap {
Expand Down

0 comments on commit e1ce2ab

Please sign in to comment.