add Parser.Subcommand and Parser.SubcommandNames
This commit is contained in:
parent
3c5e61a292
commit
bd97edec87
|
@ -19,15 +19,20 @@ func setenv(t *testing.T, name, val string) {
|
|||
}
|
||||
|
||||
func parse(cmdline string, dest interface{}) error {
|
||||
_, err := pparse(cmdline, dest)
|
||||
return err
|
||||
}
|
||||
|
||||
func pparse(cmdline string, dest interface{}) (*Parser, error) {
|
||||
p, err := NewParser(Config{}, dest)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
var parts []string
|
||||
if len(cmdline) > 0 {
|
||||
parts = strings.Split(cmdline, " ")
|
||||
}
|
||||
return p.Parse(parts)
|
||||
return p, p.Parse(parts)
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package arg
|
||||
|
||||
// Subcommand returns the user struct for the subcommand selected by
|
||||
// the command line arguments most recently processed by the parser.
|
||||
// The return value is always a pointer to a struct. If no subcommand
|
||||
// was specified then it returns the top-level arguments struct. If
|
||||
// no command line arguments have been processed by this parser then it
|
||||
// returns nil.
|
||||
func (p *Parser) Subcommand() interface{} {
|
||||
if p.lastCmd == nil || p.lastCmd.parent == nil {
|
||||
return nil
|
||||
}
|
||||
return p.readable(p.lastCmd.dest).Interface()
|
||||
}
|
||||
|
||||
// SubcommandNames returns the sequence of subcommands specified by the
|
||||
// user. If no subcommands were given then it returns an empty slice.
|
||||
func (p *Parser) SubcommandNames() []string {
|
||||
if p.lastCmd == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// make a list of ancestor commands
|
||||
var ancestors []string
|
||||
cur := p.lastCmd
|
||||
for cur.parent != nil { // we want to exclude the root
|
||||
ancestors = append(ancestors, cur.name)
|
||||
cur = cur.parent
|
||||
}
|
||||
|
||||
// reverse the list
|
||||
out := make([]string, len(ancestors))
|
||||
for i := 0; i < len(ancestors); i++ {
|
||||
out[i] = ancestors[len(ancestors)-i-1]
|
||||
}
|
||||
return out
|
||||
}
|
|
@ -41,9 +41,11 @@ func TestMinimalSubcommand(t *testing.T) {
|
|||
var args struct {
|
||||
List *listCmd `arg:"subcommand"`
|
||||
}
|
||||
err := parse("list", &args)
|
||||
p, err := pparse("list", &args)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, args.List)
|
||||
assert.Equal(t, args.List, p.Subcommand())
|
||||
assert.Equal(t, []string{"list"}, p.SubcommandNames())
|
||||
}
|
||||
|
||||
func TestNoSuchSubcommand(t *testing.T) {
|
||||
|
@ -52,7 +54,7 @@ func TestNoSuchSubcommand(t *testing.T) {
|
|||
var args struct {
|
||||
List *listCmd `arg:"subcommand"`
|
||||
}
|
||||
err := parse("invalid", &args)
|
||||
_, err := pparse("invalid", &args)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
|
@ -62,9 +64,11 @@ func TestNamedSubcommand(t *testing.T) {
|
|||
var args struct {
|
||||
List *listCmd `arg:"subcommand:ls"`
|
||||
}
|
||||
err := parse("ls", &args)
|
||||
p, err := pparse("ls", &args)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, args.List)
|
||||
assert.Equal(t, args.List, p.Subcommand())
|
||||
assert.Equal(t, []string{"ls"}, p.SubcommandNames())
|
||||
}
|
||||
|
||||
func TestEmptySubcommand(t *testing.T) {
|
||||
|
@ -73,9 +77,11 @@ func TestEmptySubcommand(t *testing.T) {
|
|||
var args struct {
|
||||
List *listCmd `arg:"subcommand"`
|
||||
}
|
||||
err := parse("", &args)
|
||||
p, err := pparse("", &args)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, args.List)
|
||||
assert.Nil(t, p.Subcommand())
|
||||
assert.Empty(t, p.SubcommandNames())
|
||||
}
|
||||
|
||||
func TestTwoSubcommands(t *testing.T) {
|
||||
|
@ -87,10 +93,12 @@ func TestTwoSubcommands(t *testing.T) {
|
|||
Get *getCmd `arg:"subcommand"`
|
||||
List *listCmd `arg:"subcommand"`
|
||||
}
|
||||
err := parse("list", &args)
|
||||
p, err := pparse("list", &args)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, args.Get)
|
||||
assert.NotNil(t, args.List)
|
||||
assert.Equal(t, args.List, p.Subcommand())
|
||||
assert.Equal(t, []string{"list"}, p.SubcommandNames())
|
||||
}
|
||||
|
||||
func TestSubcommandsWithOptions(t *testing.T) {
|
||||
|
@ -185,35 +193,43 @@ func TestNestedSubcommands(t *testing.T) {
|
|||
|
||||
{
|
||||
var args root
|
||||
err := parse("grandparent parent child", &args)
|
||||
p, err := pparse("grandparent parent child", &args)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, args.Grandparent)
|
||||
require.NotNil(t, args.Grandparent.Parent)
|
||||
require.NotNil(t, args.Grandparent.Parent.Child)
|
||||
assert.Equal(t, args.Grandparent.Parent.Child, p.Subcommand())
|
||||
assert.Equal(t, []string{"grandparent", "parent", "child"}, p.SubcommandNames())
|
||||
}
|
||||
|
||||
{
|
||||
var args root
|
||||
err := parse("grandparent parent", &args)
|
||||
p, err := pparse("grandparent parent", &args)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, args.Grandparent)
|
||||
require.NotNil(t, args.Grandparent.Parent)
|
||||
require.Nil(t, args.Grandparent.Parent.Child)
|
||||
assert.Equal(t, args.Grandparent.Parent, p.Subcommand())
|
||||
assert.Equal(t, []string{"grandparent", "parent"}, p.SubcommandNames())
|
||||
}
|
||||
|
||||
{
|
||||
var args root
|
||||
err := parse("grandparent", &args)
|
||||
p, err := pparse("grandparent", &args)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, args.Grandparent)
|
||||
require.Nil(t, args.Grandparent.Parent)
|
||||
assert.Equal(t, args.Grandparent, p.Subcommand())
|
||||
assert.Equal(t, []string{"grandparent"}, p.SubcommandNames())
|
||||
}
|
||||
|
||||
{
|
||||
var args root
|
||||
err := parse("", &args)
|
||||
p, err := pparse("", &args)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, args.Grandparent)
|
||||
assert.Nil(t, p.Subcommand())
|
||||
assert.Empty(t, p.SubcommandNames())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue