Resolve remaining test errors for v1 => v2 merge

This commit is contained in:
Dan Buch 2017-08-12 22:02:54 -04:00
parent ce3a0da1a3
commit 65b801c818
Signed by: meatballhat
GPG Key ID: 9685130D8B763EA7
7 changed files with 96 additions and 93 deletions

View File

@ -187,17 +187,20 @@ func ExampleApp_Run_noAction() {
app.Run([]string{"greet"}) app.Run([]string{"greet"})
// Output: // Output:
// NAME: // NAME:
// greet // greet - A new cli application
// //
// USAGE: // USAGE:
// [global options] command [command options] [arguments...] // greet [global options] command [command options] [arguments...]
//
// VERSION:
// 0.0.0
// //
// COMMANDS: // COMMANDS:
// help, h Shows a list of commands or help for one command // help, h Shows a list of commands or help for one command
// //
// GLOBAL OPTIONS: // GLOBAL OPTIONS:
// --help, -h show help // --help, -h show help (default: false)
// --version, -v print the version // --version, -v print the version (default: false)
} }
func ExampleApp_Run_subcommandNoAction() { func ExampleApp_Run_subcommandNoAction() {
@ -215,19 +218,22 @@ func ExampleApp_Run_subcommandNoAction() {
app.Run([]string{"greet", "describeit"}) app.Run([]string{"greet", "describeit"})
// Output: // Output:
// NAME: // NAME:
// describeit - use it to see a description // greet describeit - use it to see a description
// //
// USAGE: // USAGE:
// describeit [arguments...] // greet describeit [command options] [arguments...]
// //
// DESCRIPTION: // DESCRIPTION:
// This is how we describe describeit the function // This is how we describe describeit the function
//
// OPTIONS:
// --help, -h show help (default: false)
} }
func ExampleApp_Run_shellComplete() { func ExampleApp_Run_shellComplete() {
// set args for examples sake // set args for examples sake
os.Args = []string{"greet", "--generate-completion"} os.Args = []string{"greet", fmt.Sprintf("--%s", genCompName())}
app := &App{ app := &App{
Name: "greet", Name: "greet",
@ -311,30 +317,6 @@ func TestApp_Setup_defaultsWriter(t *testing.T) {
expect(t, app.Writer, os.Stdout) expect(t, app.Writer, os.Stdout)
} }
func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
var parsedOption, firstArg string
app := &App{
Commands: []*Command{
{
Name: "cmd",
Flags: []Flag{
&StringFlag{Name: "option", Value: "", Usage: "some option"},
},
Action: func(c *Context) error {
parsedOption = c.String("option")
firstArg = c.Args().First()
return nil
},
},
},
}
app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})
expect(t, parsedOption, "my-option")
expect(t, firstArg, "my-arg")
}
func TestApp_RunAsSubcommandParseFlags(t *testing.T) { func TestApp_RunAsSubcommandParseFlags(t *testing.T) {
var context *Context var context *Context
@ -907,6 +889,7 @@ func TestApp_OrderOfOperations(t *testing.T) {
app := &App{ app := &App{
EnableShellCompletion: true, EnableShellCompletion: true,
ShellComplete: func(c *Context) { ShellComplete: func(c *Context) {
fmt.Fprintf(os.Stderr, "---> ShellComplete(%#v)\n", c)
counts.Total++ counts.Total++
counts.ShellComplete = counts.Total counts.ShellComplete = counts.Total
}, },
@ -971,7 +954,7 @@ func TestApp_OrderOfOperations(t *testing.T) {
resetCounts() resetCounts()
_ = app.Run([]string{"command", "--generate-completion"}) _ = app.Run([]string{"command", fmt.Sprintf("--%s", genCompName())})
expect(t, counts.ShellComplete, 1) expect(t, counts.ShellComplete, 1)
expect(t, counts.Total, 1) expect(t, counts.Total, 1)

View File

@ -159,6 +159,10 @@ func (c *Command) Run(ctx *Context) (err error) {
} }
} }
if c.Action == nil {
c.Action = helpSubcommand.Action
}
context.Command = c context.Command = c
err = c.Action(context) err = c.Action(context)

View File

@ -121,7 +121,7 @@ func (c *Context) Lineage() []*Context {
return lineage return lineage
} }
// value returns the value of the flag coressponding to `name` // value returns the value of the flag corresponding to `name`
func (c *Context) value(name string) interface{} { func (c *Context) value(name string) interface{} {
return c.flagSet.Lookup(name).Value.(flag.Getter).Get() return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
} }

View File

@ -103,9 +103,8 @@ func HandleExitCoder(err error) {
} }
if multiErr, ok := err.(MultiError); ok { if multiErr, ok := err.(MultiError); ok {
for _, merr := range multiErr.Errors() { code := handleMultiError(multiErr)
HandleExitCoder(merr) OsExiter(code)
}
return return
} }
} }
@ -115,7 +114,7 @@ func handleMultiError(multiErr MultiError) int {
for _, merr := range multiErr.Errors() { for _, merr := range multiErr.Errors() {
if multiErr2, ok := merr.(MultiError); ok { if multiErr2, ok := merr.(MultiError); ok {
code = handleMultiError(multiErr2) code = handleMultiError(multiErr2)
} else { } else if merr != nil {
fmt.Fprintln(ErrWriter, merr) fmt.Fprintln(ErrWriter, merr)
if exitErr, ok := merr.(ExitCoder); ok { if exitErr, ok := merr.(ExitCoder); ok {
code = exitErr.ExitCode() code = exitErr.ExitCode()

34
flag.go
View File

@ -23,8 +23,9 @@ var (
// GenerateCompletionFlag enables completion for all commands and subcommands // GenerateCompletionFlag enables completion for all commands and subcommands
var GenerateCompletionFlag Flag = &BoolFlag{ var GenerateCompletionFlag Flag = &BoolFlag{
Name: "generate-completion", Name: "generate-completion",
Hidden: true, Aliases: []string{"compgen"},
Hidden: true,
} }
func genCompName() string { func genCompName() string {
@ -218,7 +219,7 @@ func (f *StringSliceFlag) ApplyWithError(set *flag.FlagSet) error {
for _, s := range strings.Split(envVal, ",") { for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
if err := newVal.Set(s); err != nil { if err := newVal.Set(s); err != nil {
return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as string value for flag %s: %s", envVal, f.Name, err)
} }
} }
f.Value = newVal f.Value = newVal
@ -322,7 +323,7 @@ func (f *IntSliceFlag) ApplyWithError(set *flag.FlagSet) error {
for _, s := range strings.Split(envVal, ",") { for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
if err := newVal.Set(s); err != nil { if err := newVal.Set(s); err != nil {
return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as int slice value for flag %s: %s", envVal, f.Name, err)
} }
} }
f.Value = newVal f.Value = newVal
@ -406,7 +407,7 @@ func (f *Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error {
for _, s := range strings.Split(envVal, ",") { for _, s := range strings.Split(envVal, ",") {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
if err := newVal.Set(s); err != nil { if err := newVal.Set(s); err != nil {
return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as int64 slice value for flag %s: %s", envVal, f.Name, err)
} }
} }
f.Value = newVal f.Value = newVal
@ -436,11 +437,16 @@ func (f *BoolFlag) ApplyWithError(set *flag.FlagSet) error {
if f.EnvVars != nil { if f.EnvVars != nil {
for _, envVar := range f.EnvVars { for _, envVar := range f.EnvVars {
if envVal, ok := syscall.Getenv(envVar); ok { if envVal, ok := syscall.Getenv(envVar); ok {
envValBool, err := strconv.ParseBool(envVal) if envVal == "" {
if err == nil { f.Value = false
f.Value = envValBool break
} }
envValBool, err := strconv.ParseBool(envVal)
if err != nil {
return fmt.Errorf("could not parse %q as bool value for flag %s: %s", envVal, f.Name, err)
}
f.Value = envValBool
break break
} }
} }
@ -496,7 +502,7 @@ func (f *IntFlag) ApplyWithError(set *flag.FlagSet) error {
if envVal, ok := syscall.Getenv(envVar); ok { if envVal, ok := syscall.Getenv(envVar); ok {
envValInt, err := strconv.ParseInt(envVal, 0, 64) envValInt, err := strconv.ParseInt(envVal, 0, 64)
if err != nil { if err != nil {
return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as int value for flag %s: %s", envVal, f.Name, err)
} }
f.Value = int(envValInt) f.Value = int(envValInt)
break break
@ -527,7 +533,7 @@ func (f *Int64Flag) ApplyWithError(set *flag.FlagSet) error {
if envVal, ok := syscall.Getenv(envVar); ok { if envVal, ok := syscall.Getenv(envVar); ok {
envValInt, err := strconv.ParseInt(envVal, 0, 64) envValInt, err := strconv.ParseInt(envVal, 0, 64)
if err != nil { if err != nil {
return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as int value for flag %s: %s", envVal, f.Name, err)
} }
f.Value = envValInt f.Value = envValInt
@ -559,7 +565,7 @@ func (f *UintFlag) ApplyWithError(set *flag.FlagSet) error {
if envVal, ok := syscall.Getenv(envVar); ok { if envVal, ok := syscall.Getenv(envVar); ok {
envValInt, err := strconv.ParseUint(envVal, 0, 64) envValInt, err := strconv.ParseUint(envVal, 0, 64)
if err != nil { if err != nil {
return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as uint value for flag %s: %s", envVal, f.Name, err)
} }
f.Value = uint(envValInt) f.Value = uint(envValInt)
@ -591,7 +597,7 @@ func (f *Uint64Flag) ApplyWithError(set *flag.FlagSet) error {
if envVal, ok := syscall.Getenv(envVar); ok { if envVal, ok := syscall.Getenv(envVar); ok {
envValInt, err := strconv.ParseUint(envVal, 0, 64) envValInt, err := strconv.ParseUint(envVal, 0, 64)
if err != nil { if err != nil {
return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as uint64 value for flag %s: %s", envVal, f.Name, err)
} }
f.Value = uint64(envValInt) f.Value = uint64(envValInt)
@ -623,7 +629,7 @@ func (f *DurationFlag) ApplyWithError(set *flag.FlagSet) error {
if envVal, ok := syscall.Getenv(envVar); ok { if envVal, ok := syscall.Getenv(envVar); ok {
envValDuration, err := time.ParseDuration(envVal) envValDuration, err := time.ParseDuration(envVal)
if err != nil { if err != nil {
return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as duration for flag %s: %s", envVal, f.Name, err)
} }
f.Value = envValDuration f.Value = envValDuration
@ -655,7 +661,7 @@ func (f *Float64Flag) ApplyWithError(set *flag.FlagSet) error {
if envVal, ok := syscall.Getenv(envVar); ok { if envVal, ok := syscall.Getenv(envVar); ok {
envValFloat, err := strconv.ParseFloat(envVal, 10) envValFloat, err := strconv.ParseFloat(envVal, 10)
if err != nil { if err != nil {
return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err) return fmt.Errorf("could not parse %q as float64 value for flag %s: %s", envVal, f.Name, err)
} }
f.Value = float64(envValFloat) f.Value = float64(envValFloat)

View File

@ -43,6 +43,24 @@ func TestBoolFlagApply_SetsAllNames(t *testing.T) {
} }
func TestFlagsFromEnv(t *testing.T) { func TestFlagsFromEnv(t *testing.T) {
newSetIntSlice := func(defaults ...int) IntSlice {
s := NewIntSlice(defaults...)
s.hasBeenSet = true
return *s
}
newSetInt64Slice := func(defaults ...int64) Int64Slice {
s := NewInt64Slice(defaults...)
s.hasBeenSet = true
return *s
}
newSetStringSlice := func(defaults ...string) StringSlice {
s := NewStringSlice(defaults...)
s.hasBeenSet = true
return *s
}
var flagTests = []struct { var flagTests = []struct {
input string input string
output interface{} output interface{}
@ -52,54 +70,55 @@ func TestFlagsFromEnv(t *testing.T) {
{"", false, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, ""}, {"", false, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, ""},
{"1", true, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, ""}, {"1", true, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, ""},
{"false", false, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, ""}, {"false", false, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, ""},
{"foobar", true, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, fmt.Sprintf(`could not parse foobar as bool value for flag debug: .*`)}, {"foobar", true, &BoolFlag{Name: "debug", EnvVars: []string{"DEBUG"}}, `could not parse "foobar" as bool value for flag debug: .*`},
{"1s", 1 * time.Second, &DurationFlag{Name: "time", EnvVars: []string{"TIME"}}, ""}, {"1s", 1 * time.Second, &DurationFlag{Name: "time", EnvVars: []string{"TIME"}}, ""},
{"foobar", false, &DurationFlag{Name: "time", EnvVars: []string{"TIME"}}, fmt.Sprintf(`could not parse foobar as duration for flag time: .*`)}, {"foobar", false, &DurationFlag{Name: "time", EnvVars: []string{"TIME"}}, `could not parse "foobar" as duration for flag time: .*`},
{"1.2", 1.2, &Float64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1.2", 1.2, &Float64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"1", 1.0, &Float64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1", 1.0, &Float64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"foobar", 0, &Float64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse foobar as float64 value for flag seconds: .*`)}, {"foobar", 0, &Float64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as float64 value for flag seconds: .*`},
{"1", int64(1), &Int64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1", int64(1), &Int64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"1.2", 0, &Int64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse 1.2 as int value for flag seconds: .*`)}, {"1.2", 0, &Int64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2" as int value for flag seconds: .*`},
{"foobar", 0, &Int64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse foobar as int value for flag seconds: .*`)}, {"foobar", 0, &Int64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as int value for flag seconds: .*`},
{"1", 1, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1", 1, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"1.2", 0, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse 1.2 as int value for flag seconds: .*`)}, {"1.2", 0, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2" as int value for flag seconds: .*`},
{"foobar", 0, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse foobar as int value for flag seconds: .*`)}, {"foobar", 0, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as int value for flag seconds: .*`},
{"1,2", NewIntSlice(1, 2), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1,2", newSetIntSlice(1, 2), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"1.2,2", NewIntSlice(), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse 1.2,2 as int slice value for flag seconds: .*`)}, {"1.2,2", newSetIntSlice(), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2,2" as int slice value for flag seconds: .*`},
{"foobar", NewIntSlice(), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse foobar as int slice value for flag seconds: .*`)}, {"foobar", newSetIntSlice(), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as int slice value for flag seconds: .*`},
{"1,2", NewInt64Slice(1, 2), &Int64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1,2", newSetInt64Slice(1, 2), &Int64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"1.2,2", NewInt64Slice(), &Int64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse 1.2,2 as int64 slice value for flag seconds: .*`)}, {"1.2,2", newSetInt64Slice(), &Int64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2,2" as int64 slice value for flag seconds: .*`},
{"foobar", NewInt64Slice(), &Int64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse foobar as int64 slice value for flag seconds: .*`)}, {"foobar", newSetInt64Slice(), &Int64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as int64 slice value for flag seconds: .*`},
{"foo", "foo", &StringFlag{Name: "name", EnvVars: []string{"NAME"}}, ""}, {"foo", "foo", &StringFlag{Name: "name", EnvVars: []string{"NAME"}}, ""},
{"foo,bar", NewStringSlice("foo", "bar"), &StringSliceFlag{Name: "names", EnvVars: []string{"NAMES"}}, ""}, {"foo,bar", newSetStringSlice("foo", "bar"), &StringSliceFlag{Name: "names", EnvVars: []string{"NAMES"}}, ""},
{"1", uint(1), &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1", uint(1), &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"1.2", 0, &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse 1.2 as uint value for flag seconds: .*`)}, {"1.2", 0, &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2" as uint value for flag seconds: .*`},
{"foobar", 0, &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse foobar as uint value for flag seconds: .*`)}, {"foobar", 0, &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as uint value for flag seconds: .*`},
{"1", uint64(1), &Uint64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""}, {"1", uint64(1), &Uint64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"1.2", 0, &Uint64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse 1.2 as uint64 value for flag seconds: .*`)}, {"1.2", 0, &Uint64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2" as uint64 value for flag seconds: .*`},
{"foobar", 0, &Uint64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, fmt.Sprintf(`could not parse foobar as uint64 value for flag seconds: .*`)}, {"foobar", 0, &Uint64Flag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as uint64 value for flag seconds: .*`},
{"foo,bar", &Parser{"foo", "bar"}, &GenericFlag{Name: "names", Value: &Parser{}, EnvVars: []string{"NAMES"}}, ""}, {"foo,bar", &Parser{"foo", "bar"}, &GenericFlag{Name: "names", Value: &Parser{}, EnvVars: []string{"NAMES"}}, ""},
} }
for _, test := range flagTests { for i, test := range flagTests {
clearenv() clearenv()
os.Setenv(reflect.ValueOf(test.flag).FieldByName("EnvVars").Slice(0, 1).String(), test.input) envVarSlice := reflect.Indirect(reflect.ValueOf(test.flag)).FieldByName("EnvVars").Slice(0, 1)
os.Setenv(envVarSlice.Index(0).String(), test.input)
a := App{ a := App{
Flags: []Flag{test.flag}, Flags: []Flag{test.flag},
Action: func(ctx *Context) error { Action: func(ctx *Context) error {
if !reflect.DeepEqual(ctx.value(test.flag.Names()[0]), test.output) { if !reflect.DeepEqual(ctx.value(test.flag.Names()[0]), test.output) {
t.Errorf("expected %+v to be parsed as %+v, instead was %+v", test.input, test.output, ctx.value(test.flag.Names()[0])) t.Errorf("ex:%01d expected %q to be parsed as %#v, instead was %#v", i, test.input, test.output, ctx.value(test.flag.Names()[0]))
} }
return nil return nil
}, },
@ -109,15 +128,15 @@ func TestFlagsFromEnv(t *testing.T) {
if test.errRegexp != "" { if test.errRegexp != "" {
if err == nil { if err == nil {
t.Errorf("expected error to match %s, got none", test.errRegexp) t.Errorf("expected error to match %q, got none", test.errRegexp)
} else { } else {
if matched, _ := regexp.MatchString(test.errRegexp, err.Error()); !matched { if matched, _ := regexp.MatchString(test.errRegexp, err.Error()); !matched {
t.Errorf("expected error to match %s, got error %s", test.errRegexp, err) t.Errorf("expected error to match %q, got error %s", test.errRegexp, err)
} }
} }
} else { } else {
if err != nil && test.errRegexp == "" { if err != nil && test.errRegexp == "" {
t.Errorf("expected no error got %s", err) t.Errorf("expected no error got %q", err)
} }
} }
} }

28
help.go
View File

@ -318,29 +318,21 @@ func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
} }
func checkCompletions(c *Context) bool { func checkCompletions(c *Context) bool {
if !c.Bool(genCompName()) && !c.App.EnableShellCompletion { if c.shellComplete {
return false ShowCompletions(c)
return true
} }
if args := c.Args(); args.Present() { return false
name := args.First()
if cmd := c.App.Command(name); cmd != nil {
// let the command handle the completion
return false
}
}
ShowCompletions(c)
return true
} }
func checkCommandCompletions(c *Context, name string) bool { func checkCommandCompletions(c *Context, name string) bool {
if !c.Bool(genCompName()) && !c.App.EnableShellCompletion { if c.shellComplete {
return false ShowCommandCompletions(c, name)
return true
} }
ShowCommandCompletions(c, name) return false
return true
} }
func checkInitCompletion(c *Context) (bool, error) { func checkInitCompletion(c *Context) (bool, error) {
@ -366,12 +358,12 @@ func bashCompletionCode(progName string) string {
local cur opts base; local cur opts base;
COMPREPLY=(); COMPREPLY=();
cur="${COMP_WORDS[COMP_CWORD]}"; cur="${COMP_WORDS[COMP_CWORD]}";
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-completion ); opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --%s );
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ); COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) );
return 0; return 0;
}; };
complete -F _cli_bash_autocomplete %s` complete -F _cli_bash_autocomplete %s`
return fmt.Sprintf(template, progName) return fmt.Sprintf(template, genCompName(), progName)
} }
func zshCompletionCode(progName string) string { func zshCompletionCode(progName string) string {