@@ -10,34 +10,49 @@ import (
10
10
"strings"
11
11
"text/tabwriter"
12
12
13
- "github.com/spf13/pflag "
13
+ "github.com/urfave/cli "
14
14
15
- "go.coder.com/cli"
16
15
"go.coder.com/flog"
17
16
)
18
17
19
- type urlsCmd struct {}
20
-
21
- func (cmd * urlsCmd ) Subcommands () []cli.Command {
22
- return []cli.Command {
23
- & listSubCmd {},
24
- & createSubCmd {},
25
- & delSubCmd {},
26
- }
27
- }
28
-
29
- func (cmd urlsCmd ) Spec () cli.CommandSpec {
30
- return cli.CommandSpec {
31
- Name : "urls" ,
32
- Usage : "[subcommand] <flags>" ,
33
- Desc : "interact with environment devurls" ,
18
+ func makeURLCmd () cli.Command {
19
+ var outputFmt string
20
+ return cli.Command {
21
+ Name : "urls" ,
22
+ Usage : "Interact with environment DevURLs" ,
23
+ ArgsUsage : "" ,
24
+ Before : nil ,
25
+ After : nil ,
26
+ OnUsageError : nil ,
27
+ Subcommands : []cli.Command {
28
+ makeCreateDevURL (),
29
+ {
30
+ Name : "ls" ,
31
+ Usage : "List all DevURLs for an environment" ,
32
+ ArgsUsage : "[env_name]" ,
33
+ Before : nil ,
34
+ Action : makeListDevURLs (& outputFmt ),
35
+ Flags : []cli.Flag {
36
+ cli.StringFlag {
37
+ Name : "output" ,
38
+ Usage : "human | json" ,
39
+ Value : "human" ,
40
+ Destination : & outputFmt ,
41
+ },
42
+ },
43
+ },
44
+ {
45
+ Name : "rm" ,
46
+ Usage : "Remove a dev url" ,
47
+ ArgsUsage : "" ,
48
+ Before : nil ,
49
+ Action : removeDevURL ,
50
+ Flags : nil ,
51
+ },
52
+ },
34
53
}
35
54
}
36
55
37
- func (cmd urlsCmd ) Run (fl * pflag.FlagSet ) {
38
- exitUsage (fl )
39
- }
40
-
41
56
// DevURL is the parsed json response record for a devURL from cemanager
42
57
type DevURL struct {
43
58
ID string `json:"id"`
@@ -78,64 +93,97 @@ func accessLevelIsValid(level string) bool {
78
93
return ok
79
94
}
80
95
81
- type listSubCmd struct {
82
- outputFmt string
83
- }
84
-
85
96
// Run gets the list of active devURLs from the cemanager for the
86
97
// specified environment and outputs info to stdout.
87
- func (sub listSubCmd ) Run (fl * pflag.FlagSet ) {
88
- envName := fl .Arg (0 )
89
- devURLs := urlList (envName )
90
-
91
- if len (devURLs ) == 0 {
92
- return
93
- }
98
+ func makeListDevURLs (outputFmt * string ) func (c * cli.Context ) {
99
+ return func (c * cli.Context ) {
100
+ envName := c .Args ().First ()
101
+ devURLs := urlList (envName )
94
102
95
- switch sub .outputFmt {
96
- case "human" :
97
- w := tabwriter .NewWriter (os .Stdout , 0 , 0 , 1 , ' ' , tabwriter .TabIndent )
98
- for _ , devURL := range devURLs {
99
- fmt .Fprintf (w , "%s\t %d\t %s\n " , devURL .URL , devURL .Port , devURL .Access )
103
+ if len (devURLs ) == 0 {
104
+ return
100
105
}
101
- err := w .Flush ()
102
- requireSuccess (err , "failed to flush writer: %v" , err )
103
- case "json" :
104
- err := json .NewEncoder (os .Stdout ).Encode (devURLs )
105
- requireSuccess (err , "failed to encode devurls to json: %v" , err )
106
- default :
107
- exitUsage (fl )
108
- }
109
- }
110
106
111
- func (sub * listSubCmd ) RegisterFlags (fl * pflag.FlagSet ) {
112
- fl .StringVarP (& sub .outputFmt , "output" , "o" , "human" , "output format (human | json)" )
113
- }
114
-
115
- func (sub * listSubCmd ) Spec () cli.CommandSpec {
116
- return cli.CommandSpec {
117
- Name : "ls" ,
118
- Usage : "<env> <flags>" ,
119
- Desc : "list all devurls for a given environment" ,
107
+ switch * outputFmt {
108
+ case "human" :
109
+ w := tabwriter .NewWriter (os .Stdout , 0 , 0 , 1 , ' ' , tabwriter .TabIndent )
110
+ for _ , devURL := range devURLs {
111
+ fmt .Fprintf (w , "%s\t %d\t %s\n " , devURL .URL , devURL .Port , devURL .Access )
112
+ }
113
+ err := w .Flush ()
114
+ requireSuccess (err , "failed to flush writer: %v" , err )
115
+ case "json" :
116
+ err := json .NewEncoder (os .Stdout ).Encode (devURLs )
117
+ requireSuccess (err , "failed to encode devurls to json: %v" , err )
118
+ default :
119
+ flog .Fatal ("unknown --output value %q" , * outputFmt )
120
+ }
120
121
}
121
122
}
122
123
123
- type createSubCmd struct {
124
- access string
125
- urlname string
126
- }
127
-
128
- func (sub * createSubCmd ) RegisterFlags (fl * pflag.FlagSet ) {
129
- fl .StringVarP (& sub .access , "access" , "a" , "private" , "[private | org | authed | public] set devurl access" )
130
- fl .StringVarP (& sub .urlname , "name" , "n" , "" , "devurl name" )
131
- }
132
-
133
- func (sub createSubCmd ) Spec () cli.CommandSpec {
134
- return cli.CommandSpec {
124
+ func makeCreateDevURL () cli.Command {
125
+ var (
126
+ access string
127
+ urlname string
128
+ )
129
+ return cli.Command {
135
130
Name : "create" ,
136
- Usage : "<env name> < port> [--access <level>] [--name <name>]" ,
131
+ Usage : "[env_name] [ port] [--access <level>] [--name <name>]" ,
137
132
Aliases : []string {"edit" },
138
- Desc : "create or update a devurl for external access" ,
133
+ Before : nil ,
134
+ Flags : []cli.Flag {
135
+ cli.StringFlag {
136
+ Name : "access" ,
137
+ Usage : "Set DevURL access to [private | org | authed | public]" ,
138
+ Value : "private" ,
139
+ Destination : & access ,
140
+ },
141
+ cli.StringFlag {
142
+ Name : "name" ,
143
+ Usage : "DevURL name" ,
144
+ Destination : & urlname ,
145
+ },
146
+ },
147
+ // Run creates or updates a devURL
148
+ Action : func (c * cli.Context ) {
149
+ var (
150
+ envName = c .Args ().First ()
151
+ port = c .Args ().Get (1 )
152
+ )
153
+
154
+ if envName == "" {
155
+ cli .ShowCommandHelpAndExit (c , c .Command .FullName (), 1 )
156
+ }
157
+
158
+ portNum , err := validatePort (port )
159
+ if err != nil {
160
+ cli .ShowCommandHelpAndExit (c , c .Command .FullName (), 1 )
161
+ }
162
+
163
+ access = strings .ToUpper (access )
164
+ if ! accessLevelIsValid (access ) {
165
+ cli .ShowCommandHelpAndExit (c , c .Command .FullName (), 1 )
166
+ }
167
+
168
+ if urlname != "" && ! devURLNameValidRx .MatchString (urlname ) {
169
+ flog .Fatal ("update devurl: name must be < 64 chars in length, begin with a letter and only contain letters or digits." )
170
+ return
171
+ }
172
+ entClient := requireAuth ()
173
+
174
+ env := findEnv (entClient , envName )
175
+
176
+ urlID , found := devURLID (portNum , urlList (envName ))
177
+ if found {
178
+ flog .Info ("Updating devurl for port %v" , port )
179
+ err := entClient .UpdateDevURL (env .ID , urlID , portNum , urlname , access )
180
+ requireSuccess (err , "update devurl: %s" , err )
181
+ } else {
182
+ flog .Info ("Adding devurl for port %v" , port )
183
+ err := entClient .InsertDevURL (env .ID , portNum , urlname , access )
184
+ requireSuccess (err , "insert devurl: %s" , err )
185
+ }
186
+ },
139
187
}
140
188
}
141
189
@@ -144,60 +192,6 @@ func (sub createSubCmd) Spec() cli.CommandSpec {
144
192
// consist solely of letters and digits, with a max length of 64 chars.
145
193
var devURLNameValidRx = regexp .MustCompile ("^[a-zA-Z][a-zA-Z0-9]{0,63}$" )
146
194
147
- // Run creates or updates a devURL, specified by env ID and port
148
- // (fl.Arg(0) and fl.Arg(1)), with access level (fl.Arg(2)) on
149
- // the cemanager.
150
- func (sub createSubCmd ) Run (fl * pflag.FlagSet ) {
151
- envName := fl .Arg (0 )
152
- port := fl .Arg (1 )
153
- name := fl .Arg (2 )
154
- access := fl .Arg (3 )
155
-
156
- if envName == "" {
157
- exitUsage (fl )
158
- }
159
-
160
- portNum , err := validatePort (port )
161
- if err != nil {
162
- exitUsage (fl )
163
- }
164
-
165
- access = strings .ToUpper (sub .access )
166
- if ! accessLevelIsValid (access ) {
167
- exitUsage (fl )
168
- }
169
-
170
- name = sub .urlname
171
- if name != "" && ! devURLNameValidRx .MatchString (name ) {
172
- flog .Fatal ("update devurl: name must be < 64 chars in length, begin with a letter and only contain letters or digits." )
173
- return
174
- }
175
- entClient := requireAuth ()
176
-
177
- env := findEnv (entClient , envName )
178
-
179
- urlID , found := devURLID (portNum , urlList (envName ))
180
- if found {
181
- flog .Info ("Updating devurl for port %v" , port )
182
- err := entClient .UpdateDevURL (env .ID , urlID , portNum , name , access )
183
- requireSuccess (err , "update devurl: %s" , err )
184
- } else {
185
- flog .Info ("Adding devurl for port %v" , port )
186
- err := entClient .InsertDevURL (env .ID , portNum , name , access )
187
- requireSuccess (err , "insert devurl: %s" , err )
188
- }
189
- }
190
-
191
- type delSubCmd struct {}
192
-
193
- func (sub delSubCmd ) Spec () cli.CommandSpec {
194
- return cli.CommandSpec {
195
- Name : "rm" ,
196
- Usage : "<env name> <port>" ,
197
- Desc : "remove a devurl" ,
198
- }
199
- }
200
-
201
195
// devURLID returns the ID of a devURL, given the env name and port
202
196
// from a list of DevURL records.
203
197
// ("", false) is returned if no match is found.
@@ -211,18 +205,14 @@ func devURLID(port int, urls []DevURL) (string, bool) {
211
205
}
212
206
213
207
// Run deletes a devURL, specified by env ID and port, from the cemanager.
214
- func (sub delSubCmd ) Run (fl * pflag.FlagSet ) {
215
- envName := fl .Arg (0 )
216
- port := fl .Arg (1 )
217
-
218
- if envName == "" {
219
- exitUsage (fl )
220
- }
208
+ func removeDevURL (c * cli.Context ) {
209
+ var (
210
+ envName = c .Args ().First ()
211
+ port = c .Args ().Get (1 )
212
+ )
221
213
222
214
portNum , err := validatePort (port )
223
- if err != nil {
224
- exitUsage (fl )
225
- }
215
+ requireSuccess (err , "failed to validate port: %v" , err )
226
216
227
217
entClient := requireAuth ()
228
218
env := findEnv (entClient , envName )
0 commit comments