mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Split HumanReadablePrinter struct into generator and printer structs
This commit is contained in:
parent
f4521bf5a2
commit
6d903c4787
@ -43,30 +43,25 @@ type handlerEntry struct {
|
|||||||
args []reflect.Value
|
args []reflect.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanReadablePrinter is an implementation of ResourcePrinter which attempts to provide
|
// HumanReadableGenerator is an implementation of TableGenerator used to generate
|
||||||
// more elegant output. It is not threadsafe, but you may call PrintObj repeatedly; headers
|
// a table for a specific resource. The table is printed with a TablePrinter using
|
||||||
// will only be printed if the object type changes. This makes it useful for printing items
|
// PrintObj().
|
||||||
// received from watches.
|
type HumanReadableGenerator struct {
|
||||||
type HumanReadablePrinter struct {
|
handlerMap map[reflect.Type]*handlerEntry
|
||||||
handlerMap map[reflect.Type]*handlerEntry
|
|
||||||
options PrintOptions
|
|
||||||
lastType interface{}
|
|
||||||
lastColumns []metav1beta1.TableColumnDefinition
|
|
||||||
printedHeaders bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ TableGenerator = &HumanReadablePrinter{}
|
var _ TableGenerator = &HumanReadableGenerator{}
|
||||||
var _ PrintHandler = &HumanReadablePrinter{}
|
var _ PrintHandler = &HumanReadableGenerator{}
|
||||||
|
|
||||||
// NewTableGenerator creates a HumanReadablePrinter suitable for calling GenerateTable().
|
// NewTableGenerator creates a HumanReadableGenerator suitable for calling GenerateTable().
|
||||||
func NewTableGenerator() *HumanReadablePrinter {
|
func NewTableGenerator() *HumanReadableGenerator {
|
||||||
return &HumanReadablePrinter{
|
return &HumanReadableGenerator{
|
||||||
handlerMap: make(map[reflect.Type]*handlerEntry),
|
handlerMap: make(map[reflect.Type]*handlerEntry),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// With method - accepts a list of builder functions that modify HumanReadablePrinter
|
// With method - accepts a list of builder functions that modify HumanReadableGenerator
|
||||||
func (h *HumanReadablePrinter) With(fns ...func(PrintHandler)) *HumanReadablePrinter {
|
func (h *HumanReadableGenerator) With(fns ...func(PrintHandler)) *HumanReadableGenerator {
|
||||||
for _, fn := range fns {
|
for _, fn := range fns {
|
||||||
fn(h)
|
fn(h)
|
||||||
}
|
}
|
||||||
@ -76,7 +71,7 @@ func (h *HumanReadablePrinter) With(fns ...func(PrintHandler)) *HumanReadablePri
|
|||||||
// GenerateTable returns a table for the provided object, using the printer registered for that type. It returns
|
// GenerateTable returns a table for the provided object, using the printer registered for that type. It returns
|
||||||
// a table that includes all of the information requested by options, but will not remove rows or columns. The
|
// a table that includes all of the information requested by options, but will not remove rows or columns. The
|
||||||
// caller is responsible for applying rules related to filtering rows or columns.
|
// caller is responsible for applying rules related to filtering rows or columns.
|
||||||
func (h *HumanReadablePrinter) GenerateTable(obj runtime.Object, options PrintOptions) (*metav1beta1.Table, error) {
|
func (h *HumanReadableGenerator) GenerateTable(obj runtime.Object, options PrintOptions) (*metav1beta1.Table, error) {
|
||||||
t := reflect.TypeOf(obj)
|
t := reflect.TypeOf(obj)
|
||||||
handler, ok := h.handlerMap[t]
|
handler, ok := h.handlerMap[t]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -126,9 +121,9 @@ func (h *HumanReadablePrinter) GenerateTable(obj runtime.Object, options PrintOp
|
|||||||
return table, nil
|
return table, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableHandler adds a print handler with a given set of columns to HumanReadablePrinter instance.
|
// TableHandler adds a print handler with a given set of columns to HumanReadableGenerator instance.
|
||||||
// See ValidateRowPrintHandlerFunc for required method signature.
|
// See ValidateRowPrintHandlerFunc for required method signature.
|
||||||
func (h *HumanReadablePrinter) TableHandler(columnDefinitions []metav1beta1.TableColumnDefinition, printFunc interface{}) error {
|
func (h *HumanReadableGenerator) TableHandler(columnDefinitions []metav1beta1.TableColumnDefinition, printFunc interface{}) error {
|
||||||
printFuncValue := reflect.ValueOf(printFunc)
|
printFuncValue := reflect.ValueOf(printFunc)
|
||||||
if err := ValidateRowPrintHandlerFunc(printFuncValue); err != nil {
|
if err := ValidateRowPrintHandlerFunc(printFuncValue); err != nil {
|
||||||
utilruntime.HandleError(fmt.Errorf("unable to register print function: %v", err))
|
utilruntime.HandleError(fmt.Errorf("unable to register print function: %v", err))
|
||||||
|
@ -61,13 +61,23 @@ var (
|
|||||||
withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too.
|
withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HumanReadablePrinter is an implementation of ResourcePrinter which attempts to provide
|
||||||
|
// more elegant output. It is not threadsafe, but you may call PrintObj repeatedly; headers
|
||||||
|
// will only be printed if the object type changes. This makes it useful for printing items
|
||||||
|
// received from watches.
|
||||||
|
type HumanReadablePrinter struct {
|
||||||
|
options PrintOptions
|
||||||
|
lastType interface{}
|
||||||
|
lastColumns []metav1beta1.TableColumnDefinition
|
||||||
|
printedHeaders bool
|
||||||
|
}
|
||||||
|
|
||||||
// NewTablePrinter creates a printer suitable for calling PrintObj().
|
// NewTablePrinter creates a printer suitable for calling PrintObj().
|
||||||
// TODO(seans3): Change return type to ResourcePrinter interface once we no longer need
|
// TODO(seans3): Change return type to ResourcePrinter interface once we no longer need
|
||||||
// to constuct the "handlerMap".
|
// to constuct the "handlerMap".
|
||||||
func NewTablePrinter(options PrintOptions) *HumanReadablePrinter {
|
func NewTablePrinter(options PrintOptions) *HumanReadablePrinter {
|
||||||
printer := &HumanReadablePrinter{
|
printer := &HumanReadablePrinter{
|
||||||
handlerMap: make(map[reflect.Type]*handlerEntry),
|
options: options,
|
||||||
options: options,
|
|
||||||
}
|
}
|
||||||
return printer
|
return printer
|
||||||
}
|
}
|
||||||
@ -81,6 +91,7 @@ func printHeader(columnNames []string, w io.Writer) error {
|
|||||||
|
|
||||||
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
|
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
|
||||||
func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error {
|
func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error {
|
||||||
|
|
||||||
w, found := output.(*tabwriter.Writer)
|
w, found := output.(*tabwriter.Writer)
|
||||||
if !found {
|
if !found {
|
||||||
w = GetNewTabWriter(output)
|
w = GetNewTabWriter(output)
|
||||||
@ -94,7 +105,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||||||
obj = event.Object.Object
|
obj = event.Object.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case 1: Parameter "obj" is a table from server; print it.
|
// Parameter "obj" is a table from server; print it.
|
||||||
// display tables following the rules of options
|
// display tables following the rules of options
|
||||||
if table, ok := obj.(*metav1beta1.Table); ok {
|
if table, ok := obj.(*metav1beta1.Table); ok {
|
||||||
// Do not print headers if this table has no column definitions, or they are the same as the last ones we printed
|
// Do not print headers if this table has no column definitions, or they are the same as the last ones we printed
|
||||||
@ -117,6 +128,8 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||||||
h.printedHeaders = true
|
h.printedHeaders = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(seans3): Remove the following decorateTable call. Table modification
|
||||||
|
// (and creation) should only happen in table generation (tablegenerator.go).
|
||||||
if err := decorateTable(table, localOptions); err != nil {
|
if err := decorateTable(table, localOptions); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -131,25 +144,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||||||
return printTable(table, output, localOptions)
|
return printTable(table, output, localOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case 2: Parameter "obj" is not a table; search for a handler to print it.
|
// Could not find print handler for "obj"; use the default or status print handler.
|
||||||
// TODO(seans3): Remove this case in 1.16, since table should be returned from server-side printing.
|
|
||||||
// print with a registered handler
|
|
||||||
t := reflect.TypeOf(obj)
|
|
||||||
if handler := h.handlerMap[t]; handler != nil {
|
|
||||||
includeHeaders := h.lastType != t && !h.options.NoHeaders
|
|
||||||
|
|
||||||
if h.lastType != nil && h.lastType != t && !h.options.NoHeaders {
|
|
||||||
fmt.Fprintln(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := printRowsForHandlerEntry(output, handler, eventType, obj, h.options, includeHeaders); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
h.lastType = t
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case 3: Could not find print handler for "obj"; use the default or status print handler.
|
|
||||||
// Print with the default or status handler, and use the columns from the last time
|
// Print with the default or status handler, and use the columns from the last time
|
||||||
var handler *handlerEntry
|
var handler *handlerEntry
|
||||||
if _, isStatus := obj.(*metav1.Status); isStatus {
|
if _, isStatus := obj.(*metav1.Status); isStatus {
|
||||||
@ -291,6 +286,9 @@ func addColumns(pos columnAddPosition, table *metav1beta1.Table, columns []metav
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(seans3): This method modifies the table, to it should only happen
|
||||||
|
// during table generation (tablegenerator.go), and not during table printing.
|
||||||
|
//
|
||||||
// decorateTable takes a table and attempts to add label columns and the
|
// decorateTable takes a table and attempts to add label columns and the
|
||||||
// namespace column. It will fill empty columns with nil (if the object
|
// namespace column. It will fill empty columns with nil (if the object
|
||||||
// does not expose metadata). It returns an error if the table cannot
|
// does not expose metadata). It returns an error if the table cannot
|
||||||
|
Loading…
Reference in New Issue
Block a user