func (c Command) Run(ctx *Context) (err error) {
	if len(c.Subcommands) > 0 {
		return c.startApp(ctx)
	}
	if !c.HideHelp && (HelpFlag != BoolFlag{}) {
		c.Flags = append(
			c.Flags,
			HelpFlag,
		)
	}
	if ctx.App.EnableBashCompletion {
		c.Flags = append(c.Flags, BashCompletionFlag)
	}
	set := flagSet(c.Name, c.Flags)
	set.SetOutput(ioutil.Discard)
	if !c.SkipFlagParsing {
		firstFlagIndex := -1
		terminatorIndex := -1
		for index, arg := range ctx.Args() {
			if arg == "--" {
				terminatorIndex = index
				break
			} else if arg == "-" {
				continue
			} else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
				firstFlagIndex = index
			}
		}
		if firstFlagIndex > -1 {
			args := ctx.Args()
			regularArgs := make([]string, len(args[1:firstFlagIndex]))
			copy(regularArgs, args[1:firstFlagIndex])
			var flagArgs []string
			if terminatorIndex > -1 {
				flagArgs = args[firstFlagIndex:terminatorIndex]
				regularArgs = append(regularArgs, args[terminatorIndex:]...)
			} else {
				flagArgs = args[firstFlagIndex:]
			}
			err = set.Parse(append(flagArgs, regularArgs...))
		} else {
			err = set.Parse(ctx.Args().Tail())
		}
	} else {
		if c.SkipFlagParsing {
			err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
		}
	}
	if err != nil {
		if c.OnUsageError != nil {
			err := c.OnUsageError(ctx, err)
			return err
		} else {
			fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")
			fmt.Fprintln(ctx.App.Writer)
			ShowCommandHelp(ctx, c.Name)
			return err
		}
	}
	nerr := normalizeFlags(c.Flags, set)
	if nerr != nil {
		fmt.Fprintln(ctx.App.Writer, nerr)
		fmt.Fprintln(ctx.App.Writer)
		ShowCommandHelp(ctx, c.Name)
		return nerr
	}
	context := NewContext(ctx.App, set, ctx)
	if checkCommandCompletions(context, c.Name) {
		return nil
	}
	if checkCommandHelp(context, c.Name) {
		return nil
	}
	if c.After != nil {
		defer func() {
			afterErr := c.After(context)
			if afterErr != nil {
				if err != nil {
					err = NewMultiError(err, afterErr)
				} else {
					err = afterErr
				}
			}
		}()
	}
	if c.Before != nil {
		err := c.Before(context)
		if err != nil {
			fmt.Fprintln(ctx.App.Writer, err)
			fmt.Fprintln(ctx.App.Writer)
			ShowCommandHelp(ctx, c.Name)
			return err
		}
	}
	context.Command = c
	c.Action(context)
	return nil
}
Invokes the command given the context, parses ctx.Args() to generate command-specific flags
package cli
import (
	"fmt"
	"io/ioutil"
	"strings"
)
type Command struct {
	Name string
	ShortName string
	Aliases []string
	Usage string
	UsageText string
	Description string
	ArgsUsage string
	BashComplete func(context *Context)
	Before func(context *Context) error
	After func(context *Context) error
	Action func(context *Context)
	OnUsageError func(context *Context, err error) error
	Subcommands []Command
	Flags []Flag
	SkipFlagParsing bool
	HideHelp bool
	HelpName        string
	commandNamePath []string
}
func (c Command) FullName() string {
	if c.commandNamePath == nil {
		return c.Name
	}
	return strings.Join(c.commandNamePath, " ")
}