...
1
2
3
4 package table
5
6 import (
7 "fmt"
8 "io"
9 "strings"
10 "unicode/utf8"
11
12 "k8s.io/cli-runtime/pkg/genericclioptions"
13 pe "sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
14 "sigs.k8s.io/cli-utils/pkg/object"
15 "sigs.k8s.io/cli-utils/pkg/print/common"
16 )
17
18
19 type ColumnDefinition interface {
20 Name() string
21 Header() string
22 Width() int
23 PrintResource(w io.Writer, width int, r Resource) (int, error)
24 }
25
26
27
28
29 type ResourceStates interface {
30 Resources() []Resource
31 Error() error
32 }
33
34
35
36 type Resource interface {
37 Identifier() object.ObjMetadata
38 ResourceStatus() *pe.ResourceStatus
39 SubResources() []Resource
40 }
41
42
43
44
45
46 type BaseTablePrinter struct {
47 IOStreams genericclioptions.IOStreams
48 Columns []ColumnDefinition
49 }
50
51
52
53
54
55
56 func (t *BaseTablePrinter) PrintTable(rs ResourceStates,
57 moveUpCount int) int {
58 for i := 0; i < moveUpCount; i++ {
59 t.moveUp()
60 t.eraseCurrentLine()
61 }
62
63 linePrintCount := 0
64 for i, column := range t.Columns {
65 format := fmt.Sprintf("%%-%ds", column.Width())
66 t.printOrDie(format, column.Header())
67 if i == len(t.Columns)-1 {
68 t.printOrDie("\n")
69 linePrintCount++
70 } else {
71 t.printOrDie(" ")
72 }
73 }
74
75 for _, resource := range rs.Resources() {
76 for i, column := range t.Columns {
77 written, err := column.PrintResource(t.IOStreams.Out, column.Width(), resource)
78 if err != nil {
79 panic(err)
80 }
81 remainingSpace := column.Width() - written
82 t.printOrDie(strings.Repeat(" ", remainingSpace))
83 if i == len(t.Columns)-1 {
84 t.printOrDie("\n")
85 linePrintCount++
86 } else {
87 t.printOrDie(" ")
88 }
89 }
90
91 linePrintCount += t.printSubTable(resource.SubResources(), "")
92 }
93
94 return linePrintCount
95 }
96
97
98
99
100 func (t *BaseTablePrinter) printSubTable(resources []Resource,
101 prefix string) int {
102 linePrintCount := 0
103 for j, resource := range resources {
104 for i, column := range t.Columns {
105 availableWidth := column.Width()
106 if column.Name() == "resource" {
107 if j < len(resources)-1 {
108 t.printOrDie(prefix + `├─ `)
109 } else {
110 t.printOrDie(prefix + `└─ `)
111 }
112 availableWidth -= utf8.RuneCountInString(prefix) + 3
113 }
114 written, err := column.PrintResource(t.IOStreams.Out,
115 availableWidth, resource)
116 if err != nil {
117 panic(err)
118 }
119 remainingSpace := availableWidth - written
120 t.printOrDie(strings.Repeat(" ", remainingSpace))
121 if i == len(t.Columns)-1 {
122 t.printOrDie("\n")
123 linePrintCount++
124 } else {
125 t.printOrDie(" ")
126 }
127 }
128
129 var prefix string
130 if j < len(resources)-1 {
131 prefix = `│ `
132 } else {
133 prefix = " "
134 }
135 linePrintCount += t.printSubTable(resource.SubResources(), prefix)
136 }
137 return linePrintCount
138 }
139
140 func (t *BaseTablePrinter) printOrDie(format string, a ...interface{}) {
141 _, err := fmt.Fprintf(t.IOStreams.Out, format, a...)
142 if err != nil {
143 panic(err)
144 }
145 }
146
147 func (t *BaseTablePrinter) moveUp() {
148 t.printOrDie("%c[%dA", common.ESC, 1)
149 }
150
151 func (t *BaseTablePrinter) eraseCurrentLine() {
152 t.printOrDie("%c[2K\r", common.ESC)
153 }
154
View as plain text