Skip to content

Commit 04722ef

Browse files
committed
feat: impl New to optionally provide root name or use mod name as fallback
1 parent c3a1a35 commit 04722ef

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

builder.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cli
22

33
import (
4+
"runtime/debug"
45
"slices"
56
"strings"
67
)
@@ -19,6 +20,25 @@ var (
1920
errReqArgAfterOptional = "required positional arguments cannot come after optional ones"
2021
)
2122

23+
// New is intented to initialize a new root command. If no name is provided, it will use
24+
// runtime information to get the module name and use that for the command's name.
25+
// Anything more than a single name provided is ignored.
26+
func New(name ...string) CommandInfo {
27+
var cmdName string
28+
if len(name) > 0 {
29+
cmdName = name[0]
30+
} else {
31+
info, ok := debug.ReadBuildInfo()
32+
if !ok {
33+
panic("failed to read build info")
34+
}
35+
lastSlash := strings.LastIndexByte(info.Path, '/')
36+
cmdName = info.Path[lastSlash+1:]
37+
}
38+
39+
return NewCmd(cmdName)
40+
}
41+
2242
func (c *CommandInfo) prepareAndValidate() {
2343
// Add the default help option here as long as this
2444
// command doesn't already have a help option.

examples_test.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
)
1313

1414
func ExampleInputInfo_Short() {
15-
in := cli.NewCmd("example").
15+
in := cli.New().
1616
Opt(cli.NewOpt("flag").Short('f'))
1717

1818
c1 := in.ParseOrExit("-f", "hello")
@@ -26,7 +26,7 @@ func ExampleInputInfo_Short() {
2626
}
2727

2828
func ExampleInputInfo_ShortOnly() {
29-
in := cli.NewCmd("example").
29+
in := cli.New().
3030
Opt(cli.NewOpt("flag").ShortOnly('f'))
3131

3232
c := in.ParseOrExit("-f", "hello")
@@ -40,7 +40,7 @@ func ExampleInputInfo_ShortOnly() {
4040
}
4141

4242
func ExampleInputInfo_WithValueName_option() {
43-
in := cli.NewCmd("example").
43+
in := cli.New("example").
4444
Help("example program").
4545
Opt(cli.NewOpt("aa").WithValueName("str").Help("it says '<str>' above instead of '<arg>'"))
4646

@@ -61,7 +61,7 @@ func ExampleInputInfo_WithValueName_option() {
6161
}
6262

6363
func ExampleInputInfo_WithValueName_positionalArgument() {
64-
in := cli.NewCmd("example").
64+
in := cli.New("example").
6565
Help("example program").
6666
Arg(cli.NewArg("aa").WithValueName("filename").Help("it says '[filename]' above instead of '[aa]'"))
6767

@@ -90,7 +90,7 @@ func ExampleInputInfo_WithParser() {
9090
return image.Point{X: x, Y: y}, nil
9191
}
9292

93-
c := cli.NewCmd("example").
93+
c := cli.New().
9494
Opt(cli.NewOpt("aa").WithParser(pointParser)).
9595
ParseOrExit("--aa", "3,7")
9696

@@ -100,7 +100,7 @@ func ExampleInputInfo_WithParser() {
100100
}
101101

102102
func ExampleParseURL() {
103-
in := cli.NewCmd("example").
103+
in := cli.New().
104104
Opt(cli.NewOpt("u").WithParser(cli.ParseURL))
105105

106106
c := in.ParseOrExit("-u", "https://pkg.go.dev/github.com/steverusso/cli#ParseURL")
@@ -114,7 +114,7 @@ func ExampleParseURL() {
114114
}
115115

116116
func ExampleParseDuration() {
117-
in := cli.NewCmd("example").
117+
in := cli.New().
118118
Opt(cli.NewOpt("d").WithParser(cli.ParseDuration))
119119

120120
c := in.ParseOrExit("-d", "1h2m3s")
@@ -128,7 +128,7 @@ func ExampleParseDuration() {
128128
}
129129

130130
func ExampleNewTimeParser() {
131-
in := cli.NewCmd("example").
131+
in := cli.New().
132132
Opt(cli.NewOpt("t").WithParser(cli.NewTimeParser("2006-01-02")))
133133

134134
c := in.ParseOrExit("-t", "2025-04-12")
@@ -142,7 +142,7 @@ func ExampleNewTimeParser() {
142142
}
143143

144144
func ExampleNewFileParser() {
145-
in := cli.NewCmd("example").
145+
in := cli.New().
146146
Opt(cli.NewOpt("i").WithParser(cli.NewFileParser(cli.ParseInt))).
147147
Opt(cli.NewOpt("s").WithParser(cli.NewFileParser(nil)))
148148

@@ -167,7 +167,7 @@ func ExampleNewFileParser() {
167167
}
168168

169169
func ExampleCommandInfo_ExtraHelp() {
170-
in := cli.NewCmd("example").
170+
in := cli.New("example").
171171
Help("an example command").
172172
ExtraHelp("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.")
173173

@@ -190,7 +190,7 @@ func ExampleCommandInfo_ExtraHelp() {
190190
}
191191

192192
func ExampleCommandInfo_Usage() {
193-
in := cli.NewCmd("example").
193+
in := cli.New("example").
194194
Help("an example command").
195195
Usage(
196196
"example [--aa <arg>]",
@@ -216,7 +216,7 @@ func ExampleCommandInfo_Usage() {
216216
}
217217

218218
func ExampleDefaultFullHelp() {
219-
in := cli.NewCmd("example").
219+
in := cli.New("example").
220220
Help("an example command").
221221
Opt(cli.NewOpt("aa").Env("AA").Default("def").Help("an option")).
222222
Opt(cli.NewOpt("bb").
@@ -257,7 +257,7 @@ func ExampleDefaultFullHelp() {
257257
}
258258

259259
func ExampleDefaultShortHelp_simple() {
260-
in := cli.NewCmd("example").
260+
in := cli.New("example").
261261
Help("an example command").
262262
Opt(cli.NewOpt("aa").Short('a').Env("AA").Default("def").Help("an option")).
263263
Opt(cli.NewOpt("bb").Short('b').Required().Help("another option")).
@@ -288,7 +288,7 @@ func ExampleDefaultShortHelp_simple() {
288288
}
289289

290290
func ExampleDefaultShortHelp_simpleWithSubcommands() {
291-
in := cli.NewCmd("example").
291+
in := cli.New("example").
292292
Help("an example command").
293293
Opt(cli.NewOpt("aa").Short('a').Env("AA").Default("def").Help("an option")).
294294
Opt(cli.NewOpt("bb").Short('b').Required().Help("another option")).
@@ -319,7 +319,7 @@ func ExampleDefaultShortHelp_simpleWithSubcommands() {
319319
}
320320

321321
func ExampleDefaultShortHelp_complex() {
322-
in := cli.NewCmd("example").
322+
in := cli.New("example").
323323
Help("an example command").
324324
Opt(cli.NewOpt("aa").Env("AA").Default("def").Help("an option")).
325325
Opt(cli.NewOpt("bb").
@@ -362,7 +362,7 @@ func ExampleDefaultShortHelp_complex() {
362362
}
363363

364364
func ExampleGet_option() {
365-
c := cli.NewCmd("example").
365+
c := cli.New().
366366
Opt(cli.NewOpt("a")).
367367
Opt(cli.NewOpt("b")).
368368
ParseOrExit("-b=hello")
@@ -377,7 +377,7 @@ func ExampleGet_option() {
377377
}
378378

379379
func ExampleGetOr_option() {
380-
c := cli.NewCmd("example").
380+
c := cli.New().
381381
Opt(cli.NewOpt("a")).
382382
Opt(cli.NewOpt("b")).
383383
ParseOrExit("-a=hello")
@@ -393,7 +393,7 @@ func ExampleGetOr_option() {
393393
}
394394

395395
func ExampleLookup_option() {
396-
c := cli.NewCmd("example").
396+
c := cli.New().
397397
Opt(cli.NewOpt("a")).
398398
Opt(cli.NewOpt("b")).
399399
ParseOrExit("-b=hello")
@@ -409,7 +409,7 @@ func ExampleLookup_option() {
409409
}
410410

411411
func ExampleGet_positionalArgs() {
412-
c := cli.NewCmd("example").
412+
c := cli.New().
413413
Arg(cli.NewArg("a")).
414414
Arg(cli.NewArg("b")).
415415
ParseOrExit("hello")
@@ -424,7 +424,7 @@ func ExampleGet_positionalArgs() {
424424
}
425425

426426
func ExampleGetOr_positionlArgs() {
427-
c := cli.NewCmd("example").
427+
c := cli.New().
428428
Arg(cli.NewArg("a")).
429429
Arg(cli.NewArg("b")).
430430
ParseOrExit("hello")
@@ -440,7 +440,7 @@ func ExampleGetOr_positionlArgs() {
440440
}
441441

442442
func ExampleGetOrFunc() {
443-
c := cli.NewCmd("example").
443+
c := cli.New().
444444
Opt(cli.NewOpt("a")).
445445
Opt(cli.NewOpt("b")).
446446
ParseOrExit("-a", "hello")
@@ -458,7 +458,7 @@ func ExampleGetOrFunc() {
458458
}
459459

460460
func ExampleLookup_positionalArgs() {
461-
c := cli.NewCmd("example").
461+
c := cli.New().
462462
Arg(cli.NewArg("a")).
463463
Arg(cli.NewArg("b")).
464464
ParseOrExit("hello")

0 commit comments

Comments
 (0)