mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1032 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			1032 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright © 2013 Steve Francia <spf@spf13.com>.
 | 
						|
//
 | 
						|
// 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.
 | 
						|
 | 
						|
//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 (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"runtime"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/inconshreveable/mousetrap"
 | 
						|
	flag "github.com/spf13/pflag"
 | 
						|
)
 | 
						|
 | 
						|
// Command is just that, a command for your application.
 | 
						|
// eg.  '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 string
 | 
						|
	// An array of aliases that can be used instead of the first word in Use.
 | 
						|
	Aliases []string
 | 
						|
	// The short description shown in the 'help' output.
 | 
						|
	Short string
 | 
						|
	// The long message shown in the 'help <this-command>' output.
 | 
						|
	Long string
 | 
						|
	// Examples of how to use the command
 | 
						|
	Example string
 | 
						|
	// List of all valid non-flag arguments, used for bash completions *TODO* actually validate these
 | 
						|
	ValidArgs []string
 | 
						|
	// Custom functions used by the bash autocompletion generator
 | 
						|
	BashCompletionFunction string
 | 
						|
	// Is this command deprecated and should print this string when used?
 | 
						|
	Deprecated 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
 | 
						|
	// 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
 | 
						|
	PersistentPreRun func(cmd *Command, args []string)
 | 
						|
	// PreRun: children of this command will not inherit.
 | 
						|
	PreRun func(cmd *Command, args []string)
 | 
						|
	// Run: Typically the actual work function. Most commands will only implement this
 | 
						|
	Run func(cmd *Command, args []string)
 | 
						|
	// PostRun: run after the Run command.
 | 
						|
	PostRun func(cmd *Command, args []string)
 | 
						|
	// PersistentPostRun: children of this command will inherit and execute after PostRun
 | 
						|
	PersistentPostRun func(cmd *Command, args []string)
 | 
						|
	// Commands is the list of commands supported by this program.
 | 
						|
	commands []*Command
 | 
						|
	// Parent Command for this command
 | 
						|
	parent *Command
 | 
						|
	// max lengths of commands' string lengths for use in padding
 | 
						|
	commandsMaxUseLen         int
 | 
						|
	commandsMaxCommandPathLen int
 | 
						|
	commandsMaxNameLen        int
 | 
						|
 | 
						|
	flagErrorBuf *bytes.Buffer
 | 
						|
	cmdErrorBuf  *bytes.Buffer
 | 
						|
 | 
						|
	args          []string                 // actual args parsed from flags
 | 
						|
	output        *io.Writer               // nil means stderr; use Out() method instead
 | 
						|
	usageFunc     func(*Command) error     // Usage can be defined by application
 | 
						|
	usageTemplate string                   // Can be defined by Application
 | 
						|
	helpTemplate  string                   // Can be defined by Application
 | 
						|
	helpFunc      func(*Command, []string) // Help can be defined by application
 | 
						|
	helpCommand   *Command                 // The help command
 | 
						|
	helpFlagVal   bool
 | 
						|
	// The global normalization function that we can use on every pFlag set and children commands
 | 
						|
	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
 | 
						|
}
 | 
						|
 | 
						|
// os.Args[1:] by default, if desired, can be overridden
 | 
						|
// particularly useful when testing.
 | 
						|
func (c *Command) SetArgs(a []string) {
 | 
						|
	c.args = a
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) getOut(def io.Writer) io.Writer {
 | 
						|
	if c.output != nil {
 | 
						|
		return *c.output
 | 
						|
	}
 | 
						|
 | 
						|
	if c.HasParent() {
 | 
						|
		return c.parent.Out()
 | 
						|
	} else {
 | 
						|
		return def
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) Out() io.Writer {
 | 
						|
	return c.getOut(os.Stderr)
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) getOutOrStdout() io.Writer {
 | 
						|
	return c.getOut(os.Stdout)
 | 
						|
}
 | 
						|
 | 
						|
// 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
 | 
						|
}
 | 
						|
 | 
						|
// Usage can be defined by application
 | 
						|
func (c *Command) SetUsageFunc(f func(*Command) error) {
 | 
						|
	c.usageFunc = f
 | 
						|
}
 | 
						|
 | 
						|
// Can be defined by Application
 | 
						|
func (c *Command) SetUsageTemplate(s string) {
 | 
						|
	c.usageTemplate = s
 | 
						|
}
 | 
						|
 | 
						|
// Can be defined by Application
 | 
						|
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
 | 
						|
	c.helpFunc = f
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) SetHelpCommand(cmd *Command) {
 | 
						|
	c.helpCommand = cmd
 | 
						|
}
 | 
						|
 | 
						|
// Can be defined by Application
 | 
						|
func (c *Command) SetHelpTemplate(s string) {
 | 
						|
	c.helpTemplate = s
 | 
						|
}
 | 
						|
 | 
						|
// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
 | 
						|
// The user should not have a cyclic dependency on commands.
 | 
						|
func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
 | 
						|
	c.Flags().SetNormalizeFunc(n)
 | 
						|
	c.PersistentFlags().SetNormalizeFunc(n)
 | 
						|
	c.LocalFlags().SetNormalizeFunc(n)
 | 
						|
	c.globNormFunc = n
 | 
						|
 | 
						|
	for _, command := range c.commands {
 | 
						|
		command.SetGlobalNormalizationFunc(n)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) UsageFunc() (f func(*Command) error) {
 | 
						|
	if c.usageFunc != nil {
 | 
						|
		return c.usageFunc
 | 
						|
	}
 | 
						|
 | 
						|
	if c.HasParent() {
 | 
						|
		return c.parent.UsageFunc()
 | 
						|
	} else {
 | 
						|
		return func(c *Command) error {
 | 
						|
			err := tmpl(c.Out(), c.UsageTemplate(), c)
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
func (c *Command) HelpFunc() func(*Command, []string) {
 | 
						|
	if c.helpFunc != nil {
 | 
						|
		return c.helpFunc
 | 
						|
	}
 | 
						|
 | 
						|
	if c.HasParent() {
 | 
						|
		return c.parent.HelpFunc()
 | 
						|
	} else {
 | 
						|
		return func(c *Command, args []string) {
 | 
						|
			if len(args) == 0 {
 | 
						|
				// Help called without any topic, calling on root
 | 
						|
				c.Root().Help()
 | 
						|
				return
 | 
						|
			}
 | 
						|
 | 
						|
			cmd, _, e := c.Root().Find(args)
 | 
						|
			if cmd == nil || e != nil {
 | 
						|
				c.Printf("Unknown help topic %#q.", args)
 | 
						|
 | 
						|
				c.Root().Usage()
 | 
						|
			} else {
 | 
						|
				err := cmd.Help()
 | 
						|
				if err != nil {
 | 
						|
					c.Println(err)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
var minUsagePadding int = 25
 | 
						|
 | 
						|
func (c *Command) UsagePadding() int {
 | 
						|
	if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
 | 
						|
		return minUsagePadding
 | 
						|
	} else {
 | 
						|
		return c.parent.commandsMaxUseLen
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
var minCommandPathPadding int = 11
 | 
						|
 | 
						|
//
 | 
						|
func (c *Command) CommandPathPadding() int {
 | 
						|
	if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
 | 
						|
		return minCommandPathPadding
 | 
						|
	} else {
 | 
						|
		return c.parent.commandsMaxCommandPathLen
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
var minNamePadding int = 11
 | 
						|
 | 
						|
func (c *Command) NamePadding() int {
 | 
						|
	if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
 | 
						|
		return minNamePadding
 | 
						|
	} else {
 | 
						|
		return c.parent.commandsMaxNameLen
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) UsageTemplate() string {
 | 
						|
	if c.usageTemplate != "" {
 | 
						|
		return c.usageTemplate
 | 
						|
	}
 | 
						|
 | 
						|
	if c.HasParent() {
 | 
						|
		return c.parent.UsageTemplate()
 | 
						|
	} else {
 | 
						|
		return `{{ $cmd := . }}
 | 
						|
Usage: {{if .Runnable}}
 | 
						|
  {{.UseLine}}{{if .HasFlags}} [flags]{{end}}{{end}}{{if .HasSubCommands}}
 | 
						|
  {{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}}
 | 
						|
 | 
						|
Aliases:
 | 
						|
  {{.NameAndAliases}}
 | 
						|
{{end}}{{if .HasExample}}
 | 
						|
 | 
						|
Examples:
 | 
						|
{{ .Example }}
 | 
						|
{{end}}{{ if .HasRunnableSubCommands}}
 | 
						|
 | 
						|
Available Commands: {{range .Commands}}{{if and (.Runnable) (not .Deprecated)}}
 | 
						|
  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}
 | 
						|
{{end}}
 | 
						|
{{ if .HasLocalFlags}}Flags:
 | 
						|
{{.LocalFlags.FlagUsages}}{{end}}
 | 
						|
{{ if .HasInheritedFlags}}Global Flags:
 | 
						|
{{.InheritedFlags.FlagUsages}}{{end}}{{if or (.HasHelpSubCommands) (.HasRunnableSiblings)}}
 | 
						|
Additional help topics:
 | 
						|
{{if .HasHelpSubCommands}}{{range .Commands}}{{if and (not .Runnable) (not .Deprecated)}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasRunnableSiblings }}{{range .Parent.Commands}}{{if and (not .Runnable) (not .Deprecated)}}{{if not (eq .Name $cmd.Name) }}
 | 
						|
  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}}
 | 
						|
{{end}}{{ if .HasSubCommands }}
 | 
						|
Use "{{.Root.Name}} help [command]" for more information about a command.
 | 
						|
{{end}}`
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) HelpTemplate() string {
 | 
						|
	if c.helpTemplate != "" {
 | 
						|
		return c.helpTemplate
 | 
						|
	}
 | 
						|
 | 
						|
	if c.HasParent() {
 | 
						|
		return c.parent.HelpTemplate()
 | 
						|
	} else {
 | 
						|
		return `{{with or .Long .Short }}{{. | trim}}{{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
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Test if the named flag is a boolean flag.
 | 
						|
func isBooleanFlag(name string, f *flag.FlagSet) bool {
 | 
						|
	flag := f.Lookup(name)
 | 
						|
	if flag == nil {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	return flag.Value.Type() == "bool"
 | 
						|
}
 | 
						|
 | 
						|
// Test if the named flag is a boolean flag.
 | 
						|
func isBooleanShortFlag(name string, f *flag.FlagSet) bool {
 | 
						|
	result := false
 | 
						|
	f.VisitAll(func(f *flag.Flag) {
 | 
						|
		if f.Shorthand == name && f.Value.Type() == "bool" {
 | 
						|
			result = true
 | 
						|
		}
 | 
						|
	})
 | 
						|
	return result
 | 
						|
}
 | 
						|
 | 
						|
func stripFlags(args []string, c *Command) []string {
 | 
						|
	if len(args) < 1 {
 | 
						|
		return args
 | 
						|
	}
 | 
						|
	c.mergePersistentFlags()
 | 
						|
 | 
						|
	commands := []string{}
 | 
						|
 | 
						|
	inQuote := false
 | 
						|
	inFlag := false
 | 
						|
	for _, y := range args {
 | 
						|
		if !inQuote {
 | 
						|
			switch {
 | 
						|
			case strings.HasPrefix(y, "\""):
 | 
						|
				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 = !isBooleanFlag(y[2:], c.Flags())
 | 
						|
			case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !isBooleanShortFlag(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
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if strings.HasSuffix(y, "\"") && !strings.HasSuffix(y, "\\\"") {
 | 
						|
			inQuote = false
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return commands
 | 
						|
}
 | 
						|
 | 
						|
// 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
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return args
 | 
						|
}
 | 
						|
 | 
						|
// find the target command given the args and command tree
 | 
						|
// Meant to be run on the highest node. Only searches down.
 | 
						|
func (c *Command) Find(args []string) (*Command, []string, error) {
 | 
						|
	if c == nil {
 | 
						|
		return nil, nil, fmt.Errorf("Called find() on a nil Command")
 | 
						|
	}
 | 
						|
 | 
						|
	// If there are no arguments, return the root command. If the root has no
 | 
						|
	// subcommands, args reflects arguments that should actually be passed to
 | 
						|
	// the root command, so also return the root command.
 | 
						|
	if len(args) == 0 || !c.Root().HasSubCommands() {
 | 
						|
		return c.Root(), args, nil
 | 
						|
	}
 | 
						|
 | 
						|
	var innerfind func(*Command, []string) (*Command, []string)
 | 
						|
 | 
						|
	innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
 | 
						|
		if len(innerArgs) > 0 && c.HasSubCommands() {
 | 
						|
			argsWOflags := stripFlags(innerArgs, c)
 | 
						|
			if len(argsWOflags) > 0 {
 | 
						|
				matches := make([]*Command, 0)
 | 
						|
				for _, cmd := range c.commands {
 | 
						|
					if cmd.Name() == argsWOflags[0] || cmd.HasAlias(argsWOflags[0]) { // exact name or alias match
 | 
						|
						return innerfind(cmd, argsMinusFirstX(innerArgs, argsWOflags[0]))
 | 
						|
					} else if EnablePrefixMatching {
 | 
						|
						if strings.HasPrefix(cmd.Name(), argsWOflags[0]) { // prefix match
 | 
						|
							matches = append(matches, cmd)
 | 
						|
						}
 | 
						|
						for _, x := range cmd.Aliases {
 | 
						|
							if strings.HasPrefix(x, argsWOflags[0]) {
 | 
						|
								matches = append(matches, cmd)
 | 
						|
							}
 | 
						|
						}
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				// only accept a single prefix match - multiple matches would be ambiguous
 | 
						|
				if len(matches) == 1 {
 | 
						|
					return innerfind(matches[0], argsMinusFirstX(innerArgs, argsWOflags[0]))
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return c, innerArgs
 | 
						|
	}
 | 
						|
 | 
						|
	commandFound, a := innerfind(c, args)
 | 
						|
 | 
						|
	// If we matched on the root, but we asked for a subcommand, return an error
 | 
						|
	if commandFound.Name() == c.Name() && len(stripFlags(args, c)) > 0 && commandFound.Name() != args[0] {
 | 
						|
		return nil, a, fmt.Errorf("unknown command %q", a[0])
 | 
						|
	}
 | 
						|
 | 
						|
	return commandFound, a, nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) Root() *Command {
 | 
						|
	var findRoot func(*Command) *Command
 | 
						|
 | 
						|
	findRoot = func(x *Command) *Command {
 | 
						|
		if x.HasParent() {
 | 
						|
			return findRoot(x.parent)
 | 
						|
		} else {
 | 
						|
			return x
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return findRoot(c)
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) execute(a []string) (err error) {
 | 
						|
	if c == nil {
 | 
						|
		return fmt.Errorf("Called Execute() on a nil Command")
 | 
						|
	}
 | 
						|
 | 
						|
	if len(c.Deprecated) > 0 {
 | 
						|
		c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
 | 
						|
	}
 | 
						|
 | 
						|
	err = c.ParseFlags(a)
 | 
						|
	if err == flag.ErrHelp {
 | 
						|
		c.Help()
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	if err != nil {
 | 
						|
		// We're writing subcommand usage to root command's error buffer to have it displayed to the user
 | 
						|
		r := c.Root()
 | 
						|
		if r.cmdErrorBuf == nil {
 | 
						|
			r.cmdErrorBuf = new(bytes.Buffer)
 | 
						|
		}
 | 
						|
		// for writing the usage to the buffer we need to switch the output temporarily
 | 
						|
		// since Out() returns root output, you also need to revert that on root
 | 
						|
		out := r.Out()
 | 
						|
		r.SetOutput(r.cmdErrorBuf)
 | 
						|
		c.Usage()
 | 
						|
		r.SetOutput(out)
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	// If help is called, regardless of other flags, we print that.
 | 
						|
	// Print help also if c.Run is nil.
 | 
						|
	if c.helpFlagVal || !c.Runnable() {
 | 
						|
		c.Help()
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	c.preRun()
 | 
						|
	argWoFlags := c.Flags().Args()
 | 
						|
 | 
						|
	for p := c; p != nil; p = p.Parent() {
 | 
						|
		if p.PersistentPreRun != nil {
 | 
						|
			p.PersistentPreRun(c, argWoFlags)
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if c.PreRun != nil {
 | 
						|
		c.PreRun(c, argWoFlags)
 | 
						|
	}
 | 
						|
 | 
						|
	c.Run(c, argWoFlags)
 | 
						|
 | 
						|
	if c.PostRun != nil {
 | 
						|
		c.PostRun(c, argWoFlags)
 | 
						|
	}
 | 
						|
	for p := c; p != nil; p = p.Parent() {
 | 
						|
		if p.PersistentPostRun != nil {
 | 
						|
			p.PersistentPostRun(c, argWoFlags)
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) preRun() {
 | 
						|
	for _, x := range initializers {
 | 
						|
		x()
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) errorMsgFromParse() string {
 | 
						|
	s := c.flagErrorBuf.String()
 | 
						|
 | 
						|
	x := strings.Split(s, "\n")
 | 
						|
 | 
						|
	if len(x) > 0 {
 | 
						|
		return x[0]
 | 
						|
	} else {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// 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.
 | 
						|
func (c *Command) Execute() (err error) {
 | 
						|
 | 
						|
	// Regardless of what command execute is called on, run on Root only
 | 
						|
	if c.HasParent() {
 | 
						|
		return c.Root().Execute()
 | 
						|
	}
 | 
						|
 | 
						|
	if EnableWindowsMouseTrap && runtime.GOOS == "windows" {
 | 
						|
		if mousetrap.StartedByExplorer() {
 | 
						|
			c.Print(MousetrapHelpText)
 | 
						|
			time.Sleep(5 * time.Second)
 | 
						|
			os.Exit(1)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// initialize help as the last point possible to allow for user
 | 
						|
	// overriding
 | 
						|
	c.initHelp()
 | 
						|
 | 
						|
	var args []string
 | 
						|
 | 
						|
	if len(c.args) == 0 {
 | 
						|
		args = os.Args[1:]
 | 
						|
	} else {
 | 
						|
		args = c.args
 | 
						|
	}
 | 
						|
 | 
						|
	cmd, flags, err := c.Find(args)
 | 
						|
	if err == nil {
 | 
						|
		err = cmd.execute(flags)
 | 
						|
	}
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		if err == flag.ErrHelp {
 | 
						|
			c.Help()
 | 
						|
 | 
						|
		} else {
 | 
						|
			c.Println("Error:", err.Error())
 | 
						|
			c.Printf("Run '%v help' for usage.\n", c.Root().Name())
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) initHelp() {
 | 
						|
	if c.helpCommand == nil {
 | 
						|
		if !c.HasSubCommands() {
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		c.helpCommand = &Command{
 | 
						|
			Use:   "help [command]",
 | 
						|
			Short: "Help about any command",
 | 
						|
			Long: `Help provides help for any command in the application.
 | 
						|
    Simply type ` + c.Name() + ` help [path to command] for full details.`,
 | 
						|
			Run:               c.HelpFunc(),
 | 
						|
			PersistentPreRun:  func(cmd *Command, args []string) {},
 | 
						|
			PersistentPostRun: func(cmd *Command, args []string) {},
 | 
						|
		}
 | 
						|
	}
 | 
						|
	c.AddCommand(c.helpCommand)
 | 
						|
}
 | 
						|
 | 
						|
// Used for testing
 | 
						|
func (c *Command) ResetCommands() {
 | 
						|
	c.commands = nil
 | 
						|
	c.helpCommand = nil
 | 
						|
	c.cmdErrorBuf = new(bytes.Buffer)
 | 
						|
	c.cmdErrorBuf.Reset()
 | 
						|
}
 | 
						|
 | 
						|
//Commands returns a slice of child commands.
 | 
						|
func (c *Command) Commands() []*Command {
 | 
						|
	return c.commands
 | 
						|
}
 | 
						|
 | 
						|
// AddCommand adds one or more commands to this parent command.
 | 
						|
func (c *Command) AddCommand(cmds ...*Command) {
 | 
						|
	for i, x := range cmds {
 | 
						|
		if cmds[i] == c {
 | 
						|
			panic("Command can't be a child of itself")
 | 
						|
		}
 | 
						|
		cmds[i].parent = c
 | 
						|
		// update max lengths
 | 
						|
		usageLen := len(x.Use)
 | 
						|
		if usageLen > c.commandsMaxUseLen {
 | 
						|
			c.commandsMaxUseLen = usageLen
 | 
						|
		}
 | 
						|
		commandPathLen := len(x.CommandPath())
 | 
						|
		if commandPathLen > c.commandsMaxCommandPathLen {
 | 
						|
			c.commandsMaxCommandPathLen = commandPathLen
 | 
						|
		}
 | 
						|
		nameLen := len(x.Name())
 | 
						|
		if nameLen > c.commandsMaxNameLen {
 | 
						|
			c.commandsMaxNameLen = nameLen
 | 
						|
		}
 | 
						|
		// If glabal normalization function exists, update all children
 | 
						|
		if c.globNormFunc != nil {
 | 
						|
			x.SetGlobalNormalizationFunc(c.globNormFunc)
 | 
						|
		}
 | 
						|
		c.commands = append(c.commands, x)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// AddCommand removes one or more commands from a parent command.
 | 
						|
func (c *Command) RemoveCommand(cmds ...*Command) {
 | 
						|
	commands := []*Command{}
 | 
						|
main:
 | 
						|
	for _, command := range c.commands {
 | 
						|
		for _, cmd := range cmds {
 | 
						|
			if command == cmd {
 | 
						|
				command.parent = nil
 | 
						|
				continue main
 | 
						|
			}
 | 
						|
		}
 | 
						|
		commands = append(commands, command)
 | 
						|
	}
 | 
						|
	c.commands = commands
 | 
						|
	// recompute all lengths
 | 
						|
	c.commandsMaxUseLen = 0
 | 
						|
	c.commandsMaxCommandPathLen = 0
 | 
						|
	c.commandsMaxNameLen = 0
 | 
						|
	for _, command := range c.commands {
 | 
						|
		usageLen := len(command.Use)
 | 
						|
		if usageLen > c.commandsMaxUseLen {
 | 
						|
			c.commandsMaxUseLen = usageLen
 | 
						|
		}
 | 
						|
		commandPathLen := len(command.CommandPath())
 | 
						|
		if commandPathLen > c.commandsMaxCommandPathLen {
 | 
						|
			c.commandsMaxCommandPathLen = commandPathLen
 | 
						|
		}
 | 
						|
		nameLen := len(command.Name())
 | 
						|
		if nameLen > c.commandsMaxNameLen {
 | 
						|
			c.commandsMaxNameLen = nameLen
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Convenience method to Print to the defined output
 | 
						|
func (c *Command) Print(i ...interface{}) {
 | 
						|
	fmt.Fprint(c.Out(), i...)
 | 
						|
}
 | 
						|
 | 
						|
// Convenience method to Println to the defined output
 | 
						|
func (c *Command) Println(i ...interface{}) {
 | 
						|
	str := fmt.Sprintln(i...)
 | 
						|
	c.Print(str)
 | 
						|
}
 | 
						|
 | 
						|
// Convenience method to Printf to the defined output
 | 
						|
func (c *Command) Printf(format string, i ...interface{}) {
 | 
						|
	str := fmt.Sprintf(format, i...)
 | 
						|
	c.Print(str)
 | 
						|
}
 | 
						|
 | 
						|
// Output the usage for the command
 | 
						|
// Used when a user provides invalid input
 | 
						|
// Can be defined by user by overriding UsageFunc
 | 
						|
func (c *Command) Usage() error {
 | 
						|
	c.mergePersistentFlags()
 | 
						|
	err := c.UsageFunc()(c)
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// Output the help for the command
 | 
						|
// Used when a user calls help [command]
 | 
						|
// by the default HelpFunc in the commander
 | 
						|
func (c *Command) Help() error {
 | 
						|
	c.mergePersistentFlags()
 | 
						|
	err := tmpl(c.getOutOrStdout(), c.HelpTemplate(), c)
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) UsageString() string {
 | 
						|
	tmpOutput := c.output
 | 
						|
	bb := new(bytes.Buffer)
 | 
						|
	c.SetOutput(bb)
 | 
						|
	c.Usage()
 | 
						|
	c.output = tmpOutput
 | 
						|
	return bb.String()
 | 
						|
}
 | 
						|
 | 
						|
// 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
 | 
						|
	}
 | 
						|
	return str
 | 
						|
}
 | 
						|
 | 
						|
//The full usage for a given command (including parents)
 | 
						|
func (c *Command) UseLine() string {
 | 
						|
	str := ""
 | 
						|
	if c.HasParent() {
 | 
						|
		str = c.parent.CommandPath() + " "
 | 
						|
	}
 | 
						|
	return str + c.Use
 | 
						|
}
 | 
						|
 | 
						|
// For use in determining which flags have been assigned to which commands
 | 
						|
// and which persist
 | 
						|
func (c *Command) DebugFlags() {
 | 
						|
	c.Println("DebugFlags called on", c.Name())
 | 
						|
	var debugflags func(*Command)
 | 
						|
 | 
						|
	debugflags = func(x *Command) {
 | 
						|
		if x.HasFlags() || x.HasPersistentFlags() {
 | 
						|
			c.Println(x.Name())
 | 
						|
		}
 | 
						|
		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]")
 | 
						|
					}
 | 
						|
				} else {
 | 
						|
					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
 | 
						|
				}
 | 
						|
			})
 | 
						|
		}
 | 
						|
		if x.HasPersistentFlags() {
 | 
						|
			x.pflags.VisitAll(func(f *flag.Flag) {
 | 
						|
				if x.HasFlags() {
 | 
						|
					if x.flags.Lookup(f.Name) == nil {
 | 
						|
						c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
 | 
						|
					}
 | 
						|
				} else {
 | 
						|
					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
 | 
						|
				}
 | 
						|
			})
 | 
						|
		}
 | 
						|
		c.Println(x.flagErrorBuf)
 | 
						|
		if x.HasSubCommands() {
 | 
						|
			for _, y := range x.commands {
 | 
						|
				debugflags(y)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	debugflags(c)
 | 
						|
}
 | 
						|
 | 
						|
// Name returns the command's name: the first word in the use line.
 | 
						|
func (c *Command) Name() string {
 | 
						|
	if c.name != "" {
 | 
						|
		return c.name
 | 
						|
	}
 | 
						|
	name := c.Use
 | 
						|
	i := strings.Index(name, " ")
 | 
						|
	if i >= 0 {
 | 
						|
		name = name[:i]
 | 
						|
	}
 | 
						|
	return name
 | 
						|
}
 | 
						|
 | 
						|
// Determine if a given string is an alias of the command.
 | 
						|
func (c *Command) HasAlias(s string) bool {
 | 
						|
	for _, a := range c.Aliases {
 | 
						|
		if a == s {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) NameAndAliases() string {
 | 
						|
	return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) HasExample() bool {
 | 
						|
	return len(c.Example) > 0
 | 
						|
}
 | 
						|
 | 
						|
// Determine if the command is itself runnable
 | 
						|
func (c *Command) Runnable() bool {
 | 
						|
	return c.Run != nil
 | 
						|
}
 | 
						|
 | 
						|
// Determine if the command has children commands
 | 
						|
func (c *Command) HasSubCommands() bool {
 | 
						|
	return len(c.commands) > 0
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) HasRunnableSiblings() bool {
 | 
						|
	if !c.HasParent() {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	for _, sub := range c.parent.commands {
 | 
						|
		if sub.Runnable() {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) HasHelpSubCommands() bool {
 | 
						|
	for _, sub := range c.commands {
 | 
						|
		if !sub.Runnable() {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// Determine if the command has runnable children commands
 | 
						|
func (c *Command) HasRunnableSubCommands() bool {
 | 
						|
	for _, sub := range c.commands {
 | 
						|
		if sub.Runnable() {
 | 
						|
			return true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// Determine if the command is a child command
 | 
						|
func (c *Command) HasParent() bool {
 | 
						|
	return c.parent != nil
 | 
						|
}
 | 
						|
 | 
						|
// GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists
 | 
						|
func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
 | 
						|
	return c.globNormFunc
 | 
						|
}
 | 
						|
 | 
						|
// Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents)
 | 
						|
func (c *Command) Flags() *flag.FlagSet {
 | 
						|
	if c.flags == nil {
 | 
						|
		c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
 | 
						|
		if c.flagErrorBuf == nil {
 | 
						|
			c.flagErrorBuf = new(bytes.Buffer)
 | 
						|
		}
 | 
						|
		c.flags.SetOutput(c.flagErrorBuf)
 | 
						|
		c.PersistentFlags().BoolVarP(&c.helpFlagVal, "help", "h", false, "help for "+c.Name())
 | 
						|
	}
 | 
						|
	return c.flags
 | 
						|
}
 | 
						|
 | 
						|
// Get the local FlagSet specifically set in the current command
 | 
						|
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)
 | 
						|
	})
 | 
						|
	return local
 | 
						|
}
 | 
						|
 | 
						|
// All Flags which were inherited from parents commands
 | 
						|
func (c *Command) InheritedFlags() *flag.FlagSet {
 | 
						|
	c.mergePersistentFlags()
 | 
						|
 | 
						|
	inherited := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
 | 
						|
	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)
 | 
						|
				}
 | 
						|
			})
 | 
						|
		}
 | 
						|
		if x.HasParent() {
 | 
						|
			rmerge(x.parent)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if c.HasParent() {
 | 
						|
		rmerge(c.parent)
 | 
						|
	}
 | 
						|
 | 
						|
	return inherited
 | 
						|
}
 | 
						|
 | 
						|
// All Flags which were not inherited from parent commands
 | 
						|
func (c *Command) NonInheritedFlags() *flag.FlagSet {
 | 
						|
	return c.LocalFlags()
 | 
						|
}
 | 
						|
 | 
						|
// Get the Persistent FlagSet specifically set in the current command
 | 
						|
func (c *Command) PersistentFlags() *flag.FlagSet {
 | 
						|
	if c.pflags == nil {
 | 
						|
		c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
 | 
						|
		if c.flagErrorBuf == nil {
 | 
						|
			c.flagErrorBuf = new(bytes.Buffer)
 | 
						|
		}
 | 
						|
		c.pflags.SetOutput(c.flagErrorBuf)
 | 
						|
	}
 | 
						|
	return c.pflags
 | 
						|
}
 | 
						|
 | 
						|
// For use in testing
 | 
						|
func (c *Command) ResetFlags() {
 | 
						|
	c.flagErrorBuf = new(bytes.Buffer)
 | 
						|
	c.flagErrorBuf.Reset()
 | 
						|
	c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
 | 
						|
	c.flags.SetOutput(c.flagErrorBuf)
 | 
						|
	c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
 | 
						|
	c.pflags.SetOutput(c.flagErrorBuf)
 | 
						|
}
 | 
						|
 | 
						|
// Does the command contain any flags (local plus persistent from the entire structure)
 | 
						|
func (c *Command) HasFlags() bool {
 | 
						|
	return c.Flags().HasFlags()
 | 
						|
}
 | 
						|
 | 
						|
// Does the command contain persistent flags
 | 
						|
func (c *Command) HasPersistentFlags() bool {
 | 
						|
	return c.PersistentFlags().HasFlags()
 | 
						|
}
 | 
						|
 | 
						|
// Does the command has flags specifically declared locally
 | 
						|
func (c *Command) HasLocalFlags() bool {
 | 
						|
	return c.LocalFlags().HasFlags()
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) HasInheritedFlags() bool {
 | 
						|
	return c.InheritedFlags().HasFlags()
 | 
						|
}
 | 
						|
 | 
						|
// Climbs up the command tree looking for matching flag
 | 
						|
func (c *Command) Flag(name string) (flag *flag.Flag) {
 | 
						|
	flag = c.Flags().Lookup(name)
 | 
						|
 | 
						|
	if flag == nil {
 | 
						|
		flag = c.persistentFlag(name)
 | 
						|
	}
 | 
						|
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// recursively find matching persistent flag
 | 
						|
func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
 | 
						|
	if c.HasPersistentFlags() {
 | 
						|
		flag = c.PersistentFlags().Lookup(name)
 | 
						|
	}
 | 
						|
 | 
						|
	if flag == nil && c.HasParent() {
 | 
						|
		flag = c.parent.persistentFlag(name)
 | 
						|
	}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// Parses persistent flag tree & local flags
 | 
						|
func (c *Command) ParseFlags(args []string) (err error) {
 | 
						|
	c.mergePersistentFlags()
 | 
						|
	err = c.Flags().Parse(args)
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
func (c *Command) Parent() *Command {
 | 
						|
	return c.parent
 | 
						|
}
 | 
						|
 | 
						|
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)
 | 
						|
}
 |