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 {
|
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)
|
p, err := NewParser(Config{}, dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
var parts []string
|
var parts []string
|
||||||
if len(cmdline) > 0 {
|
if len(cmdline) > 0 {
|
||||||
parts = strings.Split(cmdline, " ")
|
parts = strings.Split(cmdline, " ")
|
||||||
}
|
}
|
||||||
return p.Parse(parts)
|
return p, p.Parse(parts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestString(t *testing.T) {
|
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 {
|
var args struct {
|
||||||
List *listCmd `arg:"subcommand"`
|
List *listCmd `arg:"subcommand"`
|
||||||
}
|
}
|
||||||
err := parse("list", &args)
|
p, err := pparse("list", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, args.List)
|
assert.NotNil(t, args.List)
|
||||||
|
assert.Equal(t, args.List, p.Subcommand())
|
||||||
|
assert.Equal(t, []string{"list"}, p.SubcommandNames())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNoSuchSubcommand(t *testing.T) {
|
func TestNoSuchSubcommand(t *testing.T) {
|
||||||
|
@ -52,7 +54,7 @@ func TestNoSuchSubcommand(t *testing.T) {
|
||||||
var args struct {
|
var args struct {
|
||||||
List *listCmd `arg:"subcommand"`
|
List *listCmd `arg:"subcommand"`
|
||||||
}
|
}
|
||||||
err := parse("invalid", &args)
|
_, err := pparse("invalid", &args)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +64,11 @@ func TestNamedSubcommand(t *testing.T) {
|
||||||
var args struct {
|
var args struct {
|
||||||
List *listCmd `arg:"subcommand:ls"`
|
List *listCmd `arg:"subcommand:ls"`
|
||||||
}
|
}
|
||||||
err := parse("ls", &args)
|
p, err := pparse("ls", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, args.List)
|
assert.NotNil(t, args.List)
|
||||||
|
assert.Equal(t, args.List, p.Subcommand())
|
||||||
|
assert.Equal(t, []string{"ls"}, p.SubcommandNames())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptySubcommand(t *testing.T) {
|
func TestEmptySubcommand(t *testing.T) {
|
||||||
|
@ -73,9 +77,11 @@ func TestEmptySubcommand(t *testing.T) {
|
||||||
var args struct {
|
var args struct {
|
||||||
List *listCmd `arg:"subcommand"`
|
List *listCmd `arg:"subcommand"`
|
||||||
}
|
}
|
||||||
err := parse("", &args)
|
p, err := pparse("", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Nil(t, args.List)
|
assert.Nil(t, args.List)
|
||||||
|
assert.Nil(t, p.Subcommand())
|
||||||
|
assert.Empty(t, p.SubcommandNames())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTwoSubcommands(t *testing.T) {
|
func TestTwoSubcommands(t *testing.T) {
|
||||||
|
@ -87,10 +93,12 @@ func TestTwoSubcommands(t *testing.T) {
|
||||||
Get *getCmd `arg:"subcommand"`
|
Get *getCmd `arg:"subcommand"`
|
||||||
List *listCmd `arg:"subcommand"`
|
List *listCmd `arg:"subcommand"`
|
||||||
}
|
}
|
||||||
err := parse("list", &args)
|
p, err := pparse("list", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Nil(t, args.Get)
|
assert.Nil(t, args.Get)
|
||||||
assert.NotNil(t, args.List)
|
assert.NotNil(t, args.List)
|
||||||
|
assert.Equal(t, args.List, p.Subcommand())
|
||||||
|
assert.Equal(t, []string{"list"}, p.SubcommandNames())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSubcommandsWithOptions(t *testing.T) {
|
func TestSubcommandsWithOptions(t *testing.T) {
|
||||||
|
@ -185,35 +193,43 @@ func TestNestedSubcommands(t *testing.T) {
|
||||||
|
|
||||||
{
|
{
|
||||||
var args root
|
var args root
|
||||||
err := parse("grandparent parent child", &args)
|
p, err := pparse("grandparent parent child", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, args.Grandparent)
|
require.NotNil(t, args.Grandparent)
|
||||||
require.NotNil(t, args.Grandparent.Parent)
|
require.NotNil(t, args.Grandparent.Parent)
|
||||||
require.NotNil(t, args.Grandparent.Parent.Child)
|
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
|
var args root
|
||||||
err := parse("grandparent parent", &args)
|
p, err := pparse("grandparent parent", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, args.Grandparent)
|
require.NotNil(t, args.Grandparent)
|
||||||
require.NotNil(t, args.Grandparent.Parent)
|
require.NotNil(t, args.Grandparent.Parent)
|
||||||
require.Nil(t, args.Grandparent.Parent.Child)
|
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
|
var args root
|
||||||
err := parse("grandparent", &args)
|
p, err := pparse("grandparent", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, args.Grandparent)
|
require.NotNil(t, args.Grandparent)
|
||||||
require.Nil(t, args.Grandparent.Parent)
|
require.Nil(t, args.Grandparent.Parent)
|
||||||
|
assert.Equal(t, args.Grandparent, p.Subcommand())
|
||||||
|
assert.Equal(t, []string{"grandparent"}, p.SubcommandNames())
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var args root
|
var args root
|
||||||
err := parse("", &args)
|
p, err := pparse("", &args)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, args.Grandparent)
|
require.Nil(t, args.Grandparent)
|
||||||
|
assert.Nil(t, p.Subcommand())
|
||||||
|
assert.Empty(t, p.SubcommandNames())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue