command.go 41 KB

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