From 6644d46b81fa1831979c4cded0106e774e0ef0ab Mon Sep 17 00:00:00 2001 From: John McCabe Date: Wed, 28 Feb 2018 05:38:38 +0000 Subject: [PATCH] Prefix bash functions with root command name (#643) * 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 * 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 --- bash_completions.go | 4 ++-- bash_completions_test.go | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/bash_completions.go b/bash_completions.go index d898630..291eae7 100644 --- a/bash_completions.go +++ b/bash_completions.go @@ -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" } @@ -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" } diff --git a/bash_completions_test.go b/bash_completions_test.go index dd3a88e..02a4f15 100644 --- a/bash_completions_test.go +++ b/bash_completions_test.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "os/exec" + "regexp" "strings" "testing" ) @@ -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. @@ -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), @@ -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())