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