command.go 44 KB

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