Skip to content

Commit c88e6fc

Browse files
authored
Merge pull request urfave#2101 from dearchap/pr_2088_add_docs
Add docs for arg types
2 parents 103c934 + fbed452 commit c88e6fc

File tree

2 files changed

+225
-1
lines changed

2 files changed

+225
-1
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
---
2+
tags:
3+
- v3
4+
search:
5+
boost: 2
6+
---
7+
8+
The [Basics] showed how to access arguments for a command. They are all retrieved as strings which is fine
9+
but it we need to say get integers or timestamps the user would have to convert from string to desired type.
10+
To ease the burden on users the `cli` library offers predefined <Type>Arg and <Type>Args structure to faciliate this
11+
The value of the argument can be retrieved using the command.<Type>Arg() function. For e.g
12+
13+
<!-- {
14+
"args" : ["10"],
15+
"output": "We got 10"
16+
} -->
17+
```go
18+
package main
19+
20+
import (
21+
"fmt"
22+
"log"
23+
"os"
24+
"context"
25+
26+
"github.com/urfave/cli/v3"
27+
)
28+
29+
func main() {
30+
cmd := &cli.Command{
31+
Arguments: []cli.Argument{
32+
&cli.IntArg{
33+
Name: "someint",
34+
},
35+
},
36+
Action: func(ctx context.Context, cmd *cli.Command) error {
37+
fmt.Printf("We got %d", cmd.IntArg("someint"))
38+
return nil
39+
},
40+
}
41+
42+
if err := cmd.Run(context.Background(), os.Args); err != nil {
43+
log.Fatal(err)
44+
}
45+
}
46+
```
47+
48+
Running this program with an argument gives the following output
49+
50+
```sh-session
51+
$ greet 10
52+
We got 10
53+
```
54+
55+
Instead of using the cmd.XXXArg() function to retrieve the argument value a destination for the argument can be set
56+
for e.g
57+
58+
<!-- {
59+
"args" : ["25"],
60+
"output": "We got 25"
61+
} -->
62+
```go
63+
package main
64+
65+
import (
66+
"fmt"
67+
"log"
68+
"os"
69+
"context"
70+
71+
"github.com/urfave/cli/v3"
72+
)
73+
74+
func main() {
75+
var ival int
76+
cmd := &cli.Command{
77+
Arguments: []cli.Argument{
78+
&cli.IntArg{
79+
Name: "someint",
80+
Destination: &ival,
81+
},
82+
},
83+
Action: func(ctx context.Context, cmd *cli.Command) error {
84+
fmt.Printf("We got %d", ival)
85+
return nil
86+
},
87+
}
88+
89+
if err := cmd.Run(context.Background(), os.Args); err != nil {
90+
log.Fatal(err)
91+
}
92+
}
93+
```
94+
95+
Some of the basic types arguments suported are
96+
97+
- `FloatArg`
98+
- `IntArg`
99+
- `Int8Arg`
100+
- `Int16Arg`
101+
- `Int32Arg`
102+
- `Int64Arg`
103+
- `StringArg`
104+
- `UintArg`
105+
- `Uint8Arg`
106+
- `Uint16Arg`
107+
- `Uint32Arg`
108+
- `Uint64Arg`
109+
- `TimestampArg`
110+
111+
This is ok for single value arguments. Any number of these single value arguments can be concatenated in the `Arguments`
112+
slice field of `Command`.
113+
114+
The library also support multi value arguments for e.g
115+
116+
<!-- {
117+
"args" : ["10", "20"],
118+
"output": "We got &#91;10 20&#93;"
119+
} -->
120+
```go
121+
package main
122+
123+
import (
124+
"fmt"
125+
"log"
126+
"os"
127+
"context"
128+
129+
"github.com/urfave/cli/v3"
130+
)
131+
132+
func main() {
133+
cmd := &cli.Command{
134+
Arguments: []cli.Argument{
135+
&cli.IntArgs{
136+
Name: "someint",
137+
Min: 0,
138+
Max: -1,
139+
},
140+
},
141+
Action: func(ctx context.Context, cmd *cli.Command) error {
142+
fmt.Println("We got ", cmd.IntArgs("someint"))
143+
return nil
144+
},
145+
}
146+
147+
if err := cmd.Run(context.Background(), os.Args); err != nil {
148+
log.Fatal(err)
149+
}
150+
}
151+
```
152+
153+
Some things to note about multi value arguments
154+
155+
1. They have XXXArgs type instead of XXXArg to differentiate them from single value arguments
156+
2. The Max field needs to be defined to a non zero value without which it cannot be parsed
157+
3. Max field value needs to be greater then the Min field value
158+
159+
As with single value args the destination field can be set
160+
161+
<!-- {
162+
"args" : ["10", "30"],
163+
"output": "We got &#91;10 30&#93;"
164+
} -->
165+
```go
166+
package main
167+
168+
import (
169+
"fmt"
170+
"log"
171+
"os"
172+
"context"
173+
174+
"github.com/urfave/cli/v3"
175+
)
176+
177+
func main() {
178+
var ivals []int
179+
cmd := &cli.Command{
180+
Arguments: []cli.Argument{
181+
&cli.IntArgs{
182+
Name: "someint",
183+
Min: 0,
184+
Max: -1,
185+
Destination: &ivals,
186+
},
187+
},
188+
Action: func(ctx context.Context, cmd *cli.Command) error {
189+
fmt.Println("We got ", ivals)
190+
return nil
191+
},
192+
}
193+
194+
if err := cmd.Run(context.Background(), os.Args); err != nil {
195+
log.Fatal(err)
196+
}
197+
}
198+
```
199+
200+
Following multi value arguments are supported
201+
202+
- `FloatArgs`
203+
- `IntArgs`
204+
- `Int8Args`
205+
- `Int16Args`
206+
- `Int32Args`
207+
- `Int64Args`
208+
- `StringArgs`
209+
- `UintArgs`
210+
- `Uint8Args`
211+
- `Uint16Args`
212+
- `Uint32Args`
213+
- `Uint64Args`
214+
- `TimestampArgs`
215+
216+
It goes without saying that the chain of arguments set in the Arguments slice need to be consistent. Generally a glob
217+
argument(max=-1) should be set for the argument at the end of the slice. To glob args we arent interested in we coud add
218+
the following to the end of the Arguments slice and retrieve them as a slice
219+
220+
```
221+
&StringArgs{
222+
Max: -1,
223+
},
224+
```

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ nav:
2929
- Advanced: v3/examples/flags/advanced.md
3030
- Arguments:
3131
- Basics: v3/examples/arguments/basics.md
32-
#- Advanced: v3/examples/arguments/advanced.md
32+
- Advanced: v3/examples/arguments/advanced.md
3333
- Subcommands:
3434
- Basics: v3/examples/subcommands/basics.md
3535
- Categories: v3/examples/subcommands/categories.md

0 commit comments

Comments
 (0)