-
Notifications
You must be signed in to change notification settings - Fork 888
feat: add generic table formatter #3415
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
Conversation
$ go run ./cmd/coder users list
USERNAME EMAIL CREATED AT STATUS
...
deansheather dean@************.com Jun 1 15:28:07 active
... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FE ✅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice work! Code looks good, so I'm approving this. I'd still like us to avoid panic
ing though.
cli/cliui/table.go
Outdated
for i := 0; i < v.Len(); i++ { | ||
// Format the row as a slice. | ||
rowMap := valueToTableMap(v.Index(i)) | ||
rowSlice := make([]interface{}, len(headers)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion (non-blocking): It's a post-generics crazy world, consider:
rowSlice := make([]interface{}, len(headers)) | |
rowSlice := make([]any, len(headers)) |
(There are more instances, feel free to reject this suggestion if you don't want to make the changes.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind if you want to change them, but if we care we should really add a linter for this.
Originally this function was gonna accept []T but I decided against it because I didn't want to clutter the binary with duplicated functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a huge preference, but I see we have mixed use and it'd be nice to standardize. As you propose, a linter would be a great idea.
cli/cliui/table.go
Outdated
tw.AppendHeader(headers) | ||
tw.SetColumnConfigs(FilterTableColumns(headers, filterColumns)) | ||
tw.SortBy([]table.SortBy{{ | ||
Name: sort, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we verify that sort
is a valid column name (e.g. check headers)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New changes look great!
Adds new function
cliui.DisplayTable(items []T, sortBy string, filterColumns []string) (string, error)
which will render a table and return it as a string.Uses the reflect package to sniff the columns using a
table:"name"
struct tag. If any of the input types are invalid, this will always panic (even for empty slices!). The input must be a slice or a pointer to a slice that concretely holds a single struct type or a pointer to a struct type. The inner struct type must have at least onetable:"name"
tag.,recursive
cannot be specified if the field is not a struct or a pointer to a valid tableable struct.Gist of how it works:
table:"name,recursive"
:"$ParentName $ChildName"
[]string
containing the column names for the tablemap[string]interface{}
, a map of column names to values<nil>
if the value is not present in the map