Skip to content

Commit

Permalink
24133 fix: --no-headers works with custom columns now
Browse files Browse the repository at this point in the history
  • Loading branch information
Sylwester Brzeczkowski authored and sylwekb committed Jul 7, 2016
1 parent acda24a commit 19434e1
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 24 deletions.
8 changes: 4 additions & 4 deletions pkg/kubectl/cmd/clusterinfo_dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ based on namespace and pod name.

dumpExample = `# Dump current cluster state to stdout
kubectl cluster-info dump
# Dump current cluster state to /path/to/cluster-state
kubectl cluster-info dump --output-directory=/path/to/cluster-state
# Dump all namespaces to stdout
kubectl cluster-info dump --all-namespaces
# Dump a set of namespaces to /path/to/cluster-state
kubectl cluster-info dump --namespaces default,kube-system --output-directory=/path/to/cluster-state`
)
Expand All @@ -91,7 +91,7 @@ func dumpClusterInfo(f *cmdutil.Factory, cmd *cobra.Command, args []string, out
if c, err = f.Client(); err != nil {
return err
}
printer, _, err := kubectl.GetPrinter("json", "")
printer, _, err := kubectl.GetPrinter("json", "", false)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl/cmd/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (o *ConvertOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.
}
}
o.encoder = f.JSONEncoder()
o.printer, _, err = kubectl.GetPrinter(outputFormat, templateFile)
o.printer, _, err = kubectl.GetPrinter(outputFormat, templateFile, false)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/kubectl/cmd/util/printing.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func AddOutputFlags(cmd *cobra.Command) {

// AddNoHeadersFlags adds no-headers flags to a command.
func AddNoHeadersFlags(cmd *cobra.Command) {
cmd.Flags().Bool("no-headers", false, "When using the default output, don't print headers.")
cmd.Flags().Bool("no-headers", false, "When using the default or custom-column output format, don't print headers.")
}

// PrintSuccess prints message after finishing mutating operations
Expand Down Expand Up @@ -121,7 +121,7 @@ func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error
}
}

printer, generic, err := kubectl.GetPrinter(outputFormat, templateFile)
printer, generic, err := kubectl.GetPrinter(outputFormat, templateFile, GetFlagBool(cmd, "no-headers"))
if err != nil {
return nil, generic, err
}
Expand Down
22 changes: 13 additions & 9 deletions pkg/kubectl/custom_column_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func massageJSONPath(pathExpression string) (string, error) {
//
// NAME API_VERSION
// foo bar
func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder) (*CustomColumnsPrinter, error) {
func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder, noHeaders bool) (*CustomColumnsPrinter, error) {
if len(spec) == 0 {
return nil, fmt.Errorf("custom-columns format specified but no custom columns given")
}
Expand All @@ -90,7 +90,7 @@ func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder) (*Cus
}
columns[ix] = Column{Header: colSpec[0], FieldSpec: spec}
}
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder}, nil
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder, NoHeaders: noHeaders}, nil
}

func splitOnWhitespace(line string) []string {
Expand Down Expand Up @@ -135,7 +135,7 @@ func NewCustomColumnsPrinterFromTemplate(templateReader io.Reader, decoder runti
FieldSpec: spec,
}
}
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder}, nil
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder, NoHeaders: false}, nil
}

// Column represents a user specified column
Expand All @@ -150,17 +150,21 @@ type Column struct {
// CustomColumnPrinter is a printer that knows how to print arbitrary columns
// of data from templates specified in the `Columns` array
type CustomColumnsPrinter struct {
Columns []Column
Decoder runtime.Decoder
Columns []Column
Decoder runtime.Decoder
NoHeaders bool
}

func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
w := tabwriter.NewWriter(out, columnwidth, tabwidth, padding, padding_character, flags)
headers := make([]string, len(s.Columns))
for ix := range s.Columns {
headers[ix] = s.Columns[ix].Header

if !s.NoHeaders {
headers := make([]string, len(s.Columns))
for ix := range s.Columns {
headers[ix] = s.Columns[ix].Header
}
fmt.Fprintln(w, strings.Join(headers, "\t"))
}
fmt.Fprintln(w, strings.Join(headers, "\t"))
parsers := make([]*jsonpath.JSONPath, len(s.Columns))
for ix := range s.Columns {
parsers[ix] = jsonpath.New(fmt.Sprintf("column%d", ix))
Expand Down
22 changes: 20 additions & 2 deletions pkg/kubectl/custom_column_printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package kubectl
import (
"bytes"
"reflect"
"strings"
"testing"

"k8s.io/kubernetes/pkg/api"
Expand Down Expand Up @@ -67,6 +68,7 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
expectedColumns []Column
expectErr bool
name string
noHeaders bool
}{
{
spec: "",
Expand Down Expand Up @@ -102,9 +104,14 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
},
},
},
{
spec: "API_VERSION:apiVersion",
name: "no-headers",
noHeaders: true,
},
}
for _, test := range tests {
printer, err := NewCustomColumnsPrinterFromSpec(test.spec, api.Codecs.UniversalDecoder())
printer, err := NewCustomColumnsPrinterFromSpec(test.spec, api.Codecs.UniversalDecoder(), test.noHeaders)
if test.expectErr {
if err == nil {
t.Errorf("[%s] unexpected non-error", test.name)
Expand All @@ -115,8 +122,19 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
t.Errorf("[%s] unexpected error: %v", test.name, err)
continue
}
if test.noHeaders {
buffer := &bytes.Buffer{}

if !reflect.DeepEqual(test.expectedColumns, printer.Columns) {
printer.PrintObj(&api.Pod{}, buffer)
if err != nil {
t.Fatalf("An error occurred printing Pod: %#v", err)
}

if contains(strings.Fields(buffer.String()), "API_VERSION") {
t.Errorf("unexpected header API_VERSION")
}

} else if !reflect.DeepEqual(test.expectedColumns, printer.Columns) {
t.Errorf("[%s]\nexpected:\n%v\nsaw:\n%v\n", test.name, test.expectedColumns, printer.Columns)
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/kubectl/resource_printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const (
// is agnostic to schema versions, so you must send arguments to PrintObj in the
// version you wish them to be shown using a VersionedPrinter (typically when
// generic is true).
func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
func GetPrinter(format, formatArgument string, noHeaders bool) (ResourcePrinter, bool, error) {
var printer ResourcePrinter
switch format {
case "json":
Expand Down Expand Up @@ -119,7 +119,7 @@ func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
}
case "custom-columns":
var err error
if printer, err = NewCustomColumnsPrinterFromSpec(formatArgument, api.Codecs.UniversalDecoder()); err != nil {
if printer, err = NewCustomColumnsPrinterFromSpec(formatArgument, api.Codecs.UniversalDecoder(), noHeaders); err != nil {
return nil, false, err
}
case "custom-columns-file":
Expand Down
8 changes: 4 additions & 4 deletions pkg/kubectl/resource_printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func TestVersionedPrinter(t *testing.T) {
}

func TestPrintDefault(t *testing.T) {
printer, found, err := GetPrinter("", "")
printer, found, err := GetPrinter("", "", false)
if err != nil {
t.Fatalf("unexpected error: %#v", err)
}
Expand Down Expand Up @@ -129,7 +129,7 @@ func TestPrinter(t *testing.T) {
}
for _, test := range printerTests {
buf := bytes.NewBuffer([]byte{})
printer, found, err := GetPrinter(test.Format, test.FormatArgument)
printer, found, err := GetPrinter(test.Format, test.FormatArgument, false)
if err != nil || !found {
t.Errorf("in %s, unexpected error: %#v", test.Name, err)
}
Expand All @@ -156,7 +156,7 @@ func TestBadPrinter(t *testing.T) {
{"bad jsonpath", "jsonpath", "{.Name", fmt.Errorf("error parsing jsonpath {.Name, unclosed action\n")},
}
for _, test := range badPrinterTests {
_, _, err := GetPrinter(test.Format, test.FormatArgument)
_, _, err := GetPrinter(test.Format, test.FormatArgument, false)
if err == nil || err.Error() != test.Error.Error() {
t.Errorf("in %s, expect %s, got %s", test.Name, test.Error, err)
}
Expand Down Expand Up @@ -333,7 +333,7 @@ func TestNamePrinter(t *testing.T) {
},
"pod/foo\npod/bar\n"},
}
printer, _, _ := GetPrinter("name", "")
printer, _, _ := GetPrinter("name", "", false)
for name, item := range tests {
buff := &bytes.Buffer{}
err := printer.PrintObj(item.obj, buff)
Expand Down

0 comments on commit 19434e1

Please sign in to comment.