11import std/ [parseopt, strutils, os, json]
2+ import yaml, yaml/ presenter, yaml/ dumping
23import godon/ [client, breeder, credential, types]
34
5+ type
6+ OutputFormat * = enum
7+ Text = " text"
8+ Json = " json"
9+ Yaml = " yaml"
10+
411proc writeHelp () =
512 echo """ Godon CLI - Command line interface for Godon API
613
@@ -23,8 +30,9 @@ Global Options:
2330 --hostname, -h <host> Godon hostname (default: localhost)
2431 --port, -p <port> Godon port (default: 8080)
2532 --api-version, -v <ver> API version (default: v0)
33+ --output, -o <format> Output format: text, json, or yaml (default: text)
2634 --insecure Skip SSL certificate verification (HTTPS only)
27- --help, -h Show this help message
35+ --help Show this help message
2836
2937Examples:
3038 godon_cli breeder list
@@ -40,12 +48,13 @@ proc writeError(message: string) =
4048 stderr.writeLine (" Error: " & message)
4149 quit (1 )
4250
43- proc parseArgs (): (string , string , int , string , bool , seq [string ]) =
51+ proc parseArgs (): (string , string , int , string , bool , OutputFormat , seq [string ]) =
4452 var command = " "
4553 var hostname = " localhost"
4654 var port = 8080
4755 var apiVersion = " v0"
4856 var insecure = false
57+ var outputFormat = OutputFormat .Text
4958 var args: seq [string ] = @ []
5059
5160 var p = initOptParser (commandLineParams ())
@@ -82,7 +91,19 @@ proc parseArgs(): (string, string, int, string, bool, seq[string]) =
8291 args.add (" --id=" & val)
8392 of " insecure" :
8493 insecure = true
85- of " help" , " h" :
94+ of " output" , " o" :
95+ if val.len == 0 :
96+ writeError (" Output option requires a value (text, json, or yaml)" )
97+ case val.normalize ()
98+ of " text" :
99+ outputFormat = OutputFormat .Text
100+ of " json" :
101+ outputFormat = OutputFormat .Json
102+ of " yaml" :
103+ outputFormat = OutputFormat .Yaml
104+ else :
105+ writeError (" Unknown output format: " & val & " . Use text, json, or yaml" )
106+ of " help" :
86107 writeHelp ()
87108 quit (0 )
88109 else :
@@ -95,23 +116,38 @@ proc parseArgs(): (string, string, int, string, bool, seq[string]) =
95116 writeHelp ()
96117 quit (0 )
97118
98- (command, hostname, port, apiVersion, insecure, args)
119+ (command, hostname, port, apiVersion, insecure, outputFormat, args)
120+
121+ proc formatOutput * [T](data: T, outputFormat: OutputFormat ) =
122+ # # Format data according to output format preference
123+ case outputFormat
124+ of OutputFormat .Text :
125+ # Text mode is handled by caller with custom formatting
126+ discard
127+ of OutputFormat .Json :
128+ echo pretty (%* data)
129+ of OutputFormat .Yaml :
130+ # Convert to YAML using block style dumper
131+ var dumper = blockOnlyDumper ()
132+ echo dumper.dump (data)
99133
100- proc handleBreederCommand (client: GodonClient , command: string , args: seq [string ]) =
134+ proc handleBreederCommand (client: GodonClient , command: string , args: seq [string ], outputFormat: OutputFormat ) =
101135 let subCommand = if args.len > 0 : args[0 ] else : " "
102136
103137 case subCommand:
104138 of " list" :
105- echo " Listing breeders..."
106139 let response = client.listBreeders ()
107140 if response.success:
108- echo " Breeders:"
109- for breeder in response.data:
110- echo " ID: " , breeder.id
111- echo " Name: " , breeder.name
112- echo " Status: " , breeder.status
113- echo " Created: " , breeder.createdAt
114- echo " ---"
141+ if outputFormat == OutputFormat .Text :
142+ echo " Breeders:"
143+ for breeder in response.data:
144+ echo " ID: " , breeder.id
145+ echo " Name: " , breeder.name
146+ echo " Status: " , breeder.status
147+ echo " Created: " , breeder.createdAt
148+ echo " ---"
149+ else :
150+ formatOutput (response.data, outputFormat)
115151 else :
116152 writeError (response.error)
117153
@@ -133,14 +169,16 @@ proc handleBreederCommand(client: GodonClient, command: string, args: seq[string
133169 if not fileExists (file):
134170 writeError (" File not found: " & file)
135171
136- echo " Creating breeder '" , name, " ' from file: " , file
137172 let content = readFile (file)
138173 let response = client.createBreederFromYamlWithName (content, name)
139174 if response.success:
140- echo " Breeder created successfully:"
141- echo " ID: " , response.data.id
142- echo " Name: " , response.data.name
143- echo " Status: " , response.data.status
175+ if outputFormat == OutputFormat .Text :
176+ echo " Breeder created successfully:"
177+ echo " ID: " , response.data.id
178+ echo " Name: " , response.data.name
179+ echo " Status: " , response.data.status
180+ else :
181+ formatOutput (response.data, outputFormat)
144182 else :
145183 writeError (response.error)
146184
@@ -153,16 +191,18 @@ proc handleBreederCommand(client: GodonClient, command: string, args: seq[string
153191
154192 if id.len == 0 :
155193 writeError (" breeder show requires --id <id>" )
156-
157- echo " Getting breeder details for ID: " , id
194+
158195 let response = client.getBreeder (id)
159196 if response.success:
160- echo " Breeder Details:"
161- echo " ID: " , response.data.id
162- echo " Name: " , response.data.name
163- echo " Status: " , response.data.status
164- echo " Config: " , pretty (response.data.config)
165- echo " Created: " , response.data.createdAt
197+ if outputFormat == OutputFormat .Text :
198+ echo " Breeder Details:"
199+ echo " ID: " , response.data.id
200+ echo " Name: " , response.data.name
201+ echo " Status: " , response.data.status
202+ echo " Config: " , pretty (response.data.config)
203+ echo " Created: " , response.data.createdAt
204+ else :
205+ formatOutput (response.data, outputFormat)
166206 else :
167207 writeError (response.error)
168208
@@ -178,15 +218,17 @@ proc handleBreederCommand(client: GodonClient, command: string, args: seq[string
178218
179219 if not fileExists (file):
180220 writeError (" File not found: " & file)
181-
182- echo " Updating breeder from file: " , file
221+
183222 let content = readFile (file)
184223 let response = client.updateBreederFromYaml (content)
185224 if response.success:
186- echo " Breeder updated successfully:"
187- echo " ID: " , response.data.id
188- echo " Name: " , response.data.name
189- echo " Status: " , response.data.status
225+ if outputFormat == OutputFormat .Text :
226+ echo " Breeder updated successfully:"
227+ echo " ID: " , response.data.id
228+ echo " Name: " , response.data.name
229+ echo " Status: " , response.data.status
230+ else :
231+ formatOutput (response.data, outputFormat)
190232 else :
191233 writeError (response.error)
192234
@@ -199,36 +241,38 @@ proc handleBreederCommand(client: GodonClient, command: string, args: seq[string
199241
200242 if id.len == 0 :
201243 writeError (" breeder purge requires --id <id>" )
202-
203- echo " Deleting breeder with ID: " , id
244+
204245 let response = client.deleteBreeder (id)
205246 if response.success:
206- echo " Breeder deleted successfully"
207- if response.data != nil :
208- echo " Response: " , pretty (response.data)
247+ if outputFormat == OutputFormat .Text :
248+ echo " Breeder deleted successfully: " , id
249+ else :
250+ formatOutput (response.data, outputFormat)
209251 else :
210252 writeError (response.error)
211253
212254 else :
213255 writeError (" Unknown breeder command: " & subCommand)
214256
215- proc handleCredentialCommand (client: GodonClient , command: string , args: seq [string ]) =
257+ proc handleCredentialCommand (client: GodonClient , command: string , args: seq [string ], outputFormat: OutputFormat ) =
216258 let subCommand = if args.len > 0 : args[0 ] else : " "
217259
218260 case subCommand:
219261 of " list" :
220- echo " Listing credentials..."
221262 let response = client.listCredentials ()
222263 if response.success:
223- echo " Credentials:"
224- for credential in response.data:
225- echo " ID: " , credential.id
226- echo " Name: " , credential.name
227- echo " Type: " , credential.credentialType
228- echo " Description: " , credential.description
229- echo " Windmill Variable: " , credential.windmillVariable
230- echo " Created: " , credential.createdAt
231- echo " ---"
264+ if outputFormat == OutputFormat .Text :
265+ echo " Credentials:"
266+ for credential in response.data:
267+ echo " ID: " , credential.id
268+ echo " Name: " , credential.name
269+ echo " Type: " , credential.credentialType
270+ echo " Description: " , credential.description
271+ echo " windmillVariable: " , credential.windmillVariable
272+ echo " Created: " , credential.createdAt
273+ echo " ---"
274+ else :
275+ formatOutput (response.data, outputFormat)
232276 else :
233277 writeError (response.error)
234278
@@ -244,16 +288,18 @@ proc handleCredentialCommand(client: GodonClient, command: string, args: seq[str
244288
245289 if not fileExists (file):
246290 writeError (" File not found: " & file)
247-
248- echo " Creating credential from file: " , file
291+
249292 let content = readFile (file)
250293 let response = client.createCredentialFromYaml (content)
251294 if response.success:
252- echo " Credential created successfully:"
253- echo " ID: " , response.data.id
254- echo " Name: " , response.data.name
255- echo " Type: " , response.data.credentialType
256- echo " Windmill Variable: " , response.data.windmillVariable
295+ if outputFormat == OutputFormat .Text :
296+ echo " Credential created successfully:"
297+ echo " ID: " , response.data.id
298+ echo " Name: " , response.data.name
299+ echo " Type: " , response.data.credentialType
300+ echo " windmillVariable: " , response.data.windmillVariable
301+ else :
302+ formatOutput (response.data, outputFormat)
257303 else :
258304 writeError (response.error)
259305
@@ -266,20 +312,22 @@ proc handleCredentialCommand(client: GodonClient, command: string, args: seq[str
266312
267313 if id.len == 0 :
268314 writeError (" credential show requires --id <id>" )
269-
270- echo " Getting credential details for ID: " , id
315+
271316 let response = client.getCredential (id)
272317 if response.success:
273- echo " Credential Details:"
274- echo " ID: " , response.data.id
275- echo " Name: " , response.data.name
276- echo " Type: " , response.data.credentialType
277- echo " Description: " , response.data.description
278- echo " Windmill Variable: " , response.data.windmillVariable
279- echo " Created: " , response.data.createdAt
280- echo " Last Used: " , response.data.lastUsedAt
281- echo " Content:"
282- echo " " , response.data.content # Show actual credential content
318+ if outputFormat == OutputFormat .Text :
319+ echo " Credential Details:"
320+ echo " ID: " , response.data.id
321+ echo " Name: " , response.data.name
322+ echo " Type: " , response.data.credentialType
323+ echo " Description: " , response.data.description
324+ echo " windmillVariable: " , response.data.windmillVariable
325+ echo " Created: " , response.data.createdAt
326+ echo " Last Used: " , response.data.lastUsedAt
327+ echo " Content:"
328+ echo " " , response.data.content
329+ else :
330+ formatOutput (response.data, outputFormat)
283331 else :
284332 writeError (response.error)
285333
@@ -292,33 +340,33 @@ proc handleCredentialCommand(client: GodonClient, command: string, args: seq[str
292340
293341 if id.len == 0 :
294342 writeError (" credential delete requires --id <id>" )
295-
296- echo " Deleting credential with ID: " , id
343+
297344 let response = client.deleteCredential (id)
298345 if response.success:
299- echo " Credential deleted successfully"
300- if response.data != nil :
301- echo " Response: " , pretty (response.data)
346+ if outputFormat == OutputFormat .Text :
347+ echo " Credential deleted successfully: " , id
348+ else :
349+ formatOutput (response.data, outputFormat)
302350 else :
303351 writeError (response.error)
304352
305353 else :
306354 writeError (" Unknown credential command: " & subCommand)
307355
308- let (command, hostname, port, apiVersion, insecure, args) = parseArgs ()
356+ let (command, hostname, port, apiVersion, insecure, outputFormat, args) = parseArgs ()
309357
310358let godonClient = newGodonClient (hostname, port, apiVersion, insecure)
311359
312360case command:
313361of " breeder" :
314362 if args.len == 0 :
315363 writeError (" breeder command requires a subcommand (list, create, show, update, purge)" )
316- handleBreederCommand (godonClient, command, args)
364+ handleBreederCommand (godonClient, command, args, outputFormat )
317365
318366of " credential" :
319367 if args.len == 0 :
320368 writeError (" credential command requires a subcommand (list, create, show, delete)" )
321- handleCredentialCommand (godonClient, command, args)
369+ handleCredentialCommand (godonClient, command, args, outputFormat )
322370
323371else :
324372 writeError (" Unknown command: " & command)
0 commit comments