Hide long and multiline strings when printing

Currently both long strings and multiline strings can potentially
"break" printing. I'm adding extra formatting to ensure we cut strings
either at newline or at 100 chars with information that more information
is available.
This commit is contained in:
Maciej Szulik 2021-07-06 14:04:46 +02:00
parent f50763754a
commit d0c422fd9c
No known key found for this signature in database
GPG Key ID: F15E55D276FA84C4
2 changed files with 91 additions and 1 deletions

View File

@ -32,6 +32,8 @@ import (
"k8s.io/apimachinery/pkg/watch"
)
const maxStringLength = 100
var _ ResourcePrinter = &HumanReadablePrinter{}
type printHandler struct {
@ -208,7 +210,28 @@ func printTable(table *metav1.Table, output io.Writer, options PrintOptions) err
fmt.Fprint(output, "\t")
}
if cell != nil {
fmt.Fprint(output, cell)
switch val := cell.(type) {
case string:
print := val
more := 0
// cut to maxStringLength
if len(val) > maxStringLength {
more = len(print) - maxStringLength
print = print[:maxStringLength]
}
// and also check for newlines
newline := strings.Index(print, "\n")
if newline >= 0 {
more = more + len(print) - newline
print = print[:newline]
}
fmt.Fprint(output, print)
if more > 0 {
fmt.Fprintf(output, " + %d more...", more)
}
default:
fmt.Fprint(output, val)
}
}
}
fmt.Fprintln(output)

View File

@ -722,3 +722,70 @@ func TestUnknownTypePrinting(t *testing.T) {
t.Errorf("An error was expected from printing unknown type")
}
}
func TestStringPrinting(t *testing.T) {
tests := []struct {
columns []metav1.TableColumnDefinition
rows []metav1.TableRow
expected string
}{
// multiline string
{
columns: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string"},
{Name: "Age", Type: "string"},
{Name: "Description", Type: "string"},
},
rows: []metav1.TableRow{
{Cells: []interface{}{"test1", "20h", "This is first line\nThis is second line\nThis is third line\nand another one\n"}},
},
expected: `NAME AGE DESCRIPTION
test1 20h This is first line + 56 more...
`,
},
// lengthy string
{
columns: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string"},
{Name: "Age", Type: "string"},
{Name: "Description", Type: "string"},
},
rows: []metav1.TableRow{
{Cells: []interface{}{"test1", "20h", "This is first line which is long and goes for on and on and on an on and on and on and on and on and on and on and on and on and on and on"}},
},
expected: `NAME AGE DESCRIPTION
test1 20h This is first line which is long and goes for on and on and on an on and on and on and on and on and + 38 more...
`,
},
// lengthy string + newline
{
columns: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string"},
{Name: "Age", Type: "string"},
{Name: "Description", Type: "string"},
},
rows: []metav1.TableRow{
{Cells: []interface{}{"test1", "20h", "This is first\n line which is long and goes for on and on and on an on and on and on and on and on and on and on and on and on and on and on"}},
},
expected: `NAME AGE DESCRIPTION
test1 20h This is first + 126 more...
`,
},
}
for _, test := range tests {
// Create the table from the columns and rows.
table := &metav1.Table{
ColumnDefinitions: test.columns,
Rows: test.rows,
}
// Print the table
out := bytes.NewBuffer([]byte{})
printer := NewTablePrinter(PrintOptions{})
printer.PrintObj(table, out)
if test.expected != out.String() {
t.Errorf("Table printing error: expected \n(%s), got \n(%s)", test.expected, out.String())
}
}
}