8
8
"errors"
9
9
"fmt"
10
10
"os"
11
+ "path/filepath"
11
12
"sort"
12
13
"strings"
13
14
@@ -151,6 +152,11 @@ func (c *documentationCommand) computeReverseAliases() {
151
152
// dumpSeveralFiles is invoked when every command is dumped into
152
153
// a separated entity
153
154
func (c * documentationCommand ) dumpSeveralFiles () error {
155
+ if len (c .super .subcmds ) == 0 {
156
+ fmt .Printf ("No commands found for %s" , c .super .Name )
157
+ return nil
158
+ }
159
+
154
160
// Attempt to create output directory. This will fail if:
155
161
// - we don't have permission to create the dir
156
162
// - a file already exists at the given path
@@ -159,16 +165,6 @@ func (c *documentationCommand) dumpSeveralFiles() error {
159
165
return err
160
166
}
161
167
162
- if len (c .super .subcmds ) == 0 {
163
- fmt .Printf ("No commands found for %s" , c .super .Name )
164
- return nil
165
- }
166
-
167
- sorted := c .getSortedListCommands ()
168
- c .computeReverseAliases ()
169
-
170
- // if the ids were provided, we must have the same
171
- // number of commands and ids
172
168
if c .idsPath != "" {
173
169
// get the list of ids
174
170
c .ids , err = c .readFileIds (c .idsPath )
@@ -186,31 +182,52 @@ func (c *documentationCommand) dumpSeveralFiles() error {
186
182
}
187
183
188
184
writer := bufio .NewWriter (f )
189
- _ , err = writer .WriteString (c .commandsIndex (sorted ))
185
+ _ , err = writer .WriteString (c .commandsIndex ())
190
186
if err != nil {
191
187
return err
192
188
}
193
189
f .Close ()
194
190
}
195
191
196
- folder := c .out + "/%s.md"
197
- for _ , command := range sorted {
198
- target := fmt .Sprintf (folder , command )
192
+ return c .writeDocs (c .out , []string {c .super .Name }, true )
193
+ }
194
+
195
+ // writeDocs (recursively) writes docs for all commands in the given folder.
196
+ func (c * documentationCommand ) writeDocs (folder string , superCommands []string , printDefaultCommands bool ) error {
197
+ c .computeReverseAliases ()
198
+
199
+ for name , ref := range c .super .subcmds {
200
+ if ! printDefaultCommands && isDefaultCommand (name ) {
201
+ continue
202
+ }
203
+ commandSeq := append (superCommands , name )
204
+ target := fmt .Sprintf ("%s.md" , strings .Join (commandSeq [1 :], "_" ))
205
+ target = strings .ReplaceAll (target , " " , "_" )
206
+ target = filepath .Join (folder , target )
207
+
199
208
f , err := os .Create (target )
200
209
if err != nil {
201
210
return err
202
211
}
203
212
writer := bufio .NewWriter (f )
204
- formatted := c .formatCommand (c . super . subcmds [ command ] , false )
213
+ formatted := c .formatCommand (ref , false , commandSeq )
205
214
_ , err = writer .WriteString (formatted )
206
215
if err != nil {
207
216
return err
208
217
}
209
218
writer .Flush ()
210
219
f .Close ()
220
+
221
+ // Handle subcommands
222
+ if sc , ok := ref .command .(* SuperCommand ); ok {
223
+ err = sc .documentation .writeDocs (folder , commandSeq , false )
224
+ if err != nil {
225
+ return err
226
+ }
227
+ }
211
228
}
212
229
213
- return err
230
+ return nil
214
231
}
215
232
216
233
func (c * documentationCommand ) readFileIds (path string ) (map [string ]string , error ) {
@@ -240,27 +257,58 @@ func (c *documentationCommand) dumpEntries(writer *bufio.Writer) error {
240
257
return nil
241
258
}
242
259
243
- sorted := c .getSortedListCommands ()
244
-
245
260
if ! c .noIndex {
246
- _ , err := writer .WriteString (c .commandsIndex (sorted ))
261
+ _ , err := writer .WriteString (c .commandsIndex ())
247
262
if err != nil {
248
263
return err
249
264
}
250
265
}
251
266
252
- var err error
253
- for _ , nameCmd := range sorted {
254
- _ , err = writer .WriteString (c .formatCommand (c .super .subcmds [nameCmd ], true ))
267
+ return c .writeSections (writer , []string {c .super .Name }, true )
268
+ }
269
+
270
+ // writeSections (recursively) writes sections for all commands to the given file.
271
+ func (c * documentationCommand ) writeSections (writer * bufio.Writer , superCommands []string , printDefaultCommands bool ) error {
272
+ sorted := c .getSortedListCommands ()
273
+ for _ , name := range sorted {
274
+ if ! printDefaultCommands && isDefaultCommand (name ) {
275
+ continue
276
+ }
277
+ ref := c .super .subcmds [name ]
278
+ commandSeq := append (superCommands , name )
279
+ _ , err := writer .WriteString (c .formatCommand (ref , true , commandSeq ))
255
280
if err != nil {
256
281
return err
257
282
}
283
+
284
+ // Handle subcommands
285
+ if sc , ok := ref .command .(* SuperCommand ); ok {
286
+ err = sc .documentation .writeSections (writer , commandSeq , false )
287
+ if err != nil {
288
+ return err
289
+ }
290
+ }
258
291
}
259
292
return nil
260
293
}
261
294
262
- func (c * documentationCommand ) commandsIndex (listCommands [] string ) string {
295
+ func (c * documentationCommand ) commandsIndex () string {
263
296
index := "# Index\n "
297
+
298
+ listCommands := c .getSortedListCommands ()
299
+ for id , name := range listCommands {
300
+ if isDefaultCommand (name ) {
301
+ continue
302
+ }
303
+ index += fmt .Sprintf ("%d. [%s](%s)\n " , id , name , c .linkForCommand (name ))
304
+ // TODO: handle subcommands ??
305
+ }
306
+ index += "---\n \n "
307
+ return index
308
+ }
309
+
310
+ // Return the URL/location for the given command
311
+ func (c * documentationCommand ) linkForCommand (cmd string ) string {
264
312
prefix := "#"
265
313
if c .ids != nil {
266
314
prefix = "/t/"
@@ -269,28 +317,22 @@ func (c *documentationCommand) commandsIndex(listCommands []string) string {
269
317
prefix = c .url + "/"
270
318
}
271
319
272
- for id , name := range listCommands {
273
- if name == "documentation" || name == "help" {
274
- continue
275
- }
276
- target , err := c .getTargetCmd (name )
277
- if err != nil {
278
- fmt .Printf ("[ERROR] command [%s] has no id, please add it to the list\n " , name )
279
- }
280
- index += fmt .Sprintf ("%d. [%s](%s%s)\n " , id , name , prefix , target )
320
+ target , err := c .getTargetCmd (cmd )
321
+ if err != nil {
322
+ fmt .Printf ("[ERROR] command [%s] has no id, please add it to the list\n " , cmd )
323
+ return ""
281
324
}
282
- index += "---\n \n "
283
- return index
325
+ return prefix + target
284
326
}
285
327
286
328
// formatCommand returns a string representation of the information contained
287
329
// by a command in Markdown format. The title param can be used to set
288
330
// whether the command name should be a title or not. This is particularly
289
331
// handy when splitting the commands in different files.
290
- func (c * documentationCommand ) formatCommand (ref commandReference , title bool ) string {
332
+ func (c * documentationCommand ) formatCommand (ref commandReference , title bool , commandSeq [] string ) string {
291
333
formatted := ""
292
334
if title {
293
- formatted = "# " + strings .ToUpper (ref . name ) + "\n "
335
+ formatted = "# " + strings .ToUpper (strings . Join ( commandSeq [ 1 :], " " ) ) + "\n "
294
336
}
295
337
296
338
var info * Info
@@ -338,9 +380,9 @@ func (c *documentationCommand) formatCommand(ref commandReference, title bool) s
338
380
// Usage
339
381
if strings .TrimSpace (info .Args ) != "" {
340
382
formatted += fmt .Sprintf (`## Usage
341
- ` + "```" + `%s %s [options] %s` + "```" + `
383
+ ` + "```" + `%s [options] %s` + "```" + `
342
384
343
- ` , c . super . Name , info . Name , info .Args )
385
+ ` , strings . Join ( commandSeq , " " ) , info .Args )
344
386
}
345
387
346
388
// Options
@@ -361,6 +403,7 @@ func (c *documentationCommand) formatCommand(ref commandReference, title bool) s
361
403
formatted += "## Details\n " + doc + "\n \n "
362
404
}
363
405
406
+ formatted += c .formatSubcommands (info .Subcommands , commandSeq )
364
407
formatted += "---\n \n "
365
408
366
409
return formatted
@@ -524,3 +567,27 @@ func EscapeMarkdown(raw string) string {
524
567
525
568
return escaped .String ()
526
569
}
570
+
571
+ func (c * documentationCommand ) formatSubcommands (subcommands map [string ]string , commandSeq []string ) string {
572
+ var output string
573
+
574
+ sorted := []string {}
575
+ for name := range subcommands {
576
+ if isDefaultCommand (name ) {
577
+ continue
578
+ }
579
+ sorted = append (sorted , name )
580
+ }
581
+ sort .Strings (sorted )
582
+
583
+ if len (sorted ) > 0 {
584
+ output += "## Subcommands\n "
585
+ for _ , name := range sorted {
586
+ output += fmt .Sprintf ("- [%s](%s)\n " , name ,
587
+ c .linkForCommand (strings .Join (append (commandSeq [1 :], name ), "_" )))
588
+ }
589
+ output += "\n "
590
+ }
591
+
592
+ return output
593
+ }
0 commit comments