Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb8ba53e

Browse files
committed
include user prompt if no org specified
1 parent87863ac commitb8ba53e

File tree

1 file changed

+109
-8
lines changed

1 file changed

+109
-8
lines changed

‎cli/organization.go

Lines changed: 109 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99

1010
"github.com/coder/coder/v2/cli/clibase"
1111
"github.com/coder/coder/v2/cli/cliui"
12+
"github.com/coder/coder/v2/cli/config"
1213
"github.com/coder/coder/v2/codersdk"
14+
"github.com/coder/pretty"
1315
)
1416

1517
func (r*RootCmd)organizations()*clibase.Cmd {
@@ -52,56 +54,155 @@ func (r *RootCmd) switchOrganization() *clibase.Cmd {
5254
),
5355
Middleware:clibase.Chain(
5456
r.InitClient(client),
57+
clibase.RequireRangeArgs(0,1),
5558
),
5659
Options: clibase.OptionSet{},
5760
Handler:func(inv*clibase.Invocation)error {
58-
orgArg:=inv.Args[0]
5961
conf:=r.createConfig()
6062
orgs,err:=client.OrganizationsByUser(inv.Context(),codersdk.Me)
6163
iferr!=nil {
6264
returnfmt.Errorf("failed to get organizations: %w",err)
6365
}
66+
// Keep the list of orgs sorted
67+
slices.SortFunc(orgs,func(a,b codersdk.Organization)int {
68+
returnstrings.Compare(a.Name,b.Name)
69+
})
70+
71+
varorgArgstring
72+
iflen(inv.Args)==0 {
73+
// Pull orgArg from a prompt selector, rather than command line
74+
// args.
75+
orgArg,err=promptUserSelectOrg(inv,conf,orgs)
76+
iferr!=nil {
77+
returnerr
78+
}
79+
}else {
80+
orgArg=inv.Args[0]
81+
}
6482

6583
// If the user passes an empty string, we want to remove the organization
84+
// from the config file. This will defer to default behavior.
6685
iforgArg=="" {
6786
err:=conf.Organization().Delete()
6887
iferr!=nil&&!errors.Is(err,os.ErrNotExist) {
6988
returnfmt.Errorf("failed to unset organization: %w",err)
7089
}
90+
_,_=fmt.Fprintf(inv.Stdout,"Organization unset\n")
7191
}else {
92+
// Find the selected org in our list.
7293
index:=slices.IndexFunc(orgs,func(org codersdk.Organization)bool {
7394
returnorg.Name==orgArg||org.ID.String()==orgArg
7495
})
7596
ifindex<0 {
76-
names:=make([]string,0,len(orgs))
77-
for_,org:=rangeorgs {
78-
names=append(names,org.Name)
79-
}
80-
8197
// Using this error for better error message formatting
8298
err:=&codersdk.Error{
8399
Response: codersdk.Response{
84-
Message:fmt.Sprintf("Organization %q not found.",orgArg),
100+
Message:fmt.Sprintf("Organization %q not found. Is the name correct, and are you a member of it?",orgArg),
85101
Detail:"Ensure the organization argument is correct and you are a member of it.",
86102
},
87-
Helper:fmt.Sprintf("Valid organizations you can switch to: %q",strings.Join(names,", ")),
103+
Helper:fmt.Sprintf("Valid organizations you can switch to: %q",strings.Join(orgNames(orgs),", ")),
88104
}
89105
returnerr
90106
}
91107

108+
// Always write the uuid to the config file. Names can change.
92109
err:=conf.Organization().Write(orgs[index].ID.String())
93110
iferr!=nil {
94111
returnfmt.Errorf("failed to write organization to config file: %w",err)
95112
}
96113
}
97114

115+
// Verify it worked.
116+
current,err:=CurrentOrganization(r,inv,client)
117+
iferr!=nil {
118+
// An SDK error could be a permission error. So offer the advice to unset the org
119+
// and reset the context.
120+
varsdkError*codersdk.Error
121+
iferrors.As(err,&sdkError) {
122+
ifsdkError.Helper==""&&sdkError.StatusCode()!=500 {
123+
sdkError.Helper=fmt.Sprintf("If this error persists, try unsetting your org with 'coder organizations switch\"\"'")
124+
}
125+
returnsdkError
126+
}
127+
returnfmt.Errorf("failed to get current organization: %w",err)
128+
}
129+
130+
_,_=fmt.Fprintf(inv.Stdout,"Current organization context set to %s (%s)\n",current.Name,current.ID.String())
98131
returnnil
99132
},
100133
}
101134

102135
returncmd
103136
}
104137

138+
// promptUserSelectOrg will prompt the user to select an organization from a list
139+
// of their organizations.
140+
funcpromptUserSelectOrg(inv*clibase.Invocation,conf config.Root,orgs []codersdk.Organization) (string,error) {
141+
// Default choice
142+
vardefaultOrgstring
143+
// Comes from config file
144+
ifconf.Organization().Exists() {
145+
defaultOrg,_=conf.Organization().Read()
146+
}
147+
148+
// No config? Comes from default org in the list
149+
ifdefaultOrg=="" {
150+
defIndex:=slices.IndexFunc(orgs,func(org codersdk.Organization)bool {
151+
returnorg.IsDefault
152+
})
153+
ifdefIndex>=0 {
154+
defaultOrg=orgs[defIndex].Name
155+
}
156+
}
157+
158+
// Defer to first org
159+
ifdefaultOrg==""&&len(orgs)>0 {
160+
defaultOrg=orgs[0].Name
161+
}
162+
163+
// Ensure the `defaultOrg` value is an org name, not a uuid.
164+
// If it is a uuid, change it to the org name.
165+
index:=slices.IndexFunc(orgs,func(org codersdk.Organization)bool {
166+
returnorg.ID.String()==defaultOrg||org.Name==defaultOrg
167+
})
168+
ifindex>=0 {
169+
defaultOrg=orgs[index].Name
170+
}
171+
172+
constdeselectOption="--Deselect--"
173+
ifdefaultOrg=="" {
174+
defaultOrg=deselectOption
175+
}
176+
177+
// Pull value from a prompt
178+
_,_=fmt.Fprintln(inv.Stdout,pretty.Sprint(cliui.DefaultStyles.Wrap,"Select an organization below to switch the current cli context to:"))
179+
value,err:=cliui.Select(inv, cliui.SelectOptions{
180+
Options:append([]string{deselectOption},orgNames(orgs)...),
181+
Default:defaultOrg,
182+
Size:10,
183+
HideSearch:false,
184+
})
185+
iferr!=nil {
186+
return"",err
187+
}
188+
// Deselect is an alias for ""
189+
ifvalue==deselectOption {
190+
value=""
191+
}
192+
193+
returnvalue,nil
194+
}
195+
196+
// orgNames is a helper function to turn a list of organizations into a list of
197+
// their names as strings.
198+
funcorgNames(orgs []codersdk.Organization) []string {
199+
names:=make([]string,0,len(orgs))
200+
for_,org:=rangeorgs {
201+
names=append(names,org.Name)
202+
}
203+
returnnames
204+
}
205+
105206
func (r*RootCmd)currentOrganization()*clibase.Cmd {
106207
var (
107208
client=new(codersdk.Client)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp