chore: remove organization requirement from convertGroup() (#12195)

* feat: convertGroups() no longer requires organization info

Removing role information from some users in the api. This info is
excessive and not required. It is costly to always include
This commit is contained in:
Steven Masley
2024-02-21 15:58:11 -06:00
committed by GitHub
parent 3f65bd14cc
commit c3a7b13690
25 changed files with 350 additions and 278 deletions
+5 -1
View File
@@ -167,7 +167,11 @@ func prepareTestData(t *testing.T) (*codersdk.Client, map[string]string) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
db, pubsub := dbtestutil.NewDB(t)
// This needs to be a fixed timezone because timezones increase the length
// of timestamp strings. The increased length can pad table formatting's
// and differ the table header spacings.
//nolint:gocritic
db, pubsub := dbtestutil.NewDB(t, dbtestutil.WithTimezone("UTC"))
rootClient := coderdtest.New(t, &coderdtest.Options{
Database: db,
Pubsub: pubsub,
+1 -1
View File
@@ -106,7 +106,7 @@ func TableFormat(out any, defaultColumns []string) OutputFormat {
}
// Get the list of table column headers.
headers, defaultSort, err := typeToTableHeaders(v.Type().Elem())
headers, defaultSort, err := typeToTableHeaders(v.Type().Elem(), true)
if err != nil {
panic("parse table headers: " + err.Error())
}
+17 -4
View File
@@ -70,7 +70,7 @@ func DisplayTable(out any, sort string, filterColumns []string) (string, error)
}
// Get the list of table column headers.
headersRaw, defaultSort, err := typeToTableHeaders(v.Type().Elem())
headersRaw, defaultSort, err := typeToTableHeaders(v.Type().Elem(), true)
if err != nil {
return "", xerrors.Errorf("get table headers recursively for type %q: %w", v.Type().Elem().String(), err)
}
@@ -230,7 +230,11 @@ func isStructOrStructPointer(t reflect.Type) bool {
// 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, string, error) {
//
// requireDefault is only needed for the root call. This is recursive, so nested
// structs do not need the default sort name.
// nolint:revive
func typeToTableHeaders(t reflect.Type, requireDefault bool) ([]string, string, error) {
if !isStructOrStructPointer(t) {
return nil, "", xerrors.Errorf("typeToTableHeaders called with a non-struct or a non-pointer-to-a-struct type")
}
@@ -246,6 +250,12 @@ func typeToTableHeaders(t reflect.Type) ([]string, string, error) {
if err != nil {
return nil, "", xerrors.Errorf("parse struct tags for field %q in type %q: %w", field.Name, t.String(), err)
}
if name == "" && (recursive && skip) {
return nil, "", xerrors.Errorf("a name is required for the field %q. "+
"recursive_line will ensure this is never shown to the user, but is still needed", field.Name)
}
// If recurse and skip is set, the name is intentionally empty.
if name == "" {
continue
}
@@ -262,7 +272,7 @@ func typeToTableHeaders(t reflect.Type) ([]string, 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, defaultSort, err := typeToTableHeaders(fieldType, false)
if err != nil {
return nil, "", xerrors.Errorf("get child field header names for field %q in type %q: %w", field.Name, fieldType.String(), err)
}
@@ -273,13 +283,16 @@ func typeToTableHeaders(t reflect.Type) ([]string, string, error) {
}
headers = append(headers, fullName)
}
if defaultSortName == "" {
defaultSortName = defaultSort
}
continue
}
headers = append(headers, name)
}
if defaultSortName == "" {
if defaultSortName == "" && requireDefault {
return nil, "", xerrors.Errorf("no field marked as default_sort in type %q", t.String())
}
+2 -2
View File
@@ -46,12 +46,12 @@ type tableTest2 struct {
type tableTest3 struct {
NotIncluded string // no table tag
Sub tableTest2 `table:"inner,recursive,default_sort"`
Sub tableTest2 `table:"inner,recursive"`
}
type tableTest4 struct {
Inline tableTest2 `table:"ignored,recursive_inline"`
SortField string `table:"sort_field,default_sort"`
SortField string `table:"sort_field"`
}
func Test_DisplayTable(t *testing.T) {
+4
View File
@@ -51,6 +51,10 @@ func TestCommandHelp(t *testing.T) {
Name: "coder users list --output json",
Cmd: []string{"users", "list", "--output", "json"},
},
clitest.CommandHelpCase{
Name: "coder users list",
Cmd: []string{"users", "list"},
},
))
}
+3
View File
@@ -0,0 +1,3 @@
USERNAME EMAIL CREATED AT STATUS
testuser testuser@coder.com [timestamp] active
testuser2 testuser2@coder.com [timestamp] dormant
+8 -8
View File
@@ -2,11 +2,14 @@
{
"id": "[first user ID]",
"username": "testuser",
"avatar_url": "",
"name": "",
"email": "testuser@coder.com",
"created_at": "[timestamp]",
"last_seen_at": "[timestamp]",
"status": "active",
"login_type": "password",
"theme_preference": "",
"organization_ids": [
"[first org ID]"
],
@@ -15,25 +18,22 @@
"name": "owner",
"display_name": "Owner"
}
],
"avatar_url": "",
"login_type": "password",
"theme_preference": ""
]
},
{
"id": "[second user ID]",
"username": "testuser2",
"avatar_url": "",
"name": "",
"email": "testuser2@coder.com",
"created_at": "[timestamp]",
"last_seen_at": "[timestamp]",
"status": "dormant",
"login_type": "password",
"theme_preference": "",
"organization_ids": [
"[first org ID]"
],
"roles": [],
"avatar_url": "",
"login_type": "password",
"theme_preference": ""
"roles": []
}
]