-
Notifications
You must be signed in to change notification settings - Fork 0
/
help.go
109 lines (91 loc) · 2.39 KB
/
help.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 The Prime Citizens
package cli
import (
"io"
"os"
)
// HelperTerminal writes help messages for a terminal user.
type HelperTerminal interface {
// HelplnCmdTerminal writes help messages for the target command
// with a newline in the end.
HelplnCmdTerminal(out io.Writer, route Route, linePrefix string) (int, error)
// HelplnFlagTerminal writes help meesages for the flag with a newline
// in the end.
HelplnFlagTerminal(
out io.Writer, route Route, linePrefix string,
indent int, flag FlagInfo, groupHasShorthand bool,
) (int, error)
}
// HandleHelpRequest calls HandleArgErrorAsHelpRequest with nil error.
func HandleHelpRequest(
opts *CmdOptions, route Route, args []string, helpArgAt int,
) error {
return HandleArgErrorAsHelpRequest(opts, route, args, helpArgAt, nil)
}
// HandleArgErrorAsHelpRequest prints the error and usage text of the target
// command to stderr, it tries to cast Cmd.Extra and Flag.Extra() as
// TerminalHelper to write messages.
func HandleArgErrorAsHelpRequest(
opts *CmdOptions, route Route, args []string, badArgAt int, cmdErr error,
) error {
c := route.Target()
if c == nil {
return cmdErr
}
out := opts.PickStderr(os.Stderr)
if cmdErr != nil {
// ignore errors to always write the error line as a whole
_, _ = wstr(out, "Error: ")
_, _ = wstr(out, cmdErr.Error())
_, _ = wstr(out, "\n\n")
}
const LinePrefix = ""
switch ct := c.Extra.(type) {
case HelperTerminal:
_, _ = ct.HelplnCmdTerminal(out, route, LinePrefix)
return cmdErr
default:
var err error
if hasRouteLine(route) {
if len(LinePrefix) != 0 {
_, err = wstr(out, LinePrefix)
if err != nil {
return cmdErr
}
}
_, err = FormatRoute(out, route, " ")
if err != nil {
return cmdErr
}
}
_, err = write(out, route.Target().BriefUsage, "", "\n\n", LinePrefix)
if err != nil {
return cmdErr
}
_, err = printSubcmds(out, c.Children, "\n\n", LinePrefix)
if err != nil {
return cmdErr
}
_, err = printlnTargetCmdFlags(out, route, "\n\nFlags:\n", LinePrefix+" ")
return cmdErr
}
}
func hasRouteLine(r Route) bool {
for _, c := range r {
if len(c.Name()) != 0 {
return true
}
}
return false
}
func writeSpaces(out io.Writer, count int) (n int, err error) {
for i, x := 0, 0; i < count; i++ {
x, err = wstr(out, " ")
n += x
if err != nil {
return
}
}
return
}