@@ -28,16 +28,20 @@ const (
28
28
)
29
29
30
30
type helpFields struct {
31
- Indent string
32
- Usage string
33
- Path string
34
- Tagline string
35
- Arguments string
36
- Options string
37
- Synopsis string
38
- Subcommands string
39
- Description string
40
- MoreHelp bool
31
+ Indent string
32
+ Warning string
33
+ Usage string
34
+ Path string
35
+ Tagline string
36
+ Arguments string
37
+ Options string
38
+ Synopsis string
39
+ Subcommands string
40
+ ExperimentalSubcommands string
41
+ DeprecatedSubcommands string
42
+ RemovedSubcommands string
43
+ Description string
44
+ MoreHelp bool
41
45
}
42
46
43
47
// TrimNewlines removes extra newlines from fields. This makes aligning
@@ -50,12 +54,16 @@ type helpFields struct {
50
54
// `
51
55
func (f * helpFields ) TrimNewlines () {
52
56
f .Path = strings .Trim (f .Path , "\n " )
57
+ f .Warning = strings .Trim (f .Warning , "\n " )
53
58
f .Usage = strings .Trim (f .Usage , "\n " )
54
59
f .Tagline = strings .Trim (f .Tagline , "\n " )
55
60
f .Arguments = strings .Trim (f .Arguments , "\n " )
56
61
f .Options = strings .Trim (f .Options , "\n " )
57
62
f .Synopsis = strings .Trim (f .Synopsis , "\n " )
58
63
f .Subcommands = strings .Trim (f .Subcommands , "\n " )
64
+ f .ExperimentalSubcommands = strings .Trim (f .ExperimentalSubcommands , "\n " )
65
+ f .DeprecatedSubcommands = strings .Trim (f .DeprecatedSubcommands , "\n " )
66
+ f .RemovedSubcommands = strings .Trim (f .RemovedSubcommands , "\n " )
59
67
f .Description = strings .Trim (f .Description , "\n " )
60
68
}
61
69
@@ -68,15 +76,21 @@ func (f *helpFields) IndentAll() {
68
76
return indentString (s , indentStr )
69
77
}
70
78
79
+ f .Warning = indent (f .Warning )
71
80
f .Usage = indent (f .Usage )
72
81
f .Arguments = indent (f .Arguments )
73
82
f .Options = indent (f .Options )
74
83
f .Synopsis = indent (f .Synopsis )
75
84
f .Subcommands = indent (f .Subcommands )
85
+ f .DeprecatedSubcommands = indent (f .DeprecatedSubcommands )
86
+ f .ExperimentalSubcommands = indent (f .ExperimentalSubcommands )
87
+ f .RemovedSubcommands = indent (f .RemovedSubcommands )
76
88
f .Description = indent (f .Description )
77
89
}
78
90
79
- const longHelpFormat = `USAGE
91
+ const longHelpFormat = `{{if .Warning}}WARNING: {{.Warning}}
92
+
93
+ {{end}}USAGE
80
94
{{.Usage}}
81
95
82
96
{{if .Synopsis}}SYNOPSIS
@@ -99,9 +113,21 @@ const longHelpFormat = `USAGE
99
113
100
114
{{.Indent}}For more information about each command, use:
101
115
{{.Indent}}'{{.Path}} <subcmd> --help'
116
+
117
+ {{end}}{{if .ExperimentalSubcommands}}EXPERIMENTAL SUBCOMMANDS
118
+ {{.ExperimentalSubcommands}}
119
+
120
+ {{end}}{{if .DeprecatedSubcommands}}DEPRECATED SUBCOMMANDS
121
+ {{.DeprecatedSubcommands}}
122
+
123
+ {{end}}{{if .RemovedSubcommands}}REMOVED SUBCOMMANDS
124
+ {{.RemovedSubcommands}}
125
+
102
126
{{end}}
103
127
`
104
- const shortHelpFormat = `USAGE
128
+ const shortHelpFormat = `{{if .Warning}}WARNING: {{.Warning}}
129
+
130
+ {{end}}USAGE
105
131
{{.Usage}}
106
132
{{if .Synopsis}}
107
133
{{.Synopsis}}
@@ -113,6 +139,16 @@ SUBCOMMANDS
113
139
{{end}}{{if .MoreHelp}}
114
140
{{.Indent}}For more information about each command, use:
115
141
{{.Indent}}'{{.Path}} <subcmd> --help'
142
+
143
+ {{end}}{{if .ExperimentalSubcommands}}EXPERIMENTAL SUBCOMMANDS
144
+ {{.ExperimentalSubcommands}}
145
+
146
+ {{end}}{{if .DeprecatedSubcommands}}DEPRECATED SUBCOMMANDS
147
+ {{.DeprecatedSubcommands}}
148
+
149
+ {{end}}{{if .RemovedSubcommands}}REMOVED SUBCOMMANDS
150
+ {{.RemovedSubcommands}}
151
+
116
152
{{end}}
117
153
`
118
154
@@ -188,6 +224,7 @@ func LongHelp(rootName string, root *cmds.Command, path []string, out io.Writer)
188
224
}
189
225
190
226
// autogen fields that are empty
227
+ fields .Warning = generateWarningText (cmd )
191
228
if len (cmd .Helptext .Usage ) > 0 {
192
229
fields .Usage = cmd .Helptext .Usage
193
230
} else {
@@ -200,7 +237,10 @@ func LongHelp(rootName string, root *cmds.Command, path []string, out io.Writer)
200
237
fields .Options = strings .Join (optionText (width , cmd ), "\n " )
201
238
}
202
239
if len (fields .Subcommands ) == 0 {
203
- fields .Subcommands = strings .Join (subcommandText (width , cmd , rootName , path ), "\n " )
240
+ fields .Subcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Active ), "\n " )
241
+ fields .ExperimentalSubcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Experimental ), "\n " )
242
+ fields .DeprecatedSubcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Deprecated ), "\n " )
243
+ fields .RemovedSubcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Removed ), "\n " )
204
244
}
205
245
if len (fields .Synopsis ) == 0 {
206
246
fields .Synopsis = generateSynopsis (width , cmd , pathStr )
@@ -245,13 +285,17 @@ func ShortHelp(rootName string, root *cmds.Command, path []string, out io.Writer
245
285
width := getTerminalWidth (out ) - len (indentStr )
246
286
247
287
// autogen fields that are empty
288
+ fields .Warning = generateWarningText (cmd )
248
289
if len (cmd .Helptext .Usage ) > 0 {
249
290
fields .Usage = cmd .Helptext .Usage
250
291
} else {
251
292
fields .Usage = commandUsageText (width , cmd , rootName , path )
252
293
}
253
294
if len (fields .Subcommands ) == 0 {
254
- fields .Subcommands = strings .Join (subcommandText (width , cmd , rootName , path ), "\n " )
295
+ fields .Subcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Active ), "\n " )
296
+ fields .ExperimentalSubcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Experimental ), "\n " )
297
+ fields .DeprecatedSubcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Deprecated ), "\n " )
298
+ fields .RemovedSubcommands = strings .Join (subcommandText (width , cmd , rootName , path , cmds .Removed ), "\n " )
255
299
}
256
300
if len (fields .Synopsis ) == 0 {
257
301
fields .Synopsis = generateSynopsis (width , cmd , pathStr )
@@ -409,24 +453,28 @@ func optionText(width int, cmd ...*cmds.Command) []string {
409
453
return lines
410
454
}
411
455
412
- func subcommandText (width int , cmd * cmds.Command , rootName string , path []string ) []string {
456
+ func subcommandText (width int , cmd * cmds.Command , rootName string , path []string , status cmds. Status ) []string {
413
457
prefix := fmt .Sprintf ("%v %v" , rootName , strings .Join (path , " " ))
414
458
if len (path ) > 0 {
415
459
prefix += " "
416
460
}
417
461
462
+ subCmds := make (map [string ]* cmds.Command , len (cmd .Subcommands ))
418
463
// Sorting fixes changing order bug #2981.
419
464
sortedNames := make ([]string , 0 )
420
- for name := range cmd .Subcommands {
421
- sortedNames = append (sortedNames , name )
465
+ for name , c := range cmd .Subcommands {
466
+ if c .Status == status {
467
+ sortedNames = append (sortedNames , name )
468
+ subCmds [name ] = c
469
+ }
422
470
}
423
471
sort .Strings (sortedNames )
424
472
425
- subcmds := make ([]* cmds.Command , len (cmd . Subcommands ))
426
- lines := make ([]string , len (cmd . Subcommands ))
473
+ subcmds := make ([]* cmds.Command , len (subCmds ))
474
+ lines := make ([]string , len (subCmds ))
427
475
428
476
for i , name := range sortedNames {
429
- sub := cmd . Subcommands [name ]
477
+ sub := subCmds [name ]
430
478
usage := usageText (sub )
431
479
if len (usage ) > 0 {
432
480
usage = " " + usage
@@ -445,6 +493,23 @@ func subcommandText(width int, cmd *cmds.Command, rootName string, path []string
445
493
return lines
446
494
}
447
495
496
+ // Text printed at the beginning of --help,
497
+ // after 'WARNING: ' tag at the start of the command.
498
+ func generateWarningText (cmd * cmds.Command ) string {
499
+ switch cmd .Status {
500
+ case cmds .Active :
501
+ return "" // We don't print a warning for a normal active command.
502
+ case cmds .Deprecated :
503
+ return "DEPRECATED, command will be removed in the future"
504
+ case cmds .Experimental :
505
+ return "EXPERIMENTAL, command may change in future releases"
506
+ case cmds .Removed :
507
+ return "REMOVED, command is no longer available"
508
+ default :
509
+ panic ("unknown command status" )
510
+ }
511
+ }
512
+
448
513
func commandUsageText (width int , cmd * cmds.Command , rootName string , path []string ) string {
449
514
text := fmt .Sprintf ("%v %v" , rootName , strings .Join (path , " " ))
450
515
argUsage := usageText (cmd )
0 commit comments