forked from TrueCloudLab/rclone
Switch to using the dep tool and update all the dependencies
This commit is contained in:
parent
5135ff73cb
commit
98c2d2c41b
5321 changed files with 4483201 additions and 5922 deletions
543
vendor/github.com/spf13/cobra/command.go
generated
vendored
543
vendor/github.com/spf13/cobra/command.go
generated
vendored
|
@ -11,8 +11,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
|
||||
//In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
|
||||
// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
|
||||
// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
|
||||
package cobra
|
||||
|
||||
import (
|
||||
|
@ -28,108 +28,147 @@ import (
|
|||
)
|
||||
|
||||
// Command is just that, a command for your application.
|
||||
// eg. 'go run' ... 'run' is the command. Cobra requires
|
||||
// E.g. 'go run ...' - 'run' is the command. Cobra requires
|
||||
// you to define the usage and description as part of your command
|
||||
// definition to ensure usability.
|
||||
type Command struct {
|
||||
// Name is the command name, usually the executable's name.
|
||||
name string
|
||||
// The one-line usage message.
|
||||
// Use is the one-line usage message.
|
||||
Use string
|
||||
// An array of aliases that can be used instead of the first word in Use.
|
||||
|
||||
// Aliases is an array of aliases that can be used instead of the first word in Use.
|
||||
Aliases []string
|
||||
// An array of command names for which this command will be suggested - similar to aliases but only suggests.
|
||||
|
||||
// SuggestFor is an array of command names for which this command will be suggested -
|
||||
// similar to aliases but only suggests.
|
||||
SuggestFor []string
|
||||
// The short description shown in the 'help' output.
|
||||
|
||||
// Short is the short description shown in the 'help' output.
|
||||
Short string
|
||||
// The long message shown in the 'help <this-command>' output.
|
||||
|
||||
// Long is the long message shown in the 'help <this-command>' output.
|
||||
Long string
|
||||
// Examples of how to use the command
|
||||
|
||||
// Example is examples of how to use the command.
|
||||
Example string
|
||||
// List of all valid non-flag arguments that are accepted in bash completions
|
||||
|
||||
// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
|
||||
ValidArgs []string
|
||||
// List of aliases for ValidArgs. These are not suggested to the user in the bash
|
||||
// completion, but accepted if entered manually.
|
||||
|
||||
// ArgAliases is List of aliases for ValidArgs.
|
||||
// These are not suggested to the user in the bash completion,
|
||||
// but accepted if entered manually.
|
||||
ArgAliases []string
|
||||
// Custom functions used by the bash autocompletion generator
|
||||
|
||||
// BashCompletionFunction is custom functions used by the bash autocompletion generator.
|
||||
BashCompletionFunction string
|
||||
// Is this command deprecated and should print this string when used?
|
||||
|
||||
// Deprecated defines, if this command is deprecated and should print this string when used.
|
||||
Deprecated string
|
||||
// Is this command hidden and should NOT show up in the list of available commands?
|
||||
|
||||
// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
|
||||
Hidden bool
|
||||
|
||||
// Annotations are key/value pairs that can be used by applications to identify or
|
||||
// group commands
|
||||
// group commands.
|
||||
Annotations map[string]string
|
||||
// Full set of flags
|
||||
flags *flag.FlagSet
|
||||
// Set of flags childrens of this command will inherit
|
||||
pflags *flag.FlagSet
|
||||
// Flags that are declared specifically by this command (not inherited).
|
||||
lflags *flag.FlagSet
|
||||
// SilenceErrors is an option to quiet errors down stream
|
||||
SilenceErrors bool
|
||||
// Silence Usage is an option to silence usage when an error occurs.
|
||||
SilenceUsage bool
|
||||
|
||||
// The *Run functions are executed in the following order:
|
||||
// * PersistentPreRun()
|
||||
// * PreRun()
|
||||
// * Run()
|
||||
// * PostRun()
|
||||
// * PersistentPostRun()
|
||||
// All functions get the same args, the arguments after the command name
|
||||
// PersistentPreRun: children of this command will inherit and execute
|
||||
// All functions get the same args, the arguments after the command name.
|
||||
//
|
||||
// PersistentPreRun: children of this command will inherit and execute.
|
||||
PersistentPreRun func(cmd *Command, args []string)
|
||||
// PersistentPreRunE: PersistentPreRun but returns an error
|
||||
// PersistentPreRunE: PersistentPreRun but returns an error.
|
||||
PersistentPreRunE func(cmd *Command, args []string) error
|
||||
// PreRun: children of this command will not inherit.
|
||||
PreRun func(cmd *Command, args []string)
|
||||
// PreRunE: PreRun but returns an error
|
||||
// PreRunE: PreRun but returns an error.
|
||||
PreRunE func(cmd *Command, args []string) error
|
||||
// Run: Typically the actual work function. Most commands will only implement this
|
||||
// Run: Typically the actual work function. Most commands will only implement this.
|
||||
Run func(cmd *Command, args []string)
|
||||
// RunE: Run but returns an error
|
||||
// RunE: Run but returns an error.
|
||||
RunE func(cmd *Command, args []string) error
|
||||
// PostRun: run after the Run command.
|
||||
PostRun func(cmd *Command, args []string)
|
||||
// PostRunE: PostRun but returns an error
|
||||
// PostRunE: PostRun but returns an error.
|
||||
PostRunE func(cmd *Command, args []string) error
|
||||
// PersistentPostRun: children of this command will inherit and execute after PostRun
|
||||
// PersistentPostRun: children of this command will inherit and execute after PostRun.
|
||||
PersistentPostRun func(cmd *Command, args []string)
|
||||
// PersistentPostRunE: PersistentPostRun but returns an error
|
||||
// PersistentPostRunE: PersistentPostRun but returns an error.
|
||||
PersistentPostRunE func(cmd *Command, args []string) error
|
||||
// DisableAutoGenTag remove
|
||||
|
||||
// SilenceErrors is an option to quiet errors down stream.
|
||||
SilenceErrors bool
|
||||
|
||||
// SilenceUsage is an option to silence usage when an error occurs.
|
||||
SilenceUsage bool
|
||||
|
||||
// DisableFlagParsing disables the flag parsing.
|
||||
// If this is true all flags will be passed to the command as arguments.
|
||||
DisableFlagParsing bool
|
||||
|
||||
// DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
|
||||
// will be printed by generating docs for this command.
|
||||
DisableAutoGenTag bool
|
||||
// Commands is the list of commands supported by this program.
|
||||
|
||||
// DisableSuggestions disables the suggestions based on Levenshtein distance
|
||||
// that go along with 'unknown command' messages.
|
||||
DisableSuggestions bool
|
||||
// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
|
||||
// Must be > 0.
|
||||
SuggestionsMinimumDistance int
|
||||
|
||||
// name is the command name, usually the executable's name.
|
||||
name string
|
||||
// commands is the list of commands supported by this program.
|
||||
commands []*Command
|
||||
// Parent Command for this command
|
||||
// parent is a parent command for this command.
|
||||
parent *Command
|
||||
// max lengths of commands' string lengths for use in padding
|
||||
// Max lengths of commands' string lengths for use in padding.
|
||||
commandsMaxUseLen int
|
||||
commandsMaxCommandPathLen int
|
||||
commandsMaxNameLen int
|
||||
// is commands slice are sorted or not
|
||||
// commandsAreSorted defines, if command slice are sorted or not.
|
||||
commandsAreSorted bool
|
||||
|
||||
// args is actual args parsed from flags.
|
||||
args []string
|
||||
// flagErrorBuf contains all error messages from pflag.
|
||||
flagErrorBuf *bytes.Buffer
|
||||
|
||||
args []string // actual args parsed from flags
|
||||
output *io.Writer // out writer if set in SetOutput(w)
|
||||
usageFunc func(*Command) error // Usage can be defined by application
|
||||
usageTemplate string // Can be defined by Application
|
||||
flagErrorFunc func(*Command, error) error
|
||||
helpTemplate string // Can be defined by Application
|
||||
helpFunc func(*Command, []string) // Help can be defined by application
|
||||
helpCommand *Command // The help command
|
||||
// The global normalization function that we can use on every pFlag set and children commands
|
||||
// flags is full set of flags.
|
||||
flags *flag.FlagSet
|
||||
// pflags contains persistent flags.
|
||||
pflags *flag.FlagSet
|
||||
// lflags contains local flags.
|
||||
lflags *flag.FlagSet
|
||||
// iflags contains inherited flags.
|
||||
iflags *flag.FlagSet
|
||||
// parentsPflags is all persistent flags of cmd's parents.
|
||||
parentsPflags *flag.FlagSet
|
||||
// globNormFunc is the global normalization function
|
||||
// that we can use on every pflag set and children commands
|
||||
globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
|
||||
|
||||
// Disable the suggestions based on Levenshtein distance that go along with 'unknown command' messages
|
||||
DisableSuggestions bool
|
||||
// If displaying suggestions, allows to set the minimum levenshtein distance to display, must be > 0
|
||||
SuggestionsMinimumDistance int
|
||||
|
||||
// Disable the flag parsing. If this is true all flags will be passed to the command as arguments.
|
||||
DisableFlagParsing bool
|
||||
// output is an output writer defined by user.
|
||||
output io.Writer
|
||||
// usageFunc is usage func defined by user.
|
||||
usageFunc func(*Command) error
|
||||
// usageTemplate is usage template defined by user.
|
||||
usageTemplate string
|
||||
// flagErrorFunc is func defined by user and it's called when the parsing of
|
||||
// flags returns an error.
|
||||
flagErrorFunc func(*Command, error) error
|
||||
// helpTemplate is help template defined by user.
|
||||
helpTemplate string
|
||||
// helpFunc is help func defined by user.
|
||||
helpFunc func(*Command, []string)
|
||||
// helpCommand is command with usage 'help'. If it's not defined by user,
|
||||
// cobra uses default help command.
|
||||
helpCommand *Command
|
||||
}
|
||||
|
||||
// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
|
||||
|
@ -141,7 +180,7 @@ func (c *Command) SetArgs(a []string) {
|
|||
// SetOutput sets the destination for usage and error messages.
|
||||
// If output is nil, os.Stderr is used.
|
||||
func (c *Command) SetOutput(output io.Writer) {
|
||||
c.output = &output
|
||||
c.output = output
|
||||
}
|
||||
|
||||
// SetUsageFunc sets usage function. Usage can be defined by application.
|
||||
|
@ -155,12 +194,12 @@ func (c *Command) SetUsageTemplate(s string) {
|
|||
}
|
||||
|
||||
// SetFlagErrorFunc sets a function to generate an error when flag parsing
|
||||
// fails
|
||||
// fails.
|
||||
func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
|
||||
c.flagErrorFunc = f
|
||||
}
|
||||
|
||||
// SetHelpFunc sets help function. Can be defined by Application
|
||||
// SetHelpFunc sets help function. Can be defined by Application.
|
||||
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
|
||||
c.helpFunc = f
|
||||
}
|
||||
|
@ -187,7 +226,7 @@ func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string
|
|||
}
|
||||
}
|
||||
|
||||
// OutOrStdout returns output to stdout
|
||||
// OutOrStdout returns output to stdout.
|
||||
func (c *Command) OutOrStdout() io.Writer {
|
||||
return c.getOut(os.Stdout)
|
||||
}
|
||||
|
@ -199,7 +238,7 @@ func (c *Command) OutOrStderr() io.Writer {
|
|||
|
||||
func (c *Command) getOut(def io.Writer) io.Writer {
|
||||
if c.output != nil {
|
||||
return *c.output
|
||||
return c.output
|
||||
}
|
||||
if c.HasParent() {
|
||||
return c.parent.getOut(def)
|
||||
|
@ -213,9 +252,8 @@ func (c *Command) UsageFunc() (f func(*Command) error) {
|
|||
if c.usageFunc != nil {
|
||||
return c.usageFunc
|
||||
}
|
||||
|
||||
if c.HasParent() {
|
||||
return c.parent.UsageFunc()
|
||||
return c.Parent().UsageFunc()
|
||||
}
|
||||
return func(c *Command) error {
|
||||
c.mergePersistentFlags()
|
||||
|
@ -237,10 +275,13 @@ func (c *Command) Usage() error {
|
|||
// HelpFunc returns either the function set by SetHelpFunc for this command
|
||||
// or a parent, or it returns a function with default help behavior.
|
||||
func (c *Command) HelpFunc() func(*Command, []string) {
|
||||
if helpFunc := c.checkHelpFunc(); helpFunc != nil {
|
||||
return helpFunc
|
||||
if c.helpFunc != nil {
|
||||
return c.helpFunc
|
||||
}
|
||||
return func(*Command, []string) {
|
||||
if c.HasParent() {
|
||||
return c.Parent().HelpFunc()
|
||||
}
|
||||
return func(c *Command, a []string) {
|
||||
c.mergePersistentFlags()
|
||||
err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
|
||||
if err != nil {
|
||||
|
@ -249,20 +290,6 @@ func (c *Command) HelpFunc() func(*Command, []string) {
|
|||
}
|
||||
}
|
||||
|
||||
// checkHelpFunc checks if there is helpFunc in ancestors of c.
|
||||
func (c *Command) checkHelpFunc() func(*Command, []string) {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
if c.helpFunc != nil {
|
||||
return c.helpFunc
|
||||
}
|
||||
if c.HasParent() {
|
||||
return c.parent.checkHelpFunc()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Help puts out the help for the command.
|
||||
// Used when a user calls help [command].
|
||||
// Can be defined by user by overriding HelpFunc.
|
||||
|
@ -337,27 +364,26 @@ func (c *Command) UsageTemplate() string {
|
|||
return c.parent.UsageTemplate()
|
||||
}
|
||||
return `Usage:{{if .Runnable}}
|
||||
{{if .HasAvailableFlags}}{{appendIfNotPresent .UseLine "[flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
|
||||
{{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}}
|
||||
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
|
||||
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
|
||||
|
||||
Aliases:
|
||||
{{.NameAndAliases}}
|
||||
{{end}}{{if .HasExample}}
|
||||
{{.NameAndAliases}}{{end}}{{if .HasExample}}
|
||||
|
||||
Examples:
|
||||
{{ .Example }}{{end}}{{ if .HasAvailableSubCommands}}
|
||||
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
|
||||
|
||||
Available Commands:{{range .Commands}}{{if .IsAvailableCommand}}
|
||||
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasAvailableLocalFlags}}
|
||||
Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
|
||||
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
|
||||
|
||||
Flags:
|
||||
{{.LocalFlags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasAvailableInheritedFlags}}
|
||||
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
|
||||
|
||||
Global Flags:
|
||||
{{.InheritedFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasHelpSubCommands}}
|
||||
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
|
||||
|
||||
Additional help topics:{{range .Commands}}{{if .IsHelpCommand}}
|
||||
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasAvailableSubCommands }}
|
||||
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
|
||||
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
|
||||
|
||||
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
|
||||
`
|
||||
|
@ -372,69 +398,68 @@ func (c *Command) HelpTemplate() string {
|
|||
if c.HasParent() {
|
||||
return c.parent.HelpTemplate()
|
||||
}
|
||||
return `{{with or .Long .Short }}{{. | trim}}
|
||||
return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}
|
||||
|
||||
{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
|
||||
}
|
||||
|
||||
// Really only used when casting a command to a commander.
|
||||
func (c *Command) resetChildrensParents() {
|
||||
for _, x := range c.commands {
|
||||
x.parent = c
|
||||
}
|
||||
}
|
||||
|
||||
func hasNoOptDefVal(name string, f *flag.FlagSet) bool {
|
||||
flag := f.Lookup(name)
|
||||
func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
|
||||
flag := fs.Lookup(name)
|
||||
if flag == nil {
|
||||
return false
|
||||
}
|
||||
return len(flag.NoOptDefVal) > 0
|
||||
return flag.NoOptDefVal != ""
|
||||
}
|
||||
|
||||
func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
|
||||
result := false
|
||||
fs.VisitAll(func(flag *flag.Flag) {
|
||||
if flag.Shorthand == name && len(flag.NoOptDefVal) > 0 {
|
||||
result = true
|
||||
}
|
||||
})
|
||||
return result
|
||||
if len(name) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
flag := fs.ShorthandLookup(name[:1])
|
||||
if flag == nil {
|
||||
return false
|
||||
}
|
||||
return flag.NoOptDefVal != ""
|
||||
}
|
||||
|
||||
func stripFlags(args []string, c *Command) []string {
|
||||
if len(args) < 1 {
|
||||
if len(args) == 0 {
|
||||
return args
|
||||
}
|
||||
c.mergePersistentFlags()
|
||||
|
||||
commands := []string{}
|
||||
|
||||
inQuote := false
|
||||
inFlag := false
|
||||
for _, y := range args {
|
||||
flags := c.Flags()
|
||||
|
||||
Loop:
|
||||
for len(args) > 0 {
|
||||
s := args[0]
|
||||
args = args[1:]
|
||||
if !inQuote {
|
||||
switch {
|
||||
case strings.HasPrefix(y, "\""):
|
||||
case strings.HasPrefix(s, "\"") || strings.Contains(s, "=\""):
|
||||
inQuote = true
|
||||
case strings.Contains(y, "=\""):
|
||||
inQuote = true
|
||||
case strings.HasPrefix(y, "--") && !strings.Contains(y, "="):
|
||||
// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
|
||||
inFlag = !hasNoOptDefVal(y[2:], c.Flags())
|
||||
case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !shortHasNoOptDefVal(y[1:], c.Flags()):
|
||||
inFlag = true
|
||||
case inFlag:
|
||||
inFlag = false
|
||||
case y == "":
|
||||
// strip empty commands, as the go tests expect this to be ok....
|
||||
case !strings.HasPrefix(y, "-"):
|
||||
commands = append(commands, y)
|
||||
inFlag = false
|
||||
case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
|
||||
// If '--flag arg' then
|
||||
// delete arg from args.
|
||||
fallthrough // (do the same as below)
|
||||
case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
|
||||
// If '-f arg' then
|
||||
// delete 'arg' from args or break the loop if len(args) <= 1.
|
||||
if len(args) <= 1 {
|
||||
break Loop
|
||||
} else {
|
||||
args = args[1:]
|
||||
continue
|
||||
}
|
||||
case s != "" && !strings.HasPrefix(s, "-"):
|
||||
commands = append(commands, s)
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasSuffix(y, "\"") && !strings.HasSuffix(y, "\\\"") {
|
||||
if strings.HasSuffix(s, "\"") && !strings.HasSuffix(s, "\\\"") {
|
||||
inQuote = false
|
||||
}
|
||||
}
|
||||
|
@ -547,32 +572,18 @@ func (c *Command) SuggestionsFor(typedName string) []string {
|
|||
|
||||
// VisitParents visits all parents of the command and invokes fn on each parent.
|
||||
func (c *Command) VisitParents(fn func(*Command)) {
|
||||
var traverse func(*Command) *Command
|
||||
|
||||
traverse = func(x *Command) *Command {
|
||||
if x != c {
|
||||
fn(x)
|
||||
}
|
||||
if x.HasParent() {
|
||||
return traverse(x.parent)
|
||||
}
|
||||
return x
|
||||
if c.HasParent() {
|
||||
fn(c.Parent())
|
||||
c.Parent().VisitParents(fn)
|
||||
}
|
||||
traverse(c)
|
||||
}
|
||||
|
||||
// Root finds root command.
|
||||
func (c *Command) Root() *Command {
|
||||
var findRoot func(*Command) *Command
|
||||
|
||||
findRoot = func(x *Command) *Command {
|
||||
if x.HasParent() {
|
||||
return findRoot(x.parent)
|
||||
}
|
||||
return x
|
||||
if c.HasParent() {
|
||||
return c.Parent().Root()
|
||||
}
|
||||
|
||||
return findRoot(c)
|
||||
return c
|
||||
}
|
||||
|
||||
// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
|
||||
|
@ -594,18 +605,19 @@ func (c *Command) execute(a []string) (err error) {
|
|||
|
||||
// initialize help flag as the last point possible to allow for user
|
||||
// overriding
|
||||
c.initHelpFlag()
|
||||
c.InitDefaultHelpFlag()
|
||||
|
||||
err = c.ParseFlags(a)
|
||||
if err != nil {
|
||||
return c.FlagErrorFunc()(c, err)
|
||||
}
|
||||
// If help is called, regardless of other flags, return we want help
|
||||
|
||||
// If help is called, regardless of other flags, return we want help.
|
||||
// Also say we need help if the command isn't runnable.
|
||||
helpVal, err := c.Flags().GetBool("help")
|
||||
if err != nil {
|
||||
// should be impossible to get here as we always declare a help
|
||||
// flag in initHelpFlag()
|
||||
// flag in InitDefaultHelpFlag()
|
||||
c.Println("\"help\" flag declared as non-bool. Please correct your code")
|
||||
return err
|
||||
}
|
||||
|
@ -675,17 +687,6 @@ func (c *Command) preRun() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Command) errorMsgFromParse() string {
|
||||
s := c.flagErrorBuf.String()
|
||||
|
||||
x := strings.Split(s, "\n")
|
||||
|
||||
if len(x) > 0 {
|
||||
return x[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Execute Call execute to use the args (os.Args[1:] by default)
|
||||
// and run through the command tree finding appropriate matches
|
||||
// for commands and then corresponding flags.
|
||||
|
@ -696,7 +697,6 @@ func (c *Command) Execute() error {
|
|||
|
||||
// ExecuteC executes the command.
|
||||
func (c *Command) ExecuteC() (cmd *Command, err error) {
|
||||
|
||||
// Regardless of what command execute is called on, run on Root only
|
||||
if c.HasParent() {
|
||||
return c.Root().ExecuteC()
|
||||
|
@ -757,10 +757,19 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
return cmd, nil
|
||||
}
|
||||
|
||||
func (c *Command) initHelpFlag() {
|
||||
// InitDefaultHelpFlag adds default help flag to c.
|
||||
// It is called automatically by executing the c or by calling help and usage.
|
||||
// If c already has help flag, it will do nothing.
|
||||
func (c *Command) InitDefaultHelpFlag() {
|
||||
c.mergePersistentFlags()
|
||||
if c.Flags().Lookup("help") == nil {
|
||||
c.Flags().BoolP("help", "h", false, "help for "+c.Name())
|
||||
usage := "help for "
|
||||
if c.Name() == "" {
|
||||
usage += "this command"
|
||||
} else {
|
||||
usage += c.Name()
|
||||
}
|
||||
c.Flags().BoolP("help", "h", false, usage)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,14 +790,16 @@ func (c *Command) initHelpCmd() {
|
|||
Run: func(c *Command, args []string) {
|
||||
cmd, _, e := c.Root().Find(args)
|
||||
if cmd == nil || e != nil {
|
||||
c.Printf("Unknown help topic %#q.", args)
|
||||
c.Printf("Unknown help topic %#q\n", args)
|
||||
c.Root().Usage()
|
||||
} else {
|
||||
cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
|
||||
cmd.Help()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
c.RemoveCommand(c.helpCommand)
|
||||
c.AddCommand(c.helpCommand)
|
||||
}
|
||||
|
||||
|
@ -796,6 +807,7 @@ func (c *Command) initHelpCmd() {
|
|||
func (c *Command) ResetCommands() {
|
||||
c.commands = nil
|
||||
c.helpCommand = nil
|
||||
c.parentsPflags = nil
|
||||
}
|
||||
|
||||
// Sorts commands by their names.
|
||||
|
@ -885,34 +897,34 @@ func (c *Command) Print(i ...interface{}) {
|
|||
|
||||
// Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
|
||||
func (c *Command) Println(i ...interface{}) {
|
||||
str := fmt.Sprintln(i...)
|
||||
c.Print(str)
|
||||
c.Print(fmt.Sprintln(i...))
|
||||
}
|
||||
|
||||
// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
|
||||
func (c *Command) Printf(format string, i ...interface{}) {
|
||||
str := fmt.Sprintf(format, i...)
|
||||
c.Print(str)
|
||||
c.Print(fmt.Sprintf(format, i...))
|
||||
}
|
||||
|
||||
// CommandPath returns the full path to this command.
|
||||
func (c *Command) CommandPath() string {
|
||||
str := c.Name()
|
||||
x := c
|
||||
for x.HasParent() {
|
||||
str = x.parent.Name() + " " + str
|
||||
x = x.parent
|
||||
if c.HasParent() {
|
||||
return c.Parent().CommandPath() + " " + c.Name()
|
||||
}
|
||||
return str
|
||||
return c.Name()
|
||||
}
|
||||
|
||||
// UseLine puts out the full usage for a given command (including parents).
|
||||
func (c *Command) UseLine() string {
|
||||
str := ""
|
||||
var useline string
|
||||
if c.HasParent() {
|
||||
str = c.parent.CommandPath() + " "
|
||||
useline = c.parent.CommandPath() + " " + c.Use
|
||||
} else {
|
||||
useline = c.Use
|
||||
}
|
||||
return str + c.Use
|
||||
if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
|
||||
useline += " [flags]"
|
||||
}
|
||||
return useline
|
||||
}
|
||||
|
||||
// DebugFlags used to determine which flags have been assigned to which commands
|
||||
|
@ -927,12 +939,8 @@ func (c *Command) DebugFlags() {
|
|||
}
|
||||
if x.HasFlags() {
|
||||
x.flags.VisitAll(func(f *flag.Flag) {
|
||||
if x.HasPersistentFlags() {
|
||||
if x.persistentFlag(f.Name) == nil {
|
||||
c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
|
||||
} else {
|
||||
c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]")
|
||||
}
|
||||
if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {
|
||||
c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]")
|
||||
} else {
|
||||
c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
|
||||
}
|
||||
|
@ -962,15 +970,14 @@ func (c *Command) DebugFlags() {
|
|||
|
||||
// Name returns the command's name: the first word in the use line.
|
||||
func (c *Command) Name() string {
|
||||
if c.name != "" {
|
||||
return c.name
|
||||
if c.name == "" {
|
||||
name := c.Use
|
||||
i := strings.Index(name, " ")
|
||||
if i >= 0 {
|
||||
name = name[:i]
|
||||
}
|
||||
c.name = name
|
||||
}
|
||||
name := c.Use
|
||||
i := strings.Index(name, " ")
|
||||
if i >= 0 {
|
||||
name = name[:i]
|
||||
}
|
||||
c.name = name
|
||||
return c.name
|
||||
}
|
||||
|
||||
|
@ -1022,11 +1029,12 @@ func (c *Command) IsAvailableCommand() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// IsHelpCommand determines if a command is a 'help' command; a help command is
|
||||
// determined by the fact that it is NOT runnable/hidden/deprecated, and has no
|
||||
// sub commands that are runnable/hidden/deprecated.
|
||||
func (c *Command) IsHelpCommand() bool {
|
||||
|
||||
// IsAdditionalHelpTopicCommand determines if a command is an additional
|
||||
// help topic command; additional help topic command is determined by the
|
||||
// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that
|
||||
// are runnable/hidden/deprecated.
|
||||
// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.
|
||||
func (c *Command) IsAdditionalHelpTopicCommand() bool {
|
||||
// if a command is runnable, deprecated, or hidden it is not a 'help' command
|
||||
if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
|
||||
return false
|
||||
|
@ -1034,7 +1042,7 @@ func (c *Command) IsHelpCommand() bool {
|
|||
|
||||
// if any non-help sub commands are found, the command is not a 'help' command
|
||||
for _, sub := range c.commands {
|
||||
if !sub.IsHelpCommand() {
|
||||
if !sub.IsAdditionalHelpTopicCommand() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -1047,10 +1055,9 @@ func (c *Command) IsHelpCommand() bool {
|
|||
// that need to be shown in the usage/help default template under 'additional help
|
||||
// topics'.
|
||||
func (c *Command) HasHelpSubCommands() bool {
|
||||
|
||||
// return true on the first found available 'help' sub command
|
||||
for _, sub := range c.commands {
|
||||
if sub.IsHelpCommand() {
|
||||
if sub.IsAdditionalHelpTopicCommand() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -1062,7 +1069,6 @@ func (c *Command) HasHelpSubCommands() bool {
|
|||
// HasAvailableSubCommands determines if a command has available sub commands that
|
||||
// need to be shown in the usage/help default template under 'available commands'.
|
||||
func (c *Command) HasAvailableSubCommands() bool {
|
||||
|
||||
// return true on the first found available (non deprecated/help/hidden)
|
||||
// sub command
|
||||
for _, sub := range c.commands {
|
||||
|
@ -1096,6 +1102,7 @@ func (c *Command) Flags() *flag.FlagSet {
|
|||
}
|
||||
c.flags.SetOutput(c.flagErrorBuf)
|
||||
}
|
||||
|
||||
return c.flags
|
||||
}
|
||||
|
||||
|
@ -1116,47 +1123,44 @@ func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
|
|||
func (c *Command) LocalFlags() *flag.FlagSet {
|
||||
c.mergePersistentFlags()
|
||||
|
||||
local := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||
c.lflags.VisitAll(func(f *flag.Flag) {
|
||||
local.AddFlag(f)
|
||||
})
|
||||
if !c.HasParent() {
|
||||
flag.CommandLine.VisitAll(func(f *flag.Flag) {
|
||||
if local.Lookup(f.Name) == nil {
|
||||
local.AddFlag(f)
|
||||
}
|
||||
})
|
||||
if c.lflags == nil {
|
||||
c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||
if c.flagErrorBuf == nil {
|
||||
c.flagErrorBuf = new(bytes.Buffer)
|
||||
}
|
||||
c.lflags.SetOutput(c.flagErrorBuf)
|
||||
}
|
||||
return local
|
||||
c.lflags.SortFlags = c.Flags().SortFlags
|
||||
|
||||
addToLocal := func(f *flag.Flag) {
|
||||
if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
|
||||
c.lflags.AddFlag(f)
|
||||
}
|
||||
}
|
||||
c.Flags().VisitAll(addToLocal)
|
||||
c.PersistentFlags().VisitAll(addToLocal)
|
||||
return c.lflags
|
||||
}
|
||||
|
||||
// InheritedFlags returns all flags which were inherited from parents commands.
|
||||
func (c *Command) InheritedFlags() *flag.FlagSet {
|
||||
c.mergePersistentFlags()
|
||||
|
||||
inherited := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||
if c.iflags == nil {
|
||||
c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||
if c.flagErrorBuf == nil {
|
||||
c.flagErrorBuf = new(bytes.Buffer)
|
||||
}
|
||||
c.iflags.SetOutput(c.flagErrorBuf)
|
||||
}
|
||||
|
||||
local := c.LocalFlags()
|
||||
|
||||
var rmerge func(x *Command)
|
||||
|
||||
rmerge = func(x *Command) {
|
||||
if x.HasPersistentFlags() {
|
||||
x.PersistentFlags().VisitAll(func(f *flag.Flag) {
|
||||
if inherited.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
|
||||
inherited.AddFlag(f)
|
||||
}
|
||||
})
|
||||
c.parentsPflags.VisitAll(func(f *flag.Flag) {
|
||||
if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
|
||||
c.iflags.AddFlag(f)
|
||||
}
|
||||
if x.HasParent() {
|
||||
rmerge(x.parent)
|
||||
}
|
||||
}
|
||||
|
||||
if c.HasParent() {
|
||||
rmerge(c.parent)
|
||||
}
|
||||
|
||||
return inherited
|
||||
})
|
||||
return c.iflags
|
||||
}
|
||||
|
||||
// NonInheritedFlags returns all flags which were not inherited from parent commands.
|
||||
|
@ -1246,8 +1250,9 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
|
|||
flag = c.PersistentFlags().Lookup(name)
|
||||
}
|
||||
|
||||
if flag == nil && c.HasParent() {
|
||||
flag = c.parent.persistentFlag(name)
|
||||
if flag == nil {
|
||||
c.updateParentsPflags()
|
||||
flag = c.parentsPflags.Lookup(name)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -1267,41 +1272,27 @@ func (c *Command) Parent() *Command {
|
|||
return c.parent
|
||||
}
|
||||
|
||||
// mergePersistentFlags merges c.PersistentFlags() to c.Flags()
|
||||
// and adds missing persistent flags of all parents.
|
||||
func (c *Command) mergePersistentFlags() {
|
||||
var rmerge func(x *Command)
|
||||
|
||||
// Save the set of local flags
|
||||
if c.lflags == nil {
|
||||
c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||
if c.flagErrorBuf == nil {
|
||||
c.flagErrorBuf = new(bytes.Buffer)
|
||||
}
|
||||
c.lflags.SetOutput(c.flagErrorBuf)
|
||||
addtolocal := func(f *flag.Flag) {
|
||||
c.lflags.AddFlag(f)
|
||||
}
|
||||
c.Flags().VisitAll(addtolocal)
|
||||
c.PersistentFlags().VisitAll(addtolocal)
|
||||
}
|
||||
rmerge = func(x *Command) {
|
||||
if !x.HasParent() {
|
||||
flag.CommandLine.VisitAll(func(f *flag.Flag) {
|
||||
if x.PersistentFlags().Lookup(f.Name) == nil {
|
||||
x.PersistentFlags().AddFlag(f)
|
||||
}
|
||||
})
|
||||
}
|
||||
if x.HasPersistentFlags() {
|
||||
x.PersistentFlags().VisitAll(func(f *flag.Flag) {
|
||||
if c.Flags().Lookup(f.Name) == nil {
|
||||
c.Flags().AddFlag(f)
|
||||
}
|
||||
})
|
||||
}
|
||||
if x.HasParent() {
|
||||
rmerge(x.parent)
|
||||
}
|
||||
}
|
||||
|
||||
rmerge(c)
|
||||
c.Flags().AddFlagSet(c.PersistentFlags())
|
||||
c.updateParentsPflags()
|
||||
c.Flags().AddFlagSet(c.parentsPflags)
|
||||
}
|
||||
|
||||
// updateParentsPflags updates c.parentsPflags by adding
|
||||
// new persistent flags of all parents.
|
||||
// If c.parentsPflags == nil, it makes new.
|
||||
func (c *Command) updateParentsPflags() {
|
||||
if c.parentsPflags == nil {
|
||||
c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||
c.parentsPflags.SetOutput(c.flagErrorBuf)
|
||||
c.parentsPflags.SortFlags = false
|
||||
}
|
||||
|
||||
c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
|
||||
|
||||
c.VisitParents(func(parent *Command) {
|
||||
c.parentsPflags.AddFlagSet(parent.PersistentFlags())
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue