mirror of https://github.com/coder/coder.git
parent
028a4edbd4
commit
e6f568fcac
|
@ -67,7 +67,7 @@ func DisplayTable(out any, sort string, filterColumns []string) (string, error)
|
|||
}
|
||||
|
||||
// Get the list of table column headers.
|
||||
headersRaw, err := TypeToTableHeaders(v.Type().Elem())
|
||||
headersRaw, err := typeToTableHeaders(v.Type().Elem())
|
||||
if err != nil {
|
||||
return "", xerrors.Errorf("get table headers recursively for type %q: %w", v.Type().Elem().String(), err)
|
||||
}
|
||||
|
@ -207,10 +207,10 @@ func isStructOrStructPointer(t reflect.Type) bool {
|
|||
return t.Kind() == reflect.Struct || (t.Kind() == reflect.Pointer && t.Elem().Kind() == reflect.Struct)
|
||||
}
|
||||
|
||||
// TypeToTableHeaders converts a type to a slice of column names. If the given
|
||||
// typeToTableHeaders converts a type to a slice of column names. If the given
|
||||
// type is invalid (not a struct or a pointer to a struct, has invalid table
|
||||
// tags, etc.), an error is returned.
|
||||
func TypeToTableHeaders(t reflect.Type) ([]string, error) {
|
||||
func typeToTableHeaders(t reflect.Type) ([]string, error) {
|
||||
if !isStructOrStructPointer(t) {
|
||||
return nil, xerrors.Errorf("typeToTableHeaders called with a non-struct or a non-pointer-to-a-struct type")
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ func TypeToTableHeaders(t reflect.Type) ([]string, error) {
|
|||
return nil, xerrors.Errorf("field %q in type %q is marked as recursive but does not contain a struct or a pointer to a struct", field.Name, t.String())
|
||||
}
|
||||
|
||||
childNames, err := TypeToTableHeaders(fieldType)
|
||||
childNames, err := typeToTableHeaders(fieldType)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get child field header names for field %q in type %q: %w", field.Name, fieldType.String(), err)
|
||||
}
|
||||
|
@ -305,3 +305,18 @@ func valueToTableMap(val reflect.Value) (map[string]any, error) {
|
|||
|
||||
return row, nil
|
||||
}
|
||||
|
||||
// TableHeaders returns the table header names of all
|
||||
// fields in tSlice. tSlice must be a slice of some type.
|
||||
func TableHeaders(tSlice any) ([]string, error) {
|
||||
v := reflect.Indirect(reflect.ValueOf(tSlice))
|
||||
rawHeaders, err := typeToTableHeaders(v.Type().Elem())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("type to table headers: %w", err)
|
||||
}
|
||||
out := make([]string, 0, len(rawHeaders))
|
||||
for _, hdr := range rawHeaders {
|
||||
out = append(out, strings.Replace(hdr, " ", "_", -1))
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
|
|
@ -327,6 +327,28 @@ baz baz1 baz3 Aug 2 15:49:10
|
|||
})
|
||||
}
|
||||
|
||||
func Test_TableHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := []tableTest1{}
|
||||
expectedFields := []string{
|
||||
"name",
|
||||
"age",
|
||||
"roles",
|
||||
"sub_1_name",
|
||||
"sub_1_age",
|
||||
"sub_2_name",
|
||||
"sub_2_age",
|
||||
"sub_3_inner_name",
|
||||
"sub_3_inner_age",
|
||||
"sub_4",
|
||||
"time",
|
||||
"time_ptr",
|
||||
}
|
||||
headers, err := cliui.TableHeaders(s)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, expectedFields, headers)
|
||||
}
|
||||
|
||||
// compareTables normalizes the incoming table lines
|
||||
func compareTables(t *testing.T, expected, out string) {
|
||||
t.Helper()
|
||||
|
|
|
@ -2,7 +2,6 @@ package cli
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -128,14 +127,10 @@ func list() *cobra.Command {
|
|||
},
|
||||
}
|
||||
|
||||
v := reflect.Indirect(reflect.ValueOf(displayWorkspaces))
|
||||
availColumns, err := cliui.TypeToTableHeaders(v.Type().Elem())
|
||||
availColumns, err := cliui.TableHeaders(displayWorkspaces)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i, s := range availColumns {
|
||||
availColumns[i] = strings.Replace(s, " ", "_", -1)
|
||||
}
|
||||
columnString := strings.Join(availColumns[:], ", ")
|
||||
|
||||
cmd.Flags().BoolVarP(&all, "all", "a", false,
|
||||
|
|
Loading…
Reference in New Issue