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