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

View File

@ -44,10 +44,6 @@ type SortingPrinter struct {
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 {
if !meta.IsListType(obj) {
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)
}
// 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 {
objs, err := meta.ExtractList(obj)
if err != nil {

View File

@ -150,10 +150,6 @@ type CustomColumnsPrinter struct {
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 {
if w, found := out.(*tabwriter.Writer); !found {
w = GetNewTabWriter(out)
@ -236,11 +232,3 @@ func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jso
fmt.Fprintln(out, strings.Join(columns, "\t"))
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
}
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 {
_, err := fmt.Fprintf(w, "Unknown object: %s", string(data))
return err

View File

@ -28,12 +28,6 @@ import (
type ResourcePrinter interface {
// Print receives a runtime object, formats it and prints it to a writer.
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
@ -44,19 +38,6 @@ func (fn ResourcePrinterFunc) PrintObj(obj runtime.Object, w io.Writer) error {
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 {
// supported Format types can be found in pkg/printers/printers.go
OutputFormatType string

View File

@ -268,7 +268,7 @@ func TestPrinter(t *testing.T) {
if err != nil {
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...)
}
if err := printer.PrintObj(test.Input, buf); err != nil {

View File

@ -31,10 +31,6 @@ import (
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.
func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
switch obj := obj.(type) {
@ -58,15 +54,6 @@ func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
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.
// The input object is assumed to be in the internal version of an API and is converted
// to the given version first.
@ -75,10 +62,6 @@ type YAMLPrinter struct {
converter runtime.ObjectConvertor
}
func (p *YAMLPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj prints the data as YAML.
func (p *YAMLPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
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))
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
}
func (j *JSONPathPrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// PrintObj formats the obj with the JSONPath Template.
func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
var queryObj interface{} = obj
@ -150,12 +146,3 @@ func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
}
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
}
func (p *NamePrinter) AfterPrint(w io.Writer, res string) error {
return nil
}
// 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.
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)
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.
func (p *GoTemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
var data []byte
@ -87,15 +83,6 @@ func (p *GoTemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
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
// should the template engine panic.
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
func (p *VersionedPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
// if we're unstructured, no conversion necessary
if _, ok := obj.(*unstructured.Unstructured); ok {
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
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)
}
// TODO: implement HandledResources()
func (p *VersionedPrinter) HandledResources() []string {
return []string{}
}
func (p *VersionedPrinter) IsGeneric() bool {
return p.printer.IsGeneric()
}