You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Breaking: Completely rework how positional arguments are handled (#178)
* Implement the arg.Value approach
* Hook arg up (mostly)
* Fix command tests expecting args in a different way
* Add tests for the arg parsing mechanisms
* Rename some stuff
* Hook up the help
* Update the docs
* Update some tests
fmt.Fprintf(cmd.Stdout(), "Hello from quickstart!, my args were: %v, count was %d\n", args, *count)
91
-
returnnil
92
-
}
93
-
}
94
91
```
95
92
96
93
Will get you the following:
@@ -215,6 +212,80 @@ The types you can use for flags currently are:
215
212
> [!NOTE]
216
213
> You basically can't get this wrong, if you try and use an unsupported type, the Go compiler will yell at you
217
214
215
+
### Arguments
216
+
217
+
There are two approaches to positional arguments in `cli`, you can either just get the raw arguments yourself with `cmd.Args()` and do whatever you want with them:
218
+
219
+
```go
220
+
cli.New(
221
+
"my-command",
222
+
// ...
223
+
cli.Run(func(cmd *cli.Command) error {
224
+
fmt.Fprintf(cmd.Stdout(), "Hello! My arguments were: %v\n", cmd.Args())
225
+
returnnil
226
+
})
227
+
)
228
+
```
229
+
230
+
This will return a `[]string` containing all the positional arguments to your command (not flags, they've already been parsed elsewhere!)
231
+
232
+
Or, if you want to get smarter 🧠 `cli` allows you to define *type safe* representations of your arguments, with or without default values! This follows a similar
233
+
idea to [Flags](#flags)
234
+
235
+
That works like this:
236
+
237
+
```go
238
+
// Define a struct to hold your arguments
239
+
type myArgs struct {
240
+
name string
241
+
age int
242
+
employed bool
243
+
}
244
+
245
+
// Instantiate it
246
+
varargs myArgs
247
+
248
+
// Tell cli about your arguments with the Arg option
249
+
cli.New(
250
+
"my-command",
251
+
// ... other options here
252
+
cli.Arg(&args.name, "name", "The name of a person"),
253
+
cli.Arg(&args.age, "age", "How old the person is"),
254
+
cli.Arg(&args.employed, "employed", "Whether they are employed", cli.ArgDefault(true))
255
+
)
256
+
```
257
+
258
+
And just like [Flags](#flags), your argument types are all inferred and parsed automatically ✨, and you get nicer `--help` output too! Have a look at the [`./examples`](https://github.com/FollowTheProcess/cli/tree/main/examples)
259
+
to see more!
260
+
261
+
> [!NOTE]
262
+
> Just like flags, you can't really get this wrong. The types you can use for arguments are part of a generic constraint so using the wrong type results in a compiler error
263
+
264
+
The types you can currently use for positional args are:
265
+
266
+
-`int`
267
+
-`int8`
268
+
-`int16`
269
+
-`int32`
270
+
-`int64`
271
+
-`uint`
272
+
-`uint8`
273
+
-`uint16`
274
+
-`uint32`
275
+
-`uint64`
276
+
-`uintptr`
277
+
-`float32`
278
+
-`float64`
279
+
-`string`
280
+
-`bool`
281
+
-`[]byte` (interpreted as a hex string)
282
+
-`time.Time`
283
+
-`time.Duration`
284
+
-`net.IP`
285
+
286
+
> [!WARNING]
287
+
> Slice types are not supported (yet), for those you need to use the `cmd.Args()` method to get the arguments manually. I'm working on this!
288
+
218
289
## Core Principles
219
290
220
291
When designing and implementing `cli`, I had some core goals and guiding principles for implementation.
@@ -269,7 +340,6 @@ cmd, err := cli.New(
269
340
cli.Short("Short description of your command"),
270
341
cli.Long("Much longer text..."),
271
342
cli.Version("v1.2.3"),
272
-
cli.Allow(cli.MinArgs(1)),
273
343
cli.Stdout(os.Stdout),
274
344
cli.Example("Do a thing", "test run thing --now"),
275
345
cli.Flag(&count, "count", 'c', 0, "Count the things"),
@@ -319,8 +389,8 @@ I built `cli` for my own uses really, so I've quickly adopted it across a number
0 commit comments