command.go

   1// Copyright 2013-2023 The Cobra Authors
   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//
   7//      http://www.apache.org/licenses/LICENSE-2.0
   8//
   9// Unless required by applicable law or agreed to in writing, software
  10// distributed under the License is distributed on an "AS IS" BASIS,
  11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12// See the License for the specific language governing permissions and
  13// limitations under the License.
  14
  15// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
  16// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
  17package cobra
  18
  19import (
  20	"bytes"
  21	"context"
  22	"errors"
  23	"fmt"
  24	"io"
  25	"os"
  26	"path/filepath"
  27	"sort"
  28	"strings"
  29
  30	flag "github.com/spf13/pflag"
  31)
  32
  33const (
  34	FlagSetByCobraAnnotation     = "cobra_annotation_flag_set_by_cobra"
  35	CommandDisplayNameAnnotation = "cobra_annotation_command_display_name"
  36
  37	helpFlagName    = "help"
  38	helpCommandName = "help"
  39)
  40
  41// FParseErrWhitelist configures Flag parse errors to be ignored
  42type FParseErrWhitelist flag.ParseErrorsWhitelist
  43
  44// Group Structure to manage groups for commands
  45type Group struct {
  46	ID    string
  47	Title string
  48}
  49
  50// Command is just that, a command for your application.
  51// E.g.  'go run ...' - 'run' is the command. Cobra requires
  52// you to define the usage and description as part of your command
  53// definition to ensure usability.
  54type Command struct {
  55	// Use is the one-line usage message.
  56	// Recommended syntax is as follows:
  57	//   [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required.
  58	//   ... indicates that you can specify multiple values for the previous argument.
  59	//   |   indicates mutually exclusive information. You can use the argument to the left of the separator or the
  60	//       argument to the right of the separator. You cannot use both arguments in a single use of the command.
  61	//   { } delimits a set of mutually exclusive arguments when one of the arguments is required. If the arguments are
  62	//       optional, they are enclosed in brackets ([ ]).
  63	// Example: add [-F file | -D dir]... [-f format] profile
  64	Use string
  65
  66	// Aliases is an array of aliases that can be used instead of the first word in Use.
  67	Aliases []string
  68
  69	// SuggestFor is an array of command names for which this command will be suggested -
  70	// similar to aliases but only suggests.
  71	SuggestFor []string
  72
  73	// Short is the short description shown in the 'help' output.
  74	Short string
  75
  76	// The group id under which this subcommand is grouped in the 'help' output of its parent.
  77	GroupID string
  78
  79	// Long is the long message shown in the 'help <this-command>' output.
  80	Long string
  81
  82	// Example is examples of how to use the command.
  83	Example string
  84
  85	// ValidArgs is list of all valid non-flag arguments that are accepted in shell completions
  86	ValidArgs []Completion
  87	// ValidArgsFunction is an optional function that provides valid non-flag arguments for shell completion.
  88	// It is a dynamic version of using ValidArgs.
  89	// Only one of ValidArgs and ValidArgsFunction can be used for a command.
  90	ValidArgsFunction CompletionFunc
  91
  92	// Expected arguments
  93	Args PositionalArgs
  94
  95	// ArgAliases is List of aliases for ValidArgs.
  96	// These are not suggested to the user in the shell completion,
  97	// but accepted if entered manually.
  98	ArgAliases []string
  99
 100	// BashCompletionFunction is custom bash functions used by the legacy bash autocompletion generator.
 101	// For portability with other shells, it is recommended to instead use ValidArgsFunction
 102	BashCompletionFunction string
 103
 104	// Deprecated defines, if this command is deprecated and should print this string when used.
 105	Deprecated string
 106
 107	// Annotations are key/value pairs that can be used by applications to identify or
 108	// group commands or set special options.
 109	Annotations map[string]string
 110
 111	// Version defines the version for this command. If this value is non-empty and the command does not
 112	// define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
 113	// will print content of the "Version" variable. A shorthand "v" flag will also be added if the
 114	// command does not define one.
 115	Version string
 116
 117	// The *Run functions are executed in the following order:
 118	//   * PersistentPreRun()
 119	//   * PreRun()
 120	//   * Run()
 121	//   * PostRun()
 122	//   * PersistentPostRun()
 123	// All functions get the same args, the arguments after the command name.
 124	// The *PreRun and *PostRun functions will only be executed if the Run function of the current
 125	// command has been declared.
 126	//
 127	// PersistentPreRun: children of this command will inherit and execute.
 128	PersistentPreRun func(cmd *Command, args []string)
 129	// PersistentPreRunE: PersistentPreRun but returns an error.
 130	PersistentPreRunE func(cmd *Command, args []string) error
 131	// PreRun: children of this command will not inherit.
 132	PreRun func(cmd *Command, args []string)
 133	// PreRunE: PreRun but returns an error.
 134	PreRunE func(cmd *Command, args []string) error
 135	// Run: Typically the actual work function. Most commands will only implement this.
 136	Run func(cmd *Command, args []string)
 137	// RunE: Run but returns an error.
 138	RunE func(cmd *Command, args []string) error
 139	// PostRun: run after the Run command.
 140	PostRun func(cmd *Command, args []string)
 141	// PostRunE: PostRun but returns an error.
 142	PostRunE func(cmd *Command, args []string) error
 143	// PersistentPostRun: children of this command will inherit and execute after PostRun.
 144	PersistentPostRun func(cmd *Command, args []string)
 145	// PersistentPostRunE: PersistentPostRun but returns an error.
 146	PersistentPostRunE func(cmd *Command, args []string) error
 147
 148	// groups for subcommands
 149	commandgroups []*Group
 150
 151	// args is actual args parsed from flags.
 152	args []string
 153	// flagErrorBuf contains all error messages from pflag.
 154	flagErrorBuf *bytes.Buffer
 155	// flags is full set of flags.
 156	flags *flag.FlagSet
 157	// pflags contains persistent flags.
 158	pflags *flag.FlagSet
 159	// lflags contains local flags.
 160	// This field does not represent internal state, it's used as a cache to optimise LocalFlags function call
 161	lflags *flag.FlagSet
 162	// iflags contains inherited flags.
 163	// This field does not represent internal state, it's used as a cache to optimise InheritedFlags function call
 164	iflags *flag.FlagSet
 165	// parentsPflags is all persistent flags of cmd's parents.
 166	parentsPflags *flag.FlagSet
 167	// globNormFunc is the global normalization function
 168	// that we can use on every pflag set and children commands
 169	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
 170
 171	// usageFunc is usage func defined by user.
 172	usageFunc func(*Command) error
 173	// usageTemplate is usage template defined by user.
 174	usageTemplate *tmplFunc
 175	// flagErrorFunc is func defined by user and it's called when the parsing of
 176	// flags returns an error.
 177	flagErrorFunc func(*Command, error) error
 178	// helpTemplate is help template defined by user.
 179	helpTemplate *tmplFunc
 180	// helpFunc is help func defined by user.
 181	helpFunc func(*Command, []string)
 182	// helpCommand is command with usage 'help'. If it's not defined by user,
 183	// cobra uses default help command.
 184	helpCommand *Command
 185	// helpCommandGroupID is the group id for the helpCommand
 186	helpCommandGroupID string
 187
 188	// completionCommandGroupID is the group id for the completion command
 189	completionCommandGroupID string
 190
 191	// versionTemplate is the version template defined by user.
 192	versionTemplate *tmplFunc
 193
 194	// errPrefix is the error message prefix defined by user.
 195	errPrefix string
 196
 197	// inReader is a reader defined by the user that replaces stdin
 198	inReader io.Reader
 199	// outWriter is a writer defined by the user that replaces stdout
 200	outWriter io.Writer
 201	// errWriter is a writer defined by the user that replaces stderr
 202	errWriter io.Writer
 203
 204	// FParseErrWhitelist flag parse errors to be ignored
 205	FParseErrWhitelist FParseErrWhitelist
 206
 207	// CompletionOptions is a set of options to control the handling of shell completion
 208	CompletionOptions CompletionOptions
 209
 210	// commandsAreSorted defines, if command slice are sorted or not.
 211	commandsAreSorted bool
 212	// commandCalledAs is the name or alias value used to call this command.
 213	commandCalledAs struct {
 214		name   string
 215		called bool
 216	}
 217
 218	ctx context.Context
 219
 220	// commands is the list of commands supported by this program.
 221	commands []*Command
 222	// parent is a parent command for this command.
 223	parent *Command
 224	// Max lengths of commands' string lengths for use in padding.
 225	commandsMaxUseLen         int
 226	commandsMaxCommandPathLen int
 227	commandsMaxNameLen        int
 228
 229	// TraverseChildren parses flags on all parents before executing child command.
 230	TraverseChildren bool
 231
 232	// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
 233	Hidden bool
 234
 235	// SilenceErrors is an option to quiet errors down stream.
 236	SilenceErrors bool
 237
 238	// SilenceUsage is an option to silence usage when an error occurs.
 239	SilenceUsage bool
 240
 241	// DisableFlagParsing disables the flag parsing.
 242	// If this is true all flags will be passed to the command as arguments.
 243	DisableFlagParsing bool
 244
 245	// DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
 246	// will be printed by generating docs for this command.
 247	DisableAutoGenTag bool
 248
 249	// DisableFlagsInUseLine will disable the addition of [flags] to the usage
 250	// line of a command when printing help or generating docs
 251	DisableFlagsInUseLine bool
 252
 253	// DisableSuggestions disables the suggestions based on Levenshtein distance
 254	// that go along with 'unknown command' messages.
 255	DisableSuggestions bool
 256
 257	// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
 258	// Must be > 0.
 259	SuggestionsMinimumDistance int
 260}
 261
 262// Context returns underlying command context. If command was executed
 263// with ExecuteContext or the context was set with SetContext, the
 264// previously set context will be returned. Otherwise, nil is returned.
 265//
 266// Notice that a call to Execute and ExecuteC will replace a nil context of
 267// a command with a context.Background, so a background context will be
 268// returned by Context after one of these functions has been called.
 269func (c *Command) Context() context.Context {
 270	return c.ctx
 271}
 272
 273// SetContext sets context for the command. This context will be overwritten by
 274// Command.ExecuteContext or Command.ExecuteContextC.
 275func (c *Command) SetContext(ctx context.Context) {
 276	c.ctx = ctx
 277}
 278
 279// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
 280// particularly useful when testing.
 281func (c *Command) SetArgs(a []string) {
 282	c.args = a
 283}
 284
 285// SetOutput sets the destination for usage and error messages.
 286// If output is nil, os.Stderr is used.
 287//
 288// Deprecated: Use SetOut and/or SetErr instead
 289func (c *Command) SetOutput(output io.Writer) {
 290	c.outWriter = output
 291	c.errWriter = output
 292}
 293
 294// SetOut sets the destination for usage messages.
 295// If newOut is nil, os.Stdout is used.
 296func (c *Command) SetOut(newOut io.Writer) {
 297	c.outWriter = newOut
 298}
 299
 300// SetErr sets the destination for error messages.
 301// If newErr is nil, os.Stderr is used.
 302func (c *Command) SetErr(newErr io.Writer) {
 303	c.errWriter = newErr
 304}
 305
 306// SetIn sets the source for input data
 307// If newIn is nil, os.Stdin is used.
 308func (c *Command) SetIn(newIn io.Reader) {
 309	c.inReader = newIn
 310}
 311
 312// SetUsageFunc sets usage function. Usage can be defined by application.
 313func (c *Command) SetUsageFunc(f func(*Command) error) {
 314	c.usageFunc = f
 315}
 316
 317// SetUsageTemplate sets usage template. Can be defined by Application.
 318func (c *Command) SetUsageTemplate(s string) {
 319	if s == "" {
 320		c.usageTemplate = nil
 321		return
 322	}
 323	c.usageTemplate = tmpl(s)
 324}
 325
 326// SetFlagErrorFunc sets a function to generate an error when flag parsing
 327// fails.
 328func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
 329	c.flagErrorFunc = f
 330}
 331
 332// SetHelpFunc sets help function. Can be defined by Application.
 333func (c *Command) SetHelpFunc(f func(*Command, []string)) {
 334	c.helpFunc = f
 335}
 336
 337// SetHelpCommand sets help command.
 338func (c *Command) SetHelpCommand(cmd *Command) {
 339	c.helpCommand = cmd
 340}
 341
 342// SetHelpCommandGroupID sets the group id of the help command.
 343func (c *Command) SetHelpCommandGroupID(groupID string) {
 344	if c.helpCommand != nil {
 345		c.helpCommand.GroupID = groupID
 346	}
 347	// helpCommandGroupID is used if no helpCommand is defined by the user
 348	c.helpCommandGroupID = groupID
 349}
 350
 351// SetCompletionCommandGroupID sets the group id of the completion command.
 352func (c *Command) SetCompletionCommandGroupID(groupID string) {
 353	// completionCommandGroupID is used if no completion command is defined by the user
 354	c.Root().completionCommandGroupID = groupID
 355}
 356
 357// SetHelpTemplate sets help template to be used. Application can use it to set custom template.
 358func (c *Command) SetHelpTemplate(s string) {
 359	if s == "" {
 360		c.helpTemplate = nil
 361		return
 362	}
 363	c.helpTemplate = tmpl(s)
 364}
 365
 366// SetVersionTemplate sets version template to be used. Application can use it to set custom template.
 367func (c *Command) SetVersionTemplate(s string) {
 368	if s == "" {
 369		c.versionTemplate = nil
 370		return
 371	}
 372	c.versionTemplate = tmpl(s)
 373}
 374
 375// SetErrPrefix sets error message prefix to be used. Application can use it to set custom prefix.
 376func (c *Command) SetErrPrefix(s string) {
 377	c.errPrefix = s
 378}
 379
 380// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
 381// The user should not have a cyclic dependency on commands.
 382func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
 383	c.Flags().SetNormalizeFunc(n)
 384	c.PersistentFlags().SetNormalizeFunc(n)
 385	c.globNormFunc = n
 386
 387	for _, command := range c.commands {
 388		command.SetGlobalNormalizationFunc(n)
 389	}
 390}
 391
 392// OutOrStdout returns output to stdout.
 393func (c *Command) OutOrStdout() io.Writer {
 394	return c.getOut(os.Stdout)
 395}
 396
 397// OutOrStderr returns output to stderr
 398func (c *Command) OutOrStderr() io.Writer {
 399	return c.getOut(os.Stderr)
 400}
 401
 402// ErrOrStderr returns output to stderr
 403func (c *Command) ErrOrStderr() io.Writer {
 404	return c.getErr(os.Stderr)
 405}
 406
 407// InOrStdin returns input to stdin
 408func (c *Command) InOrStdin() io.Reader {
 409	return c.getIn(os.Stdin)
 410}
 411
 412func (c *Command) getOut(def io.Writer) io.Writer {
 413	if c.outWriter != nil {
 414		return c.outWriter
 415	}
 416	if c.HasParent() {
 417		return c.parent.getOut(def)
 418	}
 419	return def
 420}
 421
 422func (c *Command) getErr(def io.Writer) io.Writer {
 423	if c.errWriter != nil {
 424		return c.errWriter
 425	}
 426	if c.HasParent() {
 427		return c.parent.getErr(def)
 428	}
 429	return def
 430}
 431
 432func (c *Command) getIn(def io.Reader) io.Reader {
 433	if c.inReader != nil {
 434		return c.inReader
 435	}
 436	if c.HasParent() {
 437		return c.parent.getIn(def)
 438	}
 439	return def
 440}
 441
 442// UsageFunc returns either the function set by SetUsageFunc for this command
 443// or a parent, or it returns a default usage function.
 444func (c *Command) UsageFunc() (f func(*Command) error) {
 445	if c.usageFunc != nil {
 446		return c.usageFunc
 447	}
 448	if c.HasParent() {
 449		return c.Parent().UsageFunc()
 450	}
 451	return func(c *Command) error {
 452		c.mergePersistentFlags()
 453		fn := c.getUsageTemplateFunc()
 454		err := fn(c.OutOrStderr(), c)
 455		if err != nil {
 456			c.PrintErrln(err)
 457		}
 458		return err
 459	}
 460}
 461
 462// getUsageTemplateFunc returns the usage template function for the command
 463// going up the command tree if necessary.
 464func (c *Command) getUsageTemplateFunc() func(w io.Writer, data interface{}) error {
 465	if c.usageTemplate != nil {
 466		return c.usageTemplate.fn
 467	}
 468
 469	if c.HasParent() {
 470		return c.parent.getUsageTemplateFunc()
 471	}
 472	return defaultUsageFunc
 473}
 474
 475// Usage puts out the usage for the command.
 476// Used when a user provides invalid input.
 477// Can be defined by user by overriding UsageFunc.
 478func (c *Command) Usage() error {
 479	return c.UsageFunc()(c)
 480}
 481
 482// HelpFunc returns either the function set by SetHelpFunc for this command
 483// or a parent, or it returns a function with default help behavior.
 484func (c *Command) HelpFunc() func(*Command, []string) {
 485	if c.helpFunc != nil {
 486		return c.helpFunc
 487	}
 488	if c.HasParent() {
 489		return c.Parent().HelpFunc()
 490	}
 491	return func(c *Command, a []string) {
 492		c.mergePersistentFlags()
 493		fn := c.getHelpTemplateFunc()
 494		// The help should be sent to stdout
 495		// See https://github.com/spf13/cobra/issues/1002
 496		err := fn(c.OutOrStdout(), c)
 497		if err != nil {
 498			c.PrintErrln(err)
 499		}
 500	}
 501}
 502
 503// getHelpTemplateFunc returns the help template function for the command
 504// going up the command tree if necessary.
 505func (c *Command) getHelpTemplateFunc() func(w io.Writer, data interface{}) error {
 506	if c.helpTemplate != nil {
 507		return c.helpTemplate.fn
 508	}
 509
 510	if c.HasParent() {
 511		return c.parent.getHelpTemplateFunc()
 512	}
 513
 514	return defaultHelpFunc
 515}
 516
 517// Help puts out the help for the command.
 518// Used when a user calls help [command].
 519// Can be defined by user by overriding HelpFunc.
 520func (c *Command) Help() error {
 521	c.HelpFunc()(c, []string{})
 522	return nil
 523}
 524
 525// UsageString returns usage string.
 526func (c *Command) UsageString() string {
 527	// Storing normal writers
 528	tmpOutput := c.outWriter
 529	tmpErr := c.errWriter
 530
 531	bb := new(bytes.Buffer)
 532	c.outWriter = bb
 533	c.errWriter = bb
 534
 535	CheckErr(c.Usage())
 536
 537	// Setting things back to normal
 538	c.outWriter = tmpOutput
 539	c.errWriter = tmpErr
 540
 541	return bb.String()
 542}
 543
 544// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
 545// command or a parent, or it returns a function which returns the original
 546// error.
 547func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
 548	if c.flagErrorFunc != nil {
 549		return c.flagErrorFunc
 550	}
 551
 552	if c.HasParent() {
 553		return c.parent.FlagErrorFunc()
 554	}
 555	return func(c *Command, err error) error {
 556		return err
 557	}
 558}
 559
 560var minUsagePadding = 25
 561
 562// UsagePadding return padding for the usage.
 563func (c *Command) UsagePadding() int {
 564	if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
 565		return minUsagePadding
 566	}
 567	return c.parent.commandsMaxUseLen
 568}
 569
 570var minCommandPathPadding = 11
 571
 572// CommandPathPadding return padding for the command path.
 573func (c *Command) CommandPathPadding() int {
 574	if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
 575		return minCommandPathPadding
 576	}
 577	return c.parent.commandsMaxCommandPathLen
 578}
 579
 580var minNamePadding = 11
 581
 582// NamePadding returns padding for the name.
 583func (c *Command) NamePadding() int {
 584	if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
 585		return minNamePadding
 586	}
 587	return c.parent.commandsMaxNameLen
 588}
 589
 590// UsageTemplate returns usage template for the command.
 591// This function is kept for backwards-compatibility reasons.
 592func (c *Command) UsageTemplate() string {
 593	if c.usageTemplate != nil {
 594		return c.usageTemplate.tmpl
 595	}
 596
 597	if c.HasParent() {
 598		return c.parent.UsageTemplate()
 599	}
 600	return defaultUsageTemplate
 601}
 602
 603// HelpTemplate return help template for the command.
 604// This function is kept for backwards-compatibility reasons.
 605func (c *Command) HelpTemplate() string {
 606	if c.helpTemplate != nil {
 607		return c.helpTemplate.tmpl
 608	}
 609
 610	if c.HasParent() {
 611		return c.parent.HelpTemplate()
 612	}
 613	return defaultHelpTemplate
 614}
 615
 616// VersionTemplate return version template for the command.
 617// This function is kept for backwards-compatibility reasons.
 618func (c *Command) VersionTemplate() string {
 619	if c.versionTemplate != nil {
 620		return c.versionTemplate.tmpl
 621	}
 622
 623	if c.HasParent() {
 624		return c.parent.VersionTemplate()
 625	}
 626	return defaultVersionTemplate
 627}
 628
 629// getVersionTemplateFunc returns the version template function for the command
 630// going up the command tree if necessary.
 631func (c *Command) getVersionTemplateFunc() func(w io.Writer, data interface{}) error {
 632	if c.versionTemplate != nil {
 633		return c.versionTemplate.fn
 634	}
 635
 636	if c.HasParent() {
 637		return c.parent.getVersionTemplateFunc()
 638	}
 639	return defaultVersionFunc
 640}
 641
 642// ErrPrefix return error message prefix for the command
 643func (c *Command) ErrPrefix() string {
 644	if c.errPrefix != "" {
 645		return c.errPrefix
 646	}
 647
 648	if c.HasParent() {
 649		return c.parent.ErrPrefix()
 650	}
 651	return "Error:"
 652}
 653
 654func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
 655	flag := fs.Lookup(name)
 656	if flag == nil {
 657		return false
 658	}
 659	return flag.NoOptDefVal != ""
 660}
 661
 662func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
 663	if len(name) == 0 {
 664		return false
 665	}
 666
 667	flag := fs.ShorthandLookup(name[:1])
 668	if flag == nil {
 669		return false
 670	}
 671	return flag.NoOptDefVal != ""
 672}
 673
 674func stripFlags(args []string, c *Command) []string {
 675	if len(args) == 0 {
 676		return args
 677	}
 678	c.mergePersistentFlags()
 679
 680	commands := []string{}
 681	flags := c.Flags()
 682
 683Loop:
 684	for len(args) > 0 {
 685		s := args[0]
 686		args = args[1:]
 687		switch {
 688		case s == "--":
 689			// "--" terminates the flags
 690			break Loop
 691		case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
 692			// If '--flag arg' then
 693			// delete arg from args.
 694			fallthrough // (do the same as below)
 695		case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
 696			// If '-f arg' then
 697			// delete 'arg' from args or break the loop if len(args) <= 1.
 698			if len(args) <= 1 {
 699				break Loop
 700			} else {
 701				args = args[1:]
 702				continue
 703			}
 704		case s != "" && !strings.HasPrefix(s, "-"):
 705			commands = append(commands, s)
 706		}
 707	}
 708
 709	return commands
 710}
 711
 712// argsMinusFirstX removes only the first x from args.  Otherwise, commands that look like
 713// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
 714// Special care needs to be taken not to remove a flag value.
 715func (c *Command) argsMinusFirstX(args []string, x string) []string {
 716	if len(args) == 0 {
 717		return args
 718	}
 719	c.mergePersistentFlags()
 720	flags := c.Flags()
 721
 722Loop:
 723	for pos := 0; pos < len(args); pos++ {
 724		s := args[pos]
 725		switch {
 726		case s == "--":
 727			// -- means we have reached the end of the parseable args. Break out of the loop now.
 728			break Loop
 729		case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
 730			fallthrough
 731		case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
 732			// This is a flag without a default value, and an equal sign is not used. Increment pos in order to skip
 733			// over the next arg, because that is the value of this flag.
 734			pos++
 735			continue
 736		case !strings.HasPrefix(s, "-"):
 737			// This is not a flag or a flag value. Check to see if it matches what we're looking for, and if so,
 738			// return the args, excluding the one at this position.
 739			if s == x {
 740				ret := make([]string, 0, len(args)-1)
 741				ret = append(ret, args[:pos]...)
 742				ret = append(ret, args[pos+1:]...)
 743				return ret
 744			}
 745		}
 746	}
 747	return args
 748}
 749
 750func isFlagArg(arg string) bool {
 751	return ((len(arg) >= 3 && arg[0:2] == "--") ||
 752		(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
 753}
 754
 755// Find the target command given the args and command tree
 756// Meant to be run on the highest node. Only searches down.
 757func (c *Command) Find(args []string) (*Command, []string, error) {
 758	var innerfind func(*Command, []string) (*Command, []string)
 759
 760	innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
 761		argsWOflags := stripFlags(innerArgs, c)
 762		if len(argsWOflags) == 0 {
 763			return c, innerArgs
 764		}
 765		nextSubCmd := argsWOflags[0]
 766
 767		cmd := c.findNext(nextSubCmd)
 768		if cmd != nil {
 769			return innerfind(cmd, c.argsMinusFirstX(innerArgs, nextSubCmd))
 770		}
 771		return c, innerArgs
 772	}
 773
 774	commandFound, a := innerfind(c, args)
 775	if commandFound.Args == nil {
 776		return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))
 777	}
 778	return commandFound, a, nil
 779}
 780
 781func (c *Command) findSuggestions(arg string) string {
 782	if c.DisableSuggestions {
 783		return ""
 784	}
 785	if c.SuggestionsMinimumDistance <= 0 {
 786		c.SuggestionsMinimumDistance = 2
 787	}
 788	var sb strings.Builder
 789	if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
 790		sb.WriteString("\n\nDid you mean this?\n")
 791		for _, s := range suggestions {
 792			_, _ = fmt.Fprintf(&sb, "\t%v\n", s)
 793		}
 794	}
 795	return sb.String()
 796}
 797
 798func (c *Command) findNext(next string) *Command {
 799	matches := make([]*Command, 0)
 800	for _, cmd := range c.commands {
 801		if commandNameMatches(cmd.Name(), next) || cmd.HasAlias(next) {
 802			cmd.commandCalledAs.name = next
 803			return cmd
 804		}
 805		if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
 806			matches = append(matches, cmd)
 807		}
 808	}
 809
 810	if len(matches) == 1 {
 811		// Temporarily disable gosec G602, which produces a false positive.
 812		// See https://github.com/securego/gosec/issues/1005.
 813		return matches[0] // #nosec G602
 814	}
 815
 816	return nil
 817}
 818
 819// Traverse the command tree to find the command, and parse args for
 820// each parent.
 821func (c *Command) Traverse(args []string) (*Command, []string, error) {
 822	flags := []string{}
 823	inFlag := false
 824
 825	for i, arg := range args {
 826		switch {
 827		// A long flag with a space separated value
 828		case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
 829			// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
 830			inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
 831			flags = append(flags, arg)
 832			continue
 833		// A short flag with a space separated value
 834		case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
 835			inFlag = true
 836			flags = append(flags, arg)
 837			continue
 838		// The value for a flag
 839		case inFlag:
 840			inFlag = false
 841			flags = append(flags, arg)
 842			continue
 843		// A flag without a value, or with an `=` separated value
 844		case isFlagArg(arg):
 845			flags = append(flags, arg)
 846			continue
 847		}
 848
 849		cmd := c.findNext(arg)
 850		if cmd == nil {
 851			return c, args, nil
 852		}
 853
 854		if err := c.ParseFlags(flags); err != nil {
 855			return nil, args, err
 856		}
 857		return cmd.Traverse(args[i+1:])
 858	}
 859	return c, args, nil
 860}
 861
 862// SuggestionsFor provides suggestions for the typedName.
 863func (c *Command) SuggestionsFor(typedName string) []string {
 864	suggestions := []string{}
 865	for _, cmd := range c.commands {
 866		if cmd.IsAvailableCommand() {
 867			levenshteinDistance := ld(typedName, cmd.Name(), true)
 868			suggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance
 869			suggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName))
 870			if suggestByLevenshtein || suggestByPrefix {
 871				suggestions = append(suggestions, cmd.Name())
 872			}
 873			for _, explicitSuggestion := range cmd.SuggestFor {
 874				if strings.EqualFold(typedName, explicitSuggestion) {
 875					suggestions = append(suggestions, cmd.Name())
 876				}
 877			}
 878		}
 879	}
 880	return suggestions
 881}
 882
 883// VisitParents visits all parents of the command and invokes fn on each parent.
 884func (c *Command) VisitParents(fn func(*Command)) {
 885	if c.HasParent() {
 886		fn(c.Parent())
 887		c.Parent().VisitParents(fn)
 888	}
 889}
 890
 891// Root finds root command.
 892func (c *Command) Root() *Command {
 893	if c.HasParent() {
 894		return c.Parent().Root()
 895	}
 896	return c
 897}
 898
 899// ArgsLenAtDash will return the length of c.Flags().Args at the moment
 900// when a -- was found during args parsing.
 901func (c *Command) ArgsLenAtDash() int {
 902	return c.Flags().ArgsLenAtDash()
 903}
 904
 905func (c *Command) execute(a []string) (err error) {
 906	if c == nil {
 907		return fmt.Errorf("called Execute() on a nil Command")
 908	}
 909
 910	if len(c.Deprecated) > 0 {
 911		c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
 912	}
 913
 914	// initialize help and version flag at the last point possible to allow for user
 915	// overriding
 916	c.InitDefaultHelpFlag()
 917	c.InitDefaultVersionFlag()
 918
 919	err = c.ParseFlags(a)
 920	if err != nil {
 921		return c.FlagErrorFunc()(c, err)
 922	}
 923
 924	// If help is called, regardless of other flags, return we want help.
 925	// Also say we need help if the command isn't runnable.
 926	helpVal, err := c.Flags().GetBool(helpFlagName)
 927	if err != nil {
 928		// should be impossible to get here as we always declare a help
 929		// flag in InitDefaultHelpFlag()
 930		c.Println("\"help\" flag declared as non-bool. Please correct your code")
 931		return err
 932	}
 933
 934	if helpVal {
 935		return flag.ErrHelp
 936	}
 937
 938	// for back-compat, only add version flag behavior if version is defined
 939	if c.Version != "" {
 940		versionVal, err := c.Flags().GetBool("version")
 941		if err != nil {
 942			c.Println("\"version\" flag declared as non-bool. Please correct your code")
 943			return err
 944		}
 945		if versionVal {
 946			fn := c.getVersionTemplateFunc()
 947			err := fn(c.OutOrStdout(), c)
 948			if err != nil {
 949				c.Println(err)
 950			}
 951			return err
 952		}
 953	}
 954
 955	if !c.Runnable() {
 956		return flag.ErrHelp
 957	}
 958
 959	c.preRun()
 960
 961	defer c.postRun()
 962
 963	argWoFlags := c.Flags().Args()
 964	if c.DisableFlagParsing {
 965		argWoFlags = a
 966	}
 967
 968	if err := c.ValidateArgs(argWoFlags); err != nil {
 969		return err
 970	}
 971
 972	parents := make([]*Command, 0, 5)
 973	for p := c; p != nil; p = p.Parent() {
 974		if EnableTraverseRunHooks {
 975			// When EnableTraverseRunHooks is set:
 976			// - Execute all persistent pre-runs from the root parent till this command.
 977			// - Execute all persistent post-runs from this command till the root parent.
 978			parents = append([]*Command{p}, parents...)
 979		} else {
 980			// Otherwise, execute only the first found persistent hook.
 981			parents = append(parents, p)
 982		}
 983	}
 984	for _, p := range parents {
 985		if p.PersistentPreRunE != nil {
 986			if err := p.PersistentPreRunE(c, argWoFlags); err != nil {
 987				return err
 988			}
 989			if !EnableTraverseRunHooks {
 990				break
 991			}
 992		} else if p.PersistentPreRun != nil {
 993			p.PersistentPreRun(c, argWoFlags)
 994			if !EnableTraverseRunHooks {
 995				break
 996			}
 997		}
 998	}
 999	if c.PreRunE != nil {
1000		if err := c.PreRunE(c, argWoFlags); err != nil {
1001			return err
1002		}
1003	} else if c.PreRun != nil {
1004		c.PreRun(c, argWoFlags)
1005	}
1006
1007	if err := c.ValidateRequiredFlags(); err != nil {
1008		return err
1009	}
1010	if err := c.ValidateFlagGroups(); err != nil {
1011		return err
1012	}
1013
1014	if c.RunE != nil {
1015		if err := c.RunE(c, argWoFlags); err != nil {
1016			return err
1017		}
1018	} else {
1019		c.Run(c, argWoFlags)
1020	}
1021	if c.PostRunE != nil {
1022		if err := c.PostRunE(c, argWoFlags); err != nil {
1023			return err
1024		}
1025	} else if c.PostRun != nil {
1026		c.PostRun(c, argWoFlags)
1027	}
1028	for p := c; p != nil; p = p.Parent() {
1029		if p.PersistentPostRunE != nil {
1030			if err := p.PersistentPostRunE(c, argWoFlags); err != nil {
1031				return err
1032			}
1033			if !EnableTraverseRunHooks {
1034				break
1035			}
1036		} else if p.PersistentPostRun != nil {
1037			p.PersistentPostRun(c, argWoFlags)
1038			if !EnableTraverseRunHooks {
1039				break
1040			}
1041		}
1042	}
1043
1044	return nil
1045}
1046
1047func (c *Command) preRun() {
1048	for _, x := range initializers {
1049		x()
1050	}
1051}
1052
1053func (c *Command) postRun() {
1054	for _, x := range finalizers {
1055		x()
1056	}
1057}
1058
1059// ExecuteContext is the same as Execute(), but sets the ctx on the command.
1060// Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs
1061// functions.
1062func (c *Command) ExecuteContext(ctx context.Context) error {
1063	c.ctx = ctx
1064	return c.Execute()
1065}
1066
1067// Execute uses the args (os.Args[1:] by default)
1068// and run through the command tree finding appropriate matches
1069// for commands and then corresponding flags.
1070func (c *Command) Execute() error {
1071	_, err := c.ExecuteC()
1072	return err
1073}
1074
1075// ExecuteContextC is the same as ExecuteC(), but sets the ctx on the command.
1076// Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs
1077// functions.
1078func (c *Command) ExecuteContextC(ctx context.Context) (*Command, error) {
1079	c.ctx = ctx
1080	return c.ExecuteC()
1081}
1082
1083// ExecuteC executes the command.
1084func (c *Command) ExecuteC() (cmd *Command, err error) {
1085	if c.ctx == nil {
1086		c.ctx = context.Background()
1087	}
1088
1089	// Regardless of what command execute is called on, run on Root only
1090	if c.HasParent() {
1091		return c.Root().ExecuteC()
1092	}
1093
1094	// windows hook
1095	if preExecHookFn != nil {
1096		preExecHookFn(c)
1097	}
1098
1099	// initialize help at the last point to allow for user overriding
1100	c.InitDefaultHelpCmd()
1101
1102	args := c.args
1103
1104	// Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
1105	if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
1106		args = os.Args[1:]
1107	}
1108
1109	// initialize the __complete command to be used for shell completion
1110	c.initCompleteCmd(args)
1111
1112	// initialize the default completion command
1113	c.InitDefaultCompletionCmd(args...)
1114
1115	// Now that all commands have been created, let's make sure all groups
1116	// are properly created also
1117	c.checkCommandGroups()
1118
1119	var flags []string
1120	if c.TraverseChildren {
1121		cmd, flags, err = c.Traverse(args)
1122	} else {
1123		cmd, flags, err = c.Find(args)
1124	}
1125	if err != nil {
1126		// If found parse to a subcommand and then failed, talk about the subcommand
1127		if cmd != nil {
1128			c = cmd
1129		}
1130		if !c.SilenceErrors {
1131			c.PrintErrln(c.ErrPrefix(), err.Error())
1132			c.PrintErrf("Run '%v --help' for usage.\n", c.CommandPath())
1133		}
1134		return c, err
1135	}
1136
1137	cmd.commandCalledAs.called = true
1138	if cmd.commandCalledAs.name == "" {
1139		cmd.commandCalledAs.name = cmd.Name()
1140	}
1141
1142	// We have to pass global context to children command
1143	// if context is present on the parent command.
1144	if cmd.ctx == nil {
1145		cmd.ctx = c.ctx
1146	}
1147
1148	err = cmd.execute(flags)
1149	if err != nil {
1150		// Always show help if requested, even if SilenceErrors is in
1151		// effect
1152		if errors.Is(err, flag.ErrHelp) {
1153			cmd.HelpFunc()(cmd, args)
1154			return cmd, nil
1155		}
1156
1157		// If root command has SilenceErrors flagged,
1158		// all subcommands should respect it
1159		if !cmd.SilenceErrors && !c.SilenceErrors {
1160			c.PrintErrln(cmd.ErrPrefix(), err.Error())
1161		}
1162
1163		// If root command has SilenceUsage flagged,
1164		// all subcommands should respect it
1165		if !cmd.SilenceUsage && !c.SilenceUsage {
1166			c.Println(cmd.UsageString())
1167		}
1168	}
1169	return cmd, err
1170}
1171
1172func (c *Command) ValidateArgs(args []string) error {
1173	if c.Args == nil {
1174		return ArbitraryArgs(c, args)
1175	}
1176	return c.Args(c, args)
1177}
1178
1179// ValidateRequiredFlags validates all required flags are present and returns an error otherwise
1180func (c *Command) ValidateRequiredFlags() error {
1181	if c.DisableFlagParsing {
1182		return nil
1183	}
1184
1185	flags := c.Flags()
1186	missingFlagNames := []string{}
1187	flags.VisitAll(func(pflag *flag.Flag) {
1188		requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
1189		if !found {
1190			return
1191		}
1192		if (requiredAnnotation[0] == "true") && !pflag.Changed {
1193			missingFlagNames = append(missingFlagNames, pflag.Name)
1194		}
1195	})
1196
1197	if len(missingFlagNames) > 0 {
1198		return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missingFlagNames, `", "`))
1199	}
1200	return nil
1201}
1202
1203// checkCommandGroups checks if a command has been added to a group that does not exists.
1204// If so, we panic because it indicates a coding error that should be corrected.
1205func (c *Command) checkCommandGroups() {
1206	for _, sub := range c.commands {
1207		// if Group is not defined let the developer know right away
1208		if sub.GroupID != "" && !c.ContainsGroup(sub.GroupID) {
1209			panic(fmt.Sprintf("group id '%s' is not defined for subcommand '%s'", sub.GroupID, sub.CommandPath()))
1210		}
1211
1212		sub.checkCommandGroups()
1213	}
1214}
1215
1216// InitDefaultHelpFlag adds default help flag to c.
1217// It is called automatically by executing the c or by calling help and usage.
1218// If c already has help flag, it will do nothing.
1219func (c *Command) InitDefaultHelpFlag() {
1220	c.mergePersistentFlags()
1221	if c.Flags().Lookup(helpFlagName) == nil {
1222		usage := "help for "
1223		name := c.DisplayName()
1224		if name == "" {
1225			usage += "this command"
1226		} else {
1227			usage += name
1228		}
1229		c.Flags().BoolP(helpFlagName, "h", false, usage)
1230		_ = c.Flags().SetAnnotation(helpFlagName, FlagSetByCobraAnnotation, []string{"true"})
1231	}
1232}
1233
1234// InitDefaultVersionFlag adds default version flag to c.
1235// It is called automatically by executing the c.
1236// If c already has a version flag, it will do nothing.
1237// If c.Version is empty, it will do nothing.
1238func (c *Command) InitDefaultVersionFlag() {
1239	if c.Version == "" {
1240		return
1241	}
1242
1243	c.mergePersistentFlags()
1244	if c.Flags().Lookup("version") == nil {
1245		usage := "version for "
1246		if c.Name() == "" {
1247			usage += "this command"
1248		} else {
1249			usage += c.DisplayName()
1250		}
1251		if c.Flags().ShorthandLookup("v") == nil {
1252			c.Flags().BoolP("version", "v", false, usage)
1253		} else {
1254			c.Flags().Bool("version", false, usage)
1255		}
1256		_ = c.Flags().SetAnnotation("version", FlagSetByCobraAnnotation, []string{"true"})
1257	}
1258}
1259
1260// InitDefaultHelpCmd adds default help command to c.
1261// It is called automatically by executing the c or by calling help and usage.
1262// If c already has help command or c has no subcommands, it will do nothing.
1263func (c *Command) InitDefaultHelpCmd() {
1264	if !c.HasSubCommands() {
1265		return
1266	}
1267
1268	if c.helpCommand == nil {
1269		c.helpCommand = &Command{
1270			Use:   "help [command]",
1271			Short: "Help about any command",
1272			Long: `Help provides help for any command in the application.
1273Simply type ` + c.DisplayName() + ` help [path to command] for full details.`,
1274			ValidArgsFunction: func(c *Command, args []string, toComplete string) ([]Completion, ShellCompDirective) {
1275				var completions []Completion
1276				cmd, _, e := c.Root().Find(args)
1277				if e != nil {
1278					return nil, ShellCompDirectiveNoFileComp
1279				}
1280				if cmd == nil {
1281					// Root help command.
1282					cmd = c.Root()
1283				}
1284				for _, subCmd := range cmd.Commands() {
1285					if subCmd.IsAvailableCommand() || subCmd == cmd.helpCommand {
1286						if strings.HasPrefix(subCmd.Name(), toComplete) {
1287							completions = append(completions, CompletionWithDesc(subCmd.Name(), subCmd.Short))
1288						}
1289					}
1290				}
1291				return completions, ShellCompDirectiveNoFileComp
1292			},
1293			Run: func(c *Command, args []string) {
1294				cmd, _, e := c.Root().Find(args)
1295				if cmd == nil || e != nil {
1296					c.Printf("Unknown help topic %#q\n", args)
1297					CheckErr(c.Root().Usage())
1298				} else {
1299					cmd.InitDefaultHelpFlag()    // make possible 'help' flag to be shown
1300					cmd.InitDefaultVersionFlag() // make possible 'version' flag to be shown
1301					CheckErr(cmd.Help())
1302				}
1303			},
1304			GroupID: c.helpCommandGroupID,
1305		}
1306	}
1307	c.RemoveCommand(c.helpCommand)
1308	c.AddCommand(c.helpCommand)
1309}
1310
1311// ResetCommands delete parent, subcommand and help command from c.
1312func (c *Command) ResetCommands() {
1313	c.parent = nil
1314	c.commands = nil
1315	c.helpCommand = nil
1316	c.parentsPflags = nil
1317}
1318
1319// Sorts commands by their names.
1320type commandSorterByName []*Command
1321
1322func (c commandSorterByName) Len() int           { return len(c) }
1323func (c commandSorterByName) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }
1324func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() }
1325
1326// Commands returns a sorted slice of child commands.
1327func (c *Command) Commands() []*Command {
1328	// do not sort commands if it already sorted or sorting was disabled
1329	if EnableCommandSorting && !c.commandsAreSorted {
1330		sort.Sort(commandSorterByName(c.commands))
1331		c.commandsAreSorted = true
1332	}
1333	return c.commands
1334}
1335
1336// AddCommand adds one or more commands to this parent command.
1337func (c *Command) AddCommand(cmds ...*Command) {
1338	for i, x := range cmds {
1339		if cmds[i] == c {
1340			panic("Command can't be a child of itself")
1341		}
1342		cmds[i].parent = c
1343		// update max lengths
1344		usageLen := len(x.Use)
1345		if usageLen > c.commandsMaxUseLen {
1346			c.commandsMaxUseLen = usageLen
1347		}
1348		commandPathLen := len(x.CommandPath())
1349		if commandPathLen > c.commandsMaxCommandPathLen {
1350			c.commandsMaxCommandPathLen = commandPathLen
1351		}
1352		nameLen := len(x.Name())
1353		if nameLen > c.commandsMaxNameLen {
1354			c.commandsMaxNameLen = nameLen
1355		}
1356		// If global normalization function exists, update all children
1357		if c.globNormFunc != nil {
1358			x.SetGlobalNormalizationFunc(c.globNormFunc)
1359		}
1360		c.commands = append(c.commands, x)
1361		c.commandsAreSorted = false
1362	}
1363}
1364
1365// Groups returns a slice of child command groups.
1366func (c *Command) Groups() []*Group {
1367	return c.commandgroups
1368}
1369
1370// AllChildCommandsHaveGroup returns if all subcommands are assigned to a group
1371func (c *Command) AllChildCommandsHaveGroup() bool {
1372	for _, sub := range c.commands {
1373		if (sub.IsAvailableCommand() || sub == c.helpCommand) && sub.GroupID == "" {
1374			return false
1375		}
1376	}
1377	return true
1378}
1379
1380// ContainsGroup return if groupID exists in the list of command groups.
1381func (c *Command) ContainsGroup(groupID string) bool {
1382	for _, x := range c.commandgroups {
1383		if x.ID == groupID {
1384			return true
1385		}
1386	}
1387	return false
1388}
1389
1390// AddGroup adds one or more command groups to this parent command.
1391func (c *Command) AddGroup(groups ...*Group) {
1392	c.commandgroups = append(c.commandgroups, groups...)
1393}
1394
1395// RemoveCommand removes one or more commands from a parent command.
1396func (c *Command) RemoveCommand(cmds ...*Command) {
1397	commands := []*Command{}
1398main:
1399	for _, command := range c.commands {
1400		for _, cmd := range cmds {
1401			if command == cmd {
1402				command.parent = nil
1403				continue main
1404			}
1405		}
1406		commands = append(commands, command)
1407	}
1408	c.commands = commands
1409	// recompute all lengths
1410	c.commandsMaxUseLen = 0
1411	c.commandsMaxCommandPathLen = 0
1412	c.commandsMaxNameLen = 0
1413	for _, command := range c.commands {
1414		usageLen := len(command.Use)
1415		if usageLen > c.commandsMaxUseLen {
1416			c.commandsMaxUseLen = usageLen
1417		}
1418		commandPathLen := len(command.CommandPath())
1419		if commandPathLen > c.commandsMaxCommandPathLen {
1420			c.commandsMaxCommandPathLen = commandPathLen
1421		}
1422		nameLen := len(command.Name())
1423		if nameLen > c.commandsMaxNameLen {
1424			c.commandsMaxNameLen = nameLen
1425		}
1426	}
1427}
1428
1429// Print is a convenience method to Print to the defined output, fallback to Stderr if not set.
1430func (c *Command) Print(i ...interface{}) {
1431	fmt.Fprint(c.OutOrStderr(), i...)
1432}
1433
1434// Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
1435func (c *Command) Println(i ...interface{}) {
1436	c.Print(fmt.Sprintln(i...))
1437}
1438
1439// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
1440func (c *Command) Printf(format string, i ...interface{}) {
1441	c.Print(fmt.Sprintf(format, i...))
1442}
1443
1444// PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set.
1445func (c *Command) PrintErr(i ...interface{}) {
1446	fmt.Fprint(c.ErrOrStderr(), i...)
1447}
1448
1449// PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set.
1450func (c *Command) PrintErrln(i ...interface{}) {
1451	c.PrintErr(fmt.Sprintln(i...))
1452}
1453
1454// PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set.
1455func (c *Command) PrintErrf(format string, i ...interface{}) {
1456	c.PrintErr(fmt.Sprintf(format, i...))
1457}
1458
1459// CommandPath returns the full path to this command.
1460func (c *Command) CommandPath() string {
1461	if c.HasParent() {
1462		return c.Parent().CommandPath() + " " + c.Name()
1463	}
1464	return c.DisplayName()
1465}
1466
1467// DisplayName returns the name to display in help text. Returns command Name()
1468// If CommandDisplayNameAnnoation is not set
1469func (c *Command) DisplayName() string {
1470	if displayName, ok := c.Annotations[CommandDisplayNameAnnotation]; ok {
1471		return displayName
1472	}
1473	return c.Name()
1474}
1475
1476// UseLine puts out the full usage for a given command (including parents).
1477func (c *Command) UseLine() string {
1478	var useline string
1479	use := strings.Replace(c.Use, c.Name(), c.DisplayName(), 1)
1480	if c.HasParent() {
1481		useline = c.parent.CommandPath() + " " + use
1482	} else {
1483		useline = use
1484	}
1485	if c.DisableFlagsInUseLine {
1486		return useline
1487	}
1488	if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
1489		useline += " [flags]"
1490	}
1491	return useline
1492}
1493
1494// DebugFlags used to determine which flags have been assigned to which commands
1495// and which persist.
1496func (c *Command) DebugFlags() {
1497	c.Println("DebugFlags called on", c.Name())
1498	var debugflags func(*Command)
1499
1500	debugflags = func(x *Command) {
1501		if x.HasFlags() || x.HasPersistentFlags() {
1502			c.Println(x.Name())
1503		}
1504		if x.HasFlags() {
1505			x.flags.VisitAll(func(f *flag.Flag) {
1506				if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {
1507					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [LP]")
1508				} else {
1509					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
1510				}
1511			})
1512		}
1513		if x.HasPersistentFlags() {
1514			x.pflags.VisitAll(func(f *flag.Flag) {
1515				if x.HasFlags() {
1516					if x.flags.Lookup(f.Name) == nil {
1517						c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
1518					}
1519				} else {
1520					c.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
1521				}
1522			})
1523		}
1524		c.Println(x.flagErrorBuf)
1525		if x.HasSubCommands() {
1526			for _, y := range x.commands {
1527				debugflags(y)
1528			}
1529		}
1530	}
1531
1532	debugflags(c)
1533}
1534
1535// Name returns the command's name: the first word in the use line.
1536func (c *Command) Name() string {
1537	name := c.Use
1538	i := strings.Index(name, " ")
1539	if i >= 0 {
1540		name = name[:i]
1541	}
1542	return name
1543}
1544
1545// HasAlias determines if a given string is an alias of the command.
1546func (c *Command) HasAlias(s string) bool {
1547	for _, a := range c.Aliases {
1548		if commandNameMatches(a, s) {
1549			return true
1550		}
1551	}
1552	return false
1553}
1554
1555// CalledAs returns the command name or alias that was used to invoke
1556// this command or an empty string if the command has not been called.
1557func (c *Command) CalledAs() string {
1558	if c.commandCalledAs.called {
1559		return c.commandCalledAs.name
1560	}
1561	return ""
1562}
1563
1564// hasNameOrAliasPrefix returns true if the Name or any of aliases start
1565// with prefix
1566func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
1567	if strings.HasPrefix(c.Name(), prefix) {
1568		c.commandCalledAs.name = c.Name()
1569		return true
1570	}
1571	for _, alias := range c.Aliases {
1572		if strings.HasPrefix(alias, prefix) {
1573			c.commandCalledAs.name = alias
1574			return true
1575		}
1576	}
1577	return false
1578}
1579
1580// NameAndAliases returns a list of the command name and all aliases
1581func (c *Command) NameAndAliases() string {
1582	return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
1583}
1584
1585// HasExample determines if the command has example.
1586func (c *Command) HasExample() bool {
1587	return len(c.Example) > 0
1588}
1589
1590// Runnable determines if the command is itself runnable.
1591func (c *Command) Runnable() bool {
1592	return c.Run != nil || c.RunE != nil
1593}
1594
1595// HasSubCommands determines if the command has children commands.
1596func (c *Command) HasSubCommands() bool {
1597	return len(c.commands) > 0
1598}
1599
1600// IsAvailableCommand determines if a command is available as a non-help command
1601// (this includes all non deprecated/hidden commands).
1602func (c *Command) IsAvailableCommand() bool {
1603	if len(c.Deprecated) != 0 || c.Hidden {
1604		return false
1605	}
1606
1607	if c.HasParent() && c.Parent().helpCommand == c {
1608		return false
1609	}
1610
1611	if c.Runnable() || c.HasAvailableSubCommands() {
1612		return true
1613	}
1614
1615	return false
1616}
1617
1618// IsAdditionalHelpTopicCommand determines if a command is an additional
1619// help topic command; additional help topic command is determined by the
1620// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that
1621// are runnable/hidden/deprecated.
1622// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.
1623func (c *Command) IsAdditionalHelpTopicCommand() bool {
1624	// if a command is runnable, deprecated, or hidden it is not a 'help' command
1625	if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
1626		return false
1627	}
1628
1629	// if any non-help sub commands are found, the command is not a 'help' command
1630	for _, sub := range c.commands {
1631		if !sub.IsAdditionalHelpTopicCommand() {
1632			return false
1633		}
1634	}
1635
1636	// the command either has no sub commands, or no non-help sub commands
1637	return true
1638}
1639
1640// HasHelpSubCommands determines if a command has any available 'help' sub commands
1641// that need to be shown in the usage/help default template under 'additional help
1642// topics'.
1643func (c *Command) HasHelpSubCommands() bool {
1644	// return true on the first found available 'help' sub command
1645	for _, sub := range c.commands {
1646		if sub.IsAdditionalHelpTopicCommand() {
1647			return true
1648		}
1649	}
1650
1651	// the command either has no sub commands, or no available 'help' sub commands
1652	return false
1653}
1654
1655// HasAvailableSubCommands determines if a command has available sub commands that
1656// need to be shown in the usage/help default template under 'available commands'.
1657func (c *Command) HasAvailableSubCommands() bool {
1658	// return true on the first found available (non deprecated/help/hidden)
1659	// sub command
1660	for _, sub := range c.commands {
1661		if sub.IsAvailableCommand() {
1662			return true
1663		}
1664	}
1665
1666	// the command either has no sub commands, or no available (non deprecated/help/hidden)
1667	// sub commands
1668	return false
1669}
1670
1671// HasParent determines if the command is a child command.
1672func (c *Command) HasParent() bool {
1673	return c.parent != nil
1674}
1675
1676// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist.
1677func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
1678	return c.globNormFunc
1679}
1680
1681// Flags returns the complete FlagSet that applies
1682// to this command (local and persistent declared here and by all parents).
1683func (c *Command) Flags() *flag.FlagSet {
1684	if c.flags == nil {
1685		c.flags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1686		if c.flagErrorBuf == nil {
1687			c.flagErrorBuf = new(bytes.Buffer)
1688		}
1689		c.flags.SetOutput(c.flagErrorBuf)
1690	}
1691
1692	return c.flags
1693}
1694
1695// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.
1696// This function does not modify the flags of the current command, it's purpose is to return the current state.
1697func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
1698	persistentFlags := c.PersistentFlags()
1699
1700	out := flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1701	c.LocalFlags().VisitAll(func(f *flag.Flag) {
1702		if persistentFlags.Lookup(f.Name) == nil {
1703			out.AddFlag(f)
1704		}
1705	})
1706	return out
1707}
1708
1709// LocalFlags returns the local FlagSet specifically set in the current command.
1710// This function does not modify the flags of the current command, it's purpose is to return the current state.
1711func (c *Command) LocalFlags() *flag.FlagSet {
1712	c.mergePersistentFlags()
1713
1714	if c.lflags == nil {
1715		c.lflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1716		if c.flagErrorBuf == nil {
1717			c.flagErrorBuf = new(bytes.Buffer)
1718		}
1719		c.lflags.SetOutput(c.flagErrorBuf)
1720	}
1721	c.lflags.SortFlags = c.Flags().SortFlags
1722	if c.globNormFunc != nil {
1723		c.lflags.SetNormalizeFunc(c.globNormFunc)
1724	}
1725
1726	addToLocal := func(f *flag.Flag) {
1727		// Add the flag if it is not a parent PFlag, or it shadows a parent PFlag
1728		if c.lflags.Lookup(f.Name) == nil && f != c.parentsPflags.Lookup(f.Name) {
1729			c.lflags.AddFlag(f)
1730		}
1731	}
1732	c.Flags().VisitAll(addToLocal)
1733	c.PersistentFlags().VisitAll(addToLocal)
1734	return c.lflags
1735}
1736
1737// InheritedFlags returns all flags which were inherited from parent commands.
1738// This function does not modify the flags of the current command, it's purpose is to return the current state.
1739func (c *Command) InheritedFlags() *flag.FlagSet {
1740	c.mergePersistentFlags()
1741
1742	if c.iflags == nil {
1743		c.iflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1744		if c.flagErrorBuf == nil {
1745			c.flagErrorBuf = new(bytes.Buffer)
1746		}
1747		c.iflags.SetOutput(c.flagErrorBuf)
1748	}
1749
1750	local := c.LocalFlags()
1751	if c.globNormFunc != nil {
1752		c.iflags.SetNormalizeFunc(c.globNormFunc)
1753	}
1754
1755	c.parentsPflags.VisitAll(func(f *flag.Flag) {
1756		if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
1757			c.iflags.AddFlag(f)
1758		}
1759	})
1760	return c.iflags
1761}
1762
1763// NonInheritedFlags returns all flags which were not inherited from parent commands.
1764// This function does not modify the flags of the current command, it's purpose is to return the current state.
1765func (c *Command) NonInheritedFlags() *flag.FlagSet {
1766	return c.LocalFlags()
1767}
1768
1769// PersistentFlags returns the persistent FlagSet specifically set in the current command.
1770func (c *Command) PersistentFlags() *flag.FlagSet {
1771	if c.pflags == nil {
1772		c.pflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1773		if c.flagErrorBuf == nil {
1774			c.flagErrorBuf = new(bytes.Buffer)
1775		}
1776		c.pflags.SetOutput(c.flagErrorBuf)
1777	}
1778	return c.pflags
1779}
1780
1781// ResetFlags deletes all flags from command.
1782func (c *Command) ResetFlags() {
1783	c.flagErrorBuf = new(bytes.Buffer)
1784	c.flagErrorBuf.Reset()
1785	c.flags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1786	c.flags.SetOutput(c.flagErrorBuf)
1787	c.pflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1788	c.pflags.SetOutput(c.flagErrorBuf)
1789
1790	c.lflags = nil
1791	c.iflags = nil
1792	c.parentsPflags = nil
1793}
1794
1795// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
1796func (c *Command) HasFlags() bool {
1797	return c.Flags().HasFlags()
1798}
1799
1800// HasPersistentFlags checks if the command contains persistent flags.
1801func (c *Command) HasPersistentFlags() bool {
1802	return c.PersistentFlags().HasFlags()
1803}
1804
1805// HasLocalFlags checks if the command has flags specifically declared locally.
1806func (c *Command) HasLocalFlags() bool {
1807	return c.LocalFlags().HasFlags()
1808}
1809
1810// HasInheritedFlags checks if the command has flags inherited from its parent command.
1811func (c *Command) HasInheritedFlags() bool {
1812	return c.InheritedFlags().HasFlags()
1813}
1814
1815// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire
1816// structure) which are not hidden or deprecated.
1817func (c *Command) HasAvailableFlags() bool {
1818	return c.Flags().HasAvailableFlags()
1819}
1820
1821// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.
1822func (c *Command) HasAvailablePersistentFlags() bool {
1823	return c.PersistentFlags().HasAvailableFlags()
1824}
1825
1826// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden
1827// or deprecated.
1828func (c *Command) HasAvailableLocalFlags() bool {
1829	return c.LocalFlags().HasAvailableFlags()
1830}
1831
1832// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are
1833// not hidden or deprecated.
1834func (c *Command) HasAvailableInheritedFlags() bool {
1835	return c.InheritedFlags().HasAvailableFlags()
1836}
1837
1838// Flag climbs up the command tree looking for matching flag.
1839func (c *Command) Flag(name string) (flag *flag.Flag) {
1840	flag = c.Flags().Lookup(name)
1841
1842	if flag == nil {
1843		flag = c.persistentFlag(name)
1844	}
1845
1846	return
1847}
1848
1849// Recursively find matching persistent flag.
1850func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
1851	if c.HasPersistentFlags() {
1852		flag = c.PersistentFlags().Lookup(name)
1853	}
1854
1855	if flag == nil {
1856		c.updateParentsPflags()
1857		flag = c.parentsPflags.Lookup(name)
1858	}
1859	return
1860}
1861
1862// ParseFlags parses persistent flag tree and local flags.
1863func (c *Command) ParseFlags(args []string) error {
1864	if c.DisableFlagParsing {
1865		return nil
1866	}
1867
1868	if c.flagErrorBuf == nil {
1869		c.flagErrorBuf = new(bytes.Buffer)
1870	}
1871	beforeErrorBufLen := c.flagErrorBuf.Len()
1872	c.mergePersistentFlags()
1873
1874	// do it here after merging all flags and just before parse
1875	c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
1876
1877	err := c.Flags().Parse(args)
1878	// Print warnings if they occurred (e.g. deprecated flag messages).
1879	if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
1880		c.Print(c.flagErrorBuf.String())
1881	}
1882
1883	return err
1884}
1885
1886// Parent returns a commands parent command.
1887func (c *Command) Parent() *Command {
1888	return c.parent
1889}
1890
1891// mergePersistentFlags merges c.PersistentFlags() to c.Flags()
1892// and adds missing persistent flags of all parents.
1893func (c *Command) mergePersistentFlags() {
1894	c.updateParentsPflags()
1895	c.Flags().AddFlagSet(c.PersistentFlags())
1896	c.Flags().AddFlagSet(c.parentsPflags)
1897}
1898
1899// updateParentsPflags updates c.parentsPflags by adding
1900// new persistent flags of all parents.
1901// If c.parentsPflags == nil, it makes new.
1902func (c *Command) updateParentsPflags() {
1903	if c.parentsPflags == nil {
1904		c.parentsPflags = flag.NewFlagSet(c.DisplayName(), flag.ContinueOnError)
1905		c.parentsPflags.SetOutput(c.flagErrorBuf)
1906		c.parentsPflags.SortFlags = false
1907	}
1908
1909	if c.globNormFunc != nil {
1910		c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
1911	}
1912
1913	c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
1914
1915	c.VisitParents(func(parent *Command) {
1916		c.parentsPflags.AddFlagSet(parent.PersistentFlags())
1917	})
1918}
1919
1920// commandNameMatches checks if two command names are equal
1921// taking into account case sensitivity according to
1922// EnableCaseInsensitive global configuration.
1923func commandNameMatches(s string, t string) bool {
1924	if EnableCaseInsensitive {
1925		return strings.EqualFold(s, t)
1926	}
1927
1928	return s == t
1929}
1930
1931// tmplFunc holds a template and a function that will execute said template.
1932type tmplFunc struct {
1933	tmpl string
1934	fn   func(io.Writer, interface{}) error
1935}
1936
1937var defaultUsageTemplate = `Usage:{{if .Runnable}}
1938  {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
1939  {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
1940
1941Aliases:
1942  {{.NameAndAliases}}{{end}}{{if .HasExample}}
1943
1944Examples:
1945{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}}
1946
1947Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
1948  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}}
1949
1950{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}}
1951  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}}
1952
1953Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
1954  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
1955
1956Flags:
1957{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
1958
1959Global Flags:
1960{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
1961
1962Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
1963  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
1964
1965Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
1966`
1967
1968// defaultUsageFunc is equivalent to executing defaultUsageTemplate. The two should be changed in sync.
1969func defaultUsageFunc(w io.Writer, in interface{}) error {
1970	c := in.(*Command)
1971	fmt.Fprint(w, "Usage:")
1972	if c.Runnable() {
1973		fmt.Fprintf(w, "\n  %s", c.UseLine())
1974	}
1975	if c.HasAvailableSubCommands() {
1976		fmt.Fprintf(w, "\n  %s [command]", c.CommandPath())
1977	}
1978	if len(c.Aliases) > 0 {
1979		fmt.Fprintf(w, "\n\nAliases:\n")
1980		fmt.Fprintf(w, "  %s", c.NameAndAliases())
1981	}
1982	if c.HasExample() {
1983		fmt.Fprintf(w, "\n\nExamples:\n")
1984		fmt.Fprintf(w, "%s", c.Example)
1985	}
1986	if c.HasAvailableSubCommands() {
1987		cmds := c.Commands()
1988		if len(c.Groups()) == 0 {
1989			fmt.Fprintf(w, "\n\nAvailable Commands:")
1990			for _, subcmd := range cmds {
1991				if subcmd.IsAvailableCommand() || subcmd.Name() == helpCommandName {
1992					fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.Name(), subcmd.NamePadding()), subcmd.Short)
1993				}
1994			}
1995		} else {
1996			for _, group := range c.Groups() {
1997				fmt.Fprintf(w, "\n\n%s", group.Title)
1998				for _, subcmd := range cmds {
1999					if subcmd.GroupID == group.ID && (subcmd.IsAvailableCommand() || subcmd.Name() == helpCommandName) {
2000						fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.Name(), subcmd.NamePadding()), subcmd.Short)
2001					}
2002				}
2003			}
2004			if !c.AllChildCommandsHaveGroup() {
2005				fmt.Fprintf(w, "\n\nAdditional Commands:")
2006				for _, subcmd := range cmds {
2007					if subcmd.GroupID == "" && (subcmd.IsAvailableCommand() || subcmd.Name() == helpCommandName) {
2008						fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.Name(), subcmd.NamePadding()), subcmd.Short)
2009					}
2010				}
2011			}
2012		}
2013	}
2014	if c.HasAvailableLocalFlags() {
2015		fmt.Fprintf(w, "\n\nFlags:\n")
2016		fmt.Fprint(w, trimRightSpace(c.LocalFlags().FlagUsages()))
2017	}
2018	if c.HasAvailableInheritedFlags() {
2019		fmt.Fprintf(w, "\n\nGlobal Flags:\n")
2020		fmt.Fprint(w, trimRightSpace(c.InheritedFlags().FlagUsages()))
2021	}
2022	if c.HasHelpSubCommands() {
2023		fmt.Fprintf(w, "\n\nAdditional help topcis:")
2024		for _, subcmd := range c.Commands() {
2025			if subcmd.IsAdditionalHelpTopicCommand() {
2026				fmt.Fprintf(w, "\n  %s %s", rpad(subcmd.CommandPath(), subcmd.CommandPathPadding()), subcmd.Short)
2027			}
2028		}
2029	}
2030	if c.HasAvailableSubCommands() {
2031		fmt.Fprintf(w, "\n\nUse \"%s [command] --help\" for more information about a command.", c.CommandPath())
2032	}
2033	fmt.Fprintln(w)
2034	return nil
2035}
2036
2037var defaultHelpTemplate = `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}
2038
2039{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
2040
2041// defaultHelpFunc is equivalent to executing defaultHelpTemplate. The two should be changed in sync.
2042func defaultHelpFunc(w io.Writer, in interface{}) error {
2043	c := in.(*Command)
2044	usage := c.Long
2045	if usage == "" {
2046		usage = c.Short
2047	}
2048	usage = trimRightSpace(usage)
2049	if usage != "" {
2050		fmt.Fprintln(w, usage)
2051		fmt.Fprintln(w)
2052	}
2053	if c.Runnable() || c.HasSubCommands() {
2054		fmt.Fprint(w, c.UsageString())
2055	}
2056	return nil
2057}
2058
2059var defaultVersionTemplate = `{{with .DisplayName}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}}
2060`
2061
2062// defaultVersionFunc is equivalent to executing defaultVersionTemplate. The two should be changed in sync.
2063func defaultVersionFunc(w io.Writer, in interface{}) error {
2064	c := in.(*Command)
2065	_, err := fmt.Fprintf(w, "%s version %s\n", c.DisplayName(), c.Version)
2066	return err
2067}