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