mirror of
https://github.com/spf13/cobra
synced 2024-11-24 14:47:12 +00:00
Ensure all completion maps are initialized before use
This commit is contained in:
parent
f1f260eb59
commit
53fb4ebbd1
2 changed files with 23 additions and 0 deletions
|
@ -534,6 +534,7 @@ func writeLocalNonPersistentFlag(buf io.StringWriter, flag *pflag.Flag) {
|
||||||
|
|
||||||
// prepareCustomAnnotationsForFlags setup annotations for go completions for registered flags
|
// prepareCustomAnnotationsForFlags setup annotations for go completions for registered flags
|
||||||
func prepareCustomAnnotationsForFlags(cmd *Command) {
|
func prepareCustomAnnotationsForFlags(cmd *Command) {
|
||||||
|
cmd.initializeCompletionStorage()
|
||||||
cmd.flagCompletionMutex.RLock()
|
cmd.flagCompletionMutex.RLock()
|
||||||
defer cmd.flagCompletionMutex.RUnlock()
|
defer cmd.flagCompletionMutex.RUnlock()
|
||||||
for flag := range cmd.flagCompletionFunctions {
|
for flag := range cmd.flagCompletionFunctions {
|
||||||
|
|
|
@ -18,8 +18,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -134,9 +136,13 @@ func (c *Command) RegisterFlagCompletionFunc(flagName string, f func(cmd *Comman
|
||||||
if flag == nil {
|
if flag == nil {
|
||||||
return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' does not exist", flagName)
|
return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' does not exist", flagName)
|
||||||
}
|
}
|
||||||
|
// Ensure none of our relevant fields are nil.
|
||||||
|
c.initializeCompletionStorage()
|
||||||
|
|
||||||
c.flagCompletionMutex.Lock()
|
c.flagCompletionMutex.Lock()
|
||||||
defer c.flagCompletionMutex.Unlock()
|
defer c.flagCompletionMutex.Unlock()
|
||||||
|
|
||||||
|
// And attempt to bind the completion.
|
||||||
if _, exists := c.flagCompletionFunctions[flag]; exists {
|
if _, exists := c.flagCompletionFunctions[flag]; exists {
|
||||||
return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' already registered", flagName)
|
return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' already registered", flagName)
|
||||||
}
|
}
|
||||||
|
@ -144,6 +150,20 @@ func (c *Command) RegisterFlagCompletionFunc(flagName string, f func(cmd *Comman
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initializeCompletionStorage is (and should be) called in all
|
||||||
|
// functions that make use of the command's flag completion functions.
|
||||||
|
func (c *Command) initializeCompletionStorage() {
|
||||||
|
if c.flagCompletionMutex == nil {
|
||||||
|
c.flagCompletionMutex = new(sync.RWMutex)
|
||||||
|
}
|
||||||
|
|
||||||
|
var completionFn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)
|
||||||
|
|
||||||
|
if c.flagCompletionFunctions == nil {
|
||||||
|
c.flagCompletionFunctions = make(map[*flag.Flag]completionFn, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a string listing the different directive enabled in the specified parameter
|
// Returns a string listing the different directive enabled in the specified parameter
|
||||||
func (d ShellCompDirective) string() string {
|
func (d ShellCompDirective) string() string {
|
||||||
var directives []string
|
var directives []string
|
||||||
|
@ -478,6 +498,8 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi
|
||||||
// Find the completion function for the flag or command
|
// Find the completion function for the flag or command
|
||||||
var completionFn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)
|
var completionFn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)
|
||||||
if flag != nil && flagCompletion {
|
if flag != nil && flagCompletion {
|
||||||
|
c.initializeCompletionStorage()
|
||||||
|
|
||||||
finalCmd.flagCompletionMutex.RLock()
|
finalCmd.flagCompletionMutex.RLock()
|
||||||
completionFn = finalCmd.flagCompletionFunctions[flag]
|
completionFn = finalCmd.flagCompletionFunctions[flag]
|
||||||
finalCmd.flagCompletionMutex.RUnlock()
|
finalCmd.flagCompletionMutex.RUnlock()
|
||||||
|
|
Loading…
Reference in a new issue