Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format flattened output in kubectl #15499

Merged
merged 2 commits into from
Oct 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 14 additions & 3 deletions pkg/kubectl/cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"io"

"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
Expand Down Expand Up @@ -220,13 +221,23 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
}

// use the default printer for each object
printer = nil
var lastMapping *meta.RESTMapping
w := kubectl.GetNewTabWriter(out)
defer w.Flush()
return b.Flatten().Do().Visit(func(r *resource.Info, err error) error {
if err != nil {
return err
}
printer, err := f.PrinterForMapping(cmd, r.Mapping, allNamespaces)
if err != nil {
return err
if printer == nil || lastMapping == nil || r.Mapping == nil || r.Mapping.Resource != lastMapping.Resource {
printer, err = f.PrinterForMapping(cmd, r.Mapping, allNamespaces)
if err != nil {
return err
}
lastMapping = r.Mapping
}
if _, found := printer.(*kubectl.HumanReadablePrinter); found {
return printer.PrintObj(r.Object, w)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you pass the TabWriter if it's a HumanReadablePrinter vs out if it's not?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what situations would it not be a HumanReadablePrinter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are lots of other printers, such as YAMLPrinter, JSONPrinter, etc. See https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/resource_printer.go#L61. Only HumanReadablePrinter needs a tabwriter to align its table output.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, thanks!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Users use -o or --output to specify different output format (use different printers).

}
return printer.PrintObj(r.Object, out)
})
Expand Down
13 changes: 11 additions & 2 deletions pkg/kubectl/resource_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -1475,10 +1475,19 @@ func formatWideHeaders(wide bool, t reflect.Type) []string {
return nil
}

// GetNewTabWriter returns a tabwriter that translates tabbed columns in input into properly aligned text.
func GetNewTabWriter(output io.Writer) *tabwriter.Writer {
return tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, tabwriterPadding, tabwriterPadChar, tabwriterFlags)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liggitt how about wrapping it as a function?

}

// 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 {
w := tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, tabwriterPadding, tabwriterPadChar, tabwriterFlags)
defer w.Flush()
// if output is a tabwriter (when it's called by kubectl get), we use it; create a new tabwriter otherwise
w, found := output.(*tabwriter.Writer)
if !found {
w = GetNewTabWriter(output)
defer w.Flush()
}
t := reflect.TypeOf(obj)
if handler := h.handlerMap[t]; handler != nil {
if !h.noHeaders && t != h.lastType {
Expand Down