Merge pull request #63432 from deads2k/cli-46-printerinterface

Automatic merge from submit-queue (batch tested with PRs 63421, 63432, 63333). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

 slim printer interface down to printing

The printer interface only needs to know how to print.  This reduces it's interface to scope it to printing.

@kubernetes/sig-cli-maintainers 
@soltysh @juanvallejo  you've been active in the area

/assign @juanvallejo 

```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2018-05-04 10:52:07 -07:00 committed by GitHub
commit 3945a241aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 11 additions and 150 deletions

View File

@ -53,10 +53,10 @@ import (
// GetOptions contains the input to the get command. // GetOptions contains the input to the get command.
type GetOptions struct { type GetOptions struct {
PrintFlags *PrintFlags PrintFlags *PrintFlags
ToPrinter func(*meta.RESTMapping, bool) (printers.ResourcePrinterFunc, error) ToPrinter func(*meta.RESTMapping, bool) (printers.ResourcePrinterFunc, error)
IsGeneric bool IsHumanReadablePrinter bool
PrintWithOpenAPICols bool PrintWithOpenAPICols bool
CmdParent string CmdParent string
@ -216,13 +216,10 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
o.ServerPrint = false o.ServerPrint = false
} }
// obtain printer here in order to determine if we are // human readable printers have special conversion rules, so we determine if we're using one.
// printing humanreadable or generic output. if len(*o.PrintFlags.OutputFormat) == 0 || *o.PrintFlags.OutputFormat == "wide" {
printer, err := o.PrintFlags.ToPrinter() o.IsHumanReadablePrinter = true
if err != nil {
return err
} }
o.IsGeneric = printer.IsGeneric()
o.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, false) o.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, false)
o.PrintWithOpenAPICols = cmdutil.GetFlagBool(cmd, useOpenAPIPrintColumnFlagLabel) o.PrintWithOpenAPICols = cmdutil.GetFlagBool(cmd, useOpenAPIPrintColumnFlagLabel)
@ -318,7 +315,7 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
Latest(). Latest().
Flatten(). Flatten().
TransformRequests(func(req *rest.Request) { TransformRequests(func(req *rest.Request) {
if o.ServerPrint && !o.IsGeneric && !o.Sort { if o.ServerPrint && o.IsHumanReadablePrinter && !o.Sort {
group := metav1beta1.GroupName group := metav1beta1.GroupName
version := metav1beta1.SchemeGroupVersion.Version version := metav1beta1.SchemeGroupVersion.Version
@ -335,7 +332,7 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
return err return err
} }
if o.IsGeneric { if !o.IsHumanReadablePrinter {
return o.printGeneric(r) return o.printGeneric(r)
} }
@ -544,7 +541,7 @@ func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string)
objsToPrint = append(objsToPrint, obj) objsToPrint = append(objsToPrint, obj)
} }
for _, objToPrint := range objsToPrint { for _, objToPrint := range objsToPrint {
if !o.IsGeneric { if o.IsHumanReadablePrinter {
// printing always takes the internal version, but the watch event uses externals // printing always takes the internal version, but the watch event uses externals
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion() internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
objToPrint = attemptToConvertToInternal(objToPrint, legacyscheme.Scheme, internalGV) objToPrint = attemptToConvertToInternal(objToPrint, legacyscheme.Scheme, internalGV)

View File

@ -44,10 +44,6 @@ type SortingPrinter struct {
Decoder runtime.Decoder Decoder runtime.Decoder
} }
func (s *SortingPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
func (s *SortingPrinter) PrintObj(obj runtime.Object, out io.Writer) error { func (s *SortingPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
if !meta.IsListType(obj) { if !meta.IsListType(obj) {
return s.Delegate.PrintObj(obj, out) return s.Delegate.PrintObj(obj, out)
@ -59,15 +55,6 @@ func (s *SortingPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
return s.Delegate.PrintObj(obj, out) return s.Delegate.PrintObj(obj, out)
} }
// TODO: implement HandledResources()
func (s *SortingPrinter) HandledResources() []string {
return []string{}
}
func (s *SortingPrinter) IsGeneric() bool {
return s.Delegate.IsGeneric()
}
func (s *SortingPrinter) sortObj(obj runtime.Object) error { func (s *SortingPrinter) sortObj(obj runtime.Object) error {
objs, err := meta.ExtractList(obj) objs, err := meta.ExtractList(obj)
if err != nil { if err != nil {

View File

@ -150,10 +150,6 @@ type CustomColumnsPrinter struct {
lastType reflect.Type lastType reflect.Type
} }
func (s *CustomColumnsPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error { func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
if w, found := out.(*tabwriter.Writer); !found { if w, found := out.(*tabwriter.Writer); !found {
w = GetNewTabWriter(out) w = GetNewTabWriter(out)
@ -236,11 +232,3 @@ func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jso
fmt.Fprintln(out, strings.Join(columns, "\t")) fmt.Fprintln(out, strings.Join(columns, "\t"))
return nil return nil
} }
func (s *CustomColumnsPrinter) HandledResources() []string {
return []string{}
}
func (s *CustomColumnsPrinter) IsGeneric() bool {
return true
}

View File

@ -257,14 +257,6 @@ func (h *HumanReadablePrinter) HandledResources() []string {
return keys return keys
} }
func (h *HumanReadablePrinter) AfterPrint(output io.Writer, res string) error {
return nil
}
func (h *HumanReadablePrinter) IsGeneric() bool {
return false
}
func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error { func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error {
_, err := fmt.Fprintf(w, "Unknown object: %s", string(data)) _, err := fmt.Fprintf(w, "Unknown object: %s", string(data))
return err return err

View File

@ -28,12 +28,6 @@ import (
type ResourcePrinter interface { type ResourcePrinter interface {
// Print receives a runtime object, formats it and prints it to a writer. // Print receives a runtime object, formats it and prints it to a writer.
PrintObj(runtime.Object, io.Writer) error PrintObj(runtime.Object, io.Writer) error
HandledResources() []string
//Can be used to print out warning/clarifications if needed
//after all objects were printed
AfterPrint(io.Writer, string) error
// Identify if it is a generic printer
IsGeneric() bool
} }
// ResourcePrinterFunc is a function that can print objects // ResourcePrinterFunc is a function that can print objects
@ -44,19 +38,6 @@ func (fn ResourcePrinterFunc) PrintObj(obj runtime.Object, w io.Writer) error {
return fn(obj, w) return fn(obj, w)
} }
// TODO: implement HandledResources()
func (fn ResourcePrinterFunc) HandledResources() []string {
return []string{}
}
func (fn ResourcePrinterFunc) AfterPrint(io.Writer, string) error {
return nil
}
func (fn ResourcePrinterFunc) IsGeneric() bool {
return true
}
type PrintOptions struct { type PrintOptions struct {
// supported Format types can be found in pkg/printers/printers.go // supported Format types can be found in pkg/printers/printers.go
OutputFormatType string OutputFormatType string

View File

@ -268,7 +268,7 @@ func TestPrinter(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("in %s, unexpected error: %#v", test.Name, err) t.Errorf("in %s, unexpected error: %#v", test.Name, err)
} }
if printer.IsGeneric() && len(test.OutputVersions) > 0 { if len(test.OutputVersions) > 0 {
printer = printers.NewVersionedPrinter(printer, legacyscheme.Scheme, legacyscheme.Scheme, test.OutputVersions...) printer = printers.NewVersionedPrinter(printer, legacyscheme.Scheme, legacyscheme.Scheme, test.OutputVersions...)
} }
if err := printer.PrintObj(test.Input, buf); err != nil { if err := printer.PrintObj(test.Input, buf); err != nil {

View File

@ -31,10 +31,6 @@ import (
type JSONPrinter struct { type JSONPrinter struct {
} }
func (p *JSONPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj is an implementation of ResourcePrinter.PrintObj which simply writes the object to the Writer. // PrintObj is an implementation of ResourcePrinter.PrintObj which simply writes the object to the Writer.
func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
switch obj := obj.(type) { switch obj := obj.(type) {
@ -58,15 +54,6 @@ func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
return err return err
} }
// TODO: implement HandledResources()
func (p *JSONPrinter) HandledResources() []string {
return []string{}
}
func (p *JSONPrinter) IsGeneric() bool {
return true
}
// YAMLPrinter is an implementation of ResourcePrinter which outputs an object as YAML. // YAMLPrinter is an implementation of ResourcePrinter which outputs an object as YAML.
// The input object is assumed to be in the internal version of an API and is converted // The input object is assumed to be in the internal version of an API and is converted
// to the given version first. // to the given version first.
@ -75,10 +62,6 @@ type YAMLPrinter struct {
converter runtime.ObjectConvertor converter runtime.ObjectConvertor
} }
func (p *YAMLPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj prints the data as YAML. // PrintObj prints the data as YAML.
func (p *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
switch obj := obj.(type) { switch obj := obj.(type) {
@ -98,12 +81,3 @@ func (p *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
_, err = fmt.Fprint(w, string(output)) _, err = fmt.Fprint(w, string(output))
return err return err
} }
// TODO: implement HandledResources()
func (p *YAMLPrinter) HandledResources() []string {
return []string{}
}
func (p *YAMLPrinter) IsGeneric() bool {
return true
}

View File

@ -110,10 +110,6 @@ func NewJSONPathPrinter(tmpl string) (*JSONPathPrinter, error) {
return &JSONPathPrinter{tmpl, j}, nil return &JSONPathPrinter{tmpl, j}, nil
} }
func (j *JSONPathPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj formats the obj with the JSONPath Template. // PrintObj formats the obj with the JSONPath Template.
func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
var queryObj interface{} = obj var queryObj interface{} = obj
@ -150,12 +146,3 @@ func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
} }
return nil return nil
} }
// TODO: implement HandledResources()
func (p *JSONPathPrinter) HandledResources() []string {
return []string{}
}
func (p *JSONPathPrinter) IsGeneric() bool {
return true
}

View File

@ -42,10 +42,6 @@ type NamePrinter struct {
Typer runtime.ObjectTyper Typer runtime.ObjectTyper
} }
func (p *NamePrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj is an implementation of ResourcePrinter.PrintObj which decodes the object // PrintObj is an implementation of ResourcePrinter.PrintObj which decodes the object
// and print "resource/name" pair. If the object is a List, print all items in it. // and print "resource/name" pair. If the object is a List, print all items in it.
func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
@ -123,12 +119,3 @@ func printObj(w io.Writer, name string, operation string, shortOutput bool, grou
fmt.Fprintf(w, "%s.%s/%s%s\n", strings.ToLower(groupKind.Kind), groupKind.Group, name, operation) fmt.Fprintf(w, "%s.%s/%s%s\n", strings.ToLower(groupKind.Kind), groupKind.Group, name, operation)
return nil return nil
} }
// TODO: implement HandledResources()
func (p *NamePrinter) HandledResources() []string {
return []string{}
}
func (p *NamePrinter) IsGeneric() bool {
return true
}

View File

@ -57,10 +57,6 @@ func (p *GoTemplatePrinter) AllowMissingKeys(allow bool) {
} }
} }
func (p *GoTemplatePrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj formats the obj with the Go Template. // PrintObj formats the obj with the Go Template.
func (p *GoTemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *GoTemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
var data []byte var data []byte
@ -87,15 +83,6 @@ func (p *GoTemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
return nil return nil
} }
// TODO: implement HandledResources()
func (p *GoTemplatePrinter) HandledResources() []string {
return []string{}
}
func (p *GoTemplatePrinter) IsGeneric() bool {
return true
}
// safeExecute tries to execute the template, but catches panics and returns an error // safeExecute tries to execute the template, but catches panics and returns an error
// should the template engine panic. // should the template engine panic.
func (p *GoTemplatePrinter) safeExecute(w io.Writer, obj interface{}) error { func (p *GoTemplatePrinter) safeExecute(w io.Writer, obj interface{}) error {

View File

@ -45,22 +45,12 @@ func NewVersionedPrinter(printer ResourcePrinter, converter runtime.ObjectConver
} }
} }
func (p *VersionedPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj implements ResourcePrinter // PrintObj implements ResourcePrinter
func (p *VersionedPrinter) PrintObj(obj runtime.Object, w io.Writer) error { func (p *VersionedPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
// if we're unstructured, no conversion necessary // if we're unstructured, no conversion necessary
if _, ok := obj.(*unstructured.Unstructured); ok { if _, ok := obj.(*unstructured.Unstructured); ok {
return p.printer.PrintObj(obj, w) return p.printer.PrintObj(obj, w)
} }
// if we aren't a generic printer, we don't convert. This means the printer must be aware of what it is getting.
// The default printers fall into this category.
// TODO eventually, all printers must be generic
if !p.IsGeneric() {
return p.printer.PrintObj(obj, w)
}
// if we're already external, no conversion necessary // if we're already external, no conversion necessary
gvks, _, err := p.typer.ObjectKinds(obj) gvks, _, err := p.typer.ObjectKinds(obj)
@ -93,12 +83,3 @@ func (p *VersionedPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
} }
return p.printer.PrintObj(converted, w) return p.printer.PrintObj(converted, w)
} }
// TODO: implement HandledResources()
func (p *VersionedPrinter) HandledResources() []string {
return []string{}
}
func (p *VersionedPrinter) IsGeneric() bool {
return p.printer.IsGeneric()
}