mcfg: don't allow for empty sub-command, as that makes printing help weird
This commit is contained in:
parent
b35b44eb22
commit
99387d89ac
35
mcfg/cli.go
35
mcfg/cli.go
@ -59,9 +59,7 @@ type subCmd struct {
|
|||||||
// support for sub-sub-commands, and more. The callback may be nil.
|
// support for sub-sub-commands, and more. The callback may be nil.
|
||||||
//
|
//
|
||||||
// If any sub-commands have been defined on a Context which is passed into
|
// If any sub-commands have been defined on a Context which is passed into
|
||||||
// Parse, it is assumed that a sub-command is required on the command-line. The
|
// Parse, it is assumed that a sub-command is required on the command-line.
|
||||||
// exception is if a sub-command with a name of "" has been defined; if so, it
|
|
||||||
// will be used as the intended sub-command if none is specified.
|
|
||||||
//
|
//
|
||||||
// Sub-commands must be specified before any other options on the command-line.
|
// Sub-commands must be specified before any other options on the command-line.
|
||||||
func WithCLISubCommand(ctx context.Context, name, descr string, callback func(context.Context) context.Context) (context.Context, *bool) {
|
func WithCLISubCommand(ctx context.Context, name, descr string, callback func(context.Context) context.Context) (context.Context, *bool) {
|
||||||
@ -156,9 +154,7 @@ func (cli *SourceCLI) parse(
|
|||||||
if subCmd.callback != nil {
|
if subCmd.callback != nil {
|
||||||
ctx = subCmd.callback(ctx)
|
ctx = subCmd.callback(ctx)
|
||||||
}
|
}
|
||||||
if subCmd.name != "" {
|
|
||||||
subCmdPrefix = append(subCmdPrefix, subCmd.name)
|
subCmdPrefix = append(subCmdPrefix, subCmd.name)
|
||||||
}
|
|
||||||
*subCmd.flag = true
|
*subCmd.flag = true
|
||||||
return cli.parse(ctx, subCmdPrefix, args)
|
return cli.parse(ctx, subCmdPrefix, args)
|
||||||
}
|
}
|
||||||
@ -238,20 +234,16 @@ func (cli *SourceCLI) parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cli *SourceCLI) getSubCmd(subCmdM map[string]subCmd, args []string) (subCmd, []string, bool) {
|
func (cli *SourceCLI) getSubCmd(subCmdM map[string]subCmd, args []string) (subCmd, []string, bool) {
|
||||||
// if a proper sub-command is given then great, return that
|
if len(args) == 0 {
|
||||||
if len(args) > 0 {
|
|
||||||
if subCmd, ok := subCmdM[args[0]]; ok {
|
|
||||||
return subCmd, args[1:], true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the empty subCmd is set in the map it means an absent sub-command is
|
|
||||||
// allowed, check if that's the case
|
|
||||||
if subCmd, ok := subCmdM[""]; ok {
|
|
||||||
return subCmd, args, true
|
|
||||||
}
|
|
||||||
|
|
||||||
return subCmd{}, args, false
|
return subCmd{}, args, false
|
||||||
|
}
|
||||||
|
|
||||||
|
s, ok := subCmdM[args[0]]
|
||||||
|
if !ok {
|
||||||
|
return subCmd{}, args, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, args[1:], true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *SourceCLI) cliParams(params []Param) (map[string]Param, error) {
|
func (cli *SourceCLI) cliParams(params []Param) (map[string]Param, error) {
|
||||||
@ -307,9 +299,6 @@ func (cli *SourceCLI) printHelp(
|
|||||||
|
|
||||||
subCmdA := make([]subCmdEntry, 0, len(subCmdM))
|
subCmdA := make([]subCmdEntry, 0, len(subCmdM))
|
||||||
for name, subCmd := range subCmdM {
|
for name, subCmd := range subCmdM {
|
||||||
if name == "" {
|
|
||||||
name = "<None>"
|
|
||||||
}
|
|
||||||
subCmdA = append(subCmdA, subCmdEntry{name: name, subCmd: subCmd})
|
subCmdA = append(subCmdA, subCmdEntry{name: name, subCmd: subCmd})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,12 +311,8 @@ func (cli *SourceCLI) printHelp(
|
|||||||
fmt.Fprintf(w, " %s", strings.Join(subCmdPrefix, " "))
|
fmt.Fprintf(w, " %s", strings.Join(subCmdPrefix, " "))
|
||||||
}
|
}
|
||||||
if len(subCmdA) > 0 {
|
if len(subCmdA) > 0 {
|
||||||
if _, ok := subCmdM[""]; ok {
|
|
||||||
fmt.Fprint(w, " [sub-command]")
|
|
||||||
} else {
|
|
||||||
fmt.Fprint(w, " <sub-command>")
|
fmt.Fprint(w, " <sub-command>")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if len(pA) > 0 {
|
if len(pA) > 0 {
|
||||||
fmt.Fprint(w, " [options]")
|
fmt.Fprint(w, " [options]")
|
||||||
}
|
}
|
||||||
|
@ -106,32 +106,6 @@ Options:
|
|||||||
--foo \(Default: 5\)
|
--foo \(Default: 5\)
|
||||||
Test int param.
|
Test int param.
|
||||||
|
|
||||||
$`)
|
|
||||||
|
|
||||||
ctx, _ = WithCLISubCommand(ctx, "", "No sub-command", nil)
|
|
||||||
assertHelp(ctx, []string{"foo", "bar"}, `^Usage: \S+ foo bar \[sub-command\] \[options\]
|
|
||||||
|
|
||||||
Sub-commands:
|
|
||||||
|
|
||||||
<None> No sub-command
|
|
||||||
first First sub-command
|
|
||||||
second Second sub-command
|
|
||||||
|
|
||||||
Options:
|
|
||||||
|
|
||||||
--baz2 \(Required\)
|
|
||||||
|
|
||||||
--baz3 \(Required\)
|
|
||||||
|
|
||||||
--bar \(Flag\)
|
|
||||||
Test bool param.
|
|
||||||
|
|
||||||
--baz \(Default: "baz"\)
|
|
||||||
Test string param.
|
|
||||||
|
|
||||||
--foo \(Default: 5\)
|
|
||||||
Test int param.
|
|
||||||
|
|
||||||
$`)
|
$`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,10 +234,10 @@ func TestWithCLISubCommand(t *T) {
|
|||||||
bar *int
|
bar *int
|
||||||
baz *int
|
baz *int
|
||||||
aFlag *bool
|
aFlag *bool
|
||||||
defaultFlag *bool
|
bFlag *bool
|
||||||
)
|
)
|
||||||
reset := func() {
|
reset := func() {
|
||||||
foo, bar, baz, aFlag, defaultFlag = nil, nil, nil, nil, nil
|
foo, bar, baz, aFlag, bFlag = nil, nil, nil, nil, nil
|
||||||
ctx = context.Background()
|
ctx = context.Background()
|
||||||
ctx, foo = WithInt(ctx, "foo", 0, "Description of foo.")
|
ctx, foo = WithInt(ctx, "foo", 0, "Description of foo.")
|
||||||
ctx, aFlag = WithCLISubCommand(ctx, "a", "Description of a.",
|
ctx, aFlag = WithCLISubCommand(ctx, "a", "Description of a.",
|
||||||
@ -271,7 +245,7 @@ func TestWithCLISubCommand(t *T) {
|
|||||||
ctx, bar = WithInt(ctx, "bar", 0, "Description of bar.")
|
ctx, bar = WithInt(ctx, "bar", 0, "Description of bar.")
|
||||||
return ctx
|
return ctx
|
||||||
})
|
})
|
||||||
ctx, defaultFlag = WithCLISubCommand(ctx, "", "Description of default.",
|
ctx, bFlag = WithCLISubCommand(ctx, "b", "Description of b.",
|
||||||
func(ctx context.Context) context.Context {
|
func(ctx context.Context) context.Context {
|
||||||
ctx, baz = WithInt(ctx, "baz", 0, "Description of baz.")
|
ctx, baz = WithInt(ctx, "baz", 0, "Description of baz.")
|
||||||
return ctx
|
return ctx
|
||||||
@ -288,12 +262,12 @@ func TestWithCLISubCommand(t *T) {
|
|||||||
massert.Equal(2, *bar),
|
massert.Equal(2, *bar),
|
||||||
massert.Nil(baz),
|
massert.Nil(baz),
|
||||||
massert.Equal(true, *aFlag),
|
massert.Equal(true, *aFlag),
|
||||||
massert.Equal(false, *defaultFlag),
|
massert.Equal(false, *bFlag),
|
||||||
)
|
)
|
||||||
|
|
||||||
reset()
|
reset()
|
||||||
_, err = Populate(ctx, &SourceCLI{
|
_, err = Populate(ctx, &SourceCLI{
|
||||||
Args: []string{"--foo=1", "--baz=3"},
|
Args: []string{"b", "--foo=1", "--baz=3"},
|
||||||
})
|
})
|
||||||
massert.Require(t,
|
massert.Require(t,
|
||||||
massert.Comment(massert.Nil(err), "%v", err),
|
massert.Comment(massert.Nil(err), "%v", err),
|
||||||
@ -301,7 +275,7 @@ func TestWithCLISubCommand(t *T) {
|
|||||||
massert.Nil(bar),
|
massert.Nil(bar),
|
||||||
massert.Equal(3, *baz),
|
massert.Equal(3, *baz),
|
||||||
massert.Equal(false, *aFlag),
|
massert.Equal(false, *aFlag),
|
||||||
massert.Equal(true, *defaultFlag),
|
massert.Equal(true, *bFlag),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +291,7 @@ func ExampleWithCLISubCommand() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
var baz *int
|
var baz *int
|
||||||
ctx, defaultFlag := WithCLISubCommand(ctx, "", "Description of default.",
|
ctx, bFlag := WithCLISubCommand(ctx, "b", "Description of b.",
|
||||||
func(ctx context.Context) context.Context {
|
func(ctx context.Context) context.Context {
|
||||||
ctx, baz = WithInt(ctx, "baz", 0, "Description of baz.")
|
ctx, baz = WithInt(ctx, "baz", 0, "Description of baz.")
|
||||||
return ctx
|
return ctx
|
||||||
@ -327,16 +301,16 @@ func ExampleWithCLISubCommand() {
|
|||||||
if _, err := Populate(ctx, &SourceCLI{Args: args}); err != nil {
|
if _, err := Populate(ctx, &SourceCLI{Args: args}); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("foo:%d bar:%d aFlag:%v defaultFlag:%v\n", *foo, *bar, *aFlag, *defaultFlag)
|
fmt.Printf("foo:%d bar:%d aFlag:%v bFlag:%v\n", *foo, *bar, *aFlag, *bFlag)
|
||||||
|
|
||||||
// reset output for another Populate
|
// reset output for another Populate
|
||||||
*aFlag = false
|
*aFlag = false
|
||||||
args = []string{"--foo=1", "--baz=3"}
|
args = []string{"b", "--foo=1", "--baz=3"}
|
||||||
if _, err := Populate(ctx, &SourceCLI{Args: args}); err != nil {
|
if _, err := Populate(ctx, &SourceCLI{Args: args}); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("foo:%d baz:%d aFlag:%v defaultFlag:%v\n", *foo, *baz, *aFlag, *defaultFlag)
|
fmt.Printf("foo:%d baz:%d aFlag:%v bFlag:%v\n", *foo, *baz, *aFlag, *bFlag)
|
||||||
|
|
||||||
// Output: foo:1 bar:2 aFlag:true defaultFlag:false
|
// Output: foo:1 bar:2 aFlag:true bFlag:false
|
||||||
// foo:1 baz:3 aFlag:false defaultFlag:true
|
// foo:1 baz:3 aFlag:false bFlag:true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user