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