-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
325 additions
and
152 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package subcmd | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
) | ||
|
||
// ArgsStr are string positional arguments. If it is created with cap > 0, it will be used to define | ||
// the number of required arguments. | ||
// | ||
// Usage | ||
// | ||
// To get a list of arbitrary number of arguments: | ||
// | ||
// root := subcmd.Root() | ||
// | ||
// var subcmd.ArgsStr args | ||
// root.ArgsVar(&args, "[arg...]", "list of arguments") | ||
// | ||
// To get a list of specific number of arguments: | ||
// | ||
// root := subcmd.Root() | ||
// | ||
// args := make(subcmd.ArgsStr, 3) | ||
// root.ArgsVar(&args, "[arg1] [arg2] [arg3]", "list of 3 arguments") | ||
type ArgsStr []string | ||
|
||
func (a *ArgsStr) Set(args []string) error { | ||
if cap(*a) > 0 && len(args) != cap(*a) { | ||
return fmt.Errorf("required %d positional args, got %v", cap(*a), args) | ||
} | ||
*a = args | ||
return nil | ||
} | ||
|
||
// ArgsInt are int positional arguments. If it is created with cap > 0, it will be used to define | ||
// the number of required arguments. | ||
// | ||
// Usage | ||
// | ||
// To get a list of arbitrary number of integers: | ||
// | ||
// root := subcmd.Root() | ||
// | ||
// var subcmd.ArgsInt args | ||
// root.ArgsVar(&args, "[int...]", "list of integer args") | ||
// | ||
// To get a list of specific number of integers: | ||
// | ||
// root := subcmd.Root() | ||
// | ||
// args := make(subcmd.ArgsInt, 3) | ||
// root.ArgsVar(&args, "[int1] [int2] [int3]", "list of 3 integers") | ||
type ArgsInt []int | ||
|
||
func (a *ArgsInt) Set(args []string) error { | ||
if cap(*a) > 0 && len(args) != cap(*a) { | ||
return fmt.Errorf("required %d positional args, got %v", cap(*a), args) | ||
} | ||
*a = (*a)[:0] // Reset length to 0. | ||
for i, arg := range args { | ||
v, err := strconv.Atoi(arg) | ||
if err != nil { | ||
return fmt.Errorf("invalid int positional argument at position %d with value %v", i, arg) | ||
} | ||
*a = append(*a, v) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package subcmd | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestArgs(t *testing.T) { | ||
t.Parallel() | ||
|
||
t.Run("no cap", func(t *testing.T) { | ||
var args ArgsStr | ||
err := args.Set([]string{"a", "b"}) | ||
require.NoError(t, err) | ||
assert.Equal(t, []string{"a", "b"}, []string(args)) | ||
}) | ||
|
||
t.Run("with cap", func(t *testing.T) { | ||
var args = make(ArgsStr, 2) | ||
err := args.Set([]string{"a", "b"}) | ||
require.NoError(t, err) | ||
assert.Equal(t, []string{"a", "b"}, []string(args)) | ||
}) | ||
|
||
t.Run("too many args", func(t *testing.T) { | ||
var args = make(ArgsStr, 2) | ||
err := args.Set([]string{"a", "b", "c"}) | ||
require.Error(t, err) | ||
}) | ||
|
||
t.Run("not enough args", func(t *testing.T) { | ||
var args = make(ArgsStr, 2) | ||
err := args.Set([]string{"a"}) | ||
require.Error(t, err) | ||
}) | ||
} | ||
|
||
func TestArgsInt(t *testing.T) { | ||
t.Parallel() | ||
|
||
t.Run("no cap", func(t *testing.T) { | ||
var args ArgsInt | ||
err := args.Set([]string{"1", "2"}) | ||
require.NoError(t, err) | ||
assert.Equal(t, []int{1, 2}, []int(args)) | ||
}) | ||
|
||
t.Run("with cap", func(t *testing.T) { | ||
var args = make(ArgsInt, 2) | ||
err := args.Set([]string{"1", "2"}) | ||
require.NoError(t, err) | ||
assert.Equal(t, []int{1, 2}, []int(args)) | ||
}) | ||
|
||
t.Run("bad value", func(t *testing.T) { | ||
var args ArgsInt | ||
err := args.Set([]string{"a"}) | ||
require.Error(t, err) | ||
}) | ||
|
||
t.Run("too many args", func(t *testing.T) { | ||
var args = make(ArgsInt, 2) | ||
err := args.Set([]string{"1", "2", "3"}) | ||
require.Error(t, err) | ||
}) | ||
|
||
t.Run("not enough args", func(t *testing.T) { | ||
var args = make(ArgsInt, 2) | ||
err := args.Set([]string{"1"}) | ||
require.Error(t, err) | ||
}) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package subcmd_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/posener/subcmd" | ||
) | ||
|
||
var ( | ||
// Define a root command. Some options can be set using the `Opt*` functions. It returns a | ||
// `*Cmd` object. | ||
root = subcmd.Root() | ||
// The `*Cmd` object can be used as the standard library `flag.FlagSet`. | ||
flag0 = root.String("flag0", "", "root stringflag") | ||
// From each command object, a sub command can be created. This can be done recursively. | ||
sub1 = root.SubCommand("sub1", "first sub command") | ||
// Each sub command can have flags attached. | ||
flag1 = sub1.String("flag1", "", "sub1 string flag") | ||
sub2 = root.SubCommand("sub2", "second sub command") | ||
flag2 = sub1.Int("flag2", 0, "sub2 int flag") | ||
) | ||
|
||
// Definition and usage of sub commands and sub commands flags. | ||
func Example() { | ||
// In the example we use `Parse()` for a given list of command line arguments. This is useful | ||
// for testing, but should be replaced with `root.ParseArgs()` in `main()` | ||
root.Parse([]string{"cmd", "sub1", "-flag1", "value"}) | ||
|
||
// Usually the program should switch over the sub commands. The chosen sub command will return | ||
// true for the `Parsed()` method. | ||
switch { | ||
case sub1.Parsed(): | ||
fmt.Printf("Called sub1 with flag: %s", *flag1) | ||
case sub2.Parsed(): | ||
fmt.Printf("Called sub2 with flag: %d", *flag2) | ||
} | ||
// Output: Called sub1 with flag: value | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
{ | ||
"recursive": false, | ||
"badges": { | ||
"travis_ci": true, | ||
"code_cov": true, | ||
|
Oops, something went wrong.