update dependencies
This commit is contained in:
2
vendor/github.com/spf13/cobra/.gitignore
generated
vendored
2
vendor/github.com/spf13/cobra/.gitignore
generated
vendored
@@ -34,3 +34,5 @@ tags
|
||||
*.exe
|
||||
|
||||
cobra.test
|
||||
|
||||
.idea/*
|
||||
|
||||
23
vendor/github.com/spf13/cobra/.travis.yml
generated
vendored
23
vendor/github.com/spf13/cobra/.travis.yml
generated
vendored
@@ -1,18 +1,31 @@
|
||||
language: go
|
||||
|
||||
stages:
|
||||
- diff
|
||||
- test
|
||||
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.4
|
||||
- 1.6.2
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
include:
|
||||
- stage: diff
|
||||
go: 1.12.x
|
||||
script: diff -u <(echo -n) <(gofmt -d -s .)
|
||||
|
||||
before_install:
|
||||
- mkdir -p bin
|
||||
- curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.4.3/shellcheck
|
||||
- curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.6.0/shellcheck
|
||||
- chmod +x bin/shellcheck
|
||||
- go get -u github.com/kyoh86/richgo
|
||||
script:
|
||||
- PATH=$PATH:$PWD/bin go test -v ./...
|
||||
- PATH=$PATH:$PWD/bin richgo test -v ./...
|
||||
- go build
|
||||
- if [ -z $NOVET ]; then
|
||||
diff -u <(echo -n) <(go vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint');
|
||||
fi
|
||||
|
||||
901
vendor/github.com/spf13/cobra/README.md
generated
vendored
901
vendor/github.com/spf13/cobra/README.md
generated
vendored
File diff suppressed because it is too large
Load Diff
101
vendor/github.com/spf13/cobra/args.go
generated
vendored
Normal file
101
vendor/github.com/spf13/cobra/args.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
package cobra
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type PositionalArgs func(cmd *Command, args []string) error
|
||||
|
||||
// Legacy arg validation has the following behaviour:
|
||||
// - root commands with no subcommands can take arbitrary arguments
|
||||
// - root commands with subcommands will do subcommand validity checking
|
||||
// - subcommands will always accept arbitrary arguments
|
||||
func legacyArgs(cmd *Command, args []string) error {
|
||||
// no subcommand, always take args
|
||||
if !cmd.HasSubCommands() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// root command with subcommands, do subcommand checking.
|
||||
if !cmd.HasParent() && len(args) > 0 {
|
||||
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NoArgs returns an error if any args are included.
|
||||
func NoArgs(cmd *Command, args []string) error {
|
||||
if len(args) > 0 {
|
||||
return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
|
||||
func OnlyValidArgs(cmd *Command, args []string) error {
|
||||
if len(cmd.ValidArgs) > 0 {
|
||||
for _, v := range args {
|
||||
if !stringInSlice(v, cmd.ValidArgs) {
|
||||
return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ArbitraryArgs never returns an error.
|
||||
func ArbitraryArgs(cmd *Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MinimumNArgs returns an error if there is not at least N args.
|
||||
func MinimumNArgs(n int) PositionalArgs {
|
||||
return func(cmd *Command, args []string) error {
|
||||
if len(args) < n {
|
||||
return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// MaximumNArgs returns an error if there are more than N args.
|
||||
func MaximumNArgs(n int) PositionalArgs {
|
||||
return func(cmd *Command, args []string) error {
|
||||
if len(args) > n {
|
||||
return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExactArgs returns an error if there are not exactly n args.
|
||||
func ExactArgs(n int) PositionalArgs {
|
||||
return func(cmd *Command, args []string) error {
|
||||
if len(args) != n {
|
||||
return fmt.Errorf("accepts %d arg(s), received %d", n, len(args))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExactValidArgs returns an error if
|
||||
// there are not exactly N positional args OR
|
||||
// there are any positional args that are not in the `ValidArgs` field of `Command`
|
||||
func ExactValidArgs(n int) PositionalArgs {
|
||||
return func(cmd *Command, args []string) error {
|
||||
if err := ExactArgs(n)(cmd, args); err != nil {
|
||||
return err
|
||||
}
|
||||
return OnlyValidArgs(cmd, args)
|
||||
}
|
||||
}
|
||||
|
||||
// RangeArgs returns an error if the number of args is not within the expected range.
|
||||
func RangeArgs(min int, max int) PositionalArgs {
|
||||
return func(cmd *Command, args []string) error {
|
||||
if len(args) < min || len(args) > max {
|
||||
return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
479
vendor/github.com/spf13/cobra/bash_completions.go
generated
vendored
479
vendor/github.com/spf13/cobra/bash_completions.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package cobra
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@@ -10,20 +11,18 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// Annotations for Bash completion.
|
||||
const (
|
||||
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extentions"
|
||||
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extensions"
|
||||
BashCompCustom = "cobra_annotation_bash_completion_custom"
|
||||
BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
|
||||
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
|
||||
)
|
||||
|
||||
func preamble(out io.Writer, name string) error {
|
||||
_, err := fmt.Fprintf(out, "# bash completion for %-36s -*- shell-script -*-\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprint(out, `
|
||||
__debug()
|
||||
func writePreamble(buf *bytes.Buffer, name string) {
|
||||
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
|
||||
buf.WriteString(fmt.Sprintf(`
|
||||
__%[1]s_debug()
|
||||
{
|
||||
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
|
||||
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
|
||||
@@ -32,13 +31,13 @@ __debug()
|
||||
|
||||
# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
|
||||
# _init_completion. This is a very minimal version of that function.
|
||||
__my_init_completion()
|
||||
__%[1]s_init_completion()
|
||||
{
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref "$@" cur prev words cword
|
||||
}
|
||||
|
||||
__index_of_word()
|
||||
__%[1]s_index_of_word()
|
||||
{
|
||||
local w word=$1
|
||||
shift
|
||||
@@ -50,7 +49,7 @@ __index_of_word()
|
||||
index=-1
|
||||
}
|
||||
|
||||
__contains_word()
|
||||
__%[1]s_contains_word()
|
||||
{
|
||||
local w word=$1; shift
|
||||
for w in "$@"; do
|
||||
@@ -59,9 +58,9 @@ __contains_word()
|
||||
return 1
|
||||
}
|
||||
|
||||
__handle_reply()
|
||||
__%[1]s_handle_reply()
|
||||
{
|
||||
__debug "${FUNCNAME[0]}"
|
||||
__%[1]s_debug "${FUNCNAME[0]}"
|
||||
case $cur in
|
||||
-*)
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
@@ -86,14 +85,14 @@ __handle_reply()
|
||||
|
||||
local index flag
|
||||
flag="${cur%%=*}"
|
||||
__index_of_word "${flag}" "${flags_with_completion[@]}"
|
||||
__%[1]s_index_of_word "${flag}" "${flags_with_completion[@]}"
|
||||
COMPREPLY=()
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
COMPREPLY=()
|
||||
PREFIX=""
|
||||
cur="${cur#*=}"
|
||||
${flags_completion[${index}]}
|
||||
if [ -n "${ZSH_VERSION}" ]; then
|
||||
# zfs completion needs --flag= prefix
|
||||
# zsh completion needs --flag= prefix
|
||||
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
||||
fi
|
||||
fi
|
||||
@@ -104,7 +103,7 @@ __handle_reply()
|
||||
|
||||
# check if we are handling a flag with special work handling
|
||||
local index
|
||||
__index_of_word "${prev}" "${flags_with_completion[@]}"
|
||||
__%[1]s_index_of_word "${prev}" "${flags_with_completion[@]}"
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
${flags_completion[${index}]}
|
||||
return
|
||||
@@ -130,28 +129,43 @@ __handle_reply()
|
||||
fi
|
||||
|
||||
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
|
||||
declare -F __custom_func >/dev/null && __custom_func
|
||||
if declare -F __%[1]s_custom_func >/dev/null; then
|
||||
# try command name qualified custom func
|
||||
__%[1]s_custom_func
|
||||
else
|
||||
# otherwise fall back to unqualified for compatibility
|
||||
declare -F __custom_func >/dev/null && __custom_func
|
||||
fi
|
||||
fi
|
||||
|
||||
__ltrim_colon_completions "$cur"
|
||||
# available in bash-completion >= 2, not always present on macOS
|
||||
if declare -F __ltrim_colon_completions >/dev/null; then
|
||||
__ltrim_colon_completions "$cur"
|
||||
fi
|
||||
|
||||
# If there is only 1 completion and it is a flag with an = it will be completed
|
||||
# but we don't want a space after the =
|
||||
if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
|
||||
compopt -o nospace
|
||||
fi
|
||||
}
|
||||
|
||||
# The arguments should be in the form "ext1|ext2|extn"
|
||||
__handle_filename_extension_flag()
|
||||
__%[1]s_handle_filename_extension_flag()
|
||||
{
|
||||
local ext="$1"
|
||||
_filedir "@(${ext})"
|
||||
}
|
||||
|
||||
__handle_subdirs_in_dir_flag()
|
||||
__%[1]s_handle_subdirs_in_dir_flag()
|
||||
{
|
||||
local dir="$1"
|
||||
pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
|
||||
}
|
||||
|
||||
__handle_flag()
|
||||
__%[1]s_handle_flag()
|
||||
{
|
||||
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
# if a command required a flag, and we found it, unset must_have_one_flag()
|
||||
local flagname=${words[c]}
|
||||
@@ -162,27 +176,31 @@ __handle_flag()
|
||||
flagname=${flagname%%=*} # strip everything after the =
|
||||
flagname="${flagname}=" # but put the = back
|
||||
fi
|
||||
__debug "${FUNCNAME[0]}: looking for ${flagname}"
|
||||
if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then
|
||||
__%[1]s_debug "${FUNCNAME[0]}: looking for ${flagname}"
|
||||
if __%[1]s_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
|
||||
must_have_one_flag=()
|
||||
fi
|
||||
|
||||
# if you set a flag which only applies to this command, don't show subcommands
|
||||
if __contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
|
||||
if __%[1]s_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
|
||||
commands=()
|
||||
fi
|
||||
|
||||
# keep flag value with flagname as flaghash
|
||||
if [ -n "${flagvalue}" ] ; then
|
||||
flaghash[${flagname}]=${flagvalue}
|
||||
elif [ -n "${words[ $((c+1)) ]}" ] ; then
|
||||
flaghash[${flagname}]=${words[ $((c+1)) ]}
|
||||
else
|
||||
flaghash[${flagname}]="true" # pad "true" for bool flag
|
||||
# flaghash variable is an associative array which is only supported in bash > 3.
|
||||
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
|
||||
if [ -n "${flagvalue}" ] ; then
|
||||
flaghash[${flagname}]=${flagvalue}
|
||||
elif [ -n "${words[ $((c+1)) ]}" ] ; then
|
||||
flaghash[${flagname}]=${words[ $((c+1)) ]}
|
||||
else
|
||||
flaghash[${flagname}]="true" # pad "true" for bool flag
|
||||
fi
|
||||
fi
|
||||
|
||||
# skip the argument to a two word flag
|
||||
if __contains_word "${words[c]}" "${two_word_flags[@]}"; then
|
||||
if [[ ${words[c]} != *"="* ]] && __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then
|
||||
__%[1]s_debug "${FUNCNAME[0]}: found a flag ${words[c]}, skip the next argument"
|
||||
c=$((c+1))
|
||||
# if we are looking for a flags value, don't show commands
|
||||
if [[ $c -eq $cword ]]; then
|
||||
@@ -194,13 +212,13 @@ __handle_flag()
|
||||
|
||||
}
|
||||
|
||||
__handle_noun()
|
||||
__%[1]s_handle_noun()
|
||||
{
|
||||
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
|
||||
if __%[1]s_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
|
||||
must_have_one_noun=()
|
||||
elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then
|
||||
elif __%[1]s_contains_word "${words[c]}" "${noun_aliases[@]}"; then
|
||||
must_have_one_noun=()
|
||||
fi
|
||||
|
||||
@@ -208,61 +226,66 @@ __handle_noun()
|
||||
c=$((c+1))
|
||||
}
|
||||
|
||||
__handle_command()
|
||||
__%[1]s_handle_command()
|
||||
{
|
||||
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
local next_command
|
||||
if [[ -n ${last_command} ]]; then
|
||||
next_command="_${last_command}_${words[c]//:/__}"
|
||||
else
|
||||
if [[ $c -eq 0 ]]; then
|
||||
next_command="_$(basename "${words[c]//:/__}")"
|
||||
next_command="_%[1]s_root_command"
|
||||
else
|
||||
next_command="_${words[c]//:/__}"
|
||||
fi
|
||||
fi
|
||||
c=$((c+1))
|
||||
__debug "${FUNCNAME[0]}: looking for ${next_command}"
|
||||
declare -F $next_command >/dev/null && $next_command
|
||||
__%[1]s_debug "${FUNCNAME[0]}: looking for ${next_command}"
|
||||
declare -F "$next_command" >/dev/null && $next_command
|
||||
}
|
||||
|
||||
__handle_word()
|
||||
__%[1]s_handle_word()
|
||||
{
|
||||
if [[ $c -ge $cword ]]; then
|
||||
__handle_reply
|
||||
__%[1]s_handle_reply
|
||||
return
|
||||
fi
|
||||
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
if [[ "${words[c]}" == -* ]]; then
|
||||
__handle_flag
|
||||
elif __contains_word "${words[c]}" "${commands[@]}"; then
|
||||
__handle_command
|
||||
elif [[ $c -eq 0 ]] && __contains_word "$(basename "${words[c]}")" "${commands[@]}"; then
|
||||
__handle_command
|
||||
__%[1]s_handle_flag
|
||||
elif __%[1]s_contains_word "${words[c]}" "${commands[@]}"; then
|
||||
__%[1]s_handle_command
|
||||
elif [[ $c -eq 0 ]]; then
|
||||
__%[1]s_handle_command
|
||||
elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then
|
||||
# aliashash variable is an associative array which is only supported in bash > 3.
|
||||
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
|
||||
words[c]=${aliashash[${words[c]}]}
|
||||
__%[1]s_handle_command
|
||||
else
|
||||
__%[1]s_handle_noun
|
||||
fi
|
||||
else
|
||||
__handle_noun
|
||||
__%[1]s_handle_noun
|
||||
fi
|
||||
__handle_word
|
||||
__%[1]s_handle_word
|
||||
}
|
||||
|
||||
`)
|
||||
return err
|
||||
`, name))
|
||||
}
|
||||
|
||||
func postscript(w io.Writer, name string) error {
|
||||
func writePostscript(buf *bytes.Buffer, name string) {
|
||||
name = strings.Replace(name, ":", "__", -1)
|
||||
_, err := fmt.Fprintf(w, "__start_%s()\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(w, `{
|
||||
buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
|
||||
buf.WriteString(fmt.Sprintf(`{
|
||||
local cur prev words cword
|
||||
declare -A flaghash 2>/dev/null || :
|
||||
declare -A aliashash 2>/dev/null || :
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
_init_completion -s || return
|
||||
else
|
||||
__my_init_completion -n "=" || return
|
||||
__%[1]s_init_completion -n "=" || return
|
||||
fi
|
||||
|
||||
local c=0
|
||||
@@ -271,360 +294,254 @@ func postscript(w io.Writer, name string) error {
|
||||
local local_nonpersistent_flags=()
|
||||
local flags_with_completion=()
|
||||
local flags_completion=()
|
||||
local commands=("%s")
|
||||
local commands=("%[1]s")
|
||||
local must_have_one_flag=()
|
||||
local must_have_one_noun=()
|
||||
local last_command
|
||||
local nouns=()
|
||||
|
||||
__handle_word
|
||||
__%[1]s_handle_word
|
||||
}
|
||||
|
||||
`, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(w, `if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
`, name))
|
||||
buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
complete -o default -F __start_%s %s
|
||||
else
|
||||
complete -o default -o nospace -F __start_%s %s
|
||||
fi
|
||||
|
||||
`, name, name, name, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(w, "# ex: ts=4 sw=4 et filetype=sh\n")
|
||||
return err
|
||||
`, name, name, name, name))
|
||||
buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
|
||||
}
|
||||
|
||||
func writeCommands(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " commands=()\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
func writeCommands(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" commands=()\n")
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
||||
continue
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, " commands+=(%q)\n", c.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
|
||||
writeCmdAliases(buf, c)
|
||||
}
|
||||
_, err := fmt.Fprintf(w, "\n")
|
||||
return err
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
|
||||
func writeFlagHandler(name string, annotations map[string][]string, w io.Writer) error {
|
||||
func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
|
||||
for key, value := range annotations {
|
||||
switch key {
|
||||
case BashCompFilenameExt:
|
||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
|
||||
var ext string
|
||||
if len(value) > 0 {
|
||||
ext := "__handle_filename_extension_flag " + strings.Join(value, "|")
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|")
|
||||
} else {
|
||||
ext := "_filedir"
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
ext = "_filedir"
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
case BashCompCustom:
|
||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
if len(value) > 0 {
|
||||
handlers := strings.Join(value, "; ")
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", handlers)
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(:)\n")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
buf.WriteString(" flags_completion+=(:)\n")
|
||||
}
|
||||
case BashCompSubdirsInDir:
|
||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
|
||||
var ext string
|
||||
if len(value) == 1 {
|
||||
ext := "__handle_subdirs_in_dir_flag " + value[0]
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0]
|
||||
} else {
|
||||
ext := "_filedir -d"
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
ext = "_filedir -d"
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeShortFlag(flag *pflag.Flag, w io.Writer) error {
|
||||
b := (len(flag.NoOptDefVal) > 0)
|
||||
func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
|
||||
name := flag.Shorthand
|
||||
format := " "
|
||||
if !b {
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "two_word_"
|
||||
}
|
||||
format += "flags+=(\"-%s\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeFlagHandler("-"+name, flag.Annotations, w)
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
|
||||
}
|
||||
|
||||
func writeFlag(flag *pflag.Flag, w io.Writer) error {
|
||||
b := (len(flag.NoOptDefVal) > 0)
|
||||
func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
|
||||
name := flag.Name
|
||||
format := " flags+=(\"--%s"
|
||||
if !b {
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
||||
return err
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format = " two_word_flags+=(\"--%s\")\n"
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
}
|
||||
return writeFlagHandler("--"+name, flag.Annotations, w)
|
||||
writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
|
||||
}
|
||||
|
||||
func writeLocalNonPersistentFlag(flag *pflag.Flag, w io.Writer) error {
|
||||
b := (len(flag.NoOptDefVal) > 0)
|
||||
func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||
name := flag.Name
|
||||
format := " local_nonpersistent_flags+=(\"--%s"
|
||||
if !b {
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
}
|
||||
|
||||
func writeFlags(cmd *Command, w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, ` flags=()
|
||||
func writeFlags(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(` flags=()
|
||||
two_word_flags=()
|
||||
local_nonpersistent_flags=()
|
||||
flags_with_completion=()
|
||||
flags_completion=()
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
localNonPersistentFlags := cmd.LocalNonPersistentFlags()
|
||||
var visitErr error
|
||||
cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
||||
if err := writeFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
writeFlag(buf, flag, cmd)
|
||||
if len(flag.Shorthand) > 0 {
|
||||
if err := writeShortFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
writeShortFlag(buf, flag, cmd)
|
||||
}
|
||||
if localNonPersistentFlags.Lookup(flag.Name) != nil {
|
||||
if err := writeLocalNonPersistentFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
writeLocalNonPersistentFlag(buf, flag)
|
||||
}
|
||||
})
|
||||
if visitErr != nil {
|
||||
return visitErr
|
||||
}
|
||||
cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
||||
if err := writeFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
writeFlag(buf, flag, cmd)
|
||||
if len(flag.Shorthand) > 0 {
|
||||
if err := writeShortFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
writeShortFlag(buf, flag, cmd)
|
||||
}
|
||||
})
|
||||
if visitErr != nil {
|
||||
return visitErr
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(w, "\n")
|
||||
return err
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
|
||||
func writeRequiredFlag(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_flag=()\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" must_have_one_flag=()\n")
|
||||
flags := cmd.NonInheritedFlags()
|
||||
var visitErr error
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
for key := range flag.Annotations {
|
||||
switch key {
|
||||
case BashCompOneRequiredFlag:
|
||||
format := " must_have_one_flag+=(\"--%s"
|
||||
b := (flag.Value.Type() == "bool")
|
||||
if !b {
|
||||
if flag.Value.Type() != "bool" {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, flag.Name); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(format, flag.Name))
|
||||
|
||||
if len(flag.Shorthand) > 0 {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_flag+=(\"-%s\")\n", flag.Shorthand); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return visitErr
|
||||
}
|
||||
|
||||
func writeRequiredNouns(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_noun=()\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" must_have_one_noun=()\n")
|
||||
sort.Sort(sort.StringSlice(cmd.ValidArgs))
|
||||
for _, value := range cmd.ValidArgs {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_noun+=(%q)\n", value); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeArgAliases(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " noun_aliases=()\n"); err != nil {
|
||||
return err
|
||||
func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
|
||||
if len(cmd.Aliases) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
sort.Sort(sort.StringSlice(cmd.Aliases))
|
||||
|
||||
buf.WriteString(fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
|
||||
for _, value := range cmd.Aliases {
|
||||
buf.WriteString(fmt.Sprintf(" command_aliases+=(%q)\n", value))
|
||||
buf.WriteString(fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name()))
|
||||
}
|
||||
buf.WriteString(` fi`)
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" noun_aliases=()\n")
|
||||
sort.Sort(sort.StringSlice(cmd.ArgAliases))
|
||||
for _, value := range cmd.ArgAliases {
|
||||
if _, err := fmt.Fprintf(w, " noun_aliases+=(%q)\n", value); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func gen(cmd *Command, w io.Writer) error {
|
||||
func gen(buf *bytes.Buffer, cmd *Command) {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
||||
continue
|
||||
}
|
||||
if err := gen(c, w); err != nil {
|
||||
return err
|
||||
}
|
||||
gen(buf, c)
|
||||
}
|
||||
commandName := cmd.CommandPath()
|
||||
commandName = strings.Replace(commandName, " ", "_", -1)
|
||||
commandName = strings.Replace(commandName, ":", "__", -1)
|
||||
if _, err := fmt.Fprintf(w, "_%s()\n{\n", commandName); err != nil {
|
||||
return err
|
||||
|
||||
if cmd.Root() == cmd {
|
||||
buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName))
|
||||
} else {
|
||||
buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, " last_command=%q\n", commandName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeCommands(cmd, w); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeFlags(cmd, w); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeRequiredFlag(cmd, w); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeRequiredNouns(cmd, w); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeArgAliases(cmd, w); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "}\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(" command_aliases=()\n")
|
||||
buf.WriteString("\n")
|
||||
|
||||
writeCommands(buf, cmd)
|
||||
writeFlags(buf, cmd)
|
||||
writeRequiredFlag(buf, cmd)
|
||||
writeRequiredNouns(buf, cmd)
|
||||
writeArgAliases(buf, cmd)
|
||||
buf.WriteString("}\n\n")
|
||||
}
|
||||
|
||||
func (cmd *Command) GenBashCompletion(w io.Writer) error {
|
||||
if err := preamble(w, cmd.Name()); err != nil {
|
||||
return err
|
||||
// GenBashCompletion generates bash completion file and writes to the passed writer.
|
||||
func (c *Command) GenBashCompletion(w io.Writer) error {
|
||||
buf := new(bytes.Buffer)
|
||||
writePreamble(buf, c.Name())
|
||||
if len(c.BashCompletionFunction) > 0 {
|
||||
buf.WriteString(c.BashCompletionFunction + "\n")
|
||||
}
|
||||
if len(cmd.BashCompletionFunction) > 0 {
|
||||
if _, err := fmt.Fprintf(w, "%s\n", cmd.BashCompletionFunction); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := gen(cmd, w); err != nil {
|
||||
return err
|
||||
}
|
||||
return postscript(w, cmd.Name())
|
||||
gen(buf, c)
|
||||
writePostscript(buf, c.Name())
|
||||
|
||||
_, err := buf.WriteTo(w)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cmd *Command) GenBashCompletionFile(filename string) error {
|
||||
func nonCompletableFlag(flag *pflag.Flag) bool {
|
||||
return flag.Hidden || len(flag.Deprecated) > 0
|
||||
}
|
||||
|
||||
// GenBashCompletionFile generates bash completion file.
|
||||
func (c *Command) GenBashCompletionFile(filename string) error {
|
||||
outFile, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
return cmd.GenBashCompletion(outFile)
|
||||
}
|
||||
|
||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
|
||||
func (cmd *Command) MarkFlagRequired(name string) error {
|
||||
return MarkFlagRequired(cmd.Flags(), name)
|
||||
}
|
||||
|
||||
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
|
||||
func (cmd *Command) MarkPersistentFlagRequired(name string) error {
|
||||
return MarkFlagRequired(cmd.PersistentFlags(), name)
|
||||
}
|
||||
|
||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
|
||||
func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
|
||||
return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
|
||||
}
|
||||
|
||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
|
||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
||||
func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(cmd.Flags(), name, extensions...)
|
||||
}
|
||||
|
||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
|
||||
// Generated bash autocompletion will call the bash function f for the flag.
|
||||
func (cmd *Command) MarkFlagCustom(name string, f string) error {
|
||||
return MarkFlagCustom(cmd.Flags(), name, f)
|
||||
}
|
||||
|
||||
// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
|
||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
||||
func (cmd *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(cmd.PersistentFlags(), name, extensions...)
|
||||
}
|
||||
|
||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
|
||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
||||
func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
|
||||
return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
|
||||
}
|
||||
|
||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag in the flag set, if it exists.
|
||||
// Generated bash autocompletion will call the bash function f for the flag.
|
||||
func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
|
||||
return flags.SetAnnotation(name, BashCompCustom, []string{f})
|
||||
return c.GenBashCompletion(outFile)
|
||||
}
|
||||
|
||||
74
vendor/github.com/spf13/cobra/bash_completions.md
generated
vendored
74
vendor/github.com/spf13/cobra/bash_completions.md
generated
vendored
@@ -1,24 +1,60 @@
|
||||
# Generating Bash Completions For Your Own cobra.Command
|
||||
|
||||
If you are using the generator you can create a completion command by running
|
||||
|
||||
```bash
|
||||
cobra add completion
|
||||
```
|
||||
|
||||
Update the help text show how to install the bash_completion Linux show here [Kubectl docs show mac options](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion)
|
||||
|
||||
Writing the shell script to stdout allows the most flexible use.
|
||||
|
||||
```go
|
||||
// completionCmd represents the completion command
|
||||
var completionCmd = &cobra.Command{
|
||||
Use: "completion",
|
||||
Short: "Generates bash completion scripts",
|
||||
Long: `To load completion run
|
||||
|
||||
. <(bitbucket completion)
|
||||
|
||||
To configure your bash shell to load completions for each session add to your bashrc
|
||||
|
||||
# ~/.bashrc or ~/.profile
|
||||
. <(bitbucket completion)
|
||||
`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
rootCmd.GenBashCompletion(os.Stdout);
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The cobra generator may include messages printed to stdout for example if the config file is loaded, this will break the auto complete script
|
||||
|
||||
|
||||
## Example from kubectl
|
||||
|
||||
Generating bash completions from a cobra command is incredibly easy. An actual program which does so for the kubernetes kubectl binary is as follows:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
kubectl := cmd.NewFactory(nil).NewKubectlCommand(os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
kubectl.GenBashCompletionFile("out.sh")
|
||||
kubectl := cmd.NewKubectlCommand(util.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
kubectl.GenBashCompletionFile("out.sh")
|
||||
}
|
||||
```
|
||||
|
||||
That will get you completions of subcommands and flags. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
|
||||
`out.sh` will get you completions of subcommands and flags. Copy it to `/etc/bash_completion.d/` as described [here](https://debian-administration.org/article/316/An_introduction_to_bash_completion_part_1) and reset your terminal to use autocompletion. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
|
||||
|
||||
## Creating your own custom functions
|
||||
|
||||
@@ -46,7 +82,7 @@ __kubectl_get_resource()
|
||||
fi
|
||||
}
|
||||
|
||||
__custom_func() {
|
||||
__kubectl_custom_func() {
|
||||
case ${last_command} in
|
||||
kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop)
|
||||
__kubectl_get_resource
|
||||
@@ -73,7 +109,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
||||
}
|
||||
```
|
||||
|
||||
The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__custom_func()` to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods!
|
||||
The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__kubectl_custom_func()` (`__<command-use>_custom_func()`) to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__kubectl_customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__kubectl_custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods!
|
||||
|
||||
## Have the completions code complete your 'nouns'
|
||||
|
||||
@@ -106,7 +142,7 @@ node pod replicationcontroller service
|
||||
|
||||
If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
|
||||
|
||||
```go`
|
||||
```go
|
||||
argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
|
||||
|
||||
cmd := &cobra.Command{
|
||||
@@ -173,14 +209,14 @@ hello.yml test.json
|
||||
|
||||
So while there are many other files in the CWD it only shows me subdirs and those with valid extensions.
|
||||
|
||||
# Specifiy custom flag completion
|
||||
# Specify custom flag completion
|
||||
|
||||
Similar to the filename completion and filtering using cobra.BashCompFilenameExt, you can specifiy
|
||||
Similar to the filename completion and filtering using cobra.BashCompFilenameExt, you can specify
|
||||
a custom flag completion function with cobra.BashCompCustom:
|
||||
|
||||
```go
|
||||
annotation := make(map[string][]string)
|
||||
annotation[cobra.BashCompFilenameExt] = []string{"__kubectl_get_namespaces"}
|
||||
annotation[cobra.BashCompCustom] = []string{"__kubectl_get_namespaces"}
|
||||
|
||||
flag := &pflag.Flag{
|
||||
Name: "namespace",
|
||||
@@ -204,3 +240,17 @@ __kubectl_get_namespaces()
|
||||
fi
|
||||
}
|
||||
```
|
||||
# Using bash aliases for commands
|
||||
|
||||
You can also configure the `bash aliases` for the commands and they will also support completions.
|
||||
|
||||
```bash
|
||||
alias aliasname=origcommand
|
||||
complete -o default -F __start_origcommand aliasname
|
||||
|
||||
# and now when you run `aliasname` completion will make
|
||||
# suggestions as it did for `origcommand`.
|
||||
|
||||
$) aliasname <tab><tab>
|
||||
completion firstcommand secondcommand
|
||||
```
|
||||
|
||||
82
vendor/github.com/spf13/cobra/cobra.go
generated
vendored
82
vendor/github.com/spf13/cobra/cobra.go
generated
vendored
@@ -23,48 +23,71 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var templateFuncs = template.FuncMap{
|
||||
"trim": strings.TrimSpace,
|
||||
"trimRightSpace": trimRightSpace,
|
||||
"appendIfNotPresent": appendIfNotPresent,
|
||||
"rpad": rpad,
|
||||
"gt": Gt,
|
||||
"eq": Eq,
|
||||
"trim": strings.TrimSpace,
|
||||
"trimRightSpace": trimRightSpace,
|
||||
"trimTrailingWhitespaces": trimRightSpace,
|
||||
"appendIfNotPresent": appendIfNotPresent,
|
||||
"rpad": rpad,
|
||||
"gt": Gt,
|
||||
"eq": Eq,
|
||||
}
|
||||
|
||||
var initializers []func()
|
||||
|
||||
// automatic prefix matching can be a dangerous thing to automatically enable in CLI tools.
|
||||
// Set this to true to enable it
|
||||
// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
|
||||
// to automatically enable in CLI tools.
|
||||
// Set this to true to enable it.
|
||||
var EnablePrefixMatching = false
|
||||
|
||||
//AddTemplateFunc adds a template function that's available to Usage and Help
|
||||
//template generation.
|
||||
// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
|
||||
// To disable sorting, set it to false.
|
||||
var EnableCommandSorting = true
|
||||
|
||||
// MousetrapHelpText enables an information splash screen on Windows
|
||||
// if the CLI is started from explorer.exe.
|
||||
// To disable the mousetrap, just set this variable to blank string ("").
|
||||
// Works only on Microsoft Windows.
|
||||
var MousetrapHelpText string = `This is a command line tool.
|
||||
|
||||
You need to open cmd.exe and run it from there.
|
||||
`
|
||||
|
||||
// MousetrapDisplayDuration controls how long the MousetrapHelpText message is displayed on Windows
|
||||
// if the CLI is started from explorer.exe. Set to 0 to wait for the return key to be pressed.
|
||||
// To disable the mousetrap, just set MousetrapHelpText to blank string ("").
|
||||
// Works only on Microsoft Windows.
|
||||
var MousetrapDisplayDuration time.Duration = 5 * time.Second
|
||||
|
||||
// AddTemplateFunc adds a template function that's available to Usage and Help
|
||||
// template generation.
|
||||
func AddTemplateFunc(name string, tmplFunc interface{}) {
|
||||
templateFuncs[name] = tmplFunc
|
||||
}
|
||||
|
||||
//AddTemplateFuncs adds multiple template functions availalble to Usage and
|
||||
//Help template generation.
|
||||
// AddTemplateFuncs adds multiple template functions that are available to Usage and
|
||||
// Help template generation.
|
||||
func AddTemplateFuncs(tmplFuncs template.FuncMap) {
|
||||
for k, v := range tmplFuncs {
|
||||
templateFuncs[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
//OnInitialize takes a series of func() arguments and appends them to a slice of func().
|
||||
// OnInitialize sets the passed functions to be run when each command's
|
||||
// Execute method is called.
|
||||
func OnInitialize(y ...func()) {
|
||||
for _, x := range y {
|
||||
initializers = append(initializers, x)
|
||||
}
|
||||
initializers = append(initializers, y...)
|
||||
}
|
||||
|
||||
//Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
|
||||
//Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
|
||||
//ints and then compared.
|
||||
// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
|
||||
|
||||
// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
|
||||
// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
|
||||
// ints and then compared.
|
||||
func Gt(a interface{}, b interface{}) bool {
|
||||
var left, right int64
|
||||
av := reflect.ValueOf(a)
|
||||
@@ -92,7 +115,9 @@ func Gt(a interface{}, b interface{}) bool {
|
||||
return left > right
|
||||
}
|
||||
|
||||
//Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
|
||||
// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
|
||||
|
||||
// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
|
||||
func Eq(a interface{}, b interface{}) bool {
|
||||
av := reflect.ValueOf(a)
|
||||
bv := reflect.ValueOf(b)
|
||||
@@ -112,7 +137,9 @@ func trimRightSpace(s string) string {
|
||||
return strings.TrimRightFunc(s, unicode.IsSpace)
|
||||
}
|
||||
|
||||
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s
|
||||
// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
|
||||
|
||||
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
|
||||
func appendIfNotPresent(s, stringToAppend string) string {
|
||||
if strings.Contains(s, stringToAppend) {
|
||||
return s
|
||||
@@ -120,7 +147,7 @@ func appendIfNotPresent(s, stringToAppend string) string {
|
||||
return s + " " + stringToAppend
|
||||
}
|
||||
|
||||
//rpad adds padding to the right of a string
|
||||
// rpad adds padding to the right of a string.
|
||||
func rpad(s string, padding int) string {
|
||||
template := fmt.Sprintf("%%-%ds", padding)
|
||||
return fmt.Sprintf(template, s)
|
||||
@@ -134,7 +161,7 @@ func tmpl(w io.Writer, text string, data interface{}) error {
|
||||
return t.Execute(w, data)
|
||||
}
|
||||
|
||||
// ld compares two strings and returns the levenshtein distance between them
|
||||
// ld compares two strings and returns the levenshtein distance between them.
|
||||
func ld(s, t string, ignoreCase bool) int {
|
||||
if ignoreCase {
|
||||
s = strings.ToLower(s)
|
||||
@@ -169,3 +196,12 @@ func ld(s, t string, ignoreCase bool) int {
|
||||
}
|
||||
return d[len(s)][len(t)]
|
||||
}
|
||||
|
||||
func stringInSlice(a string, list []string) bool {
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
202
vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden
generated
vendored
Normal file
202
vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
1208
vendor/github.com/spf13/cobra/command.go
generated
vendored
1208
vendor/github.com/spf13/cobra/command.go
generated
vendored
File diff suppressed because it is too large
Load Diff
16
vendor/github.com/spf13/cobra/command_win.go
generated
vendored
16
vendor/github.com/spf13/cobra/command_win.go
generated
vendored
@@ -3,6 +3,7 @@
|
||||
package cobra
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
@@ -11,16 +12,15 @@ import (
|
||||
|
||||
var preExecHookFn = preExecHook
|
||||
|
||||
// enables an information splash screen on Windows if the CLI is started from explorer.exe.
|
||||
var MousetrapHelpText string = `This is a command line tool
|
||||
|
||||
You need to open cmd.exe and run it from there.
|
||||
`
|
||||
|
||||
func preExecHook(c *Command) {
|
||||
if mousetrap.StartedByExplorer() {
|
||||
if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
|
||||
c.Print(MousetrapHelpText)
|
||||
time.Sleep(5 * time.Second)
|
||||
if MousetrapDisplayDuration > 0 {
|
||||
time.Sleep(MousetrapDisplayDuration)
|
||||
} else {
|
||||
c.Println("Press return to continue...")
|
||||
fmt.Scanln()
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
13
vendor/github.com/spf13/cobra/go.mod
generated
vendored
Normal file
13
vendor/github.com/spf13/cobra/go.mod
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
module github.com/spf13/cobra
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||
github.com/cpuguy83/go-md2man v1.0.10
|
||||
github.com/inconshreveable/mousetrap v1.0.0
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/spf13/viper v1.3.2
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
)
|
||||
51
vendor/github.com/spf13/cobra/go.sum
generated
vendored
Normal file
51
vendor/github.com/spf13/cobra/go.sum
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
100
vendor/github.com/spf13/cobra/powershell_completions.go
generated
vendored
Normal file
100
vendor/github.com/spf13/cobra/powershell_completions.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// PowerShell completions are based on the amazing work from clap:
|
||||
// https://github.com/clap-rs/clap/blob/3294d18efe5f264d12c9035f404c7d189d4824e1/src/completions/powershell.rs
|
||||
//
|
||||
// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but
|
||||
// can be downloaded separately for windows 7 or 8.1).
|
||||
|
||||
package cobra
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var powerShellCompletionTemplate = `using namespace System.Management.Automation
|
||||
using namespace System.Management.Automation.Language
|
||||
Register-ArgumentCompleter -Native -CommandName '%s' -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
$commandElements = $commandAst.CommandElements
|
||||
$command = @(
|
||||
'%s'
|
||||
for ($i = 1; $i -lt $commandElements.Count; $i++) {
|
||||
$element = $commandElements[$i]
|
||||
if ($element -isnot [StringConstantExpressionAst] -or
|
||||
$element.StringConstantType -ne [StringConstantType]::BareWord -or
|
||||
$element.Value.StartsWith('-')) {
|
||||
break
|
||||
}
|
||||
$element.Value
|
||||
}
|
||||
) -join ';'
|
||||
$completions = @(switch ($command) {%s
|
||||
})
|
||||
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
|
||||
Sort-Object -Property ListItemText
|
||||
}`
|
||||
|
||||
func generatePowerShellSubcommandCases(out io.Writer, cmd *Command, previousCommandName string) {
|
||||
var cmdName string
|
||||
if previousCommandName == "" {
|
||||
cmdName = cmd.Name()
|
||||
} else {
|
||||
cmdName = fmt.Sprintf("%s;%s", previousCommandName, cmd.Name())
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "\n '%s' {", cmdName)
|
||||
|
||||
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
usage := escapeStringForPowerShell(flag.Usage)
|
||||
if len(flag.Shorthand) > 0 {
|
||||
fmt.Fprintf(out, "\n [CompletionResult]::new('-%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Shorthand, flag.Shorthand, usage)
|
||||
}
|
||||
fmt.Fprintf(out, "\n [CompletionResult]::new('--%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Name, flag.Name, usage)
|
||||
})
|
||||
|
||||
for _, subCmd := range cmd.Commands() {
|
||||
usage := escapeStringForPowerShell(subCmd.Short)
|
||||
fmt.Fprintf(out, "\n [CompletionResult]::new('%s', '%s', [CompletionResultType]::ParameterValue, '%s')", subCmd.Name(), subCmd.Name(), usage)
|
||||
}
|
||||
|
||||
fmt.Fprint(out, "\n break\n }")
|
||||
|
||||
for _, subCmd := range cmd.Commands() {
|
||||
generatePowerShellSubcommandCases(out, subCmd, cmdName)
|
||||
}
|
||||
}
|
||||
|
||||
func escapeStringForPowerShell(s string) string {
|
||||
return strings.Replace(s, "'", "''", -1)
|
||||
}
|
||||
|
||||
// GenPowerShellCompletion generates PowerShell completion file and writes to the passed writer.
|
||||
func (c *Command) GenPowerShellCompletion(w io.Writer) error {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
var subCommandCases bytes.Buffer
|
||||
generatePowerShellSubcommandCases(&subCommandCases, c, "")
|
||||
fmt.Fprintf(buf, powerShellCompletionTemplate, c.Name(), c.Name(), subCommandCases.String())
|
||||
|
||||
_, err := buf.WriteTo(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// GenPowerShellCompletionFile generates PowerShell completion file.
|
||||
func (c *Command) GenPowerShellCompletionFile(filename string) error {
|
||||
outFile, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
return c.GenPowerShellCompletion(outFile)
|
||||
}
|
||||
14
vendor/github.com/spf13/cobra/powershell_completions.md
generated
vendored
Normal file
14
vendor/github.com/spf13/cobra/powershell_completions.md
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Generating PowerShell Completions For Your Own cobra.Command
|
||||
|
||||
Cobra can generate PowerShell completion scripts. Users need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles.
|
||||
|
||||
# What's supported
|
||||
|
||||
- Completion for subcommands using their `.Short` description
|
||||
- Completion for non-hidden flags using their `.Name` and `.Shorthand`
|
||||
|
||||
# What's not yet supported
|
||||
|
||||
- Command aliases
|
||||
- Required, filename or custom flags (they will work like normal flags)
|
||||
- Custom completion scripts
|
||||
85
vendor/github.com/spf13/cobra/shell_completions.go
generated
vendored
Normal file
85
vendor/github.com/spf13/cobra/shell_completions.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
package cobra
|
||||
|
||||
import (
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
|
||||
// and causes your command to report an error if invoked without the flag.
|
||||
func (c *Command) MarkFlagRequired(name string) error {
|
||||
return MarkFlagRequired(c.Flags(), name)
|
||||
}
|
||||
|
||||
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
|
||||
// and causes your command to report an error if invoked without the flag.
|
||||
func (c *Command) MarkPersistentFlagRequired(name string) error {
|
||||
return MarkFlagRequired(c.PersistentFlags(), name)
|
||||
}
|
||||
|
||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
|
||||
// and causes your command to report an error if invoked without the flag.
|
||||
func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
|
||||
return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
|
||||
}
|
||||
|
||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
|
||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
||||
func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(c.Flags(), name, extensions...)
|
||||
}
|
||||
|
||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
|
||||
// Generated bash autocompletion will call the bash function f for the flag.
|
||||
func (c *Command) MarkFlagCustom(name string, f string) error {
|
||||
return MarkFlagCustom(c.Flags(), name, f)
|
||||
}
|
||||
|
||||
// MarkPersistentFlagFilename instructs the various shell completion
|
||||
// implementations to limit completions for this persistent flag to the
|
||||
// specified extensions (patterns).
|
||||
//
|
||||
// Shell Completion compatibility matrix: bash, zsh
|
||||
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
|
||||
}
|
||||
|
||||
// MarkFlagFilename instructs the various shell completion implementations to
|
||||
// limit completions for this flag to the specified extensions (patterns).
|
||||
//
|
||||
// Shell Completion compatibility matrix: bash, zsh
|
||||
func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
|
||||
return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
|
||||
}
|
||||
|
||||
// MarkFlagCustom instructs the various shell completion implementations to
|
||||
// limit completions for this flag to the specified extensions (patterns).
|
||||
//
|
||||
// Shell Completion compatibility matrix: bash, zsh
|
||||
func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
|
||||
return flags.SetAnnotation(name, BashCompCustom, []string{f})
|
||||
}
|
||||
|
||||
// MarkFlagDirname instructs the various shell completion implementations to
|
||||
// complete only directories with this named flag.
|
||||
//
|
||||
// Shell Completion compatibility matrix: zsh
|
||||
func (c *Command) MarkFlagDirname(name string) error {
|
||||
return MarkFlagDirname(c.Flags(), name)
|
||||
}
|
||||
|
||||
// MarkPersistentFlagDirname instructs the various shell completion
|
||||
// implementations to complete only directories with this persistent named flag.
|
||||
//
|
||||
// Shell Completion compatibility matrix: zsh
|
||||
func (c *Command) MarkPersistentFlagDirname(name string) error {
|
||||
return MarkFlagDirname(c.PersistentFlags(), name)
|
||||
}
|
||||
|
||||
// MarkFlagDirname instructs the various shell completion implementations to
|
||||
// complete only directories with this specified flag.
|
||||
//
|
||||
// Shell Completion compatibility matrix: zsh
|
||||
func MarkFlagDirname(flags *pflag.FlagSet, name string) error {
|
||||
zshPattern := "-(/)"
|
||||
return flags.SetAnnotation(name, zshCompDirname, []string{zshPattern})
|
||||
}
|
||||
336
vendor/github.com/spf13/cobra/zsh_completions.go
generated
vendored
Normal file
336
vendor/github.com/spf13/cobra/zsh_completions.go
generated
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
package cobra
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
zshCompArgumentAnnotation = "cobra_annotations_zsh_completion_argument_annotation"
|
||||
zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion"
|
||||
zshCompArgumentWordComp = "cobra_annotations_zsh_completion_argument_word_completion"
|
||||
zshCompDirname = "cobra_annotations_zsh_dirname"
|
||||
)
|
||||
|
||||
var (
|
||||
zshCompFuncMap = template.FuncMap{
|
||||
"genZshFuncName": zshCompGenFuncName,
|
||||
"extractFlags": zshCompExtractFlag,
|
||||
"genFlagEntryForZshArguments": zshCompGenFlagEntryForArguments,
|
||||
"extractArgsCompletions": zshCompExtractArgumentCompletionHintsForRendering,
|
||||
}
|
||||
zshCompletionText = `
|
||||
{{/* should accept Command (that contains subcommands) as parameter */}}
|
||||
{{define "argumentsC" -}}
|
||||
{{ $cmdPath := genZshFuncName .}}
|
||||
function {{$cmdPath}} {
|
||||
local -a commands
|
||||
|
||||
_arguments -C \{{- range extractFlags .}}
|
||||
{{genFlagEntryForZshArguments .}} \{{- end}}
|
||||
"1: :->cmnds" \
|
||||
"*::arg:->args"
|
||||
|
||||
case $state in
|
||||
cmnds)
|
||||
commands=({{range .Commands}}{{if not .Hidden}}
|
||||
"{{.Name}}:{{.Short}}"{{end}}{{end}}
|
||||
)
|
||||
_describe "command" commands
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$words[1]" in {{- range .Commands}}{{if not .Hidden}}
|
||||
{{.Name}})
|
||||
{{$cmdPath}}_{{.Name}}
|
||||
;;{{end}}{{end}}
|
||||
esac
|
||||
}
|
||||
{{range .Commands}}{{if not .Hidden}}
|
||||
{{template "selectCmdTemplate" .}}
|
||||
{{- end}}{{end}}
|
||||
{{- end}}
|
||||
|
||||
{{/* should accept Command without subcommands as parameter */}}
|
||||
{{define "arguments" -}}
|
||||
function {{genZshFuncName .}} {
|
||||
{{" _arguments"}}{{range extractFlags .}} \
|
||||
{{genFlagEntryForZshArguments . -}}
|
||||
{{end}}{{range extractArgsCompletions .}} \
|
||||
{{.}}{{end}}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{/* dispatcher for commands with or without subcommands */}}
|
||||
{{define "selectCmdTemplate" -}}
|
||||
{{if .Hidden}}{{/* ignore hidden*/}}{{else -}}
|
||||
{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
{{/* template entry point */}}
|
||||
{{define "Main" -}}
|
||||
#compdef _{{.Name}} {{.Name}}
|
||||
|
||||
{{template "selectCmdTemplate" .}}
|
||||
{{end}}
|
||||
`
|
||||
)
|
||||
|
||||
// zshCompArgsAnnotation is used to encode/decode zsh completion for
|
||||
// arguments to/from Command.Annotations.
|
||||
type zshCompArgsAnnotation map[int]zshCompArgHint
|
||||
|
||||
type zshCompArgHint struct {
|
||||
// Indicates the type of the completion to use. One of:
|
||||
// zshCompArgumentFilenameComp or zshCompArgumentWordComp
|
||||
Tipe string `json:"type"`
|
||||
|
||||
// A value for the type above (globs for file completion or words)
|
||||
Options []string `json:"options"`
|
||||
}
|
||||
|
||||
// GenZshCompletionFile generates zsh completion file.
|
||||
func (c *Command) GenZshCompletionFile(filename string) error {
|
||||
outFile, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
return c.GenZshCompletion(outFile)
|
||||
}
|
||||
|
||||
// GenZshCompletion generates a zsh completion file and writes to the passed
|
||||
// writer. The completion always run on the root command regardless of the
|
||||
// command it was called from.
|
||||
func (c *Command) GenZshCompletion(w io.Writer) error {
|
||||
tmpl, err := template.New("Main").Funcs(zshCompFuncMap).Parse(zshCompletionText)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating zsh completion template: %v", err)
|
||||
}
|
||||
return tmpl.Execute(w, c.Root())
|
||||
}
|
||||
|
||||
// MarkZshCompPositionalArgumentFile marks the specified argument (first
|
||||
// argument is 1) as completed by file selection. patterns (e.g. "*.txt") are
|
||||
// optional - if not provided the completion will search for all files.
|
||||
func (c *Command) MarkZshCompPositionalArgumentFile(argPosition int, patterns ...string) error {
|
||||
if argPosition < 1 {
|
||||
return fmt.Errorf("Invalid argument position (%d)", argPosition)
|
||||
}
|
||||
annotation, err := c.zshCompGetArgsAnnotations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) {
|
||||
return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition)
|
||||
}
|
||||
annotation[argPosition] = zshCompArgHint{
|
||||
Tipe: zshCompArgumentFilenameComp,
|
||||
Options: patterns,
|
||||
}
|
||||
return c.zshCompSetArgsAnnotations(annotation)
|
||||
}
|
||||
|
||||
// MarkZshCompPositionalArgumentWords marks the specified positional argument
|
||||
// (first argument is 1) as completed by the provided words. At east one word
|
||||
// must be provided, spaces within words will be offered completion with
|
||||
// "word\ word".
|
||||
func (c *Command) MarkZshCompPositionalArgumentWords(argPosition int, words ...string) error {
|
||||
if argPosition < 1 {
|
||||
return fmt.Errorf("Invalid argument position (%d)", argPosition)
|
||||
}
|
||||
if len(words) == 0 {
|
||||
return fmt.Errorf("Trying to set empty word list for positional argument %d", argPosition)
|
||||
}
|
||||
annotation, err := c.zshCompGetArgsAnnotations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) {
|
||||
return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition)
|
||||
}
|
||||
annotation[argPosition] = zshCompArgHint{
|
||||
Tipe: zshCompArgumentWordComp,
|
||||
Options: words,
|
||||
}
|
||||
return c.zshCompSetArgsAnnotations(annotation)
|
||||
}
|
||||
|
||||
func zshCompExtractArgumentCompletionHintsForRendering(c *Command) ([]string, error) {
|
||||
var result []string
|
||||
annotation, err := c.zshCompGetArgsAnnotations()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range annotation {
|
||||
s, err := zshCompRenderZshCompArgHint(k, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, s)
|
||||
}
|
||||
if len(c.ValidArgs) > 0 {
|
||||
if _, positionOneExists := annotation[1]; !positionOneExists {
|
||||
s, err := zshCompRenderZshCompArgHint(1, zshCompArgHint{
|
||||
Tipe: zshCompArgumentWordComp,
|
||||
Options: c.ValidArgs,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, s)
|
||||
}
|
||||
}
|
||||
sort.Strings(result)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func zshCompRenderZshCompArgHint(i int, z zshCompArgHint) (string, error) {
|
||||
switch t := z.Tipe; t {
|
||||
case zshCompArgumentFilenameComp:
|
||||
var globs []string
|
||||
for _, g := range z.Options {
|
||||
globs = append(globs, fmt.Sprintf(`-g "%s"`, g))
|
||||
}
|
||||
return fmt.Sprintf(`'%d: :_files %s'`, i, strings.Join(globs, " ")), nil
|
||||
case zshCompArgumentWordComp:
|
||||
var words []string
|
||||
for _, w := range z.Options {
|
||||
words = append(words, fmt.Sprintf("%q", w))
|
||||
}
|
||||
return fmt.Sprintf(`'%d: :(%s)'`, i, strings.Join(words, " ")), nil
|
||||
default:
|
||||
return "", fmt.Errorf("Invalid zsh argument completion annotation: %s", t)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Command) zshcompArgsAnnotationnIsDuplicatePosition(annotation zshCompArgsAnnotation, position int) bool {
|
||||
_, dup := annotation[position]
|
||||
return dup
|
||||
}
|
||||
|
||||
func (c *Command) zshCompGetArgsAnnotations() (zshCompArgsAnnotation, error) {
|
||||
annotation := make(zshCompArgsAnnotation)
|
||||
annotationString, ok := c.Annotations[zshCompArgumentAnnotation]
|
||||
if !ok {
|
||||
return annotation, nil
|
||||
}
|
||||
err := json.Unmarshal([]byte(annotationString), &annotation)
|
||||
if err != nil {
|
||||
return annotation, fmt.Errorf("Error unmarshaling zsh argument annotation: %v", err)
|
||||
}
|
||||
return annotation, nil
|
||||
}
|
||||
|
||||
func (c *Command) zshCompSetArgsAnnotations(annotation zshCompArgsAnnotation) error {
|
||||
jsn, err := json.Marshal(annotation)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error marshaling zsh argument annotation: %v", err)
|
||||
}
|
||||
if c.Annotations == nil {
|
||||
c.Annotations = make(map[string]string)
|
||||
}
|
||||
c.Annotations[zshCompArgumentAnnotation] = string(jsn)
|
||||
return nil
|
||||
}
|
||||
|
||||
func zshCompGenFuncName(c *Command) string {
|
||||
if c.HasParent() {
|
||||
return zshCompGenFuncName(c.Parent()) + "_" + c.Name()
|
||||
}
|
||||
return "_" + c.Name()
|
||||
}
|
||||
|
||||
func zshCompExtractFlag(c *Command) []*pflag.Flag {
|
||||
var flags []*pflag.Flag
|
||||
c.LocalFlags().VisitAll(func(f *pflag.Flag) {
|
||||
if !f.Hidden {
|
||||
flags = append(flags, f)
|
||||
}
|
||||
})
|
||||
c.InheritedFlags().VisitAll(func(f *pflag.Flag) {
|
||||
if !f.Hidden {
|
||||
flags = append(flags, f)
|
||||
}
|
||||
})
|
||||
return flags
|
||||
}
|
||||
|
||||
// zshCompGenFlagEntryForArguments returns an entry that matches _arguments
|
||||
// zsh-completion parameters. It's too complicated to generate in a template.
|
||||
func zshCompGenFlagEntryForArguments(f *pflag.Flag) string {
|
||||
if f.Name == "" || f.Shorthand == "" {
|
||||
return zshCompGenFlagEntryForSingleOptionFlag(f)
|
||||
}
|
||||
return zshCompGenFlagEntryForMultiOptionFlag(f)
|
||||
}
|
||||
|
||||
func zshCompGenFlagEntryForSingleOptionFlag(f *pflag.Flag) string {
|
||||
var option, multiMark, extras string
|
||||
|
||||
if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) {
|
||||
multiMark = "*"
|
||||
}
|
||||
|
||||
option = "--" + f.Name
|
||||
if option == "--" {
|
||||
option = "-" + f.Shorthand
|
||||
}
|
||||
extras = zshCompGenFlagEntryExtras(f)
|
||||
|
||||
return fmt.Sprintf(`'%s%s[%s]%s'`, multiMark, option, zshCompQuoteFlagDescription(f.Usage), extras)
|
||||
}
|
||||
|
||||
func zshCompGenFlagEntryForMultiOptionFlag(f *pflag.Flag) string {
|
||||
var options, parenMultiMark, curlyMultiMark, extras string
|
||||
|
||||
if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) {
|
||||
parenMultiMark = "*"
|
||||
curlyMultiMark = "\\*"
|
||||
}
|
||||
|
||||
options = fmt.Sprintf(`'(%s-%s %s--%s)'{%s-%s,%s--%s}`,
|
||||
parenMultiMark, f.Shorthand, parenMultiMark, f.Name, curlyMultiMark, f.Shorthand, curlyMultiMark, f.Name)
|
||||
extras = zshCompGenFlagEntryExtras(f)
|
||||
|
||||
return fmt.Sprintf(`%s'[%s]%s'`, options, zshCompQuoteFlagDescription(f.Usage), extras)
|
||||
}
|
||||
|
||||
func zshCompGenFlagEntryExtras(f *pflag.Flag) string {
|
||||
if f.NoOptDefVal != "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
extras := ":" // allow options for flag (even without assistance)
|
||||
for key, values := range f.Annotations {
|
||||
switch key {
|
||||
case zshCompDirname:
|
||||
extras = fmt.Sprintf(":filename:_files -g %q", values[0])
|
||||
case BashCompFilenameExt:
|
||||
extras = ":filename:_files"
|
||||
for _, pattern := range values {
|
||||
extras = extras + fmt.Sprintf(` -g "%s"`, pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extras
|
||||
}
|
||||
|
||||
func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool {
|
||||
return strings.Contains(f.Value.Type(), "Slice") ||
|
||||
strings.Contains(f.Value.Type(), "Array")
|
||||
}
|
||||
|
||||
func zshCompQuoteFlagDescription(s string) string {
|
||||
return strings.Replace(s, "'", `'\''`, -1)
|
||||
}
|
||||
39
vendor/github.com/spf13/cobra/zsh_completions.md
generated
vendored
Normal file
39
vendor/github.com/spf13/cobra/zsh_completions.md
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
## Generating Zsh Completion for your cobra.Command
|
||||
|
||||
Cobra supports native Zsh completion generated from the root `cobra.Command`.
|
||||
The generated completion script should be put somewhere in your `$fpath` named
|
||||
`_<YOUR COMMAND>`.
|
||||
|
||||
### What's Supported
|
||||
|
||||
* Completion for all non-hidden subcommands using their `.Short` description.
|
||||
* Completion for all non-hidden flags using the following rules:
|
||||
* Filename completion works by marking the flag with `cmd.MarkFlagFilename...`
|
||||
family of commands.
|
||||
* The requirement for argument to the flag is decided by the `.NoOptDefVal`
|
||||
flag value - if it's empty then completion will expect an argument.
|
||||
* Flags of one of the various `*Array` and `*Slice` types supports multiple
|
||||
specifications (with or without argument depending on the specific type).
|
||||
* Completion of positional arguments using the following rules:
|
||||
* Argument position for all options below starts at `1`. If argument position
|
||||
`0` is requested it will raise an error.
|
||||
* Use `command.MarkZshCompPositionalArgumentFile` to complete filenames. Glob
|
||||
patterns (e.g. `"*.log"`) are optional - if not specified it will offer to
|
||||
complete all file types.
|
||||
* Use `command.MarkZshCompPositionalArgumentWords` to offer specific words for
|
||||
completion. At least one word is required.
|
||||
* It's possible to specify completion for some arguments and leave some
|
||||
unspecified (e.g. offer words for second argument but nothing for first
|
||||
argument). This will cause no completion for first argument but words
|
||||
completion for second argument.
|
||||
* If no argument completion was specified for 1st argument (but optionally was
|
||||
specified for 2nd) and the command has `ValidArgs` it will be used as
|
||||
completion options for 1st argument.
|
||||
* Argument completions only offered for commands with no subcommands.
|
||||
|
||||
### What's not yet Supported
|
||||
|
||||
* Custom completion scripts are not supported yet (We should probably create zsh
|
||||
specific one, doesn't make sense to re-use the bash one as the functions will
|
||||
be different).
|
||||
* Whatever other feature you're looking for and doesn't exist :)
|
||||
Reference in New Issue
Block a user