Skip to content

Commit 50bdce3

Browse files
Merge pull request #50 from manther/tables
feat: Add simple table formatting support for collection of objects
2 parents 47de8a5 + 441898f commit 50bdce3

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

cli/cli.go

+1
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ Not after (expires): %s (%s)
335335
AddGlobalFlag("rsh-client-cert", "", "Path to a PEM encoded client certificate", "", false)
336336
AddGlobalFlag("rsh-client-key", "", "Path to a PEM encoded private key", "", false)
337337
AddGlobalFlag("rsh-ca-cert", "", "Path to a PEM encoded CA cert", "", false)
338+
AddGlobalFlag("rsh-table", "t", "Enable table formatted output for array of objects", false, false)
338339

339340
initAPIConfig()
340341
}

cli/formatter.go

+64
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cli
33
import (
44
"bytes"
55
"encoding/json"
6+
"errors"
67
"fmt"
78
"image/color"
89
"net/http"
@@ -18,6 +19,7 @@ import (
1819
"golang.org/x/crypto/ssh/terminal"
1920
"gopkg.in/yaml.v2"
2021

22+
"github.com/alexeyco/simpletable"
2123
"github.com/eliukblau/pixterm/pkg/ansimage"
2224
)
2325

@@ -160,6 +162,22 @@ func (f *DefaultFormatter) Format(resp Response) error {
160162

161163
handled := false
162164
kind := reflect.ValueOf(data).Kind()
165+
166+
// Handle table formatting
167+
if viper.GetBool("rsh-table") && kind == reflect.Slice {
168+
d, ok := data.([]interface{})
169+
if ok {
170+
ret, err := setTable(d)
171+
if err != nil {
172+
return err
173+
}
174+
encoded = *ret
175+
handled = true
176+
} else {
177+
return errors.New("error building table. Collection not supported. Must be array of objects")
178+
}
179+
}
180+
163181
if viper.GetBool("rsh-raw") && kind == reflect.String {
164182
handled = true
165183
dStr := data.(string)
@@ -311,3 +329,49 @@ func (f *DefaultFormatter) Format(resp Response) error {
311329

312330
return nil
313331
}
332+
333+
// Only applicable to collection of repeating objects.
334+
// Filter down to a collection of objects first then apply --table.
335+
// Simpletable has much more styling that can be applied.
336+
func setTable(data []interface{}) (*[]byte, error) {
337+
table := simpletable.New()
338+
339+
var headerCells []*simpletable.Cell
340+
defineHeader := true
341+
for _, maps := range data {
342+
var bodyCells []*simpletable.Cell
343+
if mapData, ok := maps.(map[string]interface{}); ok {
344+
// Discover headers for repeating objects
345+
// Iterate first instance of one of the repeating objects
346+
if defineHeader {
347+
for k, _ := range mapData {
348+
headerCells = append(headerCells, &simpletable.Cell{Align: simpletable.AlignCenter, Text: k})
349+
}
350+
}
351+
defineHeader = false
352+
353+
// Add body cells based on order of header cells
354+
// Will gt out of order otherwise
355+
for _, cellKey := range headerCells {
356+
if val, ok := mapData[cellKey.Text]; ok {
357+
bodyCells = append(bodyCells, &simpletable.Cell{Align: simpletable.AlignRight, Text: fmt.Sprintf("%v", val)})
358+
} else {
359+
return nil, fmt.Errorf("error building table. Header Key not found in repeating object: %s", cellKey.Text)
360+
}
361+
}
362+
table.Body.Cells = append(table.Body.Cells, bodyCells)
363+
} else {
364+
// Defensive just in case
365+
return nil, errors.New("error building table. Collection not supported")
366+
}
367+
}
368+
369+
table.Header = &simpletable.Header{
370+
Cells: headerCells,
371+
}
372+
373+
table.SetStyle(simpletable.StyleCompactLite)
374+
375+
ret := []byte(table.String())
376+
return &ret, nil
377+
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e // indirect
88
github.com/alecthomas/chroma v0.8.2
99
github.com/alecthomas/repr v0.0.0-20210301060118-828286944d6a // indirect
10+
github.com/alexeyco/simpletable v1.0.0
1011
github.com/amzn/ion-go v1.1.0
1112
github.com/andybalholm/brotli v1.0.1
1213
github.com/creack/pty v1.1.11 // indirect

go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ github.com/alecthomas/repr v0.0.0-20210301060118-828286944d6a h1:GY6ZI5mOHoiQ+g2
5555
github.com/alecthomas/repr v0.0.0-20210301060118-828286944d6a/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
5656
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
5757
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
58+
github.com/alexeyco/simpletable v1.0.0 h1:ZQ+LvJ4bmoeHb+dclF64d0LX+7QAi7awsfCrptZrpHk=
59+
github.com/alexeyco/simpletable v1.0.0/go.mod h1:VJWVTtGUnW7EKbMRH8cE13SigKGx/1fO2SeeOiGeBkk=
5860
github.com/amzn/ion-go v1.1.0 h1:699A2uZDtkPf5yTMcRkTMoCBYa0UELLgAt0k8Psw+RY=
5961
github.com/amzn/ion-go v1.1.0/go.mod h1:93Bu1K0O/CDosTCDzJ1cNY7XpdHGAGE2NepHcGsiV70=
6062
github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
@@ -281,6 +283,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
281283
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
282284
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
283285
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
286+
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
287+
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
284288
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
285289
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
286290
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
@@ -333,6 +337,8 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
333337
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
334338
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=
335339
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q=
340+
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
341+
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
336342
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
337343
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
338344
github.com/rs/zerolog v1.11.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=

0 commit comments

Comments
 (0)