-
Notifications
You must be signed in to change notification settings - Fork 2
/
option.go
145 lines (122 loc) · 3.66 KB
/
option.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package mcli
import (
"flag"
"strings"
"github.com/MakeNowJust/heredoc/v2"
)
func newParseOptions(opts ...ParseOpt) *parseOptions {
out := &parseOptions{
errorHandling: flag.ExitOnError,
}
return out.apply(opts...)
}
type parseOptions struct {
cmdName *string
args *[]string
errorHandling flag.ErrorHandling
examples string
argCompFuncs map[string]ArgCompletionFunc
customUsage func() string
helpFooter func() string
disableGlobalFlags bool
}
func (p *parseOptions) apply(opts ...ParseOpt) *parseOptions {
for _, o := range opts {
o.f(p)
}
return p
}
// ParseOpt specifies options to customize the behavior of Parse.
type ParseOpt struct {
f func(*parseOptions)
}
// WithArgs tells Parse to parse from the given args, instead of
// parsing from the command line arguments.
func WithArgs(args []string) ParseOpt {
return ParseOpt{f: func(options *parseOptions) {
options.args = &args
}}
}
// WithErrorHandling tells Parse to use the given ErrorHandling.
// By default, Parse exits the program when an error happens.
func WithErrorHandling(h flag.ErrorHandling) ParseOpt {
return ParseOpt{f: func(options *parseOptions) {
options.errorHandling = h
}}
}
// WithName specifies the command name to use when printing usage doc.
func WithName(name string) ParseOpt {
return ParseOpt{f: func(options *parseOptions) {
options.cmdName = &name
}}
}
// DisableGlobalFlags tells Parse to don't parse and print global flags in help.
func DisableGlobalFlags() ParseOpt {
return ParseOpt{f: func(options *parseOptions) {
options.disableGlobalFlags = true
}}
}
// ReplaceUsage specifies a function to generate a usage help to replace the
// default help.
func ReplaceUsage(f func() string) ParseOpt {
return ParseOpt{f: func(options *parseOptions) {
options.customUsage = f
}}
}
// WithExamples specifies examples for a command.
// Examples will be showed after flags in the command's help.
func WithExamples(examples string) ParseOpt {
return ParseOpt{f: func(options *parseOptions) {
options.examples = strings.TrimSpace(heredoc.Doc(examples))
}}
}
// WithFooter specifies a function to generate extra help text to print
// after the default help.
// If this option is provided, the option function's output overrides
// the App's optional help-footer setting.
func WithFooter(f func() string) ParseOpt {
return ParseOpt{f: func(options *parseOptions) {
options.helpFooter = f
}}
}
func newCmdOptions(opts ...CmdOpt) cmdOptions {
return *(new(cmdOptions).apply(opts...))
}
type cmdOptions struct {
category string
longDesc string
enableFlagCompletion bool
argCompFunc ArgCompletionFunc
}
func (p *cmdOptions) apply(opts ...CmdOpt) *cmdOptions {
for _, o := range opts {
o.f(p)
}
return p
}
// CmdOpt specifies options to customize the behavior of a Command.
type CmdOpt struct {
f func(*cmdOptions)
}
// WithCategory groups commands into different categories in help.
func WithCategory(category string) CmdOpt {
return CmdOpt{f: func(options *cmdOptions) {
options.category = category
}}
}
// WithLongDesc specifies a long description of a command,
// which will be showed in the command's help.
func WithLongDesc(long string) CmdOpt {
return CmdOpt{f: func(options *cmdOptions) {
options.longDesc = strings.TrimSpace(heredoc.Doc(long))
}}
}
// EnableFlagCompletion enables flag completion for a command.
// By default, flag completion is disabled to avoid unexpectedly running
// the user command when doing flag completion, in case that
// the user does not call `Parse` in the command.
func EnableFlagCompletion() CmdOpt {
return CmdOpt{f: func(options *cmdOptions) {
options.enableFlagCompletion = true
}}
}