mirror of https://github.com/docker/cli.git
vendor: github.com/spf13/cobra v1.7.0
release notes: https://github.com/spf13/cobra/releases/tag/v1.7.0 Features - Allow to preserve ordering of completions in bash, zsh, pwsh, & fish - Add support for PowerShell 7.2+ in completions - Allow sourcing zsh completion script Bug fixes - Don't remove flag values that match sub-command name - Fix powershell completions not returning single word - Remove masked template import variable name - Correctly detect completions with dash in argument Testing & CI/CD - Deprecate Go 1.15 in CI - Deprecate Go 1.16 in CI - Add testing for Go 1.20 in CI - Add tests to illustrate unknown flag bug Maintenance - Update main image to better handle dark backgrounds - Fix stale.yaml mispellings - Remove stale bot from GitHub actions - Add makefile target for installing dependencies - Add Sia to projects using Cobra - Add Vitess and Arewefastyet to projects using cobra - Fixup for Kubescape github org - Fix route for GitHub workflows badge - Fixup for GoDoc style documentation - Various bash scripting improvements for completion - Add Constellation to projects using Cobra Documentation - Add documentation about disabling completion descriptions - Improve MarkFlagsMutuallyExclusive example in user guide - Update shell_completions.md - Update copywrite year - Document suggested layout of subcommands - Replace deprecated ExactValidArgs with MatchAll in doc full diff: https://github.com/spf13/cobra/compare/v1.6.1...v1.7.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
d49b8ff855
commit
c25b8f803e
|
@ -32,7 +32,7 @@ require (
|
|||
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/theupdateframework/notary v0.7.1-0.20210315103452-bf96a202a09a
|
||||
github.com/tonistiigi/go-rosetta v0.0.0-20200727161949-f79598599c5d
|
||||
|
|
|
@ -230,7 +230,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
|||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8 h1:CZkYfurY6KGhVtlalI4QwQ6T0Cu6iuY3e0x5RLu96WE=
|
||||
|
@ -379,8 +378,8 @@ github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
|
|||
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 h1:JmfC365KywYwHB946TTiQWEb8kqPY+pybPLoGE9GgVk=
|
||||
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
|
||||
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431 h1:XTHrT015sxHyJ5FnQ0AeemSspZWaDq7DoTRW0EVsDCE=
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2013-2022 The Cobra Authors
|
||||
# Copyright 2013-2023 The Cobra Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -5,10 +5,6 @@ ifeq (, $(shell which golangci-lint))
|
|||
$(warning "could not find golangci-lint in $(PATH), run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh")
|
||||
endif
|
||||
|
||||
ifeq (, $(shell which richgo))
|
||||
$(warning "could not find richgo in $(PATH), run: go install github.com/kyoh86/richgo@latest")
|
||||
endif
|
||||
|
||||
.PHONY: fmt lint test install_deps clean
|
||||
|
||||
default: all
|
||||
|
@ -25,6 +21,10 @@ lint:
|
|||
|
||||
test: install_deps
|
||||
$(info ******************** running tests ********************)
|
||||
go test -v ./...
|
||||
|
||||
richtest: install_deps
|
||||
$(info ******************** running tests with kyoh86/richgo ********************)
|
||||
richgo test -v ./...
|
||||
|
||||
install_deps:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
![cobra logo](https://cloud.githubusercontent.com/assets/173412/10886352/ad566232-814f-11e5-9cd0-aa101788c117.png)
|
||||
![cobra logo](assets/CobraMain.png)
|
||||
|
||||
Cobra is a library for creating powerful modern CLI applications.
|
||||
|
||||
|
@ -6,7 +6,7 @@ Cobra is used in many Go projects such as [Kubernetes](https://kubernetes.io/),
|
|||
[Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to
|
||||
name a few. [This list](./projects_using_cobra.md) contains a more extensive list of projects using Cobra.
|
||||
|
||||
[![](https://img.shields.io/github/workflow/status/spf13/cobra/Test?longCache=tru&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest)
|
||||
[![](https://img.shields.io/github/actions/workflow/status/spf13/cobra/test.yml?branch=main&longCache=true&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest)
|
||||
[![Go Reference](https://pkg.go.dev/badge/github.com/spf13/cobra.svg)](https://pkg.go.dev/github.com/spf13/cobra)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra)
|
||||
[![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -21,7 +21,7 @@ import (
|
|||
|
||||
type PositionalArgs func(cmd *Command, args []string) error
|
||||
|
||||
// Legacy arg validation has the following behaviour:
|
||||
// legacyArgs 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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -532,7 +532,7 @@ func writeLocalNonPersistentFlag(buf io.StringWriter, flag *pflag.Flag) {
|
|||
}
|
||||
}
|
||||
|
||||
// Setup annotations for go completions for registered flags
|
||||
// prepareCustomAnnotationsForFlags setup annotations for go completions for registered flags
|
||||
func prepareCustomAnnotationsForFlags(cmd *Command) {
|
||||
flagCompletionMutex.RLock()
|
||||
defer flagCompletionMutex.RUnlock()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -38,7 +38,7 @@ func genBashComp(buf io.StringWriter, name string, includeDesc bool) {
|
|||
|
||||
__%[1]s_debug()
|
||||
{
|
||||
if [[ -n ${BASH_COMP_DEBUG_FILE:-} ]]; then
|
||||
if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
|
||||
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
|
||||
fi
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ __%[1]s_get_completion_results() {
|
|||
lastChar=${lastParam:$((${#lastParam}-1)):1}
|
||||
__%[1]s_debug "lastParam ${lastParam}, lastChar ${lastChar}"
|
||||
|
||||
if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then
|
||||
if [[ -z ${cur} && ${lastChar} != = ]]; then
|
||||
# If the last parameter is complete (there is a space following it)
|
||||
# We add an extra empty parameter so we can indicate this to the go method.
|
||||
__%[1]s_debug "Adding extra empty parameter"
|
||||
|
@ -75,7 +75,7 @@ __%[1]s_get_completion_results() {
|
|||
# When completing a flag with an = (e.g., %[1]s -n=<TAB>)
|
||||
# bash focuses on the part after the =, so we need to remove
|
||||
# the flag part from $cur
|
||||
if [[ "${cur}" == -*=* ]]; then
|
||||
if [[ ${cur} == -*=* ]]; then
|
||||
cur="${cur#*=}"
|
||||
fi
|
||||
|
||||
|
@ -87,7 +87,7 @@ __%[1]s_get_completion_results() {
|
|||
directive=${out##*:}
|
||||
# Remove the directive
|
||||
out=${out%%:*}
|
||||
if [ "${directive}" = "${out}" ]; then
|
||||
if [[ ${directive} == "${out}" ]]; then
|
||||
# There is not directive specified
|
||||
directive=0
|
||||
fi
|
||||
|
@ -101,22 +101,36 @@ __%[1]s_process_completion_results() {
|
|||
local shellCompDirectiveNoFileComp=%[5]d
|
||||
local shellCompDirectiveFilterFileExt=%[6]d
|
||||
local shellCompDirectiveFilterDirs=%[7]d
|
||||
local shellCompDirectiveKeepOrder=%[8]d
|
||||
|
||||
if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
|
||||
if (((directive & shellCompDirectiveError) != 0)); then
|
||||
# Error code. No completion.
|
||||
__%[1]s_debug "Received error from custom completion go code"
|
||||
return
|
||||
else
|
||||
if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
if (((directive & shellCompDirectiveNoSpace) != 0)); then
|
||||
if [[ $(type -t compopt) == builtin ]]; then
|
||||
__%[1]s_debug "Activating no space"
|
||||
compopt -o nospace
|
||||
else
|
||||
__%[1]s_debug "No space directive not supported in this version of bash"
|
||||
fi
|
||||
fi
|
||||
if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
if (((directive & shellCompDirectiveKeepOrder) != 0)); then
|
||||
if [[ $(type -t compopt) == builtin ]]; then
|
||||
# no sort isn't supported for bash less than < 4.4
|
||||
if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then
|
||||
__%[1]s_debug "No sort directive not supported in this version of bash"
|
||||
else
|
||||
__%[1]s_debug "Activating keep order"
|
||||
compopt -o nosort
|
||||
fi
|
||||
else
|
||||
__%[1]s_debug "No sort directive not supported in this version of bash"
|
||||
fi
|
||||
fi
|
||||
if (((directive & shellCompDirectiveNoFileComp) != 0)); then
|
||||
if [[ $(type -t compopt) == builtin ]]; then
|
||||
__%[1]s_debug "Activating no file completion"
|
||||
compopt +o default
|
||||
else
|
||||
|
@ -130,7 +144,7 @@ __%[1]s_process_completion_results() {
|
|||
local activeHelp=()
|
||||
__%[1]s_extract_activeHelp
|
||||
|
||||
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
|
||||
if (((directive & shellCompDirectiveFilterFileExt) != 0)); then
|
||||
# File extension filtering
|
||||
local fullFilter filter filteringCmd
|
||||
|
||||
|
@ -143,13 +157,12 @@ __%[1]s_process_completion_results() {
|
|||
filteringCmd="_filedir $fullFilter"
|
||||
__%[1]s_debug "File filtering command: $filteringCmd"
|
||||
$filteringCmd
|
||||
elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
|
||||
elif (((directive & shellCompDirectiveFilterDirs) != 0)); then
|
||||
# File completion for directories only
|
||||
|
||||
# Use printf to strip any trailing newline
|
||||
local subdir
|
||||
subdir=$(printf "%%s" "${completions[0]}")
|
||||
if [ -n "$subdir" ]; then
|
||||
subdir=${completions[0]}
|
||||
if [[ -n $subdir ]]; then
|
||||
__%[1]s_debug "Listing directories in $subdir"
|
||||
pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
|
||||
else
|
||||
|
@ -164,7 +177,7 @@ __%[1]s_process_completion_results() {
|
|||
__%[1]s_handle_special_char "$cur" =
|
||||
|
||||
# Print the activeHelp statements before we finish
|
||||
if [ ${#activeHelp[*]} -ne 0 ]; then
|
||||
if ((${#activeHelp[*]} != 0)); then
|
||||
printf "\n";
|
||||
printf "%%s\n" "${activeHelp[@]}"
|
||||
printf "\n"
|
||||
|
@ -184,21 +197,21 @@ __%[1]s_process_completion_results() {
|
|||
# Separate activeHelp lines from real completions.
|
||||
# Fills the $activeHelp and $completions arrays.
|
||||
__%[1]s_extract_activeHelp() {
|
||||
local activeHelpMarker="%[8]s"
|
||||
local activeHelpMarker="%[9]s"
|
||||
local endIndex=${#activeHelpMarker}
|
||||
|
||||
while IFS='' read -r comp; do
|
||||
if [ "${comp:0:endIndex}" = "$activeHelpMarker" ]; then
|
||||
if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then
|
||||
comp=${comp:endIndex}
|
||||
__%[1]s_debug "ActiveHelp found: $comp"
|
||||
if [ -n "$comp" ]; then
|
||||
if [[ -n $comp ]]; then
|
||||
activeHelp+=("$comp")
|
||||
fi
|
||||
else
|
||||
# Not an activeHelp line but a normal completion
|
||||
completions+=("$comp")
|
||||
fi
|
||||
done < <(printf "%%s\n" "${out}")
|
||||
done <<<"${out}"
|
||||
}
|
||||
|
||||
__%[1]s_handle_completion_types() {
|
||||
|
@ -254,7 +267,7 @@ __%[1]s_handle_standard_completion_case() {
|
|||
done < <(printf "%%s\n" "${completions[@]}")
|
||||
|
||||
# If there is a single completion left, remove the description text
|
||||
if [ ${#COMPREPLY[*]} -eq 1 ]; then
|
||||
if ((${#COMPREPLY[*]} == 1)); then
|
||||
__%[1]s_debug "COMPREPLY[0]: ${COMPREPLY[0]}"
|
||||
comp="${COMPREPLY[0]%%%%$tab*}"
|
||||
__%[1]s_debug "Removed description from single completion, which is now: ${comp}"
|
||||
|
@ -271,8 +284,8 @@ __%[1]s_handle_special_char()
|
|||
if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then
|
||||
local word=${comp%%"${comp##*${char}}"}
|
||||
local idx=${#COMPREPLY[*]}
|
||||
while [[ $((--idx)) -ge 0 ]]; do
|
||||
COMPREPLY[$idx]=${COMPREPLY[$idx]#"$word"}
|
||||
while ((--idx >= 0)); do
|
||||
COMPREPLY[idx]=${COMPREPLY[idx]#"$word"}
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
@ -298,7 +311,7 @@ __%[1]s_format_comp_descriptions()
|
|||
|
||||
# Make sure we can fit a description of at least 8 characters
|
||||
# if we are to align the descriptions.
|
||||
if [[ $maxdesclength -gt 8 ]]; then
|
||||
if ((maxdesclength > 8)); then
|
||||
# Add the proper number of spaces to align the descriptions
|
||||
for ((i = ${#comp} ; i < longest ; i++)); do
|
||||
comp+=" "
|
||||
|
@ -310,8 +323,8 @@ __%[1]s_format_comp_descriptions()
|
|||
|
||||
# If there is enough space for any description text,
|
||||
# truncate the descriptions that are too long for the shell width
|
||||
if [ $maxdesclength -gt 0 ]; then
|
||||
if [ ${#desc} -gt $maxdesclength ]; then
|
||||
if ((maxdesclength > 0)); then
|
||||
if ((${#desc} > maxdesclength)); then
|
||||
desc=${desc:0:$(( maxdesclength - 1 ))}
|
||||
desc+="…"
|
||||
fi
|
||||
|
@ -332,9 +345,9 @@ __start_%[1]s()
|
|||
# Call _init_completion from the bash-completion package
|
||||
# to prepare the arguments properly
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
_init_completion -n "=:" || return
|
||||
_init_completion -n =: || return
|
||||
else
|
||||
__%[1]s_init_completion -n "=:" || return
|
||||
__%[1]s_init_completion -n =: || return
|
||||
fi
|
||||
|
||||
__%[1]s_debug
|
||||
|
@ -361,7 +374,7 @@ fi
|
|||
# ex: ts=4 sw=4 et filetype=sh
|
||||
`, name, compCmd,
|
||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,
|
||||
activeHelpMarker))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -167,8 +167,8 @@ func appendIfNotPresent(s, stringToAppend string) 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)
|
||||
formattedString := fmt.Sprintf("%%-%ds", padding)
|
||||
return fmt.Sprintf(formattedString, s)
|
||||
}
|
||||
|
||||
// tmpl executes the given template text on data, writing the result to w.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -35,7 +35,7 @@ const FlagSetByCobraAnnotation = "cobra_annotation_flag_set_by_cobra"
|
|||
// FParseErrWhitelist configures Flag parse errors to be ignored
|
||||
type FParseErrWhitelist flag.ParseErrorsWhitelist
|
||||
|
||||
// Structure to manage groups for commands
|
||||
// Group Structure to manage groups for commands
|
||||
type Group struct {
|
||||
ID string
|
||||
Title string
|
||||
|
@ -47,7 +47,7 @@ type Group struct {
|
|||
// definition to ensure usability.
|
||||
type Command struct {
|
||||
// Use is the one-line usage message.
|
||||
// Recommended syntax is as follow:
|
||||
// Recommended syntax is as follows:
|
||||
// [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required.
|
||||
// ... indicates that you can specify multiple values for the previous argument.
|
||||
// | indicates mutually exclusive information. You can use the argument to the left of the separator or the
|
||||
|
@ -321,7 +321,7 @@ func (c *Command) SetHelpCommand(cmd *Command) {
|
|||
c.helpCommand = cmd
|
||||
}
|
||||
|
||||
// SetHelpCommandGroup sets the group id of the help command.
|
||||
// SetHelpCommandGroupID sets the group id of the help command.
|
||||
func (c *Command) SetHelpCommandGroupID(groupID string) {
|
||||
if c.helpCommand != nil {
|
||||
c.helpCommand.GroupID = groupID
|
||||
|
@ -330,7 +330,7 @@ func (c *Command) SetHelpCommandGroupID(groupID string) {
|
|||
c.helpCommandGroupID = groupID
|
||||
}
|
||||
|
||||
// SetCompletionCommandGroup sets the group id of the completion command.
|
||||
// SetCompletionCommandGroupID sets the group id of the completion command.
|
||||
func (c *Command) SetCompletionCommandGroupID(groupID string) {
|
||||
// completionCommandGroupID is used if no completion command is defined by the user
|
||||
c.Root().completionCommandGroupID = groupID
|
||||
|
@ -655,20 +655,44 @@ Loop:
|
|||
|
||||
// argsMinusFirstX removes only the first x from args. Otherwise, commands that look like
|
||||
// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
|
||||
func argsMinusFirstX(args []string, x string) []string {
|
||||
for i, y := range args {
|
||||
if x == y {
|
||||
ret := []string{}
|
||||
ret = append(ret, args[:i]...)
|
||||
ret = append(ret, args[i+1:]...)
|
||||
return ret
|
||||
// Special care needs to be taken not to remove a flag value.
|
||||
func (c *Command) argsMinusFirstX(args []string, x string) []string {
|
||||
if len(args) == 0 {
|
||||
return args
|
||||
}
|
||||
c.mergePersistentFlags()
|
||||
flags := c.Flags()
|
||||
|
||||
Loop:
|
||||
for pos := 0; pos < len(args); pos++ {
|
||||
s := args[pos]
|
||||
switch {
|
||||
case s == "--":
|
||||
// -- means we have reached the end of the parseable args. Break out of the loop now.
|
||||
break Loop
|
||||
case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
|
||||
fallthrough
|
||||
case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
|
||||
// This is a flag without a default value, and an equal sign is not used. Increment pos in order to skip
|
||||
// over the next arg, because that is the value of this flag.
|
||||
pos++
|
||||
continue
|
||||
case !strings.HasPrefix(s, "-"):
|
||||
// This is not a flag or a flag value. Check to see if it matches what we're looking for, and if so,
|
||||
// return the args, excluding the one at this position.
|
||||
if s == x {
|
||||
ret := []string{}
|
||||
ret = append(ret, args[:pos]...)
|
||||
ret = append(ret, args[pos+1:]...)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
func isFlagArg(arg string) bool {
|
||||
return ((len(arg) >= 3 && arg[1] == '-') ||
|
||||
return ((len(arg) >= 3 && arg[0:2] == "--") ||
|
||||
(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
|
||||
}
|
||||
|
||||
|
@ -686,7 +710,7 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
|
|||
|
||||
cmd := c.findNext(nextSubCmd)
|
||||
if cmd != nil {
|
||||
return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
|
||||
return innerfind(cmd, c.argsMinusFirstX(innerArgs, nextSubCmd))
|
||||
}
|
||||
return c, innerArgs
|
||||
}
|
||||
|
@ -1272,7 +1296,7 @@ func (c *Command) AllChildCommandsHaveGroup() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// ContainGroups return if groupID exists in the list of command groups.
|
||||
// ContainsGroup return if groupID exists in the list of command groups.
|
||||
func (c *Command) ContainsGroup(groupID string) bool {
|
||||
for _, x := range c.commandgroups {
|
||||
if x.ID == groupID {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -77,6 +77,10 @@ const (
|
|||
// obtain the same behavior but only for flags.
|
||||
ShellCompDirectiveFilterDirs
|
||||
|
||||
// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order
|
||||
// in which the completions are provided
|
||||
ShellCompDirectiveKeepOrder
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
// All directives using iota should be above this one.
|
||||
|
@ -159,6 +163,9 @@ func (d ShellCompDirective) string() string {
|
|||
if d&ShellCompDirectiveFilterDirs != 0 {
|
||||
directives = append(directives, "ShellCompDirectiveFilterDirs")
|
||||
}
|
||||
if d&ShellCompDirectiveKeepOrder != 0 {
|
||||
directives = append(directives, "ShellCompDirectiveKeepOrder")
|
||||
}
|
||||
if len(directives) == 0 {
|
||||
directives = append(directives, "ShellCompDirectiveDefault")
|
||||
}
|
||||
|
@ -169,7 +176,7 @@ func (d ShellCompDirective) string() string {
|
|||
return strings.Join(directives, ", ")
|
||||
}
|
||||
|
||||
// Adds a special hidden command that can be used to request custom completions.
|
||||
// initCompleteCmd adds a special hidden command that can be used to request custom completions.
|
||||
func (c *Command) initCompleteCmd(args []string) {
|
||||
completeCmd := &Command{
|
||||
Use: fmt.Sprintf("%s [command-line]", ShellCompRequestCmd),
|
||||
|
@ -727,7 +734,7 @@ to enable it. You can execute the following once:
|
|||
|
||||
To load completions in your current shell session:
|
||||
|
||||
source <(%[1]s completion zsh); compdef _%[1]s %[1]s
|
||||
source <(%[1]s completion zsh)
|
||||
|
||||
To load completions for every new session, execute once:
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -53,7 +53,7 @@ function __%[1]s_perform_completion
|
|||
__%[1]s_debug "last arg: $lastArg"
|
||||
|
||||
# Disable ActiveHelp which is not supported for fish shell
|
||||
set -l requestComp "%[9]s=0 $args[1] %[3]s $args[2..-1] $lastArg"
|
||||
set -l requestComp "%[10]s=0 $args[1] %[3]s $args[2..-1] $lastArg"
|
||||
|
||||
__%[1]s_debug "Calling $requestComp"
|
||||
set -l results (eval $requestComp 2> /dev/null)
|
||||
|
@ -89,6 +89,60 @@ function __%[1]s_perform_completion
|
|||
printf "%%s\n" "$directiveLine"
|
||||
end
|
||||
|
||||
# this function limits calls to __%[1]s_perform_completion, by caching the result behind $__%[1]s_perform_completion_once_result
|
||||
function __%[1]s_perform_completion_once
|
||||
__%[1]s_debug "Starting __%[1]s_perform_completion_once"
|
||||
|
||||
if test -n "$__%[1]s_perform_completion_once_result"
|
||||
__%[1]s_debug "Seems like a valid result already exists, skipping __%[1]s_perform_completion"
|
||||
return 0
|
||||
end
|
||||
|
||||
set --global __%[1]s_perform_completion_once_result (__%[1]s_perform_completion)
|
||||
if test -z "$__%[1]s_perform_completion_once_result"
|
||||
__%[1]s_debug "No completions, probably due to a failure"
|
||||
return 1
|
||||
end
|
||||
|
||||
__%[1]s_debug "Performed completions and set __%[1]s_perform_completion_once_result"
|
||||
return 0
|
||||
end
|
||||
|
||||
# this function is used to clear the $__%[1]s_perform_completion_once_result variable after completions are run
|
||||
function __%[1]s_clear_perform_completion_once_result
|
||||
__%[1]s_debug ""
|
||||
__%[1]s_debug "========= clearing previously set __%[1]s_perform_completion_once_result variable =========="
|
||||
set --erase __%[1]s_perform_completion_once_result
|
||||
__%[1]s_debug "Succesfully erased the variable __%[1]s_perform_completion_once_result"
|
||||
end
|
||||
|
||||
function __%[1]s_requires_order_preservation
|
||||
__%[1]s_debug ""
|
||||
__%[1]s_debug "========= checking if order preservation is required =========="
|
||||
|
||||
__%[1]s_perform_completion_once
|
||||
if test -z "$__%[1]s_perform_completion_once_result"
|
||||
__%[1]s_debug "Error determining if order preservation is required"
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1])
|
||||
__%[1]s_debug "Directive is: $directive"
|
||||
|
||||
set -l shellCompDirectiveKeepOrder %[9]d
|
||||
set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) %% 2)
|
||||
__%[1]s_debug "Keeporder is: $keeporder"
|
||||
|
||||
if test $keeporder -ne 0
|
||||
__%[1]s_debug "This does require order preservation"
|
||||
return 0
|
||||
end
|
||||
|
||||
__%[1]s_debug "This doesn't require order preservation"
|
||||
return 1
|
||||
end
|
||||
|
||||
|
||||
# This function does two things:
|
||||
# - Obtain the completions and store them in the global __%[1]s_comp_results
|
||||
# - Return false if file completion should be performed
|
||||
|
@ -99,17 +153,17 @@ function __%[1]s_prepare_completions
|
|||
# Start fresh
|
||||
set --erase __%[1]s_comp_results
|
||||
|
||||
set -l results (__%[1]s_perform_completion)
|
||||
__%[1]s_debug "Completion results: $results"
|
||||
__%[1]s_perform_completion_once
|
||||
__%[1]s_debug "Completion results: $__%[1]s_perform_completion_once_result"
|
||||
|
||||
if test -z "$results"
|
||||
if test -z "$__%[1]s_perform_completion_once_result"
|
||||
__%[1]s_debug "No completion, probably due to a failure"
|
||||
# Might as well do file completion, in case it helps
|
||||
return 1
|
||||
end
|
||||
|
||||
set -l directive (string sub --start 2 $results[-1])
|
||||
set --global __%[1]s_comp_results $results[1..-2]
|
||||
set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1])
|
||||
set --global __%[1]s_comp_results $__%[1]s_perform_completion_once_result[1..-2]
|
||||
|
||||
__%[1]s_debug "Completions are: $__%[1]s_comp_results"
|
||||
__%[1]s_debug "Directive is: $directive"
|
||||
|
@ -205,13 +259,17 @@ end
|
|||
# Remove any pre-existing completions for the program since we will be handling all of them.
|
||||
complete -c %[2]s -e
|
||||
|
||||
# this will get called after the two calls below and clear the $__%[1]s_perform_completion_once_result global
|
||||
complete -c %[2]s -n '__%[1]s_clear_perform_completion_once_result'
|
||||
# The call to __%[1]s_prepare_completions will setup __%[1]s_comp_results
|
||||
# which provides the program's completion choices.
|
||||
complete -c %[2]s -n '__%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
|
||||
|
||||
# If this doesn't require order preservation, we don't use the -k flag
|
||||
complete -c %[2]s -n 'not __%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
|
||||
# otherwise we use the -k flag
|
||||
complete -k -c %[2]s -n '__%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'
|
||||
`, nameForVar, name, compCmd,
|
||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))
|
||||
}
|
||||
|
||||
// GenFishCompletion generates fish completion file and writes to the passed writer.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -77,6 +77,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
|||
$ShellCompDirectiveNoFileComp=%[6]d
|
||||
$ShellCompDirectiveFilterFileExt=%[7]d
|
||||
$ShellCompDirectiveFilterDirs=%[8]d
|
||||
$ShellCompDirectiveKeepOrder=%[9]d
|
||||
|
||||
# Prepare the command to request completions for the program.
|
||||
# Split the command at the first space to separate the program and arguments.
|
||||
|
@ -106,13 +107,22 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
|||
# If the last parameter is complete (there is a space following it)
|
||||
# We add an extra empty parameter so we can indicate this to the go method.
|
||||
__%[1]s_debug "Adding extra empty parameter"
|
||||
`+" # We need to use `\"`\" to pass an empty argument a \"\" or '' does not work!!!"+`
|
||||
`+" $RequestComp=\"$RequestComp\" + ' `\"`\"'"+`
|
||||
# PowerShell 7.2+ changed the way how the arguments are passed to executables,
|
||||
# so for pre-7.2 or when Legacy argument passing is enabled we need to use
|
||||
`+" # `\"`\" to pass an empty argument, a \"\" or '' does not work!!!"+`
|
||||
if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or
|
||||
($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or
|
||||
(($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and
|
||||
$PSNativeCommandArgumentPassing -eq 'Legacy')) {
|
||||
`+" $RequestComp=\"$RequestComp\" + ' `\"`\"'"+`
|
||||
} else {
|
||||
$RequestComp="$RequestComp" + ' ""'
|
||||
}
|
||||
}
|
||||
|
||||
__%[1]s_debug "Calling $RequestComp"
|
||||
# First disable ActiveHelp which is not supported for Powershell
|
||||
$env:%[9]s=0
|
||||
$env:%[10]s=0
|
||||
|
||||
#call the command store the output in $out and redirect stderr and stdout to null
|
||||
# $Out is an array contains each line per element
|
||||
|
@ -137,7 +147,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
|||
}
|
||||
|
||||
$Longest = 0
|
||||
$Values = $Out | ForEach-Object {
|
||||
[Array]$Values = $Out | ForEach-Object {
|
||||
#Split the output in name and description
|
||||
`+" $Name, $Description = $_.Split(\"`t\",2)"+`
|
||||
__%[1]s_debug "Name: $Name Description: $Description"
|
||||
|
@ -182,6 +192,11 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
|||
}
|
||||
}
|
||||
|
||||
# we sort the values in ascending order by name if keep order isn't passed
|
||||
if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) {
|
||||
$Values = $Values | Sort-Object -Property Name
|
||||
}
|
||||
|
||||
if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
|
||||
__%[1]s_debug "ShellCompDirectiveNoFileComp is called"
|
||||
|
||||
|
@ -267,7 +282,7 @@ filter __%[1]s_escapeStringWithSpecialChars {
|
|||
Register-ArgumentCompleter -CommandName '%[1]s' -ScriptBlock $__%[2]sCompleterBlock
|
||||
`, name, nameForVar, compCmd,
|
||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))
|
||||
}
|
||||
|
||||
func (c *Command) genPowerShellCompletion(w io.Writer, includeDesc bool) error {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
## Projects using Cobra
|
||||
|
||||
- [Allero](https://github.com/allero-io/allero)
|
||||
- [Arewefastyet](https://benchmark.vitess.io)
|
||||
- [Arduino CLI](https://github.com/arduino/arduino-cli)
|
||||
- [Bleve](https://blevesearch.com/)
|
||||
- [Cilium](https://cilium.io/)
|
||||
- [CloudQuery](https://github.com/cloudquery/cloudquery)
|
||||
- [CockroachDB](https://www.cockroachlabs.com/)
|
||||
- [Constellation](https://github.com/edgelesssys/constellation)
|
||||
- [Cosmos SDK](https://github.com/cosmos/cosmos-sdk)
|
||||
- [Datree](https://github.com/datreeio/datree)
|
||||
- [Delve](https://github.com/derekparker/delve)
|
||||
|
@ -25,7 +27,7 @@
|
|||
- [Istio](https://istio.io)
|
||||
- [Kool](https://github.com/kool-dev/kool)
|
||||
- [Kubernetes](https://kubernetes.io/)
|
||||
- [Kubescape](https://github.com/armosec/kubescape)
|
||||
- [Kubescape](https://github.com/kubescape/kubescape)
|
||||
- [KubeVirt](https://github.com/kubevirt/kubevirt)
|
||||
- [Linkerd](https://linkerd.io/)
|
||||
- [Mattermost-server](https://github.com/mattermost/mattermost-server)
|
||||
|
@ -51,10 +53,12 @@
|
|||
- [Random](https://github.com/erdaltsksn/random)
|
||||
- [Rclone](https://rclone.org/)
|
||||
- [Scaleway CLI](https://github.com/scaleway/scaleway-cli)
|
||||
- [Sia](https://github.com/SiaFoundation/siad)
|
||||
- [Skaffold](https://skaffold.dev/)
|
||||
- [Tendermint](https://github.com/tendermint/tendermint)
|
||||
- [Twitch CLI](https://github.com/twitchdev/twitch-cli)
|
||||
- [UpCloud CLI (`upctl`)](https://github.com/UpCloudLtd/upcloud-cli)
|
||||
- [Vitess](https://vitess.io)
|
||||
- VMware's [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) & [Tanzu Framework](https://github.com/vmware-tanzu/tanzu-framework)
|
||||
- [Werf](https://werf.io/)
|
||||
- [ZITADEL](https://github.com/zitadel/zitadel)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -71,7 +71,7 @@ PowerShell:
|
|||
`,cmd.Root().Name()),
|
||||
DisableFlagsInUseLine: true,
|
||||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
||||
Args: cobra.ExactValidArgs(1),
|
||||
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
switch args[0] {
|
||||
case "bash":
|
||||
|
@ -162,16 +162,7 @@ cmd := &cobra.Command{
|
|||
}
|
||||
```
|
||||
|
||||
The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by
|
||||
the completion algorithm if entered manually, e.g. in:
|
||||
|
||||
```bash
|
||||
$ kubectl get rc [tab][tab]
|
||||
backend frontend database
|
||||
```
|
||||
|
||||
Note that without declaring `rc` as an alias, the completion algorithm would not know to show the list of
|
||||
replication controllers following `rc`.
|
||||
The aliases are shown to the user on tab completion only if no completions were found within sub-commands or `ValidArgs`.
|
||||
|
||||
### Dynamic completion of nouns
|
||||
|
||||
|
@ -237,6 +228,10 @@ ShellCompDirectiveFilterFileExt
|
|||
// return []string{"themes"}, ShellCompDirectiveFilterDirs
|
||||
//
|
||||
ShellCompDirectiveFilterDirs
|
||||
|
||||
// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order
|
||||
// in which the completions are provided
|
||||
ShellCompDirectiveKeepOrder
|
||||
```
|
||||
|
||||
***Note***: When using the `ValidArgsFunction`, Cobra will call your registered function after having parsed all flags and arguments provided in the command-line. You therefore don't need to do this parsing yourself. For example, when a user calls `helm status --namespace my-rook-ns [tab][tab]`, Cobra will call your registered `ValidArgsFunction` after having parsed the `--namespace` flag, as it would have done when calling the `RunE` function.
|
||||
|
@ -385,6 +380,19 @@ or
|
|||
```go
|
||||
ValidArgs: []string{"bash\tCompletions for bash", "zsh\tCompletions for zsh"}
|
||||
```
|
||||
|
||||
If you don't want to show descriptions in the completions, you can add `--no-descriptions` to the default `completion` command to disable them, like:
|
||||
|
||||
```bash
|
||||
$ source <(helm completion bash)
|
||||
$ helm completion [tab][tab]
|
||||
bash (generate autocompletion script for bash) powershell (generate autocompletion script for powershell)
|
||||
fish (generate autocompletion script for fish) zsh (generate autocompletion script for zsh)
|
||||
|
||||
$ source <(helm completion bash --no-descriptions)
|
||||
$ helm completion [tab][tab]
|
||||
bash fish powershell zsh
|
||||
```
|
||||
## Bash completions
|
||||
|
||||
### Dependencies
|
||||
|
|
|
@ -188,6 +188,37 @@ var versionCmd = &cobra.Command{
|
|||
}
|
||||
```
|
||||
|
||||
### Organizing subcommands
|
||||
|
||||
A command may have subcommands which in turn may have other subcommands. This is achieved by using
|
||||
`AddCommand`. In some cases, especially in larger applications, each subcommand may be defined in
|
||||
its own go package.
|
||||
|
||||
The suggested approach is for the parent command to use `AddCommand` to add its most immediate
|
||||
subcommands. For example, consider the following directory structure:
|
||||
|
||||
```text
|
||||
├── cmd
|
||||
│ ├── root.go
|
||||
│ └── sub1
|
||||
│ ├── sub1.go
|
||||
│ └── sub2
|
||||
│ ├── leafA.go
|
||||
│ ├── leafB.go
|
||||
│ └── sub2.go
|
||||
└── main.go
|
||||
```
|
||||
|
||||
In this case:
|
||||
|
||||
* The `init` function of `root.go` adds the command defined in `sub1.go` to the root command.
|
||||
* The `init` function of `sub1.go` adds the command defined in `sub2.go` to the sub1 command.
|
||||
* The `init` function of `sub2.go` adds the commands defined in `leafA.go` and `leafB.go` to the
|
||||
sub2 command.
|
||||
|
||||
This approach ensures the subcommands are always included at compile time while avoiding cyclic
|
||||
references.
|
||||
|
||||
### Returning and handling errors
|
||||
|
||||
If you wish to return an error to the caller of a command, `RunE` can be used.
|
||||
|
@ -313,8 +344,8 @@ rootCmd.MarkFlagsRequiredTogether("username", "password")
|
|||
You can also prevent different flags from being provided together if they represent mutually
|
||||
exclusive options such as specifying an output format as either `--json` or `--yaml` but never both:
|
||||
```go
|
||||
rootCmd.Flags().BoolVar(&u, "json", false, "Output in JSON")
|
||||
rootCmd.Flags().BoolVar(&pw, "yaml", false, "Output in YAML")
|
||||
rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
|
||||
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
|
||||
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")
|
||||
```
|
||||
|
||||
|
@ -349,7 +380,7 @@ shown below:
|
|||
```go
|
||||
var cmd = &cobra.Command{
|
||||
Short: "hello",
|
||||
Args: MatchAll(ExactArgs(2), OnlyValidArgs),
|
||||
Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("Hello, World!")
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013-2022 The Cobra Authors
|
||||
// Copyright 2013-2023 The Cobra Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -90,6 +90,7 @@ func genZshComp(buf io.StringWriter, name string, includeDesc bool) {
|
|||
compCmd = ShellCompNoDescRequestCmd
|
||||
}
|
||||
WriteStringAndCheck(buf, fmt.Sprintf(`#compdef %[1]s
|
||||
compdef _%[1]s %[1]s
|
||||
|
||||
# zsh completion for %-36[1]s -*- shell-script -*-
|
||||
|
||||
|
@ -108,8 +109,9 @@ _%[1]s()
|
|||
local shellCompDirectiveNoFileComp=%[5]d
|
||||
local shellCompDirectiveFilterFileExt=%[6]d
|
||||
local shellCompDirectiveFilterDirs=%[7]d
|
||||
local shellCompDirectiveKeepOrder=%[8]d
|
||||
|
||||
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace
|
||||
local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
|
||||
local -a completions
|
||||
|
||||
__%[1]s_debug "\n========= starting completion logic =========="
|
||||
|
@ -177,7 +179,7 @@ _%[1]s()
|
|||
return
|
||||
fi
|
||||
|
||||
local activeHelpMarker="%[8]s"
|
||||
local activeHelpMarker="%[9]s"
|
||||
local endIndex=${#activeHelpMarker}
|
||||
local startIndex=$((${#activeHelpMarker}+1))
|
||||
local hasActiveHelp=0
|
||||
|
@ -227,6 +229,11 @@ _%[1]s()
|
|||
noSpace="-S ''"
|
||||
fi
|
||||
|
||||
if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
|
||||
__%[1]s_debug "Activating keep order."
|
||||
keepOrder="-V"
|
||||
fi
|
||||
|
||||
if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
|
||||
# File extension filtering
|
||||
local filteringCmd
|
||||
|
@ -262,7 +269,7 @@ _%[1]s()
|
|||
return $result
|
||||
else
|
||||
__%[1]s_debug "Calling _describe"
|
||||
if eval _describe "completions" completions $flagPrefix $noSpace; then
|
||||
if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then
|
||||
__%[1]s_debug "_describe found some completions"
|
||||
|
||||
# Return the success of having called _describe
|
||||
|
@ -296,6 +303,6 @@ if [ "$funcstack[1]" = "_%[1]s" ]; then
|
|||
fi
|
||||
`, name, compCmd,
|
||||
ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs,
|
||||
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,
|
||||
activeHelpMarker))
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ github.com/rivo/uniseg
|
|||
# github.com/sirupsen/logrus v1.9.0
|
||||
## explicit; go 1.13
|
||||
github.com/sirupsen/logrus
|
||||
# github.com/spf13/cobra v1.6.1
|
||||
# github.com/spf13/cobra v1.7.0
|
||||
## explicit; go 1.15
|
||||
github.com/spf13/cobra
|
||||
# github.com/spf13/pflag v1.0.5
|
||||
|
|
Loading…
Reference in New Issue