Skip to content

Commit

Permalink
fix shell autocomplete evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
Integralist committed Oct 14, 2021
1 parent 9e9f7e2 commit 6e11b63
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 6 deletions.
29 changes: 29 additions & 0 deletions pkg/app/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,35 @@ _fastly_bash_autocomplete() {
return 0
}
complete -F _fastly_bash_autocomplete fastly
`,
},
{
Name: "shell evaluate completion options",
Args: args("--completion-bash"),
WantOutput: `help
acl
acl-entry
auth-token
backend
compute
configure
dictionary
dictionaryitem
domain
healthcheck
ip-list
logging
logs
pops
purge
service
service-version
stats
update
user
vcl
version
whoami
`,
},
}
Expand Down
12 changes: 8 additions & 4 deletions pkg/app/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ func processCommandInput(
// error on things not already caught by ParseContext().
noargs := len(opts.Args) == 0
ctx, err := app.ParseContext(opts.Args)
if err != nil || noargs {
if err != nil && !cmd.IsCompletion(opts.Args) || noargs {
if noargs {
err = fmt.Errorf("command not specified")
}
Expand All @@ -359,7 +359,7 @@ func processCommandInput(
// completion flag, as that depends on kingpin.Parse() being called, and so
// the ctx is otherwise empty.
var found bool
if !cmd.IsHelpOnly(opts.Args) && !cmd.IsHelpFlagOnly(opts.Args) && !cmd.IsCompletion(opts.Args) {
if !cmd.IsHelpOnly(opts.Args) && !cmd.IsHelpFlagOnly(opts.Args) && !cmd.IsCompletion(opts.Args) && !cmd.IsCompletionScript(opts.Args) {
command, found = cmd.Select(ctx.SelectedCommand.FullCommand(), commands)
if !found {
return command, cmdName, help(vars, err)
Expand All @@ -385,7 +385,11 @@ func processCommandInput(
// command that we can safely append to the arguments and not have to worry
// about it getting removed accidentally in the future as we now have a test
// to validate the shell autocomplete behaviours.
if cmd.IsCompletion(opts.Args) {
//
// Lastly, we don't want to append our hidden shellcomplete command if the
// caller passes --completion-bash because adding a command to the arguments
// list would prevent the user's shell autocomplete logic to break.
if cmd.IsCompletionScript(opts.Args) {
opts.Args = append(opts.Args, "shellcomplete")
}

Expand All @@ -399,7 +403,7 @@ func processCommandInput(

// Kingpin generates shell completion as a side-effect of kingpin.Parse() so
// we allow it to call os.Exit, only if a completion flag is present.
if cmd.IsCompletion(opts.Args) {
if cmd.IsCompletion(opts.Args) || cmd.IsCompletionScript(opts.Args) {
app.Terminate(os.Exit)
return command, "shell-autocomplete", nil
}
Expand Down
18 changes: 16 additions & 2 deletions pkg/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import (
)

var (
completionRegExp = regexp.MustCompile("completion-(?:script-)?(?:bash|zsh)$")
completionRegExp = regexp.MustCompile("completion-bash$")
completionScriptRegExp = regexp.MustCompile("completion-script-(?:bash|zsh)$")
)

// RegisterServiceIDFlag defines a --service-id flag that will attempt to
Expand Down Expand Up @@ -195,8 +196,21 @@ func ContextHasHelpFlag(ctx *kingpin.ParseContext) bool {
return ok
}

// IsCompletionScript determines whether the supplied command arguments are for
// shell completion output that is then eval()'ed by the user's shell.
func IsCompletionScript(args []string) bool {
var found bool
for _, arg := range args {
if completionScriptRegExp.MatchString(arg) {
found = true
}
}
return found
}

// IsCompletion determines whether the supplied command arguments are for
// bash/zsh completion output.
// shell completion (i.e. --completion-bash) that should produce output that
// the user's shell can utilise for handling autocomplete behaviour.
func IsCompletion(args []string) bool {
var found bool
for _, arg := range args {
Expand Down

0 comments on commit 6e11b63

Please sign in to comment.