/
doc.go
275 lines (234 loc) · 9.15 KB
/
doc.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
// Copyright (C) 2023-2024 Takayuki Sato. All Rights Reserved.
// This program is free software under MIT License.
// See the file LICENSE in this distribution for more details.
/*
Package github.com/sttk/cliargs is a library to parse command line arguments.
# Parse without configurations
This library provides the function Parse which parses command line arguments
without configurations.
This function automatically divides command line arguments to options and
command arguments.
Command line arguments starting with - or -- are options, and others are
command arguments.
If you want to specify a value to an option, follows "=" and the value after
the option, like foo=123.
All command line arguments after -- are command arguments, even they starts
with - or --.
// osArgs := []string{"path/to/app", "--foo-bar", "hoge", "--baz", "1", "-z=2", "-xyz=3", "fuga"}
cmd, err := cliargs.Parse()
cmd.Name // app
cmd.Args() // [hoge fuga]
cmd.HasOpt("foo-bar") // true
cmd.HasOpt("baz") // true
cmd.HasOpt("x") // true
cmd.HasOpt("y") // true
cmd.HasOpt("z") // true
cmd.OptArg("foo-bar") // true
cmd.OptArg("baz") // 1
cmd.OptArg("x") // true
cmd.OptArg("y") // true
cmd.OptArg("z") // 2
cmd.OptArgs("foo-bar") // []
cmd.OptArgs("baz") // [1]
cmd.OptArgs("x") // []
cmd.OptArgs("y") // []
cmd.OptArgs("z") // [2 3]
# Parse with configurations
This library provides the function ParseWith which parses command line
arguments with configurations.
This function takes an array of option configurations: []OptCfg as the second
argument, and divides command line arguments to options and command arguments
with this configurations.
An option configuration has fields: StoreKey, Names, HasArg, IsArray, Defaults,
Desc, and ArgInHelp.
StoreKey field is specified the key name to store the option value st the
option map.
If this field is not specified, the first element of Names field is set
instead.
Names field is a string array and specified the option names, that are both
long options and short options.
The order of elements in this field is used in a help text.
If you want to prioritize the output of short option name first in the help
text, like `-f, --foo-bar`, but use the long option name as the key in the
option map, write StoreKey and Names fields as follows:
`OptCfg {StoreKey: "foo-bar", Names: []string{"f", "foo-bar"}}`.
HasArg field indicates the option requires one or more values.
IsArray field indicates the option can have multiple values.
Defaults field is an array of string which is used as default one or more
values if the option is not specified.
Desc field is a description of the option for help text.
ArgInHelp field is a text which is output after option name and aliases as an
option value in help text.
// osArgs := []string{"app", "--foo-bar", "hoge", "--baz", "1", "-z=2", "-x" "fuga"}
optCfgs := []cliargs.OptCfg{
cliargs.OptCfg{
StoreKey: "FooBar",
Names: []string{"foo-bar"},
Desc: "This is description of foo-bar.",
},
cliargs.OptCfg{
Names: []string{"baz", "z"},
HasArg:true,
IsArray: true,
Defaults: [9,8,7],
Desc:"This is description of baz.",
ArgHelp:"<text>",
},
cliargs.OptCfg{
Names: []string{"*"},
Desc: "(Any options are accepted)",
},
}
cmd, err := cliargs.ParseWith(optCfgs)
cmd.Name // app
cmd.Args() // [hoge fuga]
cmd.HasOpt("FooBar") // true
cmd.HasOpt("baz") // true
cmd.HasOpt("x") // true, due to "*" config
cmd.OptArg("FooBar") // true
cmd.OptArg("baz") // 1
cmd.OptArg("x") // true
cmd.OptArgs("FooBar") // []
cmd.OptArgs("baz") // [1 2]
cmd.OptArgs("x") // []
This library provides Help struct which generates help text from a OptCfg
array.
The following help text is generated from the above optCfgs.
help := cliargs.NewHelp()
help.AddText("This is the usage description.")
help.AddOpts(optCfgs, 0, 2)
help.Print()
// (stdout)
// This is the usage description.
// --foo-bar, -f This is description of foo-bar.
// --baz, -z <text> This is description of baz.
# Parse for an option store with struct tags
This library provides the function ParseFor which takes a pointer of a struct
as the second argument, which will put option values by parsing command line
arguments.
This struct needs to struct tags for its fields.
This function creates a Cmd instance and also an array of OptCfg which is
transformed from these struct tags and is used to parse command line arguments.
The struct tags used in a option store struct are optcfg, optdesc, and optarg.
optcfg is what to specify option configurations other than Desc and AtgInHelp.
The format of optcfg is as follows:
`optcfg:"name"` // only name
`optcfg:"name,alias1,alias2"` // with two aliases
`optcfg:"name=value"` // with a default value
`optcfg:"name=[value1,value2]` // with defalt values for array
`optcfg:"name=:[value1:value2]` // with default values and separator is :
optdesc is what to specify a option description.
And optarg is what to specify a text for an option argument value in help text.
// osArgs := []string{"app", "--foo-bar", "hoge", "--baz", "1", "-z=2", "-x", "fuga"}
type Options struct {
FooBar bool `optcfg:"foo-bar" optdesc:"This is description of foo-bar."`
Baz []int `optcfg:"baz,z=[9,8,7]" optdesc:"This is description of baz." optarg:"<num>"`
Qux bool `optcfg:"qux,x" optdesc:"This is description of qux"`
}
options := Options{}
cmd, optCfgs, err := cliargs.ParseFor(osArgs, &options)
cmd.Name // app
cmd.Args() // [hoge fuga]
cmd.HasOpt("FooBar") // true
cmd.HasOpt("Baz") // true
cmd.HasOpt("Qux") // true
cmd.OptArg("FooBar") // true
cmd.OptArg("Baz") // 1
cmd.OptArg("Qux") // true
cmd.OptArgs("FooBar") // []
cmd.OptArgs("Baz") // [1 2]
cmd.OptArgs("Qux") // []
options.FooBar // true
options.Baz // [1 2]
options.Qux // true
optCfgs // []OptCfg{
// OptCfg{
// StoreKey: "FooBar",
// Names: []string{"foo-bar"},
// Desc: "This is description of foo-bar.",
// HasArg: false,
// IsArray: false,
// Defaults: []string(nil),
// ArgInHelp: "",
// },
// OptCfg{
// StoreKey: "Baz",
// Aliases: []string{"baz", "z"},
// Desc: "This is description of baz.",
// HasArg: true,
// IsArray: true,
// Defaults: []string{"9","8","7"},
// ArgInHelp: "<num>",
// },
// OptCfg{
// StoreKey: "Qux",
// Aliases: []string{"qux", "x"},
// Desc: "This is description of qux.",
// HasArg: false,
// IsArray: false,
// Defaults: []string(nil),
// ArgInHelp: "",
// },
// }
The following help text is generated from the above optCfgs (without Help#Print but Help#Iter in this example).
help := cliargs.NewHelp()
help.AddText("This is the usage description.")
help.AddOpts(optCfgs, 12, 1)
iter := help.Iter()
for line, status := iter.Next() {
fmt.Println(line)
if status == cliargs.ITER_NO_MORE { break }
}
// (stdout)
// This is the usage description.
// --foo-bar This is description of foo-bar.
// --baz, -z <num>
// This is description of baz.
// --qux This is description of qux.
# Parse command line arguments including sub commands
This library provides the function FindFirstArg which returns an index, an
argument, an existent flag.
This function can be used to parse command line arguments including sub
commands, as follows:
i, arg, exists := cliargs.FindFirstArg(osArgs)
if !exists { return }
topCmd, topOptCfgs, err := cliargs.ParseFor(osArgs[0:i], &topOptions)
if err != nil { return }
switch arg {
case "list":
subCmd, subErr := cliargs.ParseWidth(osArgs[i:], &listOptCfgs)
if subErr != nil { return }
case "use":
subCmd, ubErr := cliargs.ParseWidth(osArgs[i:], &useOptCfgs)
if subErr != nil { return }
...
}
And help text can be generated as follows:
help := cliargs.NewHelp()
help.AddText("This is the usage of this command.")
help.AddText("\nOPTIONS:")
help.AddOpts(topOptCfgs, 12, 2)
help.AddText("\nSUB COMMANDS:")
help.AddText(fmt.Sprintf("%12s%s", "list", "The description of list sub-command.")
help.AddOpts(listOptCfgs, 12, 2)
help.AddText(fmt.Sprintf("%12s%s", "use", "The description of use sub-command.")
help.AddOpts(useOptCfgs, 12, 2)
...
help.Print()
// (stdout)
// This is the usage of this command.
//
// OPTIONS:
// --foo The description of foo option.
// ...
//
// SUB COMMANDS:
// list The description of list sub-command.
// --bar The description of bar option.
// ...
//
// use The description of use sub-command.
// --baz The description of baz option.
// ...
*/
package cliargs