Revert the custom cobra vendor

Vendor in the latest cobra release v1.1.1

This will hurt the completion experience but is required for
proper packaging, see: #8528.

The best solution is to keep the current scripts since they
work fine with cobra v1.1.1.

Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
This commit is contained in:
Paul Holzinger
2020-12-01 12:32:27 +01:00
parent ca612a3407
commit 3d4a0e42b3
9 changed files with 640 additions and 449 deletions

View File

@@ -51,11 +51,6 @@ const (
// obtain the same behavior but only for flags.
ShellCompDirectiveFilterDirs
// For internal use only.
// Used to maintain backwards-compatibility with the legacy bash custom completions.
shellCompDirectiveLegacyCustomComp
shellCompDirectiveLegacyCustomArgsComp
// ===========================================================================
// All directives using iota should be above this one.
@@ -99,12 +94,6 @@ func (d ShellCompDirective) string() string {
if d&ShellCompDirectiveFilterDirs != 0 {
directives = append(directives, "ShellCompDirectiveFilterDirs")
}
if d&shellCompDirectiveLegacyCustomComp != 0 {
directives = append(directives, "shellCompDirectiveLegacyCustomComp")
}
if d&shellCompDirectiveLegacyCustomArgsComp != 0 {
directives = append(directives, "shellCompDirectiveLegacyCustomArgsComp")
}
if len(directives) == 0 {
directives = append(directives, "ShellCompDirectiveDefault")
}
@@ -160,6 +149,10 @@ func (c *Command) initCompleteCmd(args []string) {
fmt.Fprintln(finalCmd.OutOrStdout(), comp)
}
if directive >= shellCompDirectiveMaxValue {
directive = ShellCompDirectiveDefault
}
// As the last printout, print the completion directive for the completion script to parse.
// The directive integer must be that last character following a single colon (:).
// The completion script expects :<directive>
@@ -369,10 +362,6 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi
var comps []string
comps, directive = completionFn(finalCmd, finalArgs, toComplete)
completions = append(completions, comps...)
} else {
// If there is no Go custom completion defined, check for legacy bash
// custom completion to preserve backwards-compatibility
completions, directive = checkLegacyCustomCompletion(finalCmd, finalArgs, flag, completions, directive)
}
return finalCmd, completions, directive, nil
@@ -453,16 +442,7 @@ func checkIfFlagCompletion(finalCmd *Command, args []string, lastArg string) (*p
if len(lastArg) > 0 && lastArg[0] == '-' {
if index := strings.Index(lastArg, "="); index >= 0 {
// Flag with an =
if strings.HasPrefix(lastArg[:index], "--") {
// Flag has full name
flagName = lastArg[2:index]
} else {
// Flag is shorthand
// We have to get the last shorthand flag name
// e.g. `-asd` => d to provide the correct completion
// https://github.com/spf13/cobra/issues/1257
flagName = lastArg[index-1 : index]
}
flagName = strings.TrimLeft(lastArg[:index], "-")
lastArg = lastArg[index+1:]
flagWithEqual = true
} else {
@@ -479,16 +459,8 @@ func checkIfFlagCompletion(finalCmd *Command, args []string, lastArg string) (*p
// If the flag contains an = it means it has already been fully processed,
// so we don't need to deal with it here.
if index := strings.Index(prevArg, "="); index < 0 {
if strings.HasPrefix(prevArg, "--") {
// Flag has full name
flagName = prevArg[2:]
} else {
// Flag is shorthand
// We have to get the last shorthand flag name
// e.g. `-asd` => d to provide the correct completion
// https://github.com/spf13/cobra/issues/1257
flagName = prevArg[len(prevArg)-1:]
}
flagName = strings.TrimLeft(prevArg, "-")
// Remove the uncompleted flag or else there could be an error created
// for an invalid value for that flag
trimmedArgs = args[:len(args)-1]
@@ -541,65 +513,6 @@ func findFlag(cmd *Command, name string) *pflag.Flag {
return cmd.Flag(name)
}
func nonCompletableFlag(flag *pflag.Flag) bool {
return flag.Hidden || len(flag.Deprecated) > 0
}
// This function checks if legacy bash custom completion should be performed and if so,
// it provides the shell script with the necessary information.
func checkLegacyCustomCompletion(cmd *Command, args []string, flag *pflag.Flag, completions []string, directive ShellCompDirective) ([]string, ShellCompDirective) {
// Check if any legacy custom completion is defined for the program
if len(cmd.Root().BashCompletionFunction) > 0 {
// Legacy custom completion is only triggered if no other completions were found.
if len(completions) == 0 {
if flag != nil {
// For legacy custom flag completion, we must let the script know the bash
// functions it should call based on the content of the annotation BashCompCustom.
if values, present := flag.Annotations[BashCompCustom]; present {
if len(values) > 0 {
handlers := strings.Join(values, "; ")
// We send the commands to set the shell variables that are needed
// for legacy custom completions followed by the functions to call
// to perform the actual flag completion
completions = append(prepareLegacyCustomCompletionVars(cmd, args), handlers)
directive = directive | shellCompDirectiveLegacyCustomComp
}
}
} else {
// Check if the legacy custom_func is defined.
// This check will work for both "__custom_func" and "__<program>_custom_func".
// This could happen if the program defined some functions for legacy flag completion
// but not the legacy custom_func.
if strings.Contains(cmd.Root().BashCompletionFunction, "_custom_func") {
// For legacy args completion, the script already knows what to call
// so we only need to tell it the commands to set the shell variables needed
completions = prepareLegacyCustomCompletionVars(cmd, args)
directive = directive | shellCompDirectiveLegacyCustomComp | shellCompDirectiveLegacyCustomArgsComp
}
}
}
}
return completions, directive
}
// The original bash completion script had some shell variables that are used by legacy bash
// custom completions. Let's set those variables to allow those legacy custom completions
// to continue working.
func prepareLegacyCustomCompletionVars(cmd *Command, args []string) []string {
var compVarCmds []string
// "last_command" variable
commandName := cmd.CommandPath()
commandName = strings.Replace(commandName, " ", "_", -1)
commandName = strings.Replace(commandName, ":", "__", -1)
compVarCmds = append(compVarCmds, fmt.Sprintf("last_command=%s", commandName))
// "nouns" array variable
compVarCmds = append(compVarCmds, fmt.Sprintf("nouns=(%s)", strings.Join(args, " ")))
return compVarCmds
}
// CompDebug prints the specified string to the same file as where the
// completion script prints its logs.
// Note that completion printouts should never be on stdout as they would