command.go 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359
  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. //Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
  14. //In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
  15. package cobra
  16. import (
  17. "bytes"
  18. "fmt"
  19. "io"
  20. "os"
  21. "path/filepath"
  22. "sort"
  23. "strings"
  24. flag "github.com/spf13/pflag"
  25. )
  26. // Command is just that, a command for your application.
  27. // eg. 'go run' ... 'run' is the command. Cobra requires
  28. // you to define the usage and description as part of your command
  29. // definition to ensure usability.
  30. type Command struct {
  31. // Name is the command name, usually the executable's name.
  32. name string
  33. // The one-line usage message.
  34. Use string
  35. // An array of aliases that can be used instead of the first word in Use.
  36. Aliases []string
  37. // An array of command names for which this command will be suggested - similar to aliases but only suggests.
  38. SuggestFor []string
  39. // The short description shown in the 'help' output.
  40. Short string
  41. // The long message shown in the 'help <this-command>' output.
  42. Long string
  43. // Examples of how to use the command
  44. Example string
  45. // List of all valid non-flag arguments that are accepted in bash completions
  46. ValidArgs []string
  47. // List of aliases for ValidArgs. These are not suggested to the user in the bash
  48. // completion, but accepted if entered manually.
  49. ArgAliases []string
  50. // Expected arguments
  51. Args PositionalArgs
  52. // Custom functions used by the bash autocompletion generator
  53. BashCompletionFunction string
  54. // Is this command deprecated and should print this string when used?
  55. Deprecated string
  56. // Is this command hidden and should NOT show up in the list of available commands?
  57. Hidden bool
  58. // Tags are key/value pairs that can be used by applications to identify or
  59. // group commands
  60. Tags map[string]string
  61. // Full set of flags
  62. flags *flag.FlagSet
  63. // Set of flags childrens of this command will inherit
  64. pflags *flag.FlagSet
  65. // Flags that are declared specifically by this command (not inherited).
  66. lflags *flag.FlagSet
  67. // SilenceErrors is an option to quiet errors down stream
  68. SilenceErrors bool
  69. // Silence Usage is an option to silence usage when an error occurs.
  70. SilenceUsage bool
  71. // The *Run functions are executed in the following order:
  72. // * PersistentPreRun()
  73. // * PreRun()
  74. // * Run()
  75. // * PostRun()
  76. // * PersistentPostRun()
  77. // All functions get the same args, the arguments after the command name
  78. // PersistentPreRun: children of this command will inherit and execute
  79. PersistentPreRun func(cmd *Command, args []string)
  80. // PersistentPreRunE: PersistentPreRun but returns an error
  81. PersistentPreRunE func(cmd *Command, args []string) error
  82. // PreRun: children of this command will not inherit.
  83. PreRun func(cmd *Command, args []string)
  84. // PreRunE: PreRun but returns an error
  85. PreRunE func(cmd *Command, args []string) error
  86. // Run: Typically the actual work function. Most commands will only implement this
  87. Run func(cmd *Command, args []string)
  88. // RunE: Run but returns an error
  89. RunE func(cmd *Command, args []string) error
  90. // PostRun: run after the Run command.
  91. PostRun func(cmd *Command, args []string)
  92. // PostRunE: PostRun but returns an error
  93. PostRunE func(cmd *Command, args []string) error
  94. // PersistentPostRun: children of this command will inherit and execute after PostRun
  95. PersistentPostRun func(cmd *Command, args []string)
  96. // PersistentPostRunE: PersistentPostRun but returns an error
  97. PersistentPostRunE func(cmd *Command, args []string) error
  98. // DisableAutoGenTag remove
  99. DisableAutoGenTag bool
  100. // Commands is the list of commands supported by this program.
  101. commands []*Command
  102. // Parent Command for this command
  103. parent *Command
  104. // max lengths of commands' string lengths for use in padding
  105. commandsMaxUseLen int
  106. commandsMaxCommandPathLen int
  107. commandsMaxNameLen int
  108. // is commands slice are sorted or not
  109. commandsAreSorted bool
  110. flagErrorBuf *bytes.Buffer
  111. args []string // actual args parsed from flags
  112. output *io.Writer // nil means stderr; use Out() method instead
  113. usageFunc func(*Command) error // Usage can be defined by application
  114. usageTemplate string // Can be defined by Application
  115. flagErrorFunc func(*Command, error) error
  116. helpTemplate string // Can be defined by Application
  117. helpFunc func(*Command, []string) // Help can be defined by application
  118. helpCommand *Command // The help command
  119. // The global normalization function that we can use on every pFlag set and children commands
  120. globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
  121. // Disable the suggestions based on Levenshtein distance that go along with 'unknown command' messages
  122. DisableSuggestions bool
  123. // If displaying suggestions, allows to set the minimum levenshtein distance to display, must be > 0
  124. SuggestionsMinimumDistance int
  125. // Disable the flag parsing. If this is true all flags will be passed to the command as arguments.
  126. DisableFlagParsing bool
  127. // TraverseChildren parses flags on all parents before executing child command
  128. TraverseChildren bool
  129. }
  130. // os.Args[1:] by default, if desired, can be overridden
  131. // particularly useful when testing.
  132. func (c *Command) SetArgs(a []string) {
  133. c.args = a
  134. }
  135. func (c *Command) getOut(def io.Writer) io.Writer {
  136. if c.output != nil {
  137. return *c.output
  138. }
  139. if c.HasParent() {
  140. return c.parent.Out()
  141. }
  142. return def
  143. }
  144. func (c *Command) Out() io.Writer {
  145. return c.getOut(os.Stderr)
  146. }
  147. func (c *Command) getOutOrStdout() io.Writer {
  148. return c.getOut(os.Stdout)
  149. }
  150. // SetOutput sets the destination for usage and error messages.
  151. // If output is nil, os.Stderr is used.
  152. func (c *Command) SetOutput(output io.Writer) {
  153. c.output = &output
  154. }
  155. // Usage can be defined by application
  156. func (c *Command) SetUsageFunc(f func(*Command) error) {
  157. c.usageFunc = f
  158. }
  159. // Can be defined by Application
  160. func (c *Command) SetUsageTemplate(s string) {
  161. c.usageTemplate = s
  162. }
  163. // SetFlagErrorFunc sets a function to generate an error when flag parsing
  164. // fails
  165. func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
  166. c.flagErrorFunc = f
  167. }
  168. // Can be defined by Application
  169. func (c *Command) SetHelpFunc(f func(*Command, []string)) {
  170. c.helpFunc = f
  171. }
  172. func (c *Command) SetHelpCommand(cmd *Command) {
  173. c.helpCommand = cmd
  174. }
  175. // Can be defined by Application
  176. func (c *Command) SetHelpTemplate(s string) {
  177. c.helpTemplate = s
  178. }
  179. // SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
  180. // The user should not have a cyclic dependency on commands.
  181. func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
  182. c.Flags().SetNormalizeFunc(n)
  183. c.PersistentFlags().SetNormalizeFunc(n)
  184. c.globNormFunc = n
  185. for _, command := range c.commands {
  186. command.SetGlobalNormalizationFunc(n)
  187. }
  188. }
  189. func (c *Command) UsageFunc() (f func(*Command) error) {
  190. if c.usageFunc != nil {
  191. return c.usageFunc
  192. }
  193. if c.HasParent() {
  194. return c.parent.UsageFunc()
  195. }
  196. return func(c *Command) error {
  197. err := tmpl(c.Out(), c.UsageTemplate(), c)
  198. if err != nil {
  199. fmt.Print(err)
  200. }
  201. return err
  202. }
  203. }
  204. // HelpFunc returns either the function set by SetHelpFunc for this command
  205. // or a parent, or it returns a function which calls c.Help()
  206. func (c *Command) HelpFunc() func(*Command, []string) {
  207. cmd := c
  208. for cmd != nil {
  209. if cmd.helpFunc != nil {
  210. return cmd.helpFunc
  211. }
  212. cmd = cmd.parent
  213. }
  214. return func(*Command, []string) {
  215. err := c.Help()
  216. if err != nil {
  217. c.Println(err)
  218. }
  219. }
  220. }
  221. // FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
  222. // command or a parent, or it returns a function which returns the original
  223. // error.
  224. func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
  225. if c.flagErrorFunc != nil {
  226. return c.flagErrorFunc
  227. }
  228. if c.HasParent() {
  229. return c.parent.FlagErrorFunc()
  230. }
  231. return func(c *Command, err error) error {
  232. return err
  233. }
  234. }
  235. var minUsagePadding = 25
  236. func (c *Command) UsagePadding() int {
  237. if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
  238. return minUsagePadding
  239. }
  240. return c.parent.commandsMaxUseLen
  241. }
  242. var minCommandPathPadding = 11
  243. //
  244. func (c *Command) CommandPathPadding() int {
  245. if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
  246. return minCommandPathPadding
  247. }
  248. return c.parent.commandsMaxCommandPathLen
  249. }
  250. var minNamePadding = 11
  251. func (c *Command) NamePadding() int {
  252. if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
  253. return minNamePadding
  254. }
  255. return c.parent.commandsMaxNameLen
  256. }
  257. func (c *Command) UsageTemplate() string {
  258. if c.usageTemplate != "" {
  259. return c.usageTemplate
  260. }
  261. if c.HasParent() {
  262. return c.parent.UsageTemplate()
  263. }
  264. return `Usage:{{if .Runnable}}
  265. {{if .HasAvailableFlags}}{{appendIfNotPresent .UseLine "[flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
  266. {{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}}
  267. Aliases:
  268. {{.NameAndAliases}}
  269. {{end}}{{if .HasExample}}
  270. Examples:
  271. {{ .Example }}{{end}}{{ if .HasAvailableSubCommands}}
  272. Available Commands:{{range .Commands}}{{if .IsAvailableCommand}}
  273. {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasAvailableLocalFlags}}
  274. Flags:
  275. {{.LocalFlags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasAvailableInheritedFlags}}
  276. Global Flags:
  277. {{.InheritedFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasHelpSubCommands}}
  278. Additional help topics:{{range .Commands}}{{if .IsHelpCommand}}
  279. {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasAvailableSubCommands }}
  280. Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
  281. `
  282. }
  283. func (c *Command) HelpTemplate() string {
  284. if c.helpTemplate != "" {
  285. return c.helpTemplate
  286. }
  287. if c.HasParent() {
  288. return c.parent.HelpTemplate()
  289. }
  290. return `{{with or .Long .Short }}{{. | trim}}
  291. {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
  292. }
  293. // Really only used when casting a command to a commander
  294. func (c *Command) resetChildrensParents() {
  295. for _, x := range c.commands {
  296. x.parent = c
  297. }
  298. }
  299. // Test if the named flag is a boolean flag.
  300. func isBooleanFlag(name string, f *flag.FlagSet) bool {
  301. flag := f.Lookup(name)
  302. if flag == nil {
  303. return false
  304. }
  305. return flag.Value.Type() == "bool"
  306. }
  307. // Test if the named flag is a boolean flag.
  308. func isBooleanShortFlag(name string, f *flag.FlagSet) bool {
  309. result := false
  310. f.VisitAll(func(f *flag.Flag) {
  311. if f.Shorthand == name && f.Value.Type() == "bool" {
  312. result = true
  313. }
  314. })
  315. return result
  316. }
  317. func stripFlags(args []string, c *Command) []string {
  318. if len(args) < 1 {
  319. return args
  320. }
  321. c.mergePersistentFlags()
  322. commands := []string{}
  323. inQuote := false
  324. inFlag := false
  325. for _, y := range args {
  326. if !inQuote {
  327. switch {
  328. case strings.HasPrefix(y, "\""):
  329. inQuote = true
  330. case strings.Contains(y, "=\""):
  331. inQuote = true
  332. case strings.HasPrefix(y, "--") && !strings.Contains(y, "="):
  333. // TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
  334. inFlag = !isBooleanFlag(y[2:], c.Flags())
  335. case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !isBooleanShortFlag(y[1:], c.Flags()):
  336. inFlag = true
  337. case inFlag:
  338. inFlag = false
  339. case y == "":
  340. // strip empty commands, as the go tests expect this to be ok....
  341. case !strings.HasPrefix(y, "-"):
  342. commands = append(commands, y)
  343. inFlag = false
  344. }
  345. }
  346. if strings.HasSuffix(y, "\"") && !strings.HasSuffix(y, "\\\"") {
  347. inQuote = false
  348. }
  349. }
  350. return commands
  351. }
  352. // argsMinusFirstX removes only the first x from args. Otherwise, commands that look like
  353. // openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
  354. func argsMinusFirstX(args []string, x string) []string {
  355. for i, y := range args {
  356. if x == y {
  357. ret := []string{}
  358. ret = append(ret, args[:i]...)
  359. ret = append(ret, args[i+1:]...)
  360. return ret
  361. }
  362. }
  363. return args
  364. }
  365. func isFlagArg(arg string) bool {
  366. return ((len(arg) >= 3 && arg[1] == '-') ||
  367. (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
  368. }
  369. // Find the target command given the args and command tree
  370. // Meant to be run on the highest node. Only searches down.
  371. func (c *Command) Find(args []string) (*Command, []string, error) {
  372. var innerfind func(*Command, []string) (*Command, []string)
  373. innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
  374. argsWOflags := stripFlags(innerArgs, c)
  375. if len(argsWOflags) == 0 {
  376. return c, innerArgs
  377. }
  378. nextSubCmd := argsWOflags[0]
  379. cmd := c.findNext(nextSubCmd)
  380. if cmd != nil {
  381. return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
  382. }
  383. return c, innerArgs
  384. }
  385. commandFound, a := innerfind(c, args)
  386. if commandFound.Args == nil {
  387. return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))
  388. }
  389. return commandFound, a, nil
  390. }
  391. func (c *Command) findNext(next string) *Command {
  392. matches := make([]*Command, 0)
  393. for _, cmd := range c.commands {
  394. if cmd.Name() == next || cmd.HasAlias(next) {
  395. return cmd
  396. }
  397. if EnablePrefixMatching && cmd.HasNameOrAliasPrefix(next) {
  398. matches = append(matches, cmd)
  399. }
  400. }
  401. if len(matches) == 1 {
  402. return matches[0]
  403. }
  404. return nil
  405. }
  406. // Traverse the command tree to find the command, and parse args for
  407. // each parent.
  408. func (c *Command) Traverse(args []string) (*Command, []string, error) {
  409. flags := []string{}
  410. inFlag := false
  411. for i, arg := range args {
  412. switch {
  413. // A long flag with a space separated value
  414. case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
  415. // TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
  416. inFlag = !isBooleanFlag(arg[2:], c.Flags())
  417. flags = append(flags, arg)
  418. continue
  419. // A short flag with a space separated value
  420. case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !isBooleanShortFlag(arg[1:], c.Flags()):
  421. inFlag = true
  422. flags = append(flags, arg)
  423. continue
  424. // The value for a flag
  425. case inFlag:
  426. inFlag = false
  427. flags = append(flags, arg)
  428. continue
  429. // A flag without a value, or with an `=` separated value
  430. case isFlagArg(arg):
  431. flags = append(flags, arg)
  432. continue
  433. }
  434. cmd := c.findNext(arg)
  435. if cmd == nil {
  436. return c, args, nil
  437. }
  438. if err := c.ParseFlags(flags); err != nil {
  439. return nil, args, err
  440. }
  441. return cmd.Traverse(args[i+1:])
  442. }
  443. return c, args, nil
  444. }
  445. func (c *Command) findSuggestions(arg string) string {
  446. if c.DisableSuggestions {
  447. return ""
  448. }
  449. if c.SuggestionsMinimumDistance <= 0 {
  450. c.SuggestionsMinimumDistance = 2
  451. }
  452. suggestionsString := ""
  453. if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
  454. suggestionsString += "\n\nDid you mean this?\n"
  455. for _, s := range suggestions {
  456. suggestionsString += fmt.Sprintf("\t%v\n", s)
  457. }
  458. }
  459. return suggestionsString
  460. }
  461. func (c *Command) SuggestionsFor(typedName string) []string {
  462. suggestions := []string{}
  463. for _, cmd := range c.commands {
  464. if cmd.IsAvailableCommand() {
  465. levenshteinDistance := ld(typedName, cmd.Name(), true)
  466. suggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance
  467. suggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName))
  468. if suggestByLevenshtein || suggestByPrefix {
  469. suggestions = append(suggestions, cmd.Name())
  470. }
  471. for _, explicitSuggestion := range cmd.SuggestFor {
  472. if strings.EqualFold(typedName, explicitSuggestion) {
  473. suggestions = append(suggestions, cmd.Name())
  474. }
  475. }
  476. }
  477. }
  478. return suggestions
  479. }
  480. func (c *Command) VisitParents(fn func(*Command)) {
  481. var traverse func(*Command) *Command
  482. traverse = func(x *Command) *Command {
  483. if x != c {
  484. fn(x)
  485. }
  486. if x.HasParent() {
  487. return traverse(x.parent)
  488. }
  489. return x
  490. }
  491. traverse(c)
  492. }
  493. func (c *Command) Root() *Command {
  494. var findRoot func(*Command) *Command
  495. findRoot = func(x *Command) *Command {
  496. if x.HasParent() {
  497. return findRoot(x.parent)
  498. }
  499. return x
  500. }
  501. return findRoot(c)
  502. }
  503. // ArgsLenAtDash will return the length of f.Args at the moment when a -- was
  504. // found during arg parsing. This allows your program to know which args were
  505. // before the -- and which came after. (Description from
  506. // https://godoc.org/github.com/spf13/pflag#FlagSet.ArgsLenAtDash).
  507. func (c *Command) ArgsLenAtDash() int {
  508. return c.Flags().ArgsLenAtDash()
  509. }
  510. func (c *Command) execute(a []string) (err error) {
  511. if c == nil {
  512. return fmt.Errorf("Called Execute() on a nil Command")
  513. }
  514. if len(c.Deprecated) > 0 {
  515. c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
  516. }
  517. // initialize help flag as the last point possible to allow for user
  518. // overriding
  519. c.initHelpFlag()
  520. err = c.ParseFlags(a)
  521. if err != nil {
  522. return c.FlagErrorFunc()(c, err)
  523. }
  524. // If help is called, regardless of other flags, return we want help
  525. // Also say we need help if the command isn't runnable.
  526. helpVal, err := c.Flags().GetBool("help")
  527. if err != nil {
  528. // should be impossible to get here as we always declare a help
  529. // flag in initHelpFlag()
  530. c.Println("\"help\" flag declared as non-bool. Please correct your code")
  531. return err
  532. }
  533. if helpVal || !c.Runnable() {
  534. return flag.ErrHelp
  535. }
  536. c.preRun()
  537. argWoFlags := c.Flags().Args()
  538. if c.DisableFlagParsing {
  539. argWoFlags = a
  540. }
  541. if err := c.ValidateArgs(argWoFlags); err != nil {
  542. return err
  543. }
  544. for p := c; p != nil; p = p.Parent() {
  545. if p.PersistentPreRunE != nil {
  546. if err := p.PersistentPreRunE(c, argWoFlags); err != nil {
  547. return err
  548. }
  549. break
  550. } else if p.PersistentPreRun != nil {
  551. p.PersistentPreRun(c, argWoFlags)
  552. break
  553. }
  554. }
  555. if c.PreRunE != nil {
  556. if err := c.PreRunE(c, argWoFlags); err != nil {
  557. return err
  558. }
  559. } else if c.PreRun != nil {
  560. c.PreRun(c, argWoFlags)
  561. }
  562. if c.RunE != nil {
  563. if err := c.RunE(c, argWoFlags); err != nil {
  564. return err
  565. }
  566. } else {
  567. c.Run(c, argWoFlags)
  568. }
  569. if c.PostRunE != nil {
  570. if err := c.PostRunE(c, argWoFlags); err != nil {
  571. return err
  572. }
  573. } else if c.PostRun != nil {
  574. c.PostRun(c, argWoFlags)
  575. }
  576. for p := c; p != nil; p = p.Parent() {
  577. if p.PersistentPostRunE != nil {
  578. if err := p.PersistentPostRunE(c, argWoFlags); err != nil {
  579. return err
  580. }
  581. break
  582. } else if p.PersistentPostRun != nil {
  583. p.PersistentPostRun(c, argWoFlags)
  584. break
  585. }
  586. }
  587. return nil
  588. }
  589. func (c *Command) preRun() {
  590. for _, x := range initializers {
  591. x()
  592. }
  593. }
  594. func (c *Command) errorMsgFromParse() string {
  595. s := c.flagErrorBuf.String()
  596. x := strings.Split(s, "\n")
  597. if len(x) > 0 {
  598. return x[0]
  599. }
  600. return ""
  601. }
  602. // Call execute to use the args (os.Args[1:] by default)
  603. // and run through the command tree finding appropriate matches
  604. // for commands and then corresponding flags.
  605. func (c *Command) Execute() error {
  606. _, err := c.ExecuteC()
  607. return err
  608. }
  609. func (c *Command) ExecuteC() (cmd *Command, err error) {
  610. // Regardless of what command execute is called on, run on Root only
  611. if c.HasParent() {
  612. return c.Root().ExecuteC()
  613. }
  614. // windows hook
  615. if preExecHookFn != nil {
  616. preExecHookFn(c)
  617. }
  618. // initialize help as the last point possible to allow for user
  619. // overriding
  620. c.initHelpCmd()
  621. var args []string
  622. // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
  623. if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
  624. args = os.Args[1:]
  625. } else {
  626. args = c.args
  627. }
  628. var flags []string
  629. if c.TraverseChildren {
  630. cmd, flags, err = c.Traverse(args)
  631. } else {
  632. cmd, flags, err = c.Find(args)
  633. }
  634. if err != nil {
  635. // If found parse to a subcommand and then failed, talk about the subcommand
  636. if cmd != nil {
  637. c = cmd
  638. }
  639. if !c.SilenceErrors {
  640. c.Println("Error:", err.Error())
  641. c.Printf("Run '%v --help' for usage.\n", c.CommandPath())
  642. }
  643. return c, err
  644. }
  645. err = cmd.execute(flags)
  646. if err != nil {
  647. // Always show help if requested, even if SilenceErrors is in
  648. // effect
  649. if err == flag.ErrHelp {
  650. cmd.HelpFunc()(cmd, args)
  651. return cmd, nil
  652. }
  653. // If root command has SilentErrors flagged,
  654. // all subcommands should respect it
  655. if !cmd.SilenceErrors && !c.SilenceErrors {
  656. c.Println("Error:", err.Error())
  657. }
  658. // If root command has SilentUsage flagged,
  659. // all subcommands should respect it
  660. if !cmd.SilenceUsage && !c.SilenceUsage {
  661. c.Println(cmd.UsageString())
  662. }
  663. return cmd, err
  664. }
  665. return cmd, nil
  666. }
  667. func (c *Command) ValidateArgs(args []string) error {
  668. if c.Args == nil {
  669. return nil
  670. }
  671. return c.Args(c, args)
  672. }
  673. func (c *Command) initHelpFlag() {
  674. c.mergePersistentFlags()
  675. if c.Flags().Lookup("help") == nil {
  676. c.Flags().BoolP("help", "h", false, "help for "+c.Name())
  677. }
  678. }
  679. func (c *Command) initHelpCmd() {
  680. if c.helpCommand == nil {
  681. if !c.HasSubCommands() {
  682. return
  683. }
  684. c.helpCommand = &Command{
  685. Use: "help [command]",
  686. Short: "Help about any command",
  687. Long: `Help provides help for any command in the application.
  688. Simply type ` + c.Name() + ` help [path to command] for full details.`,
  689. PersistentPreRun: func(cmd *Command, args []string) {},
  690. PersistentPostRun: func(cmd *Command, args []string) {},
  691. Run: func(c *Command, args []string) {
  692. cmd, _, e := c.Root().Find(args)
  693. if cmd == nil || e != nil {
  694. c.Printf("Unknown help topic %#q.", args)
  695. c.Root().Usage()
  696. } else {
  697. helpFunc := cmd.HelpFunc()
  698. helpFunc(cmd, args)
  699. }
  700. },
  701. }
  702. }
  703. c.AddCommand(c.helpCommand)
  704. }
  705. // Used for testing
  706. func (c *Command) ResetCommands() {
  707. c.commands = nil
  708. c.helpCommand = nil
  709. }
  710. // Sorts commands by their names
  711. type commandSorterByName []*Command
  712. func (c commandSorterByName) Len() int { return len(c) }
  713. func (c commandSorterByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
  714. func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() }
  715. // Commands returns a sorted slice of child commands.
  716. func (c *Command) Commands() []*Command {
  717. // do not sort commands if it already sorted or sorting was disabled
  718. if EnableCommandSorting && !c.commandsAreSorted {
  719. sort.Sort(commandSorterByName(c.commands))
  720. c.commandsAreSorted = true
  721. }
  722. return c.commands
  723. }
  724. // AddCommand adds one or more commands to this parent command.
  725. func (c *Command) AddCommand(cmds ...*Command) {
  726. for i, x := range cmds {
  727. if cmds[i] == c {
  728. panic("Command can't be a child of itself")
  729. }
  730. cmds[i].parent = c
  731. // update max lengths
  732. usageLen := len(x.Use)
  733. if usageLen > c.commandsMaxUseLen {
  734. c.commandsMaxUseLen = usageLen
  735. }
  736. commandPathLen := len(x.CommandPath())
  737. if commandPathLen > c.commandsMaxCommandPathLen {
  738. c.commandsMaxCommandPathLen = commandPathLen
  739. }
  740. nameLen := len(x.Name())
  741. if nameLen > c.commandsMaxNameLen {
  742. c.commandsMaxNameLen = nameLen
  743. }
  744. // If global normalization function exists, update all children
  745. if c.globNormFunc != nil {
  746. x.SetGlobalNormalizationFunc(c.globNormFunc)
  747. }
  748. c.commands = append(c.commands, x)
  749. c.commandsAreSorted = false
  750. }
  751. }
  752. // RemoveCommand removes one or more commands from a parent command.
  753. func (c *Command) RemoveCommand(cmds ...*Command) {
  754. commands := []*Command{}
  755. main:
  756. for _, command := range c.commands {
  757. for _, cmd := range cmds {
  758. if command == cmd {
  759. command.parent = nil
  760. continue main
  761. }
  762. }
  763. commands = append(commands, command)
  764. }
  765. c.commands = commands
  766. // recompute all lengths
  767. c.commandsMaxUseLen = 0
  768. c.commandsMaxCommandPathLen = 0
  769. c.commandsMaxNameLen = 0
  770. for _, command := range c.commands {
  771. usageLen := len(command.Use)
  772. if usageLen > c.commandsMaxUseLen {
  773. c.commandsMaxUseLen = usageLen
  774. }
  775. commandPathLen := len(command.CommandPath())
  776. if commandPathLen > c.commandsMaxCommandPathLen {
  777. c.commandsMaxCommandPathLen = commandPathLen
  778. }
  779. nameLen := len(command.Name())
  780. if nameLen > c.commandsMaxNameLen {
  781. c.commandsMaxNameLen = nameLen
  782. }
  783. }
  784. }
  785. // Print is a convenience method to Print to the defined output
  786. func (c *Command) Print(i ...interface{}) {
  787. fmt.Fprint(c.Out(), i...)
  788. }
  789. // Println is a convenience method to Println to the defined output
  790. func (c *Command) Println(i ...interface{}) {
  791. str := fmt.Sprintln(i...)
  792. c.Print(str)
  793. }
  794. // Printf is a convenience method to Printf to the defined output
  795. func (c *Command) Printf(format string, i ...interface{}) {
  796. str := fmt.Sprintf(format, i...)
  797. c.Print(str)
  798. }
  799. // Output the usage for the command
  800. // Used when a user provides invalid input
  801. // Can be defined by user by overriding UsageFunc
  802. func (c *Command) Usage() error {
  803. c.mergePersistentFlags()
  804. err := c.UsageFunc()(c)
  805. return err
  806. }
  807. // Output the help for the command
  808. // Used when a user calls help [command]
  809. // by the default HelpFunc in the commander
  810. func (c *Command) Help() error {
  811. c.mergePersistentFlags()
  812. err := tmpl(c.getOutOrStdout(), c.HelpTemplate(), c)
  813. return err
  814. }
  815. func (c *Command) UsageString() string {
  816. tmpOutput := c.output
  817. bb := new(bytes.Buffer)
  818. c.SetOutput(bb)
  819. c.Usage()
  820. c.output = tmpOutput
  821. return bb.String()
  822. }
  823. // CommandPath returns the full path to this command.
  824. func (c *Command) CommandPath() string {
  825. str := c.Name()
  826. x := c
  827. for x.HasParent() {
  828. str = x.parent.Name() + " " + str
  829. x = x.parent
  830. }
  831. return str
  832. }
  833. //The full usage for a given command (including parents)
  834. func (c *Command) UseLine() string {
  835. str := ""
  836. if c.HasParent() {
  837. str = c.parent.CommandPath() + " "
  838. }
  839. return str + c.Use
  840. }
  841. // For use in determining which flags have been assigned to which commands
  842. // and which persist
  843. func (c *Command) DebugFlags() {
  844. c.Println("DebugFlags called on", c.Name())
  845. var debugflags func(*Command)
  846. debugflags = func(x *Command) {
  847. if x.HasFlags() || x.HasPersistentFlags() {
  848. c.Println(x.Name())
  849. }
  850. if x.HasFlags() {
  851. x.flags.VisitAll(func(f *flag.Flag) {
  852. if x.HasPersistentFlags() {
  853. if x.persistentFlag(f.Name) == nil {
  854. c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
  855. } else {
  856. c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]")
  857. }
  858. } else {
  859. c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
  860. }
  861. })
  862. }
  863. if x.HasPersistentFlags() {
  864. x.pflags.VisitAll(func(f *flag.Flag) {
  865. if x.HasFlags() {
  866. if x.flags.Lookup(f.Name) == nil {
  867. c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
  868. }
  869. } else {
  870. c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
  871. }
  872. })
  873. }
  874. c.Println(x.flagErrorBuf)
  875. if x.HasSubCommands() {
  876. for _, y := range x.commands {
  877. debugflags(y)
  878. }
  879. }
  880. }
  881. debugflags(c)
  882. }
  883. // Name returns the command's name: the first word in the use line.
  884. func (c *Command) Name() string {
  885. if c.name != "" {
  886. return c.name
  887. }
  888. name := c.Use
  889. i := strings.Index(name, " ")
  890. if i >= 0 {
  891. name = name[:i]
  892. }
  893. return name
  894. }
  895. // HasAlias determines if a given string is an alias of the command.
  896. func (c *Command) HasAlias(s string) bool {
  897. for _, a := range c.Aliases {
  898. if a == s {
  899. return true
  900. }
  901. }
  902. return false
  903. }
  904. // HasNameOrAliasPrefix returns true if the Name or any of aliases start
  905. // with prefix
  906. func (c *Command) HasNameOrAliasPrefix(prefix string) bool {
  907. if strings.HasPrefix(c.Name(), prefix) {
  908. return true
  909. }
  910. for _, alias := range c.Aliases {
  911. if strings.HasPrefix(alias, prefix) {
  912. return true
  913. }
  914. }
  915. return false
  916. }
  917. func (c *Command) NameAndAliases() string {
  918. return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
  919. }
  920. func (c *Command) HasExample() bool {
  921. return len(c.Example) > 0
  922. }
  923. // Runnable determines if the command is itself runnable
  924. func (c *Command) Runnable() bool {
  925. return c.Run != nil || c.RunE != nil
  926. }
  927. // HasSubCommands determines if the command has children commands
  928. func (c *Command) HasSubCommands() bool {
  929. return len(c.commands) > 0
  930. }
  931. // IsAvailableCommand determines if a command is available as a non-help command
  932. // (this includes all non deprecated/hidden commands)
  933. func (c *Command) IsAvailableCommand() bool {
  934. if len(c.Deprecated) != 0 || c.Hidden {
  935. return false
  936. }
  937. if c.HasParent() && c.Parent().helpCommand == c {
  938. return false
  939. }
  940. if c.Runnable() || c.HasAvailableSubCommands() {
  941. return true
  942. }
  943. return false
  944. }
  945. // IsHelpCommand determines if a command is a 'help' command; a help command is
  946. // determined by the fact that it is NOT runnable/hidden/deprecated, and has no
  947. // sub commands that are runnable/hidden/deprecated
  948. func (c *Command) IsHelpCommand() bool {
  949. // if a command is runnable, deprecated, or hidden it is not a 'help' command
  950. if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
  951. return false
  952. }
  953. // if any non-help sub commands are found, the command is not a 'help' command
  954. for _, sub := range c.commands {
  955. if !sub.IsHelpCommand() {
  956. return false
  957. }
  958. }
  959. // the command either has no sub commands, or no non-help sub commands
  960. return true
  961. }
  962. // HasHelpSubCommands determines if a command has any avilable 'help' sub commands
  963. // that need to be shown in the usage/help default template under 'additional help
  964. // topics'
  965. func (c *Command) HasHelpSubCommands() bool {
  966. // return true on the first found available 'help' sub command
  967. for _, sub := range c.commands {
  968. if sub.IsHelpCommand() {
  969. return true
  970. }
  971. }
  972. // the command either has no sub commands, or no available 'help' sub commands
  973. return false
  974. }
  975. // HasAvailableSubCommands determines if a command has available sub commands that
  976. // need to be shown in the usage/help default template under 'available commands'
  977. func (c *Command) HasAvailableSubCommands() bool {
  978. // return true on the first found available (non deprecated/help/hidden)
  979. // sub command
  980. for _, sub := range c.commands {
  981. if sub.IsAvailableCommand() {
  982. return true
  983. }
  984. }
  985. // the command either has no sub comamnds, or no available (non deprecated/help/hidden)
  986. // sub commands
  987. return false
  988. }
  989. // Determine if the command is a child command
  990. func (c *Command) HasParent() bool {
  991. return c.parent != nil
  992. }
  993. // GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists
  994. func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
  995. return c.globNormFunc
  996. }
  997. // Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents)
  998. func (c *Command) Flags() *flag.FlagSet {
  999. if c.flags == nil {
  1000. c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1001. if c.flagErrorBuf == nil {
  1002. c.flagErrorBuf = new(bytes.Buffer)
  1003. }
  1004. c.flags.SetOutput(c.flagErrorBuf)
  1005. }
  1006. return c.flags
  1007. }
  1008. // LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands
  1009. func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
  1010. persistentFlags := c.PersistentFlags()
  1011. out := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1012. c.LocalFlags().VisitAll(func(f *flag.Flag) {
  1013. if persistentFlags.Lookup(f.Name) == nil {
  1014. out.AddFlag(f)
  1015. }
  1016. })
  1017. return out
  1018. }
  1019. // Get the local FlagSet specifically set in the current command
  1020. func (c *Command) LocalFlags() *flag.FlagSet {
  1021. c.mergePersistentFlags()
  1022. local := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1023. c.lflags.VisitAll(func(f *flag.Flag) {
  1024. local.AddFlag(f)
  1025. })
  1026. if !c.HasParent() {
  1027. flag.CommandLine.VisitAll(func(f *flag.Flag) {
  1028. if local.Lookup(f.Name) == nil {
  1029. local.AddFlag(f)
  1030. }
  1031. })
  1032. }
  1033. return local
  1034. }
  1035. // All Flags which were inherited from parents commands
  1036. func (c *Command) InheritedFlags() *flag.FlagSet {
  1037. c.mergePersistentFlags()
  1038. inherited := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1039. local := c.LocalFlags()
  1040. var rmerge func(x *Command)
  1041. rmerge = func(x *Command) {
  1042. if x.HasPersistentFlags() {
  1043. x.PersistentFlags().VisitAll(func(f *flag.Flag) {
  1044. if inherited.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
  1045. inherited.AddFlag(f)
  1046. }
  1047. })
  1048. }
  1049. if x.HasParent() {
  1050. rmerge(x.parent)
  1051. }
  1052. }
  1053. if c.HasParent() {
  1054. rmerge(c.parent)
  1055. }
  1056. return inherited
  1057. }
  1058. // All Flags which were not inherited from parent commands
  1059. func (c *Command) NonInheritedFlags() *flag.FlagSet {
  1060. return c.LocalFlags()
  1061. }
  1062. // Get the Persistent FlagSet specifically set in the current command
  1063. func (c *Command) PersistentFlags() *flag.FlagSet {
  1064. if c.pflags == nil {
  1065. c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1066. if c.flagErrorBuf == nil {
  1067. c.flagErrorBuf = new(bytes.Buffer)
  1068. }
  1069. c.pflags.SetOutput(c.flagErrorBuf)
  1070. }
  1071. return c.pflags
  1072. }
  1073. // For use in testing
  1074. func (c *Command) ResetFlags() {
  1075. c.flagErrorBuf = new(bytes.Buffer)
  1076. c.flagErrorBuf.Reset()
  1077. c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1078. c.flags.SetOutput(c.flagErrorBuf)
  1079. c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1080. c.pflags.SetOutput(c.flagErrorBuf)
  1081. }
  1082. // Does the command contain any flags (local plus persistent from the entire structure)
  1083. func (c *Command) HasFlags() bool {
  1084. return c.Flags().HasFlags()
  1085. }
  1086. // Does the command contain persistent flags
  1087. func (c *Command) HasPersistentFlags() bool {
  1088. return c.PersistentFlags().HasFlags()
  1089. }
  1090. // Does the command has flags specifically declared locally
  1091. func (c *Command) HasLocalFlags() bool {
  1092. return c.LocalFlags().HasFlags()
  1093. }
  1094. // Does the command have flags inherited from its parent command
  1095. func (c *Command) HasInheritedFlags() bool {
  1096. return c.InheritedFlags().HasFlags()
  1097. }
  1098. // Does the command contain any flags (local plus persistent from the entire
  1099. // structure) which are not hidden or deprecated
  1100. func (c *Command) HasAvailableFlags() bool {
  1101. return c.Flags().HasAvailableFlags()
  1102. }
  1103. // Does the command contain persistent flags which are not hidden or deprecated
  1104. func (c *Command) HasAvailablePersistentFlags() bool {
  1105. return c.PersistentFlags().HasAvailableFlags()
  1106. }
  1107. // Does the command has flags specifically declared locally which are not hidden
  1108. // or deprecated
  1109. func (c *Command) HasAvailableLocalFlags() bool {
  1110. return c.LocalFlags().HasAvailableFlags()
  1111. }
  1112. // Does the command have flags inherited from its parent command which are
  1113. // not hidden or deprecated
  1114. func (c *Command) HasAvailableInheritedFlags() bool {
  1115. return c.InheritedFlags().HasAvailableFlags()
  1116. }
  1117. // Flag climbs up the command tree looking for matching flag
  1118. func (c *Command) Flag(name string) (flag *flag.Flag) {
  1119. flag = c.Flags().Lookup(name)
  1120. if flag == nil {
  1121. flag = c.persistentFlag(name)
  1122. }
  1123. return
  1124. }
  1125. // recursively find matching persistent flag
  1126. func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
  1127. if c.HasPersistentFlags() {
  1128. flag = c.PersistentFlags().Lookup(name)
  1129. }
  1130. if flag == nil && c.HasParent() {
  1131. flag = c.parent.persistentFlag(name)
  1132. }
  1133. return
  1134. }
  1135. // ParseFlags parses persistent flag tree & local flags
  1136. func (c *Command) ParseFlags(args []string) (err error) {
  1137. if c.DisableFlagParsing {
  1138. return nil
  1139. }
  1140. c.mergePersistentFlags()
  1141. err = c.Flags().Parse(args)
  1142. return
  1143. }
  1144. // Parent returns a commands parent command
  1145. func (c *Command) Parent() *Command {
  1146. return c.parent
  1147. }
  1148. func (c *Command) mergePersistentFlags() {
  1149. var rmerge func(x *Command)
  1150. // Save the set of local flags
  1151. if c.lflags == nil {
  1152. c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
  1153. if c.flagErrorBuf == nil {
  1154. c.flagErrorBuf = new(bytes.Buffer)
  1155. }
  1156. c.lflags.SetOutput(c.flagErrorBuf)
  1157. addtolocal := func(f *flag.Flag) {
  1158. c.lflags.AddFlag(f)
  1159. }
  1160. c.Flags().VisitAll(addtolocal)
  1161. c.PersistentFlags().VisitAll(addtolocal)
  1162. }
  1163. rmerge = func(x *Command) {
  1164. if !x.HasParent() {
  1165. flag.CommandLine.VisitAll(func(f *flag.Flag) {
  1166. if x.PersistentFlags().Lookup(f.Name) == nil {
  1167. x.PersistentFlags().AddFlag(f)
  1168. }
  1169. })
  1170. }
  1171. if x.HasPersistentFlags() {
  1172. x.PersistentFlags().VisitAll(func(f *flag.Flag) {
  1173. if c.Flags().Lookup(f.Name) == nil {
  1174. c.Flags().AddFlag(f)
  1175. }
  1176. })
  1177. }
  1178. if x.HasParent() {
  1179. rmerge(x.parent)
  1180. }
  1181. }
  1182. rmerge(c)
  1183. }