1
1
package cli
2
2
3
3
import (
4
- "errors"
5
4
"fmt"
6
- "os"
7
5
"slices"
8
6
"strings"
9
7
@@ -17,6 +15,8 @@ import (
17
15
)
18
16
19
17
func (r * RootCmd )organizations ()* serpent.Command {
18
+ orgContext := NewOrganizationContext ()
19
+
20
20
cmd := & serpent.Command {
21
21
Use :"organizations [subcommand]" ,
22
22
Short :"Organization related commands" ,
@@ -26,114 +26,14 @@ func (r *RootCmd) organizations() *serpent.Command {
26
26
return inv .Command .HelpHandler (inv )
27
27
},
28
28
Children : []* serpent.Command {
29
- r .currentOrganization (),
30
- r .switchOrganization (),
29
+ r .showOrganization (orgContext ),
31
30
r .createOrganization (),
32
- r .organizationMembers (),
33
- r .organizationRoles (),
34
- },
35
- }
36
-
37
- cmd .Options = serpent.OptionSet {}
38
- return cmd
39
- }
40
-
41
- func (r * RootCmd )switchOrganization ()* serpent.Command {
42
- client := new (codersdk.Client )
43
-
44
- cmd := & serpent.Command {
45
- Use :"set <organization name | ID>" ,
46
- Short :"set the organization used by the CLI. Pass an empty string to reset to the default organization." ,
47
- Long :"set the organization used by the CLI. Pass an empty string to reset to the default organization.\n " + FormatExamples (
48
- Example {
49
- Description :"Remove the current organization and defer to the default." ,
50
- Command :"coder organizations set ''" ,
51
- },
52
- Example {
53
- Description :"Switch to a custom organization." ,
54
- Command :"coder organizations set my-org" ,
55
- },
56
- ),
57
- Middleware :serpent .Chain (
58
- r .InitClient (client ),
59
- serpent .RequireRangeArgs (0 ,1 ),
60
- ),
61
- Options : serpent.OptionSet {},
62
- Handler :func (inv * serpent.Invocation )error {
63
- conf := r .createConfig ()
64
- orgs ,err := client .OrganizationsByUser (inv .Context (),codersdk .Me )
65
- if err != nil {
66
- return xerrors .Errorf ("failed to get organizations: %w" ,err )
67
- }
68
- // Keep the list of orgs sorted
69
- slices .SortFunc (orgs ,func (a ,b codersdk.Organization )int {
70
- return strings .Compare (a .Name ,b .Name )
71
- })
72
-
73
- var switchToOrg string
74
- if len (inv .Args )== 0 {
75
- // Pull switchToOrg from a prompt selector, rather than command line
76
- // args.
77
- switchToOrg ,err = promptUserSelectOrg (inv ,conf ,orgs )
78
- if err != nil {
79
- return err
80
- }
81
- }else {
82
- switchToOrg = inv .Args [0 ]
83
- }
84
-
85
- // If the user passes an empty string, we want to remove the organization
86
- // from the config file. This will defer to default behavior.
87
- if switchToOrg == "" {
88
- err := conf .Organization ().Delete ()
89
- if err != nil && ! errors .Is (err ,os .ErrNotExist ) {
90
- return xerrors .Errorf ("failed to unset organization: %w" ,err )
91
- }
92
- _ ,_ = fmt .Fprintf (inv .Stdout ,"Organization unset\n " )
93
- }else {
94
- // Find the selected org in our list.
95
- index := slices .IndexFunc (orgs ,func (org codersdk.Organization )bool {
96
- return org .Name == switchToOrg || org .ID .String ()== switchToOrg
97
- })
98
- if index < 0 {
99
- // Using this error for better error message formatting
100
- err := & codersdk.Error {
101
- Response : codersdk.Response {
102
- Message :fmt .Sprintf ("Organization %q not found. Is the name correct, and are you a member of it?" ,switchToOrg ),
103
- Detail :"Ensure the organization argument is correct and you are a member of it." ,
104
- },
105
- Helper :fmt .Sprintf ("Valid organizations you can switch to: %s" ,strings .Join (orgNames (orgs ),", " )),
106
- }
107
- return err
108
- }
109
-
110
- // Always write the uuid to the config file. Names can change.
111
- err := conf .Organization ().Write (orgs [index ].ID .String ())
112
- if err != nil {
113
- return xerrors .Errorf ("failed to write organization to config file: %w" ,err )
114
- }
115
- }
116
-
117
- // Verify it worked.
118
- current ,err := CurrentOrganization (r ,inv ,client )
119
- if err != nil {
120
- // An SDK error could be a permission error. So offer the advice to unset the org
121
- // and reset the context.
122
- var sdkError * codersdk.Error
123
- if errors .As (err ,& sdkError ) {
124
- if sdkError .Helper == "" && sdkError .StatusCode ()!= 500 {
125
- sdkError .Helper = `If this error persists, try unsetting your org with 'coder organizations set ""'`
126
- }
127
- return sdkError
128
- }
129
- return xerrors .Errorf ("failed to get current organization: %w" ,err )
130
- }
131
-
132
- _ ,_ = fmt .Fprintf (inv .Stdout ,"Current organization context set to %s (%s)\n " ,current .Name ,current .ID .String ())
133
- return nil
31
+ r .organizationMembers (orgContext ),
32
+ r .organizationRoles (orgContext ),
134
33
},
135
34
}
136
35
36
+ orgContext .AttachOptions (cmd )
137
37
return cmd
138
38
}
139
39
@@ -207,7 +107,7 @@ func orgNames(orgs []codersdk.Organization) []string {
207
107
return names
208
108
}
209
109
210
- func (r * RootCmd )currentOrganization ( )* serpent.Command {
110
+ func (r * RootCmd )showOrganization ( orgContext * OrganizationContext )* serpent.Command {
211
111
var (
212
112
stringFormat func (orgs []codersdk.Organization ) (string ,error )
213
113
client = new (codersdk.Client )
@@ -226,8 +126,29 @@ func (r *RootCmd) currentOrganization() *serpent.Command {
226
126
onlyID = false
227
127
)
228
128
cmd := & serpent.Command {
229
- Use :"show [current|me|uuid]" ,
230
- Short :"Show the organization, if no argument is given, the organization currently in use will be shown." ,
129
+ Use :"show [\" selected\" |\" me\" |uuid|org_name]" ,
130
+ Short :"Show the organization. " +
131
+ "Using\" selected\" will show the selected organization from the\" --org\" flag. " +
132
+ "Using\" me\" will show all organizations you are a member of." ,
133
+ Long :FormatExamples (
134
+ Example {
135
+ Description :"coder org show selected" ,
136
+ Command :"Shows the organizations selected with '--org=<org_name>'. " +
137
+ "This organization is the organization used by the cli." ,
138
+ },
139
+ Example {
140
+ Description :"coder org show me" ,
141
+ Command :"List of all organizations you are a member of." ,
142
+ },
143
+ Example {
144
+ Description :"coder org show developers" ,
145
+ Command :"Show organization with name 'developers'" ,
146
+ },
147
+ Example {
148
+ Description :"coder org show 90ee1875-3db5-43b3-828e-af3687522e43" ,
149
+ Command :"Show organization with the given ID." ,
150
+ },
151
+ ),
231
152
Middleware :serpent .Chain (
232
153
r .InitClient (client ),
233
154
serpent .RequireRangeArgs (0 ,1 ),
@@ -242,22 +163,22 @@ func (r *RootCmd) currentOrganization() *serpent.Command {
242
163
},
243
164
},
244
165
Handler :func (inv * serpent.Invocation )error {
245
- orgArg := "current "
166
+ orgArg := "selected "
246
167
if len (inv .Args )>= 1 {
247
168
orgArg = inv .Args [0 ]
248
169
}
249
170
250
171
var orgs []codersdk.Organization
251
172
var err error
252
173
switch strings .ToLower (orgArg ) {
253
- case "current " :
174
+ case "selected " :
254
175
stringFormat = func (orgs []codersdk.Organization ) (string ,error ) {
255
176
if len (orgs )!= 1 {
256
177
return "" ,xerrors .Errorf ("expected 1 organization, got %d" ,len (orgs ))
257
178
}
258
179
return fmt .Sprintf ("Current CLI Organization: %s (%s)\n " ,orgs [0 ].Name ,orgs [0 ].ID .String ()),nil
259
180
}
260
- org ,err := CurrentOrganization ( r , inv ,client )
181
+ org ,err := orgContext . Selected ( inv ,client )
261
182
if err != nil {
262
183
return err
263
184
}