-
Notifications
You must be signed in to change notification settings - Fork 69
/
text.go
125 lines (103 loc) · 2.6 KB
/
text.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package output
import (
"errors"
"fmt"
"os"
"reflect"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
)
func (o *Output) text(data interface{}) error {
// Early quit on no data
if data == nil {
return nil
}
if o == nil {
return errors.New("invalid output formatter")
}
// Let's see what they sent us
switch v := reflect.ValueOf(data); v.Kind() {
case reflect.String:
fmt.Println(data)
case reflect.Slice, reflect.Struct:
return o.renderAsTable(data)
default:
return fmt.Errorf("unable to format data type: %T", data)
}
return nil
}
func (o *Output) renderAsTable(data interface{}) error {
// Early quit on no data
if data == nil {
return nil
}
if o == nil {
return errors.New("invalid output formatter")
}
tw := o.newTableWriter()
// Let's see what they sent us
switch v := reflect.ValueOf(data); v.Kind() {
case reflect.Slice:
// Create the header from the field names
typ := reflect.TypeOf(data).Elem()
cols := typ.NumField()
header := make([]interface{}, cols)
colConfig := make([]table.ColumnConfig, cols)
for i := 0; i < cols; i++ {
header[i] = typ.Field(i).Name
colConfig[i].Name = typ.Field(i).Name
colConfig[i].WidthMin = len(typ.Field(i).Name)
colConfig[i].WidthMax = o.terminalWidth * 3 / 4
colConfig[i].WidthMaxEnforcer = text.WrapSoft
}
tw.SetColumnConfigs(colConfig)
tw.AppendHeader(table.Row(header))
// Add all the rows
for i := 0; i < v.Len(); i++ {
row := make([]interface{}, v.Index(i).NumField())
for f := 0; f < v.Index(i).NumField(); f++ {
row[f] = v.Index(i).Field(f).Interface()
}
tw.AppendRow(table.Row(row))
}
// Single Struct becomes table view of Field | Value
case reflect.Struct:
typ := reflect.TypeOf(data)
tw.AppendHeader(table.Row{"Field", "Value"})
for f := 0; f < typ.NumField(); f++ {
row := []interface{}{
typ.Field(f).Name,
v.Field(f).Interface(),
}
tw.AppendRow(table.Row(row))
}
default:
return fmt.Errorf("unable to format data as table - type: %T", data)
}
tw.Render()
return nil
}
func (o *Output) newTableWriter() table.Writer {
t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.SetAllowedRowLength(o.terminalWidth)
t.SetStyle(table.StyleRounded)
t.SetStyle(table.Style{
Name: "nr-cli-table",
//Box: table.StyleBoxRounded,
Box: table.BoxStyle{
MiddleHorizontal: "-",
MiddleSeparator: " ",
MiddleVertical: " ",
},
Color: table.ColorOptions{
Header: text.Colors{text.Bold},
},
Options: table.Options{
DrawBorder: false,
SeparateColumns: true,
SeparateHeader: true,
},
})
return t
}