1// Copyright © 2013 Steve Francia <spf@spf13.com>.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
15// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
16package cobra
17
18import (
19	"bytes"
20	"fmt"
21	"io"
22	"os"
23	"path/filepath"
24	"sort"
25	"strings"
26
27	flag "github.com/spf13/pflag"
28)
29
30// FParseErrWhitelist configures Flag parse errors to be ignored
31type FParseErrWhitelist flag.ParseErrorsWhitelist
32
33// Command is just that, a command for your application.
34// E.g.  'go run ...' - 'run' is the command. Cobra requires
35// you to define the usage and description as part of your command
36// definition to ensure usability.
37type Command struct {
38	// Use is the one-line usage message.
39	Use string
40
41	// Aliases is an array of aliases that can be used instead of the first word in Use.
42	Aliases []string
43
44	// SuggestFor is an array of command names for which this command will be suggested -
45	// similar to aliases but only suggests.
46	SuggestFor []string
47
48	// Short is the short description shown in the 'help' output.
49	Short string
50
51	// Long is the long message shown in the 'help <this-command>' output.
52	Long string
53
54	// Example is examples of how to use the command.
55	Example string
56
57	// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
58	ValidArgs []string
59
60	// Expected arguments
61	Args PositionalArgs
62
63	// ArgAliases is List of aliases for ValidArgs.
64	// These are not suggested to the user in the bash completion,
65	// but accepted if entered manually.
66	ArgAliases []string
67
68	// BashCompletionFunction is custom functions used by the bash autocompletion generator.
69	BashCompletionFunction string
70
71	// Deprecated defines, if this command is deprecated and should print this string when used.
72	Deprecated string
73
74	// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
75	Hidden bool
76
77	// Annotations are key/value pairs that can be used by applications to identify or
78	// group commands.
79	Annotations map[string]string
80
81	// Version defines the version for this command. If this value is non-empty and the command does not
82	// define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
83	// will print content of the "Version" variable.
84	Version string
85
86	// The *Run functions are executed in the following order:
87	//   * PersistentPreRun()
88	//   * PreRun()
89	//   * Run()
90	//   * PostRun()
91	//   * PersistentPostRun()
92	// All functions get the same args, the arguments after the command name.
93	//
94	// PersistentPreRun: children of this command will inherit and execute.
95	PersistentPreRun func(cmd *Command, args []string)
96	// PersistentPreRunE: PersistentPreRun but returns an error.
97	PersistentPreRunE func(cmd *Command, args []string) error
98	// PreRun: children of this command will not inherit.
99	PreRun func(cmd *Command, args []string)
100	// PreRunE: PreRun but returns an error.
101	PreRunE func(cmd *Command, args []string) error
102	// Run: Typically the actual work function. Most commands will only implement this.
103	Run func(cmd *Command, args []string)
104	// RunE: Run but returns an error.
105	RunE func(cmd *Command, args []string) error
106	// PostRun: run after the Run command.
107	PostRun func(cmd *Command, args []string)
108	// PostRunE: PostRun but returns an error.
109	PostRunE func(cmd *Command, args []string) error
110	// PersistentPostRun: children of this command will inherit and execute after PostRun.
111	PersistentPostRun func(cmd *Command, args []string)
112	// PersistentPostRunE: PersistentPostRun but returns an error.
113	PersistentPostRunE func(cmd *Command, args []string) error
114
115	// SilenceErrors is an option to quiet errors down stream.
116	SilenceErrors bool
117
118	// SilenceUsage is an option to silence usage when an error occurs.
119	SilenceUsage bool
120
121	// DisableFlagParsing disables the flag parsing.
122	// If this is true all flags will be passed to the command as arguments.
123	DisableFlagParsing bool
124
125	// DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
126	// will be printed by generating docs for this command.
127	DisableAutoGenTag bool
128
129	// DisableFlagsInUseLine will disable the addition of [flags] to the usage
130	// line of a command when printing help or generating docs
131	DisableFlagsInUseLine bool
132
133	// DisableSuggestions disables the suggestions based on Levenshtein distance
134	// that go along with 'unknown command' messages.
135	DisableSuggestions bool
136	// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
137	// Must be > 0.
138	SuggestionsMinimumDistance int
139
140	// TraverseChildren parses flags on all parents before executing child command.
141	TraverseChildren bool
142
143	//FParseErrWhitelist flag parse errors to be ignored
144	FParseErrWhitelist FParseErrWhitelist
145
146	// commands is the list of commands supported by this program.
147	commands []*Command
148	// parent is a parent command for this command.
149	parent *Command
150	// Max lengths of commands' string lengths for use in padding.
151	commandsMaxUseLen         int
152	commandsMaxCommandPathLen int
153	commandsMaxNameLen        int
154	// commandsAreSorted defines, if command slice are sorted or not.
155	commandsAreSorted bool
156	// commandCalledAs is the name or alias value used to call this command.
157	commandCalledAs struct {
158		name   string
159		called bool
160	}
161
162	// args is actual args parsed from flags.
163	args []string
164	// flagErrorBuf contains all error messages from pflag.
165	flagErrorBuf *bytes.Buffer
166	// flags is full set of flags.
167	flags *flag.FlagSet
168	// pflags contains persistent flags.
169	pflags *flag.FlagSet
170	// lflags contains local flags.
171	lflags *flag.FlagSet
172	// iflags contains inherited flags.
173	iflags *flag.FlagSet
174	// parentsPflags is all persistent flags of cmd's parents.
175	parentsPflags *flag.FlagSet
176	// globNormFunc is the global normalization function
177	// that we can use on every pflag set and children commands
178	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
179
180	// usageFunc is usage func defined by user.
181	usageFunc func(*Command) error
182	// usageTemplate is usage template defined by user.
183	usageTemplate string
184	// flagErrorFunc is func defined by user and it's called when the parsing of
185	// flags returns an error.
186	flagErrorFunc func(*Command, error) error
187	// helpTemplate is help template defined by user.
188	helpTemplate string
189	// helpFunc is help func defined by user.
190	helpFunc func(*Command, []string)
191	// helpCommand is command with usage 'help'. If it's not defined by user,
192	// cobra uses default help command.
193	helpCommand *Command
194	// versionTemplate is the version template defined by user.
195	versionTemplate string
196
197	// inReader is a reader defined by the user that replaces stdin
198	inReader io.Reader
199	// outWriter is a writer defined by the user that replaces stdout
200	outWriter io.Writer
201	// errWriter is a writer defined by the user that replaces stderr
202	errWriter io.Writer
203}
204
205// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
206// particularly useful when testing.
207func (c *Command) SetArgs(a []string) {
208	c.args = a
209}
210
211// SetOutput sets the destination for usage and error messages.
212// If output is nil, os.Stderr is used.
213// Deprecated: Use SetOut and/or SetErr instead
214func (c *Command) SetOutput(output io.Writer) {
215	c.outWriter = output
216	c.errWriter = output
217}
218
219// SetOut sets the destination for usage messages.
220// If newOut is nil, os.Stdout is used.
221func (c *Command) SetOut(newOut io.Writer) {
222	c.outWriter = newOut
223}
224
225// SetErr sets the destination for error messages.
226// If newErr is nil, os.Stderr is used.
227func (c *Command) SetErr(newErr io.Writer) {
228	c.errWriter = newErr
229}
230
231// SetOut sets the source for input data
232// If newIn is nil, os.Stdin is used.
233func (c *Command) SetIn(newIn io.Reader) {
234	c.inReader = newIn
235}
236
237// SetUsageFunc sets usage function. Usage can be defined by application.
238func (c *Command) SetUsageFunc(f func(*Command) error) {
239	c.usageFunc = f
240}
241
242// SetUsageTemplate sets usage template. Can be defined by Application.
243func (c *Command) SetUsageTemplate(s string) {
244	c.usageTemplate = s
245}
246
247// SetFlagErrorFunc sets a function to generate an error when flag parsing
248// fails.
249func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
250	c.flagErrorFunc = f
251}
252
253// SetHelpFunc sets help function. Can be defined by Application.
254func (c *Command) SetHelpFunc(f func(*Command, []string)) {
255	c.helpFunc = f
256}
257
258// SetHelpCommand sets help command.
259func (c *Command) SetHelpCommand(cmd *Command) {
260	c.helpCommand = cmd
261}
262
263// SetHelpTemplate sets help template to be used. Application can use it to set custom template.
264func (c *Command) SetHelpTemplate(s string) {
265	c.helpTemplate = s
266}
267
268// SetVersionTemplate sets version template to be used. Application can use it to set custom template.
269func (c *Command) SetVersionTemplate(s string) {
270	c.versionTemplate = s
271}
272
273// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
274// The user should not have a cyclic dependency on commands.
275func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
276	c.Flags().SetNormalizeFunc(n)
277	c.PersistentFlags().SetNormalizeFunc(n)
278	c.globNormFunc = n
279
280	for _, command := range c.commands {
281		command.SetGlobalNormalizationFunc(n)
282	}
283}
284
285// OutOrStdout returns output to stdout.
286func (c *Command) OutOrStdout() io.Writer {
287	return c.getOut(os.Stdout)
288}
289
290// OutOrStderr returns output to stderr
291func (c *Command) OutOrStderr() io.Writer {
292	return c.getOut(os.Stderr)
293}
294
295// ErrOrStderr returns output to stderr
296func (c *Command) ErrOrStderr() io.Writer {
297	return c.getErr(os.Stderr)
298}
299
300// ErrOrStderr returns output to stderr
301func (c *Command) InOrStdin() io.Reader {
302	return c.getIn(os.Stdin)
303}
304
305func (c *Command) getOut(def io.Writer) io.Writer {
306	if c.outWriter != nil {
307		return c.outWriter
308	}
309	if c.HasParent() {
310		return c.parent.getOut(def)
311	}
312	return def
313}
314
315func (c *Command) getErr(def io.Writer) io.Writer {
316	if c.errWriter != nil {
317		return c.errWriter
318	}
319	if c.HasParent() {
320		return c.parent.getErr(def)
321	}
322	return def
323}
324
325func (c *Command) getIn(def io.Reader) io.Reader {
326	if c.inReader != nil {
327		return c.inReader
328	}
329	if c.HasParent() {
330		return c.parent.getIn(def)
331	}
332	return def
333}
334
335// UsageFunc returns either the function set by SetUsageFunc for this command
336// or a parent, or it returns a default usage function.
337func (c *Command) UsageFunc() (f func(*Command) error) {
338	if c.usageFunc != nil {
339		return c.usageFunc
340	}
341	if c.HasParent() {
342		return c.Parent().UsageFunc()
343	}
344	return func(c *Command) error {
345		c.mergePersistentFlags()
346		err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c)
347		if err != nil {
348			c.Println(err)
349		}
350		return err
351	}
352}
353
354// Usage puts out the usage for the command.
355// Used when a user provides invalid input.
356// Can be defined by user by overriding UsageFunc.
357func (c *Command) Usage() error {
358	return c.UsageFunc()(c)
359}
360
361// HelpFunc returns either the function set by SetHelpFunc for this command
362// or a parent, or it returns a function with default help behavior.
363func (c *Command) HelpFunc() func(*Command, []string) {
364	if c.helpFunc != nil {
365		return c.helpFunc
366	}
367	if c.HasParent() {
368		return c.Parent().HelpFunc()
369	}
370	return func(c *Command, a []string) {
371		c.mergePersistentFlags()
372		err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
373		if err != nil {
374			c.Println(err)
375		}
376	}
377}
378
379// Help puts out the help for the command.
380// Used when a user calls help [command].
381// Can be defined by user by overriding HelpFunc.
382func (c *Command) Help() error {
383	c.HelpFunc()(c, []string{})
384	return nil
385}
386
387// UsageString returns usage string.
388func (c *Command) UsageString() string {
389	// Storing normal writers
390	tmpOutput := c.outWriter
391	tmpErr := c.errWriter
392
393	bb := new(bytes.Buffer)
394	c.outWriter = bb
395	c.errWriter = bb
396
397	c.Usage()
398
399	// Setting things back to normal
400	c.outWriter = tmpOutput
401	c.errWriter = tmpErr
402
403	return bb.String()
404}
405
406// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
407// command or a parent, or it returns a function which returns the original
408// error.
409func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
410	if c.flagErrorFunc != nil {
411		return c.flagErrorFunc
412	}
413
414	if c.HasParent() {
415		return c.parent.FlagErrorFunc()
416	}
417	return func(c *Command, err error) error {
418		return err
419	}
420}
421
422var minUsagePadding = 25
423
424// UsagePadding return padding for the usage.
425func (c *Command) UsagePadding() int {
426	if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
427		return minUsagePadding
428	}
429	return c.parent.commandsMaxUseLen
430}
431
432var minCommandPathPadding = 11
433
434// CommandPathPadding return padding for the command path.
435func (c *Command) CommandPathPadding() int {
436	if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
437		return minCommandPathPadding
438	}
439	return c.parent.commandsMaxCommandPathLen
440}
441
442var minNamePadding = 11
443
444// NamePadding returns padding for the name.
445func (c *Command) NamePadding() int {
446	if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
447		return minNamePadding
448	}
449	return c.parent.commandsMaxNameLen
450}
451
452// UsageTemplate returns usage template for the command.
453func (c *Command) UsageTemplate() string {
454	if c.usageTemplate != "" {
455		return c.usageTemplate
456	}
457
458	if c.HasParent() {
459		return c.parent.UsageTemplate()
460	}
461	return `Usage:{{if .Runnable}}
462  {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
463  {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
464
465Aliases:
466  {{.NameAndAliases}}{{end}}{{if .HasExample}}
467
468Examples:
469{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
470
471Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
472  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
473
474Flags:
475{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
476
477Global Flags:
478{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
479
480Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
481  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
482
483Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
484`
485}
486
487// HelpTemplate return help template for the command.
488func (c *Command) HelpTemplate() string {
489	if c.helpTemplate != "" {
490		return c.helpTemplate
491	}
492
493	if c.HasParent() {
494		return c.parent.HelpTemplate()
495	}
496	return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}
497
498{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
499}
500
501// VersionTemplate return version template for the command.
502func (c *Command) VersionTemplate() string {
503	if c.versionTemplate != "" {
504		return c.versionTemplate
505	}
506
507	if c.HasParent() {
508		return c.parent.VersionTemplate()
509	}
510	return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}}
511`
512}
513
514func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
515	flag := fs.Lookup(name)
516	if flag == nil {
517		return false
518	}
519	return flag.NoOptDefVal != ""
520}
521
522func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
523	if len(name) == 0 {
524		return false
525	}
526
527	flag := fs.ShorthandLookup(name[:1])
528	if flag == nil {
529		return false
530	}
531	return flag.NoOptDefVal != ""
532}
533
534func stripFlags(args []string, c *Command) []string {
535	if len(args) == 0 {
536		return args
537	}
538	c.mergePersistentFlags()
539
540	commands := []string{}
541	flags := c.Flags()
542
543Loop:
544	for len(args) > 0 {
545		s := args[0]
546		args = args[1:]
547		switch {
548		case s == "--":
549			// "--" terminates the flags
550			break Loop
551		case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
552			// If '--flag arg' then
553			// delete arg from args.
554			fallthrough // (do the same as below)
555		case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
556			// If '-f arg' then
557			// delete 'arg' from args or break the loop if len(args) <= 1.
558			if len(args) <= 1 {
559				break Loop
560			} else {
561				args = args[1:]
562				continue
563			}
564		case s != "" && !strings.HasPrefix(s, "-"):
565			commands = append(commands, s)
566		}
567	}
568
569	return commands
570}
571
572// argsMinusFirstX removes only the first x from args.  Otherwise, commands that look like
573// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
574func argsMinusFirstX(args []string, x string) []string {
575	for i, y := range args {
576		if x == y {
577			ret := []string{}
578			ret = append(ret, args[:i]...)
579			ret = append(ret, args[i+1:]...)
580			return ret
581		}
582	}
583	return args
584}
585
586func isFlagArg(arg string) bool {
587	return ((len(arg) >= 3 && arg[1] == '-') ||
588		(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
589}
590
591// Find the target command given the args and command tree
592// Meant to be run on the highest node. Only searches down.
593func (c *Command) Find(args []string) (*Command, []string, error) {
594	var innerfind func(*Command, []string) (*Command, []string)
595
596	innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
597		argsWOflags := stripFlags(innerArgs, c)
598		if len(argsWOflags) == 0 {
599			return c, innerArgs
600		}
601		nextSubCmd := argsWOflags[0]
602
603		cmd := c.findNext(nextSubCmd)
604		if cmd != nil {
605			return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
606		}
607		return c, innerArgs
608	}
609
610	commandFound, a := innerfind(c, args)
611	if commandFound.Args == nil {
612		return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))
613	}
614	return commandFound, a, nil
615}
616
617func (c *Command) findSuggestions(arg string) string {
618	if c.DisableSuggestions {
619		return ""
620	}
621	if c.SuggestionsMinimumDistance <= 0 {
622		c.SuggestionsMinimumDistance = 2
623	}
624	suggestionsString := ""
625	if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
626		suggestionsString += "\n\nDid you mean this?\n"
627		for _, s := range suggestions {
628			suggestionsString += fmt.Sprintf("\t%v\n", s)
629		}
630	}
631	return suggestionsString
632}
633
634func (c *Command) findNext(next string) *Command {
635	matches := make([]*Command, 0)
636	for _, cmd := range c.commands {
637		if cmd.Name() == next || cmd.HasAlias(next) {
638			cmd.commandCalledAs.name = next
639			return cmd
640		}
641		if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
642			matches = append(matches, cmd)
643		}
644	}
645
646	if len(matches) == 1 {
647		return matches[0]
648	}
649
650	return nil
651}
652
653// Traverse the command tree to find the command, and parse args for
654// each parent.
655func (c *Command) Traverse(args []string) (*Command, []string, error) {
656	flags := []string{}
657	inFlag := false
658
659	for i, arg := range args {
660		switch {
661		// A long flag with a space separated value
662		case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
663			// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
664			inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
665			flags = append(flags, arg)
666			continue
667		// A short flag with a space separated value
668		case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
669			inFlag = true
670			flags = append(flags, arg)
671			continue
672		// The value for a flag
673		case inFlag:
674			inFlag = false
675			flags = append(flags, arg)
676			continue
677		// A flag without a value, or with an `=` separated value
678		case isFlagArg(arg):
679			flags = append(flags, arg)
680			continue
681		}
682
683		cmd := c.findNext(arg)
684		if cmd == nil {
685			return c, args, nil
686		}
687
688		if err := c.ParseFlags(flags); err != nil {
689			return nil, args, err
690		}
691		return cmd.Traverse(args[i+1:])
692	}
693	return c, args, nil
694}
695
696// SuggestionsFor provides suggestions for the typedName.
697func (c *Command) SuggestionsFor(typedName string) []string {
698	suggestions := []string{}
699	for _, cmd := range c.commands {
700		if cmd.IsAvailableCommand() {
701			levenshteinDistance := ld(typedName, cmd.Name(), true)
702			suggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance
703			suggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName))
704			if suggestByLevenshtein || suggestByPrefix {
705				suggestions = append(suggestions, cmd.Name())
706			}
707			for _, explicitSuggestion := range cmd.SuggestFor {
708				if strings.EqualFold(typedName, explicitSuggestion) {
709					suggestions = append(suggestions, cmd.Name())
710				}
711			}
712		}
713	}
714	return suggestions
715}
716
717// VisitParents visits all parents of the command and invokes fn on each parent.
718func (c *Command) VisitParents(fn func(*Command)) {
719	if c.HasParent() {
720		fn(c.Parent())
721		c.Parent().VisitParents(fn)
722	}
723}
724
725// Root finds root command.
726func (c *Command) Root() *Command {
727	if c.HasParent() {
728		return c.Parent().Root()
729	}
730	return c
731}
732
733// ArgsLenAtDash will return the length of c.Flags().Args at the moment
734// when a -- was found during args parsing.
735func (c *Command) ArgsLenAtDash() int {
736	return c.Flags().ArgsLenAtDash()
737}
738
739func (c *Command) execute(a []string) (err error) {
740	if c == nil {
741		return fmt.Errorf("Called Execute() on a nil Command")
742	}
743
744	if len(c.Deprecated) > 0 {
745		c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
746	}
747
748	// initialize help and version flag at the last point possible to allow for user
749	// overriding
750	c.InitDefaultHelpFlag()
751	c.InitDefaultVersionFlag()
752
753	err = c.ParseFlags(a)
754	if err != nil {
755		return c.FlagErrorFunc()(c, err)
756	}
757
758	// If help is called, regardless of other flags, return we want help.
759	// Also say we need help if the command isn't runnable.
760	helpVal, err := c.Flags().GetBool("help")
761	if err != nil {
762		// should be impossible to get here as we always declare a help
763		// flag in InitDefaultHelpFlag()
764		c.Println("\"help\" flag declared as non-bool. Please correct your code")
765		return err
766	}
767
768	if helpVal {
769		return flag.ErrHelp
770	}
771
772	// for back-compat, only add version flag behavior if version is defined
773	if c.Version != "" {
774		versionVal, err := c.Flags().GetBool("version")
775		if err != nil {
776			c.Println("\"version\" flag declared as non-bool. Please correct your code")
777			return err
778		}
779		if versionVal {
780			err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c)
781			if err != nil {
782				c.Println(err)
783			}
784			return err
785		}
786	}
787
788	if !c.Runnable() {
789		return flag.ErrHelp
790	}
791
792	c.preRun()
793
794	argWoFlags := c.Flags().Args()
795	if c.DisableFlagParsing {
796		argWoFlags = a
797	}
798
799	if err := c.ValidateArgs(argWoFlags); err != nil {
800		return err
801	}
802
803	for p := c; p != nil; p = p.Parent() {
804		if p.PersistentPreRunE != nil {
805			if err := p.PersistentPreRunE(c, argWoFlags); err != nil {
806				return err
807			}
808			break
809		} else if p.PersistentPreRun != nil {
810			p.PersistentPreRun(c, argWoFlags)
811			break
812		}
813	}
814	if c.PreRunE != nil {
815		if err := c.PreRunE(c, argWoFlags); err != nil {
816			return err
817		}
818	} else if c.PreRun != nil {
819		c.PreRun(c, argWoFlags)
820	}
821
822	if err := c.validateRequiredFlags(); err != nil {
823		return err
824	}
825	if c.RunE != nil {
826		if err := c.RunE(c, argWoFlags); err != nil {
827			return err
828		}
829	} else {
830		c.Run(c, argWoFlags)
831	}
832	if c.PostRunE != nil {
833		if err := c.PostRunE(c, argWoFlags); err != nil {
834			return err
835		}
836	} else if c.PostRun != nil {
837		c.PostRun(c, argWoFlags)
838	}
839	for p := c; p != nil; p = p.Parent() {
840		if p.PersistentPostRunE != nil {
841			if err := p.PersistentPostRunE(c, argWoFlags); err != nil {
842				return err
843			}
844			break
845		} else if p.PersistentPostRun != nil {
846			p.PersistentPostRun(c, argWoFlags)
847			break
848		}
849	}
850
851	return nil
852}
853
854func (c *Command) preRun() {
855	for _, x := range initializers {
856		x()
857	}
858}
859
860// Execute uses the args (os.Args[1:] by default)
861// and run through the command tree finding appropriate matches
862// for commands and then corresponding flags.
863func (c *Command) Execute() error {
864	_, err := c.ExecuteC()
865	return err
866}
867
868// ExecuteC executes the command.
869func (c *Command) ExecuteC() (cmd *Command, err error) {
870	// Regardless of what command execute is called on, run on Root only
871	if c.HasParent() {
872		return c.Root().ExecuteC()
873	}
874
875	// windows hook
876	if preExecHookFn != nil {
877		preExecHookFn(c)
878	}
879
880	// initialize help as the last point possible to allow for user
881	// overriding
882	c.InitDefaultHelpCmd()
883
884	args := c.args
885
886	// Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
887	if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
888		args = os.Args[1:]
889	}
890
891	var flags []string
892	if c.TraverseChildren {
893		cmd, flags, err = c.Traverse(args)
894	} else {
895		cmd, flags, err = c.Find(args)
896	}
897	if err != nil {
898		// If found parse to a subcommand and then failed, talk about the subcommand
899		if cmd != nil {
900			c = cmd
901		}
902		if !c.SilenceErrors {
903			c.Println("Error:", err.Error())
904			c.Printf("Run '%v --help' for usage.\n", c.CommandPath())
905		}
906		return c, err
907	}
908
909	cmd.commandCalledAs.called = true
910	if cmd.commandCalledAs.name == "" {
911		cmd.commandCalledAs.name = cmd.Name()
912	}
913
914	err = cmd.execute(flags)
915	if err != nil {
916		// Always show help if requested, even if SilenceErrors is in
917		// effect
918		if err == flag.ErrHelp {
919			cmd.HelpFunc()(cmd, args)
920			return cmd, nil
921		}
922
923		// If root command has SilentErrors flagged,
924		// all subcommands should respect it
925		if !cmd.SilenceErrors && !c.SilenceErrors {
926			c.Println("Error:", err.Error())
927		}
928
929		// If root command has SilentUsage flagged,
930		// all subcommands should respect it
931		if !cmd.SilenceUsage && !c.SilenceUsage {
932			c.Println(cmd.UsageString())
933		}
934	}
935	return cmd, err
936}
937
938func (c *Command) ValidateArgs(args []string) error {
939	if c.Args == nil {
940		return nil
941	}
942	return c.Args(c, args)
943}
944
945func (c *Command) validateRequiredFlags() error {
946	flags := c.Flags()
947	missingFlagNames := []string{}
948	flags.VisitAll(func(pflag *flag.Flag) {
949		requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
950		if !found {
951			return
952		}
953		if (requiredAnnotation[0] == "true") && !pflag.Changed {
954			missingFlagNames = append(missingFlagNames, pflag.Name)
955		}
956	})
957
958	if len(missingFlagNames) > 0 {
959		return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missingFlagNames, `", "`))
960	}
961	return nil
962}
963
964// InitDefaultHelpFlag adds default help flag to c.
965// It is called automatically by executing the c or by calling help and usage.
966// If c already has help flag, it will do nothing.
967func (c *Command) InitDefaultHelpFlag() {
968	c.mergePersistentFlags()
969	if c.Flags().Lookup("help") == nil {
970		usage := "help for "
971		if c.Name() == "" {
972			usage += "this command"
973		} else {
974			usage += c.Name()
975		}
976		c.Flags().BoolP("help", "h", false, usage)
977	}
978}
979
980// InitDefaultVersionFlag adds default version flag to c.
981// It is called automatically by executing the c.
982// If c already has a version flag, it will do nothing.
983// If c.Version is empty, it will do nothing.
984func (c *Command) InitDefaultVersionFlag() {
985	if c.Version == "" {
986		return
987	}
988
989	c.mergePersistentFlags()
990	if c.Flags().Lookup("version") == nil {
991		usage := "version for "
992		if c.Name() == "" {
993			usage += "this command"
994		} else {
995			usage += c.Name()
996		}
997		c.Flags().Bool("version", false, usage)
998	}
999}
1000
1001// InitDefaultHelpCmd adds default help command to c.
1002// It is called automatically by executing the c or by calling help and usage.
1003// If c already has help command or c has no subcommands, it will do nothing.
1004func (c *Command) InitDefaultHelpCmd() {
1005	if !c.HasSubCommands() {
1006		return
1007	}
1008
1009	if c.helpCommand == nil {
1010		c.helpCommand = &Command{
1011			Use:   "help [command]",
1012			Short: "Help about any command",
1013			Long: `Help provides help for any command in the application.
1014Simply type ` + c.Name() + ` help [path to command] for full details.`,
1015
1016			Run: func(c *Command, args []string) {
1017				cmd, _, e := c.Root().Find(args)
1018				if cmd == nil || e != nil {
1019					c.Printf("Unknown help topic %#q\n", args)
1020					c.Root().Usage()
1021				} else {
1022					cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
1023					cmd.Help()
1024				}
1025			},
1026		}
1027	}
1028	c.RemoveCommand(c.helpCommand)
1029	c.AddCommand(c.helpCommand)
1030}
1031
1032// ResetCommands delete parent, subcommand and help command from c.
1033func (c *Command) ResetCommands() {
1034	c.parent = nil
1035	c.commands = nil
1036	c.helpCommand = nil
1037	c.parentsPflags = nil
1038}
1039
1040// Sorts commands by their names.
1041type commandSorterByName []*Command
1042
1043func (c commandSorterByName) Len() int           { return len(c) }
1044func (c commandSorterByName) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }
1045func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() }
1046
1047// Commands returns a sorted slice of child commands.
1048func (c *Command) Commands() []*Command {
1049	// do not sort commands if it already sorted or sorting was disabled
1050	if EnableCommandSorting && !c.commandsAreSorted {
1051		sort.Sort(commandSorterByName(c.commands))
1052		c.commandsAreSorted = true
1053	}
1054	return c.commands
1055}
1056
1057// AddCommand adds one or more commands to this parent command.
1058func (c *Command) AddCommand(cmds ...*Command) {
1059	for i, x := range cmds {
1060		if cmds[i] == c {
1061			panic("Command can't be a child of itself")
1062		}
1063		cmds[i].parent = c
1064		// update max lengths
1065		usageLen := len(x.Use)
1066		if usageLen > c.commandsMaxUseLen {
1067			c.commandsMaxUseLen = usageLen
1068		}
1069		commandPathLen := len(x.CommandPath())
1070		if commandPathLen > c.commandsMaxCommandPathLen {
1071			c.commandsMaxCommandPathLen = commandPathLen
1072		}
1073		nameLen := len(x.Name())
1074		if nameLen > c.commandsMaxNameLen {
1075			c.commandsMaxNameLen = nameLen
1076		}
1077		// If global normalization function exists, update all children
1078		if c.globNormFunc != nil {
1079			x.SetGlobalNormalizationFunc(c.globNormFunc)
1080		}
1081		c.commands = append(c.commands, x)
1082		c.commandsAreSorted = false
1083	}
1084}
1085
1086// RemoveCommand removes one or more commands from a parent command.
1087func (c *Command) RemoveCommand(cmds ...*Command) {
1088	commands := []*Command{}
1089main:
1090	for _, command := range c.commands {
1091		for _, cmd := range cmds {
1092			if command == cmd {
1093				command.parent = nil
1094				continue main
1095			}
1096		}
1097		commands = append(commands, command)
1098	}
1099	c.commands = commands
1100	// recompute all lengths
1101	c.commandsMaxUseLen = 0
1102	c.commandsMaxCommandPathLen = 0
1103	c.commandsMaxNameLen = 0
1104	for _, command := range c.commands {
1105		usageLen := len(command.Use)
1106		if usageLen > c.commandsMaxUseLen {
1107			c.commandsMaxUseLen = usageLen
1108		}
1109		commandPathLen := len(command.CommandPath())
1110		if commandPathLen > c.commandsMaxCommandPathLen {
1111			c.commandsMaxCommandPathLen = commandPathLen
1112		}
1113		nameLen := len(command.Name())
1114		if nameLen > c.commandsMaxNameLen {
1115			c.commandsMaxNameLen = nameLen
1116		}
1117	}
1118}
1119
1120// Print is a convenience method to Print to the defined output, fallback to Stderr if not set.
1121func (c *Command) Print(i ...interface{}) {
1122	fmt.Fprint(c.OutOrStderr(), i...)
1123}
1124
1125// Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
1126func (c *Command) Println(i ...interface{}) {
1127	c.Print(fmt.Sprintln(i...))
1128}
1129
1130// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
1131func (c *Command) Printf(format string, i ...interface{}) {
1132	c.Print(fmt.Sprintf(format, i...))
1133}
1134
1135// PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set.
1136func (c *Command) PrintErr(i ...interface{}) {
1137	fmt.Fprint(c.ErrOrStderr(), i...)
1138}
1139
1140// PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set.
1141func (c *Command) PrintErrln(i ...interface{}) {
1142	c.Print(fmt.Sprintln(i...))
1143}
1144
1145// PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set.
1146func (c *Command) PrintErrf(format string, i ...interface{}) {
1147	c.Print(fmt.Sprintf(format, i...))
1148}
1149
1150// CommandPath returns the full path to this command.
1151func (c *Command) CommandPath() string {
1152	if c.HasParent() {
1153		return c.Parent().CommandPath() + " " + c.Name()
1154	}
1155	return c.Name()
1156}
1157
1158// UseLine puts out the full usage for a given command (including parents).
1159func (c *Command) UseLine() string {
1160	var useline string
1161	if c.HasParent() {
1162		useline = c.parent.CommandPath() + " " + c.Use
1163	} else {
1164		useline = c.Use
1165	}
1166	if c.DisableFlagsInUseLine {
1167		return useline
1168	}
1169	if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
1170		useline += " [flags]"
1171	}
1172	return useline
1173}
1174
1175// DebugFlags used to determine which flags have been assigned to which commands
1176// and which persist.
1177func (c *Command) DebugFlags() {
1178	c.Println("DebugFlags called on", c.Name())
1179	var debugflags func(*Command)
1180
1181	debugflags = func(x *Command) {
1182		if x.HasFlags() || x.HasPersistentFlags() {
1183			c.Println(x.Name())
1184		}
1185		if x.HasFlags() {
1186			x.flags.VisitAll(func(f *flag.Flag) {
1187				if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {
1188					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [LP]")
1189				} else {
1190					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
1191				}
1192			})
1193		}
1194		if x.HasPersistentFlags() {
1195			x.pflags.VisitAll(func(f *flag.Flag) {
1196				if x.HasFlags() {
1197					if x.flags.Lookup(f.Name) == nil {
1198						c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
1199					}
1200				} else {
1201					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
1202				}
1203			})
1204		}
1205		c.Println(x.flagErrorBuf)
1206		if x.HasSubCommands() {
1207			for _, y := range x.commands {
1208				debugflags(y)
1209			}
1210		}
1211	}
1212
1213	debugflags(c)
1214}
1215
1216// Name returns the command's name: the first word in the use line.
1217func (c *Command) Name() string {
1218	name := c.Use
1219	i := strings.Index(name, " ")
1220	if i >= 0 {
1221		name = name[:i]
1222	}
1223	return name
1224}
1225
1226// HasAlias determines if a given string is an alias of the command.
1227func (c *Command) HasAlias(s string) bool {
1228	for _, a := range c.Aliases {
1229		if a == s {
1230			return true
1231		}
1232	}
1233	return false
1234}
1235
1236// CalledAs returns the command name or alias that was used to invoke
1237// this command or an empty string if the command has not been called.
1238func (c *Command) CalledAs() string {
1239	if c.commandCalledAs.called {
1240		return c.commandCalledAs.name
1241	}
1242	return ""
1243}
1244
1245// hasNameOrAliasPrefix returns true if the Name or any of aliases start
1246// with prefix
1247func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
1248	if strings.HasPrefix(c.Name(), prefix) {
1249		c.commandCalledAs.name = c.Name()
1250		return true
1251	}
1252	for _, alias := range c.Aliases {
1253		if strings.HasPrefix(alias, prefix) {
1254			c.commandCalledAs.name = alias
1255			return true
1256		}
1257	}
1258	return false
1259}
1260
1261// NameAndAliases returns a list of the command name and all aliases
1262func (c *Command) NameAndAliases() string {
1263	return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
1264}
1265
1266// HasExample determines if the command has example.
1267func (c *Command) HasExample() bool {
1268	return len(c.Example) > 0
1269}
1270
1271// Runnable determines if the command is itself runnable.
1272func (c *Command) Runnable() bool {
1273	return c.Run != nil || c.RunE != nil
1274}
1275
1276// HasSubCommands determines if the command has children commands.
1277func (c *Command) HasSubCommands() bool {
1278	return len(c.commands) > 0
1279}
1280
1281// IsAvailableCommand determines if a command is available as a non-help command
1282// (this includes all non deprecated/hidden commands).
1283func (c *Command) IsAvailableCommand() bool {
1284	if len(c.Deprecated) != 0 || c.Hidden {
1285		return false
1286	}
1287
1288	if c.HasParent() && c.Parent().helpCommand == c {
1289		return false
1290	}
1291
1292	if c.Runnable() || c.HasAvailableSubCommands() {
1293		return true
1294	}
1295
1296	return false
1297}
1298
1299// IsAdditionalHelpTopicCommand determines if a command is an additional
1300// help topic command; additional help topic command is determined by the
1301// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that
1302// are runnable/hidden/deprecated.
1303// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.
1304func (c *Command) IsAdditionalHelpTopicCommand() bool {
1305	// if a command is runnable, deprecated, or hidden it is not a 'help' command
1306	if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
1307		return false
1308	}
1309
1310	// if any non-help sub commands are found, the command is not a 'help' command
1311	for _, sub := range c.commands {
1312		if !sub.IsAdditionalHelpTopicCommand() {
1313			return false
1314		}
1315	}
1316
1317	// the command either has no sub commands, or no non-help sub commands
1318	return true
1319}
1320
1321// HasHelpSubCommands determines if a command has any available 'help' sub commands
1322// that need to be shown in the usage/help default template under 'additional help
1323// topics'.
1324func (c *Command) HasHelpSubCommands() bool {
1325	// return true on the first found available 'help' sub command
1326	for _, sub := range c.commands {
1327		if sub.IsAdditionalHelpTopicCommand() {
1328			return true
1329		}
1330	}
1331
1332	// the command either has no sub commands, or no available 'help' sub commands
1333	return false
1334}
1335
1336// HasAvailableSubCommands determines if a command has available sub commands that
1337// need to be shown in the usage/help default template under 'available commands'.
1338func (c *Command) HasAvailableSubCommands() bool {
1339	// return true on the first found available (non deprecated/help/hidden)
1340	// sub command
1341	for _, sub := range c.commands {
1342		if sub.IsAvailableCommand() {
1343			return true
1344		}
1345	}
1346
1347	// the command either has no sub commands, or no available (non deprecated/help/hidden)
1348	// sub commands
1349	return false
1350}
1351
1352// HasParent determines if the command is a child command.
1353func (c *Command) HasParent() bool {
1354	return c.parent != nil
1355}
1356
1357// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist.
1358func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
1359	return c.globNormFunc
1360}
1361
1362// Flags returns the complete FlagSet that applies
1363// to this command (local and persistent declared here and by all parents).
1364func (c *Command) Flags() *flag.FlagSet {
1365	if c.flags == nil {
1366		c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1367		if c.flagErrorBuf == nil {
1368			c.flagErrorBuf = new(bytes.Buffer)
1369		}
1370		c.flags.SetOutput(c.flagErrorBuf)
1371	}
1372
1373	return c.flags
1374}
1375
1376// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.
1377func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
1378	persistentFlags := c.PersistentFlags()
1379
1380	out := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1381	c.LocalFlags().VisitAll(func(f *flag.Flag) {
1382		if persistentFlags.Lookup(f.Name) == nil {
1383			out.AddFlag(f)
1384		}
1385	})
1386	return out
1387}
1388
1389// LocalFlags returns the local FlagSet specifically set in the current command.
1390func (c *Command) LocalFlags() *flag.FlagSet {
1391	c.mergePersistentFlags()
1392
1393	if c.lflags == nil {
1394		c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1395		if c.flagErrorBuf == nil {
1396			c.flagErrorBuf = new(bytes.Buffer)
1397		}
1398		c.lflags.SetOutput(c.flagErrorBuf)
1399	}
1400	c.lflags.SortFlags = c.Flags().SortFlags
1401	if c.globNormFunc != nil {
1402		c.lflags.SetNormalizeFunc(c.globNormFunc)
1403	}
1404
1405	addToLocal := func(f *flag.Flag) {
1406		if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
1407			c.lflags.AddFlag(f)
1408		}
1409	}
1410	c.Flags().VisitAll(addToLocal)
1411	c.PersistentFlags().VisitAll(addToLocal)
1412	return c.lflags
1413}
1414
1415// InheritedFlags returns all flags which were inherited from parent commands.
1416func (c *Command) InheritedFlags() *flag.FlagSet {
1417	c.mergePersistentFlags()
1418
1419	if c.iflags == nil {
1420		c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1421		if c.flagErrorBuf == nil {
1422			c.flagErrorBuf = new(bytes.Buffer)
1423		}
1424		c.iflags.SetOutput(c.flagErrorBuf)
1425	}
1426
1427	local := c.LocalFlags()
1428	if c.globNormFunc != nil {
1429		c.iflags.SetNormalizeFunc(c.globNormFunc)
1430	}
1431
1432	c.parentsPflags.VisitAll(func(f *flag.Flag) {
1433		if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
1434			c.iflags.AddFlag(f)
1435		}
1436	})
1437	return c.iflags
1438}
1439
1440// NonInheritedFlags returns all flags which were not inherited from parent commands.
1441func (c *Command) NonInheritedFlags() *flag.FlagSet {
1442	return c.LocalFlags()
1443}
1444
1445// PersistentFlags returns the persistent FlagSet specifically set in the current command.
1446func (c *Command) PersistentFlags() *flag.FlagSet {
1447	if c.pflags == nil {
1448		c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1449		if c.flagErrorBuf == nil {
1450			c.flagErrorBuf = new(bytes.Buffer)
1451		}
1452		c.pflags.SetOutput(c.flagErrorBuf)
1453	}
1454	return c.pflags
1455}
1456
1457// ResetFlags deletes all flags from command.
1458func (c *Command) ResetFlags() {
1459	c.flagErrorBuf = new(bytes.Buffer)
1460	c.flagErrorBuf.Reset()
1461	c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1462	c.flags.SetOutput(c.flagErrorBuf)
1463	c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1464	c.pflags.SetOutput(c.flagErrorBuf)
1465
1466	c.lflags = nil
1467	c.iflags = nil
1468	c.parentsPflags = nil
1469}
1470
1471// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
1472func (c *Command) HasFlags() bool {
1473	return c.Flags().HasFlags()
1474}
1475
1476// HasPersistentFlags checks if the command contains persistent flags.
1477func (c *Command) HasPersistentFlags() bool {
1478	return c.PersistentFlags().HasFlags()
1479}
1480
1481// HasLocalFlags checks if the command has flags specifically declared locally.
1482func (c *Command) HasLocalFlags() bool {
1483	return c.LocalFlags().HasFlags()
1484}
1485
1486// HasInheritedFlags checks if the command has flags inherited from its parent command.
1487func (c *Command) HasInheritedFlags() bool {
1488	return c.InheritedFlags().HasFlags()
1489}
1490
1491// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire
1492// structure) which are not hidden or deprecated.
1493func (c *Command) HasAvailableFlags() bool {
1494	return c.Flags().HasAvailableFlags()
1495}
1496
1497// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.
1498func (c *Command) HasAvailablePersistentFlags() bool {
1499	return c.PersistentFlags().HasAvailableFlags()
1500}
1501
1502// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden
1503// or deprecated.
1504func (c *Command) HasAvailableLocalFlags() bool {
1505	return c.LocalFlags().HasAvailableFlags()
1506}
1507
1508// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are
1509// not hidden or deprecated.
1510func (c *Command) HasAvailableInheritedFlags() bool {
1511	return c.InheritedFlags().HasAvailableFlags()
1512}
1513
1514// Flag climbs up the command tree looking for matching flag.
1515func (c *Command) Flag(name string) (flag *flag.Flag) {
1516	flag = c.Flags().Lookup(name)
1517
1518	if flag == nil {
1519		flag = c.persistentFlag(name)
1520	}
1521
1522	return
1523}
1524
1525// Recursively find matching persistent flag.
1526func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
1527	if c.HasPersistentFlags() {
1528		flag = c.PersistentFlags().Lookup(name)
1529	}
1530
1531	if flag == nil {
1532		c.updateParentsPflags()
1533		flag = c.parentsPflags.Lookup(name)
1534	}
1535	return
1536}
1537
1538// ParseFlags parses persistent flag tree and local flags.
1539func (c *Command) ParseFlags(args []string) error {
1540	if c.DisableFlagParsing {
1541		return nil
1542	}
1543
1544	if c.flagErrorBuf == nil {
1545		c.flagErrorBuf = new(bytes.Buffer)
1546	}
1547	beforeErrorBufLen := c.flagErrorBuf.Len()
1548	c.mergePersistentFlags()
1549
1550	//do it here after merging all flags and just before parse
1551	c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
1552
1553	err := c.Flags().Parse(args)
1554	// Print warnings if they occurred (e.g. deprecated flag messages).
1555	if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
1556		c.Print(c.flagErrorBuf.String())
1557	}
1558
1559	return err
1560}
1561
1562// Parent returns a commands parent command.
1563func (c *Command) Parent() *Command {
1564	return c.parent
1565}
1566
1567// mergePersistentFlags merges c.PersistentFlags() to c.Flags()
1568// and adds missing persistent flags of all parents.
1569func (c *Command) mergePersistentFlags() {
1570	c.updateParentsPflags()
1571	c.Flags().AddFlagSet(c.PersistentFlags())
1572	c.Flags().AddFlagSet(c.parentsPflags)
1573}
1574
1575// updateParentsPflags updates c.parentsPflags by adding
1576// new persistent flags of all parents.
1577// If c.parentsPflags == nil, it makes new.
1578func (c *Command) updateParentsPflags() {
1579	if c.parentsPflags == nil {
1580		c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
1581		c.parentsPflags.SetOutput(c.flagErrorBuf)
1582		c.parentsPflags.SortFlags = false
1583	}
1584
1585	if c.globNormFunc != nil {
1586		c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
1587	}
1588
1589	c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
1590
1591	c.VisitParents(func(parent *Command) {
1592		c.parentsPflags.AddFlagSet(parent.PersistentFlags())
1593	})
1594}
1595