From 94822da119fb64b6659d48adc436c96535feb9a3 Mon Sep 17 00:00:00 2001 From: Brian Pursley Date: Wed, 11 Mar 2020 14:55:11 -0400 Subject: [PATCH] Allow command name to have an escaped space --- command.go | 26 ++++++++++++++++++++++---- command_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/command.go b/command.go index 55ddc50f..83eb3c57 100644 --- a/command.go +++ b/command.go @@ -1203,9 +1203,9 @@ func (c *Command) CommandPath() string { func (c *Command) UseLine() string { var useline string if c.HasParent() { - useline = c.parent.CommandPath() + " " + c.Use + useline = c.parent.CommandPath() + " " + replaceEscapedSpaces(c.Use) } else { - useline = c.Use + useline = replaceEscapedSpaces(c.Use) } if c.DisableFlagsInUseLine { return useline @@ -1260,11 +1260,29 @@ func (c *Command) DebugFlags() { // Name returns the command's name: the first word in the use line. func (c *Command) Name() string { name := c.Use - i := strings.Index(name, " ") + i := getIndexOfFirstNonEscapedSpace(name) if i >= 0 { name = name[:i] } - return name + return replaceEscapedSpaces(name) +} + +func getIndexOfFirstNonEscapedSpace(s string) int { + i := 0 + for i < len(s) { + switch s[i] { + case '\\': + i++ // The next character is escaped, so advance another position to skip over it + case ' ': + return i + } + i++ + } + return -1 +} + +func replaceEscapedSpaces(s string) string { + return strings.Replace(s, "\\ ", " ", -1) } // HasAlias determines if a given string is an alias of the command. diff --git a/command_test.go b/command_test.go index 12155937..44cc233a 100644 --- a/command_test.go +++ b/command_test.go @@ -1955,3 +1955,28 @@ func TestFParseErrWhitelistSiblingCommand(t *testing.T) { } checkStringContains(t, output, "unknown flag: --unknown") } + +func TestHelpDisplaysRootCommandNameWithEscapedSpace(t *testing.T) { + rootCmd := &Command{Use: "kubectl\\ myplugin", Run: emptyRun} + rootCmd.AddCommand(&Command{Use: "child", Run: emptyRun}) + + output, err := executeCommand(rootCmd, "help") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + checkStringContains(t, output, "kubectl myplugin [command]") +} + +func TestSubcommandHelpDisplaysRootCommandNameWithEscapedSpace(t *testing.T) { + rootCmd := &Command{Use: "kubectl\\ myplugin", Run: emptyRun} + childCmd := &Command{Use: "child", Long: "Long description", Run: emptyRun} + rootCmd.AddCommand(childCmd) + + output, err := executeCommand(rootCmd, "help", "child") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + checkStringContains(t, output, "kubectl myplugin child [flags]") +}