Skip to content

Commit

Permalink
Prefix bash functions with root command name (#643)
Browse files Browse the repository at this point in the history
* Prefix bash functions with root command name

Prior to this commit the autocomplete bash functions were being prefixed
with the root command name, but references to those functions from
subcommands were having the subcommands prefixed instead - causing the
function lookups to fail and error out.

For example (as observed in kubernetes/kubernetes#60517):

kubectl create -f [Tab] failed with the following message: kubectl
create -f __create_handle_filename_extension_flag: command not found

in this case the function being invoked should be __kubectl_handle_filename_extension_flag

Signed-off-by: John McCabe <john@johnmccabe.net>

* Test filename extension and subdirs_in_dir for subcommands

This commit adds two regex based tests to ensure that the handle
filename extension and handle subdirs in dir functions are prefixed by
the root command when present in subcommands.

Previously they had been prefixed incorrectly with the subcommand name.

Signed-off-by: John McCabe <john@johnmccabe.net>
  • Loading branch information
johnmccabe authored and eparis committed Feb 28, 2018
1 parent a1e4933 commit 6644d46
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
4 changes: 2 additions & 2 deletions bash_completions.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s

var ext string
if len(value) > 0 {
ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Name()) + strings.Join(value, "|")
ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|")
} else {
ext = "_filedir"
}
Expand All @@ -335,7 +335,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s

var ext string
if len(value) == 1 {
ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Name()) + value[0]
ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0]
} else {
ext = "_filedir -d"
}
Expand Down
20 changes: 20 additions & 0 deletions bash_completions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"os/exec"
"regexp"
"strings"
"testing"
)
Expand All @@ -21,6 +22,16 @@ func check(t *testing.T, found, expected string) {
}
}

func checkRegex(t *testing.T, found, pattern string) {
matched, err := regexp.MatchString(pattern, found)
if err != nil {
t.Errorf("Error thrown performing MatchString: \n %s\n", err)
}
if !matched {
t.Errorf("Expecting to match: \n %q\nGot:\n %q\n", pattern, found)
}
}

func runShellCheck(s string) error {
excluded := []string{
"SC2034", // PREFIX appears unused. Verify it or export it.
Expand Down Expand Up @@ -86,6 +97,11 @@ func TestBashCompletions(t *testing.T) {
Run: emptyRun,
}

echoCmd.Flags().String("filename", "", "Enter a filename")
echoCmd.MarkFlagFilename("filename", "json", "yaml", "yml")
echoCmd.Flags().String("config", "", "config to use (located in /config/PROFILE/)")
echoCmd.Flags().SetAnnotation("config", BashCompSubdirsInDir, []string{"config"})

printCmd := &Command{
Use: "print [string to print]",
Args: MinimumNArgs(1),
Expand Down Expand Up @@ -148,10 +164,14 @@ func TestBashCompletions(t *testing.T) {
check(t, output, `must_have_one_noun+=("three")`)
// check for filename extension flags
check(t, output, fmt.Sprintf(`flags_completion+=("__%s_handle_filename_extension_flag json|yaml|yml")`, rootCmd.Name()))
// check for filename extension flags in a subcommand
checkRegex(t, output, fmt.Sprintf(`_root_echo\(\)\n{[^}]*flags_completion\+=\("__%s_handle_filename_extension_flag json\|yaml\|yml"\)`, rootCmd.Name()))
// check for custom flags
check(t, output, `flags_completion+=("__complete_custom")`)
// check for subdirs_in_dir flags
check(t, output, fmt.Sprintf(`flags_completion+=("__%s_handle_subdirs_in_dir_flag themes")`, rootCmd.Name()))
// check for subdirs_in_dir flags in a subcommand
checkRegex(t, output, fmt.Sprintf(`_root_echo\(\)\n{[^}]*flags_completion\+=\("__%s_handle_subdirs_in_dir_flag config"\)`, rootCmd.Name()))

checkOmit(t, output, deprecatedCmd.Name())

Expand Down

0 comments on commit 6644d46

Please sign in to comment.